Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between trap flag (TF) and monitor trap flag?

Debugging features like GDB work by setting the TF flag of eflags register which causes an exception after every execution of instruction by the processor, letting tools like gdb control over the debugging.When we are running a virtual machine Ex in case of kvm to do the same thing you need to set a flag called the MONITOR TRAP FLAG (pg 15 of current intel software manual 3c), which will cause the virtual macine to EXIT (VMEXIT) after every instruction giving debugging abitily to the hypervisor.

The hypervisor can set almost any bit/register of the VM(guest). Why do we need a seperate flag in the VMCS (virtual Macine control Structure) when such a flag is already present in the architecture (EFLAG)??

I read somewhere that, the reason for this is that guest can override VMM’s (hypervisor) intention to single step if EFLAGS were used.

A:Whats the point of emulating hardware if you don't have control??

B: I am facing a issue where I need to set BTF (branch Trap Flag)(PG 689 vOLUME 3a INTEL sotfware manual). In a normal scenario this cause DEBUG EXCEPTION on every branch instruction but since I want to this on a VM, I am not able to figure which bit to set in the VMCS. There seems to be no direct way doing this like in the case of single stepping. Can anyone let me know If there some way to do the same thing using other means ?

Thanks

like image 816
Deepthought Avatar asked Oct 05 '22 03:10

Deepthought


1 Answers

No, there is no Branch Monitor Trap Flag.

Intel could probably make one, but hasn't.

Details

Let's first go through and define terms:

[Note that all of this is only relevant to Intel x86]

Trap Flag (TF)

As described in the question, causes #DBG after the execution of an instruction (Traps through exception 0x1). Controlled using bit 8 of RFLAGS.

Branch Trap Flag (BTF)

TLDR: The BTF modifies the behavior of the TF to only trigger exceptions on branches.

From the April 2016 Edition of the Intel SDM:

When software sets both the BTF flag (bit 1) in the IA32_DEBUGCTL MSR and the TF flag in the EFLAGS register, the processor generates a single-step debug exception only after instructions that cause a branch.[1] This mechanism allows a debugger to single-step on control transfers caused by branches. This “branch single stepping” helps isolate a bug to a particular block of code before instruction single-stepping further narrows the search. The processor clears the BTF flag when it generates a debug exception. The debugger must set the BTF flag before resuming program execution to continue single-stepping on branches.

[1] Executions of CALL, IRET, and JMP that cause task switches never cause single-step debug exceptions (regardless of the value of the BTF flag). A debugger desiring debug exceptions on switches to a task should set the T flag (debug trap flag) in the TSS of that task. See Section 7.2.1, “Task-State Segment (TSS).”

Monitor Trap Flag (MTF)

The MTF is a bit in the VMCS that triggers Monitor Trap Flag VMEXITs on certain instruction boundaries while in a guest.

Generally speaking, the exit occurs whenever the guest is making forward progress, and nothing occurs host side that would be of higher priority than the MTF VMEXIT. There are weird edge cases, like REP MOV (an instruction which can be interrupted) and SMIs (Interrupts that are invisible-ish to the host OS). See the Monitor Trap Flag section of the SDM for specifics (25.5.2 in April 2016).

Responses

Why do we need a seperate flag in the VMCS (virtual Macine control Structure) when such a flag is already present in the architecture (EFLAG)?

Host and Guest State need to be separate. If you are debugging a guest that is running GDB, the host needs to be able to trigger VMEXITs, rather than exceptions within the guest. Note that when the trap flag is set, the default is to fire an exception within the current context (the guest's if you are running in the guest, the host's if you are running in the host).

The host could attempt to debug without using the MTF by forcibly setting the guest's TF and configuring VMEXITs on debug exceptions using the exception bitmaps in the VMCS. Unfortunately, if the guest has also enabled debug exceptions, there is no clean way for the host to know who the debug exception belongs to (If I recall correctly, there is no way to exit on writes to RFLAGS). The existence of MTF makes it possible to debug a VM running a debugger.

... Can anyone let me know If there some way to do the same thing using other means?

There is no Branch Monitor Trap Flag. You could implement something equivalent by looking at the decoded instruction at the guest's RIP (which should be in the VMCS), but that will require a bunch of extra VMEXITS. Obviously, that's not ideal.

If you were to set the BTF before entering the guest, things will get messy fast. It will be perceived as the guest's BTF rather than a BTF related to the host. If you also set the MTF in the VMCS, the BTF will not delay the MTF VMEXIT. On the other hand, it will delay the guest's next debug trap.

Whenever the guest VMEXITs next, the BTF will get clobbered, if it was not already cleared by a debug exception (IA32_DEBUGCTL is cleared on exit). You could save the value using the MSR LOAD/STORE lists, but that doesn't accomplish much.

like image 116
ruthafjord Avatar answered Oct 13 '22 10:10

ruthafjord