[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] vmi: supporting single-stepping on AMD processors


I am working on making libvmi[1] work on AMD, and one big issue is the lack
of support for single-stepping on AMD processors in the vmi api offered by xen.
I think i have a way to get it to work, and I would like to know if you see
any issues with this approach, and if there is any reason it hasnt been
implemented like this.

Looking at the code the reason why single-stepping works for intel,
but not for amd seems to be that Intel-vtx has the handy
'Monitor Trap Flag' (MTF), while AMD does not offer such a feature in SVM.
On Intel, if the MTF is set, after one guest instruction there is a
vmexit with reason
EXIT_REASON_MONITOR_TRAP_FLAG, which is then directly passed up as a

Studying the AMD manual and reading between the lines a bit I see the
following way to implement single stepping on AMD:

AMD Manual 15.6#VMEXIT:
> When VMRUN loads a guest value of 1 in
> EFLAGS.TF, that value does not cause a trace trap between
> the VMRUN and the first guest
> instruction, but rather after completion of the first guest instruction.


1. check if guest has rflags.tf set
2. set rflags.tf in the guest context
3. continue
4. get a vmexit with exception #DB
5. if rflags.tf was initially set, re-inject the event into the guest
(to not interfere with standard singlestepping inside the guest)

Most of the code that would be needed is already there in svm.c,
i am preparing a patch to implement it as I imagine it above, but it will take
me some time to test it.

So is there any reason it has not been implemented like that already,
and would you generally accept it to be done like this?


[1] https://github.com/libvmi/libvmi

p.s. Looking at the debugger that comes with virtualbox, they seem to
implement it like this too (however, the entire debugger seems to be in
a broken state right now):

 4079     if (pVCpu->hm.s.fSingleInstruction)
 4080     {
 4081         /* If the CPU supports the monitor trap flag, use it for
single stepping in DBGF and avoid intercepting #DB. */
 4082         PVM pVM = pVCpu->CTX_SUFF(pVM);
 4083         if (pVM->hm.s.vmx.Msrs.ProcCtls.n.allowed1 &
 4084         {
 4085             uProcCtls |= VMX_PROC_CTLS_MONITOR_TRAP_FLAG;
 4086             Assert(fSteppingDB == false);
 4087         }
 4088         else
 4089         {
 4090             pVCpu->cpum.GstCtx.eflags.u32 |= X86_EFL_TF;
 4091             pVCpu->hm.s.fCtxChanged |= HM_CHANGED_GUEST_RFLAGS;
 4092             pVCpu->hm.s.fClearTrapFlag = true;
 4093             fSteppingDB = true;
 4094         }
 4095     }

Xen-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.