On 13/12/2022 4:31 pm, Roger Pau Monne wrote:
> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
> index a0d5e8d6ab..3d7c471a3f 100644
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -1290,6 +1296,17 @@ static int construct_vmcs(struct vcpu *v)
> v->arch.hvm.vmx.exception_bitmap = HVM_TRAP_MASK
> | (paging_mode_hap(d) ? 0 : (1U << TRAP_page_fault))
> | (v->arch.fully_eager_fpu ? 0 : (1U << TRAP_no_device));
> + if ( cpu_has_vmx_notify_vm_exiting )
> + {
> + __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);
>
> v->arch.hvm.guest_cr[0] = X86_CR0_PE | X86_CR0_ET;
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index dabf4a3552..b11578777a 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -1428,10 +1428,19 @@ static void cf_check vmx_update_host_cr3(struct vcpu
> *v)
>
> void vmx_update_debug_state(struct vcpu *v)
> {
> + unsigned int mask = 1u << TRAP_int3;
> +
> + if ( !cpu_has_monitor_trap_flag && cpu_has_vmx_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 |= 1U << TRAP_int3;
> + v->arch.hvm.vmx.exception_bitmap |= mask;
> else
> - v->arch.hvm.vmx.exception_bitmap &= ~(1U << TRAP_int3);
> + v->arch.hvm.vmx.exception_bitmap &= ~mask;
>
> vmx_vmcs_enter(v);
> vmx_update_exception_bitmap(v);
> @@ -4180,6 +4189,9 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
> switch ( vector )
> {
> case TRAP_debug:
> + if ( cpu_has_monitor_trap_flag && cpu_has_vmx_notify_vm_exiting )
> + goto exit_and_crash;
This breaks GDBSX and introspection.
For XSA-156, we were forced to intercept #DB unilaterally for safety,
but both GDBSX and Introspection can optionally intercepting #DB for
logical reasons too.
i.e. we can legitimately end up here even on an system with VM Notify.
What I can't figure out is why made any reference to MTF. MTF has
absolutely nothing to do with TRAP_debug.
Furthermore, there's no CPU in practice that has VM Notify but lacks
MTF, so the head of vmx_update_debug_state() looks like dead code...
~Andrew