On Thu, May 19, 2022 at 04:45:20PM +0200, Roger Pau Monné wrote:
> On Thu, May 19, 2022 at 12:10:24AM +0000, Andrew Cooper wrote:
> > On 17/05/2022 14:21, Roger Pau Monne wrote:
> > > @@ -1333,6 +1338,19 @@ static int construct_vmcs(struct vcpu *v)
> > >          rc = vmx_add_msr(v, MSR_FLUSH_CMD, FLUSH_CMD_L1D,
> > >                           VMX_MSR_GUEST_LOADONLY);
> > >  
> > > +    if ( cpu_has_vmx_notify_vm_exiting && vm_notify_window >= 0 )
> > > +    {
> > > +        __vmwrite(NOTIFY_WINDOW, vm_notify_window);
> > > +        /*
> > > +         * Disable #AC and #DB interception: by using VM Notify Xen is
> > > +         * guaranteed to get a VM exit even if the guest manages to lock 
> > > the
> > > +         * CPU.
> > > +         */
> > > +        v->arch.hvm.vmx.exception_bitmap &= ~((1U << TRAP_debug) |
> > > +                                              (1U << 
> > > TRAP_alignment_check));
> > > +        vmx_update_exception_bitmap(v);
> > 
> > IIRC, it's not quite this easy.  There are conditions, e.g. attaching
> > gdbsx, where #DB interception wants turning on/off dynamically, and the
> > logic got simplified to nothing following XSA-156, so will need
> > reintroducing.
> > 
> > AMD Milan (Zen3) actually has NoNestedDataBp in CPUID.80000021.eax[0]
> > which allows us to not intercept #DB, so perhaps that might offer an
> > easier way of adjusting the interception logic.  (Or maybe not.  I can't
> > remember).
> 
> OK, will look into it.

So after taking a look, I think we need to modify vmx_update_debug_state() so 
it's:

void vmx_update_debug_state(struct vcpu *v)
{
    unsigned int mask = 1u << TRAP_int3;

    if ( v->arch.hvm.vmx.secondary_exec_control &
         SECONDARY_EXEC_NOTIFY_VM_EXITING )
        /*
         * Only allow toggling TRAP_debug if notify VM exit is enabled, as
         * unconditionally setting TRAP_debug is part of the XSA-156 fix.
         */
        mask |= 1u << TRAP_debug;

    if ( v->arch.hvm.debug_state_latch )
        v->arch.hvm.vmx.exception_bitmap |= mask;
    else
        v->arch.hvm.vmx.exception_bitmap &= ~mask;

[...]

I'm however confused by the usage of cpu_has_monitor_trap_flag
previous to XSA-156, which was:

void vmx_update_debug_state(struct vcpu *v)
{
    unsigned long mask;

    mask = 1u << TRAP_int3;
    if ( !cpu_has_monitor_trap_flag )
        mask |= 1u << TRAP_debug;

Was it fine to not set TRAP_debug only if cpu_has_monitor_trap_flag
is supported by the CPU? (even if not currently set on
secondary_exec_control)?

Thanks, Roger.

Reply via email to