[PATCH v1 07/17] xen/riscv: introduce vCPU AIA initialization
Oleksii Kurochko <[email protected]>
| Newsgroups | org.xenproject.lists.xen-devel |
|---|---|
| Message-ID | <b3aca8278dfd70bf6ce888bfcb0a3fbc32bb4971.1784560663.git.oleksii.kurochko@gmail.com> |
Introduce vcpu_aia_init() to initialize the AIA-related state needed for a vCPU to have a working guest interrupt file. A guest (VS) interrupt file must be mapped to one of a pCPU's hardware interrupt files (if they exist), so the pCPU a vCPU will actually run on needs to be known first. arch_vcpu_create() is therefore not a suitable place to call vcpu_aia_init(), since the pCPU assigned to a vCPU can still change before it is first scheduled. To avoid reassigning the VS interrupt file id and remapping it to a different pCPU's hardware interrupt file, vcpu_aia_init() will instead be called from a later point in the scheduling path (e.g. continue_to_new_vcpu()), to be introduced in a follow-up patch. Since it will end up being called from a non-__init context, it is not itself marked __init. Introduce imsic_update_state() to update a vCPU's guest IMSIC state (the guest interrupt file id and the pCPU whose hardware interrupt file it is mapped to) as a single consistent unit. This state can be read concurrently, e.g. by a future helper that checks whether a vCPU has a pending IMSIC interrupt, though no such consumer exists yet at this stage - so it is protected by a lock. Signed-off-by: Oleksii Kurochko <[email protected]> --- xen/arch/riscv/aia.c | 30 ++++++++++++++++++++++++++++++ xen/arch/riscv/imsic.c | 13 +++++++++++++ xen/arch/riscv/include/asm/aia.h | 2 ++ xen/arch/riscv/include/asm/imsic.h | 2 ++ 4 files changed, 47 insertions(+) diff --git a/xen/arch/riscv/aia.c b/xen/arch/riscv/aia.c index 4f7f46f58f0b..ed19600d4644 100644 --- a/xen/arch/riscv/aia.c +++ b/xen/arch/riscv/aia.c @@ -14,6 +14,7 @@ #include <asm/cpufeature.h> #include <asm/csr.h> #include <asm/current.h> +#include <asm/imsic.h> struct vgein_ctrl { unsigned long bmp; @@ -36,6 +37,35 @@ bool aia_usable(void) return _aia_usable; } +void vcpu_aia_init(struct vcpu *v) +{ + unsigned int new_vsfile_id; + int rc; + + if ( !aia_usable() ) + return; + + new_vsfile_id = vgein_assign(v); + + /* + * vgein_assign() returns 0 when no free h/w guest interrupt file is + * available (including GEILEN == 0); imsic_map_guest_file() maps nothing + * in that case. + */ + rc = imsic_map_guest_file(v, new_vsfile_id); + if ( rc ) + { + /* Can't continue w/o correctly mapped IMSIC interrupt file */ + domain_crash(v->domain); + return; + } + + vcpu_guest_cpu_user_regs(v)->hstatus |= + MASK_INSR(new_vsfile_id, HSTATUS_VGEIN); + + imsic_update_state(v, new_vsfile_id); +} + static int vgein_init(unsigned int cpu) { struct vgein_ctrl *vgein = &per_cpu(vgein, cpu); diff --git a/xen/arch/riscv/imsic.c b/xen/arch/riscv/imsic.c index c5ae74e456e8..2a792e756c4e 100644 --- a/xen/arch/riscv/imsic.c +++ b/xen/arch/riscv/imsic.c @@ -83,6 +83,19 @@ unsigned int vcpu_guest_file_id(const struct vcpu *v) return ACCESS_ONCE(v->arch.vimsic_state->guest_file_id); } +void imsic_update_state(struct vcpu *v, unsigned int guest_file_id) +{ + unsigned long flags; + struct vimsic_state *vimsic_state = v->arch.vimsic_state; + unsigned long pcpu = ( !guest_file_id ) ? + NR_CPUS : cpuid_to_hartid(v->processor); + + write_lock_irqsave(&vimsic_state->vsfile_lock, flags); + vimsic_state->guest_file_id = guest_file_id; + vimsic_state->vsfile_pcpu = pcpu; + write_unlock_irqrestore(&vimsic_state->vsfile_lock, flags); +} + void __init imsic_ids_local_delivery(bool enable) { if ( enable ) diff --git a/xen/arch/riscv/include/asm/aia.h b/xen/arch/riscv/include/asm/aia.h index c67be0069a1d..2aef24cad4c0 100644 --- a/xen/arch/riscv/include/asm/aia.h +++ b/xen/arch/riscv/include/asm/aia.h @@ -15,4 +15,6 @@ void aia_init(void); unsigned int vgein_assign(struct vcpu *v); void vgein_release(struct vcpu *v, unsigned int vgein_id); +void vcpu_aia_init(struct vcpu *v); + #endif /* RISCV_AIA_H */ diff --git a/xen/arch/riscv/include/asm/imsic.h b/xen/arch/riscv/include/asm/imsic.h index f2c649517fd1..8e3797690f99 100644 --- a/xen/arch/riscv/include/asm/imsic.h +++ b/xen/arch/riscv/include/asm/imsic.h @@ -104,6 +104,8 @@ int vcpu_imsic_init(struct vcpu *v); void vcpu_imsic_deinit(struct vcpu *v); unsigned int vcpu_guest_file_id(const struct vcpu *v); +void imsic_update_state(struct vcpu *v, unsigned int guest_file_id); + int vimsic_make_domu_dt_node(struct kernel_info *kinfo, unsigned int *phandle); int imsic_map_guest_file(struct vcpu *v, unsigned int vsfile_id); -- 2.54.0