mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
KVM: arm64: gic-v5: Add GIC VDPEND hyp call
With PPIs, their state is injected via the ICH_PPI_x_EL2 system registers. For SPIs and LPIs, there are no such registers as these would limit the number of interrupts significantly. Instead, SPI and LPI pending state can be managed from the hypervisor using the GIC VDPEND instruction. This provides a way to set an SPI or LPI for a VM as pending or non-pending, i.e., to inject interrupts into a guest. This system instruction is only executable from EL2, and therefore must be wrapped in a hypercall for NVHE/hVHE configurations. With pKVM this hypercall is explicitly a no-op as we currently don't support the combination of GICv5 and pKVM. Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com> Link: https://patch.msgid.link/20260904113404.4051341-26-sascha.bischoff@arm.com Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
parent
414e17f21c
commit
32b253d304
|
|
@ -89,6 +89,7 @@ enum __kvm_host_smccc_func {
|
|||
__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v5_make_resident,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v5_make_non_resident,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v5_vdpend,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v5_save_apr,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v5_restore_vmcr_apr,
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ void __vgic_v5_save_ppi_state(struct vgic_v5_cpu_if *cpu_if);
|
|||
void __vgic_v5_restore_ppi_state(struct vgic_v5_cpu_if *cpu_if);
|
||||
void __vgic_v5_save_state(struct vgic_v5_cpu_if *cpu_if);
|
||||
void __vgic_v5_restore_state(struct vgic_v5_cpu_if *cpu_if);
|
||||
void __vgic_v5_vdpend(u32 intid, bool pending, u16 vm);
|
||||
|
||||
#ifdef __KVM_NVHE_HYPERVISOR__
|
||||
void __timer_enable_traps(struct kvm_vcpu *vcpu);
|
||||
|
|
|
|||
|
|
@ -919,6 +919,18 @@ static void handle___vgic_v5_restore_vmcr_apr(struct kvm_cpu_context *host_ctxt)
|
|||
__vgic_v5_restore_vmcr_apr(kern_hyp_va(cpu_if));
|
||||
}
|
||||
|
||||
static void handle___vgic_v5_vdpend(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
DECLARE_REG(u32, intid, host_ctxt, 1);
|
||||
DECLARE_REG(bool, pending, host_ctxt, 2);
|
||||
DECLARE_REG(u16, vm, host_ctxt, 3);
|
||||
|
||||
if (unlikely(is_protected_kvm_enabled()))
|
||||
return;
|
||||
|
||||
__vgic_v5_vdpend(intid, pending, vm);
|
||||
}
|
||||
|
||||
typedef void (*hcall_t)(struct kvm_cpu_context *);
|
||||
|
||||
#define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x
|
||||
|
|
@ -954,6 +966,7 @@ static const hcall_t host_hcall[] = {
|
|||
HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
|
||||
HANDLE_FUNC(__vgic_v5_make_resident),
|
||||
HANDLE_FUNC(__vgic_v5_make_non_resident),
|
||||
HANDLE_FUNC(__vgic_v5_vdpend),
|
||||
HANDLE_FUNC(__vgic_v5_save_apr),
|
||||
HANDLE_FUNC(__vgic_v5_restore_vmcr_apr),
|
||||
|
||||
|
|
|
|||
|
|
@ -149,3 +149,13 @@ void __vgic_v5_restore_state(struct vgic_v5_cpu_if *cpu_if)
|
|||
{
|
||||
write_sysreg_s(cpu_if->vgic_icsr, SYS_ICC_ICSR_EL1);
|
||||
}
|
||||
|
||||
void __vgic_v5_vdpend(u32 intid, bool pending, u16 vm)
|
||||
{
|
||||
u64 value;
|
||||
|
||||
value = intid & (GICV5_GIC_VDPEND_ID_MASK | GICV5_GIC_VDPEND_TYPE_MASK);
|
||||
value |= FIELD_PREP(GICV5_GIC_VDPEND_PENDING_MASK, pending);
|
||||
value |= FIELD_PREP(GICV5_GIC_VDPEND_VM_MASK, vm);
|
||||
gic_insn(value, VDPEND);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user