From a4abeaf980a5cdc5ea4079d571feab5a34c6948b Mon Sep 17 00:00:00 2001 From: "Yan, Like" Date: Tue, 2 Jul 2019 16:39:19 +0800 Subject: [PATCH] hv: enforce no interrupt to RT VM via vlapic once lapic pt Because we depend on guest OS to switch x2apic mode to enable lapic pass-thru, vlapic is working at the early stage of booting, eg: in virtual boot loader. After lapic pass-thru enabled, no interrupt should be injected via vlapic any more. This commit resets the vlapic to clear the pending status and adds ptapic_ops to enforce that no more interrupt accepted/injected via vlapic. Tracked-On: #3227 Signed-off-by: Yan, Like --- hypervisor/arch/x86/guest/vlapic.c | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index c82e67e04..bca1bdbfb 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -1699,6 +1699,39 @@ uint64_t vlapic_get_apicbase(const struct acrn_vlapic *vlapic) return vlapic->msr_apicbase; } +static void ptapic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, __unused bool level) +{ + pr_err("Invalid op %s, VM%u, vCPU%u, vector %u", __func__, + vlapic->vm->vm_id, vlapic->vcpu->vcpu_id, vector); +} + +static bool ptapic_inject_intr(struct acrn_vlapic *vlapic, + __unused bool guest_irq_enabled, __unused bool injected) +{ + pr_err("Invalid op %s, VM%u, vCPU%u", __func__, vlapic->vm->vm_id, vlapic->vcpu->vcpu_id); + return injected; +} + +static bool ptapic_has_pending_delivery_intr(__unused struct acrn_vcpu *vcpu) +{ + return false; +} + +static bool ptapic_invalid(__unused uint32_t offset) +{ + return false; +} + +static const struct acrn_apicv_ops ptapic_ops = { + .accept_intr = ptapic_accept_intr, + .inject_intr = ptapic_inject_intr, + .has_pending_delivery_intr = ptapic_has_pending_delivery_intr, + .apic_read_access_may_valid = ptapic_invalid, + .apic_write_access_may_valid = ptapic_invalid, + .x2apic_read_msr_may_valid = ptapic_invalid, + .x2apic_write_msr_may_valid = ptapic_invalid, +}; + int32_t vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new) { int32_t ret = 0; @@ -1722,6 +1755,9 @@ int32_t vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new) if (change_in_vlapic_mode) { if ((new & APICBASE_LAPIC_MODE) == (APICBASE_XAPIC | APICBASE_X2APIC)) { + if (is_lapic_pt_configured(vcpu->vm)) { + vlapic_reset(vlapic, &ptapic_ops); + } vlapic->msr_apicbase = new; vlapic_build_x2apic_id(vlapic); switch_apicv_mode_x2apic(vlapic->vcpu);