Message ID | 20250317184044.560367-1-andrew.cooper3@citrix.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | x86/emul: Emulate %cr8 accesses | expand |
On 17.03.2025 19:40, Andrew Cooper wrote: > Petr reports: > > (XEN) MMIO emulation failed (1): d12v1 64bit @ 0010:fffff8057ba7dfbf -> 45 0f 20 c2 ... > > during introspection. > > This is MOV %cr8, which is wired up for hvm_mov_{to,from}_cr(); the VMExit > fastpaths, but not for the full emulation slowpaths. Wire %cr8 up in > hvmemul_{read,write}_cr() too. > > Reported-by: Petr Beneš <w1benny@gmail.com> > Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Like in a few other cases I guess there's no good Fixes: tag to use, as the omission must have been there basically forever. > --- a/xen/arch/x86/hvm/emulate.c > +++ b/xen/arch/x86/hvm/emulate.c > @@ -2285,6 +2285,11 @@ static int cf_check hvmemul_read_cr( > *val = current->arch.hvm.guest_cr[reg]; > TRACE(TRC_HVM_CR_READ64, reg, *val, *val >> 32); > return X86EMUL_OKAY; > + > + case 8: > + *val = (vlapic_get_reg(vcpu_vlapic(current), APIC_TASKPRI) & 0xf0) >> 4; I think it would be nice to add a #define to apicdef.h that could be utilized to use MASK_EXTR() here (and MASK_INSR() below). Otherwise even without such a #define I'd like to ask that we use the two macros here. > + return X86EMUL_OKAY; > + > default: > break; > } > @@ -2325,6 +2330,11 @@ static int cf_check hvmemul_write_cr( > rc = hvm_set_cr4(val, true); > break; > > + case 8: > + vlapic_set_reg(vcpu_vlapic(current), APIC_TASKPRI, ((val & 0x0f) << 4)); > + rc = X86EMUL_OKAY; > + break; Both SDM and PM say #GP upon writes to reserved bits, without there being a place where it is said which bits are reserved. Don't we therefore need to treat bits 4 and up as must-be-zero, implying that all bits which have no meaning are reserved? Jan
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index dbf6b5543adf..852240b29d74 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -2285,6 +2285,11 @@ static int cf_check hvmemul_read_cr( *val = current->arch.hvm.guest_cr[reg]; TRACE(TRC_HVM_CR_READ64, reg, *val, *val >> 32); return X86EMUL_OKAY; + + case 8: + *val = (vlapic_get_reg(vcpu_vlapic(current), APIC_TASKPRI) & 0xf0) >> 4; + return X86EMUL_OKAY; + default: break; } @@ -2325,6 +2330,11 @@ static int cf_check hvmemul_write_cr( rc = hvm_set_cr4(val, true); break; + case 8: + vlapic_set_reg(vcpu_vlapic(current), APIC_TASKPRI, ((val & 0x0f) << 4)); + rc = X86EMUL_OKAY; + break; + default: rc = X86EMUL_UNHANDLEABLE; break;
Petr reports: (XEN) MMIO emulation failed (1): d12v1 64bit @ 0010:fffff8057ba7dfbf -> 45 0f 20 c2 ... during introspection. This is MOV %cr8, which is wired up for hvm_mov_{to,from}_cr(); the VMExit fastpaths, but not for the full emulation slowpaths. Wire %cr8 up in hvmemul_{read,write}_cr() too. Reported-by: Petr Beneš <w1benny@gmail.com> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> --- CC: Jan Beulich <JBeulich@suse.com> CC: Roger Pau Monné <roger.pau@citrix.com> CC: Petr Beneš <w1benny@gmail.com> Like the fastpaths, this depends on all HVM/PVH guests strictly getting an LAPIC, which is guaranteed by XSA-256. There's no such thing as a 64bit CPU without a Local APIC, so no such thing as %cr8 not being TPR. --- xen/arch/x86/hvm/emulate.c | 10 ++++++++++ 1 file changed, 10 insertions(+) base-commit: e7e0d485e993e97b1c816adcfc610e7c7258ce96