mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/riscv: introduce per-vCPU IMSIC state
Each vCPU interacting with the IMSIC requires state to track the associated guest interrupt file and its backing context. Introduce a per-vCPU structure to hold IMSIC-related state, including the guest interrupt file identifier and the CPU providing the backing VS-file. Access to the guest file identifier is protected by a lock. Initialize this structure during vCPU setup and store it in arch_vcpu. The initial state marks the VS-file as software-backed until it becomes associated with a physical CPU. Add helper to retrieve the guest interrupt file identifier: - vcpu_guest_file_id() is going to be used during update of APLIC's target register with the pair of information <guest_file_id, cpu_id> (to have MSI delivery mode work properly) when guest is trying to access vAPLIC's target register. It will be used in the follow up patches. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
24a61ce264
commit
bbbe70852a
3 files changed
+59
No files matched your search
@@ -16,6 +16,7 @@
|
||||
#include <xen/errno.h>
|
||||
#include <xen/init.h>
|
||||
#include <xen/macros.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/smp.h>
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/xvmalloc.h>
|
||||
@@ -56,6 +57,11 @@ do { \
|
||||
csr_clear(CSR_SIREG, v); \
|
||||
} while (0)
|
||||
|
||||
unsigned int vcpu_guest_file_id(const struct vcpu *v)
|
||||
{
|
||||
return ACCESS_ONCE(v->arch.vimsic_state->guest_file_id);
|
||||
}
|
||||
|
||||
void __init imsic_ids_local_delivery(bool enable)
|
||||
{
|
||||
if ( enable )
|
||||
@@ -312,6 +318,35 @@ static int imsic_parse_node(const struct dt_device_node *node,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vcpu_imsic_init(struct vcpu *v)
|
||||
{
|
||||
struct vimsic_state *imsic_state;
|
||||
|
||||
/* Allocate IMSIC context */
|
||||
imsic_state = xvzalloc(struct vimsic_state);
|
||||
if ( !imsic_state )
|
||||
return -ENOMEM;
|
||||
|
||||
/* Setup IMSIC context */
|
||||
rwlock_init(&imsic_state->vsfile_lock);
|
||||
|
||||
/*
|
||||
* xvzalloc() already cleared the context, so guest_file_id == 0, i.e. the
|
||||
* always-available s/w IMSIC VS-file. Only vsfile_cpu needs an explicit
|
||||
* initializer as its s/w VS-file value is NR_CPUS rather than 0.
|
||||
*/
|
||||
imsic_state->vsfile_cpu = NR_CPUS;
|
||||
|
||||
v->arch.vimsic_state = imsic_state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vcpu_imsic_deinit(struct vcpu *v)
|
||||
{
|
||||
XVFREE(v->arch.vimsic_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the imsic_cfg structure based on the IMSIC DT node.
|
||||
*
|
||||
|
||||
@@ -54,6 +54,8 @@ struct arch_vcpu {
|
||||
|
||||
struct vtimer vtimer;
|
||||
|
||||
struct vimsic_state *vimsic_state;
|
||||
|
||||
register_t hcounteren;
|
||||
register_t hedeleg;
|
||||
register_t hideleg;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#ifndef ASM_RISCV_IMSIC_H
|
||||
#define ASM_RISCV_IMSIC_H
|
||||
|
||||
#include <xen/rwlock.h>
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/stdbool.h>
|
||||
#include <xen/types.h>
|
||||
@@ -61,7 +62,24 @@ struct imsic_config {
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
struct vimsic_state {
|
||||
/* IMSIC VS-file */
|
||||
rwlock_t vsfile_lock;
|
||||
/*
|
||||
* s/w IMSIC VS-file -> guest_file_id == 0
|
||||
* h/w IMSIC VS-file -> guest_file_id > 0
|
||||
*/
|
||||
unsigned int guest_file_id;
|
||||
/*
|
||||
* s/w IMSIC VS-file -> vsfile_cpu == NR_CPUS
|
||||
* h/w IMSIC VS-file -> vsfile_cpu < NR_CPUS
|
||||
*/
|
||||
unsigned int vsfile_cpu;
|
||||
};
|
||||
|
||||
struct dt_device_node;
|
||||
struct vcpu;
|
||||
|
||||
int imsic_init(const struct dt_device_node *node);
|
||||
|
||||
const struct imsic_config *imsic_get_config(void);
|
||||
@@ -71,4 +89,8 @@ void imsic_irq_disable(unsigned int hwirq);
|
||||
|
||||
void imsic_ids_local_delivery(bool enable);
|
||||
|
||||
int vcpu_imsic_init(struct vcpu *v);
|
||||
void vcpu_imsic_deinit(struct vcpu *v);
|
||||
unsigned int vcpu_guest_file_id(const struct vcpu *v);
|
||||
|
||||
#endif /* ASM_RISCV_IMSIC_H */
|
||||