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

Reply via email to