mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/vmx: Rework #DB intercept logic to fix VMEntry failure with BTF
The consistency checks in effect when Blocked-by-STI/MovSS are active includes
DEBUGCTL.BTF too. Take this into account when editing PENDING_DBG.BS.
This ends up narrowing the cases where PENDING_DBG is modified. Rework the
comment to be more precise.
This is XSA-518 / CVE-2026-79611.
Fixes: 1d3eb82598 ("x86/vtx: Work around SingleStep + STI/MovSS VMEntry failures")
Reported-by: Teddy Astie <teddy.astie@vates.tech>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
This commit is contained in:
1 parent
e0a0823ee0
commit
1017562ac0
1 file changed
+18
-23
+18
-23
@@ -4396,33 +4396,28 @@ void asmlinkage vmx_vmexit_handler(struct cpu_user_regs *regs)
|
|||||||
* We intercept #DB unconditionally to work around CVE-2015-8104 /
|
* We intercept #DB unconditionally to work around CVE-2015-8104 /
|
||||||
* XSA-156 (guest-kernel induced host DoS).
|
* XSA-156 (guest-kernel induced host DoS).
|
||||||
*
|
*
|
||||||
* STI/MovSS shadows block/defer interrupts/exceptions (exact
|
* Most sources of #DB accumuate status in PENDING_DBG, which are
|
||||||
* details are complicated and poorly documented). Debug
|
* then dispatched in priority order prior to fetching the next
|
||||||
* exceptions delayed for any reason are stored in the
|
* instruction. When the #DB intercept triggers, PENDING_DBG is 0
|
||||||
* PENDING_DBG_EXCEPTIONS field.
|
* with the status bits having moved into EXIT_QUALIFICATION.
|
||||||
*
|
*
|
||||||
* The falling edge of PENDING_DBG causes #DB to be delivered,
|
* At any point if Blocked-by-STI/MovSS are active, extra VMEntry
|
||||||
* resulting in a VMExit, as #DB is intercepted. The VMCS still
|
* consistency checks are applied, cross-checking EFLAGS.TF,
|
||||||
* reports blocked-by-STI/MovSS.
|
* PENDING_DBG.BS and DEBUGCTL.BTF. These consistency checks
|
||||||
|
* apply to Activity-state-HLT too, but Xen doesn't support this.
|
||||||
*
|
*
|
||||||
* The VMEntry checks when EFLAGS.TF is set don't like a VMCS in
|
* The VMCS state at the point of #DB intercept does not satisfy
|
||||||
* this state. Despite a #DB queued in VMENTRY_INTR_INFO, the
|
* the consistency checks. In the case that a SingleStep should
|
||||||
* state is rejected as DR6.BS isn't pending. Fix this up.
|
* be pending, fill PENDING_DBG back in to satisfy the consitency
|
||||||
|
* check.
|
||||||
*/
|
*/
|
||||||
if ( unlikely(regs->eflags & X86_EFLAGS_TF) )
|
if ( unlikely(regs->eflags & X86_EFLAGS_TF) &&
|
||||||
|
(vmread(GUEST_INTERRUPTIBILITY_INFO) &
|
||||||
|
(VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS)) &&
|
||||||
|
!(vmread(GUEST_IA32_DEBUGCTL) & IA32_DEBUGCTLMSR_BTF) )
|
||||||
{
|
{
|
||||||
unsigned long int_info;
|
ASSERT(vmread(GUEST_PENDING_DBG_EXCEPTIONS) == 0);
|
||||||
|
__vmwrite(GUEST_PENDING_DBG_EXCEPTIONS, X86_DR6_BS);
|
||||||
__vmread(GUEST_INTERRUPTIBILITY_INFO, &int_info);
|
|
||||||
|
|
||||||
if ( int_info & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) )
|
|
||||||
{
|
|
||||||
unsigned long pending_dbg;
|
|
||||||
|
|
||||||
__vmread(GUEST_PENDING_DBG_EXCEPTIONS, &pending_dbg);
|
|
||||||
__vmwrite(GUEST_PENDING_DBG_EXCEPTIONS,
|
|
||||||
pending_dbg | DR_STEP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !v->domain->debugger_attached )
|
if ( !v->domain->debugger_attached )
|
||||||
|
|||||||