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.