On 26/03/2025 11:19 am, Jan Beulich wrote:
> On 25.03.2025 18:41, 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.
>>
>> Xen's handling of %cr8 turns out to be quite wrong. At a minimum, we need
>> storage for %cr8 separate to APIC_TPR, and to alter intercepts based on
>> whether the vLAPIC is enabled or not. But that's more work than there is
>> time
>> for in the short term, so make a stopgap fix.
>>
>> Extend hvmemul_{read,write}_cr() with %cr8 cases. Unlike hvm_mov_to_cr(),
>> hardware hasn't filtered out invalid values (#GP checks are ahead of
>> intercepts), so introduce X86_CR8_VALID_MASK.
>>
>> Reported-by: Petr Beneš <[email protected]>
>> Signed-off-by: Andrew Cooper <[email protected]>
> Reviewed-by: Jan Beulich <[email protected]>
Thanks.
>
>> --- a/xen/arch/x86/hvm/emulate.c
>> +++ b/xen/arch/x86/hvm/emulate.c
>> @@ -2288,6 +2288,10 @@ static int cf_check hvmemul_read_cr(
>> val = curr->arch.hvm.guest_cr[reg];
>> break;
>>
>> + case 8:
>> + val = (vlapic_get_reg(vcpu_vlapic(curr), APIC_TASKPRI) & 0xf0) >> 4;
> No new #define then to use MASK_EXTR() here and ...
>
>> @@ -2333,6 +2337,17 @@ static int cf_check hvmemul_write_cr(
>> rc = hvm_set_cr4(val, true);
>> break;
>>
>> + case 8:
>> + if ( val & ~X86_CR8_VALID_MASK )
>> + {
>> + rc = X86EMUL_EXCEPTION;
>> + break;
>> + }
>> +
>> + vlapic_set_reg(vcpu_vlapic(curr), APIC_TASKPRI, val << 4);
> ... MASK_INSR() here?
No. The logic wont survive fixing cr8 I don't think.
AFAICT, what we need is plain storage, and vlapic_{get,set}_tpr()
accessors which account for hw-disable, and then call back into
hvm_set_reg() to adjust intercepts.
~Andrew