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:
Oleksii Kurochko authored and Jan Beulich committed 2026-09-21 10:08:21 +02:00
1 parent 24a61ce264
commit bbbe70852a
3 files changed
+59

No files matched your search

+35
View File
@@ -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.
*
+2
View File
@@ -54,6 +54,8 @@ struct arch_vcpu {
struct vtimer vtimer;
struct vimsic_state *vimsic_state;
register_t hcounteren;
register_t hedeleg;
register_t hideleg;
+22
View File
@@ -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 */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.