|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/vlapic: Don't change ICR on x2APIC SELF_IPI write
The Intel SDM (Vol 3A-13.12.11, June 2026) says
> The semantics of sending a self-IPI via the SELF IPI register
> are identical to sending a self targeted edge triggered fixed
> interrupt with the specified vector.
However, this is not expected to alter the ICR register.
Fix the Xen behavior by sending the Self-IPI directly instead of
emulating it by modifying ICR register.
Fixes: 21c4d089ba2a ("x86 hvm: x2APIC emulation")
Assisted-by: Claude Fable 5.1
Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
---
Linux/KVM has a similar patch :
KVM: x86: Do not change ICR on write to APIC_SELF_IPI
https://github.com/torvalds/linux/commit/d22a81b304a27fca6124174a8e842e826c193466
xen/arch/x86/hvm/vlapic.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index 885f5d304b..bb105225e2 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -963,6 +963,17 @@ static int cf_check vlapic_mmio_write(
return X86EMUL_OKAY;
}
+/*
+ * A write to the SELF IPI register sends a fixed, edge triggered IPI with
+ * the given vector to the local APIC itself. Unlike an ICR write it doesn't
+ * update the ICR, which is guest visible, in x2APIC mode even without any
+ * intervention by Xen when APIC-register virtualization is in use.
+ */
+static void vlapic_self_ipi(struct vlapic *vlapic, uint32_t val)
+{
+ vlapic_ipi(vlapic, APIC_DEST_SELF | (val & APIC_VECTOR_MASK), 0);
+}
+
int vlapic_apicv_write(struct vcpu *v, unsigned int offset)
{
struct vlapic *vlapic = vcpu_vlapic(v);
@@ -973,8 +984,9 @@ int vlapic_apicv_write(struct vcpu *v, unsigned int offset)
if ( offset != APIC_SELF_IPI )
return X86EMUL_UNHANDLEABLE;
- offset = APIC_ICR;
- val = APIC_DEST_SELF | (val & APIC_VECTOR_MASK);
+ vlapic_self_ipi(vlapic, val);
+
+ return X86EMUL_OKAY;
}
vlapic_reg_write(v, offset, val);
@@ -1050,9 +1062,8 @@ int guest_wrmsr_x2apic(struct vcpu *v, uint32_t msr,
uint64_t val)
case APIC_SELF_IPI:
if ( val & ~APIC_VECTOR_MASK )
return X86EMUL_EXCEPTION;
- offset = APIC_ICR;
- val = APIC_DEST_SELF | (val & APIC_VECTOR_MASK);
- break;
+ vlapic_self_ipi(vlapic, val);
+ return X86EMUL_OKAY;
case APIC_EOI:
case APIC_ESR:
--
2.56.0
--
Teddy Astie | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |