像GDB这样的调试功能通过设置eflags寄存器的TF标志来工作,该标志在处理器每次执行指令后都会导致异常,让像gdb这样的工具控制调试。当我们运行虚拟机Ex时,如果是kvm要做同样的事情,你需要设置一个名为MONITOR TRAP FLAG的标志(当前英特尔软件手册3c第15页),这将导致虚拟宏在每条指令给出管理程序之后进行EXIT(VMEXIT)。
虚拟机管理程序几乎可以设置VM(guest虚拟机)的任何位/寄存器。当架构中已存在此类标志(EFLAG)时,为什么我们需要VMCS(虚拟Macine控制结构)中的单独标志?
我在某地读过,其原因是如果使用EFLAGS,访客可以将VMM(管理程序)的意图覆盖为单步。
答:如果你没有控制权,那么模仿硬件是什么意思?
B:我正面临一个问题,我需要设置BTF(分支陷阱标志)(PG 689 vOLUME 3a INTEL sotfware手册)。在正常情况下,这会导致每个分支指令出现DEBUG EXCEPTION,但由于我想在VM上执行此操作,因此我无法确定要在VMCS中设置哪个位。在单步执行的情况下似乎没有直接的方法。任何人都可以让我知道如果有某种方法可以使用其他方法做同样的事情吗?
由于
答案 0 :(得分:3)
英特尔可能会制造一个,但却没有。
让我们首先完成并定义术语:
[请注意,所有这些仅与英特尔x86相关]
如问题中所述,在执行指令后会导致#DBG(陷阱通过异常0x1)。 使用RFLAGS的第8位进行控制。
TLDR:BTF修改TF的行为仅触发分支上的异常。
从2016年4月版的英特尔SDM开始:
当软件在IA32_DEBUGCTL MSR中设置BTF标志(位1)时 和EFLAGS寄存器中的TF标志,处理器生成一个 仅在导致a的指令之后的单步调试异常 分支。[1]此机制允许调试器单步执行控制 分支机构造成的转账。这种“分支单步”有帮助 在指令之前将错误隔离到特定的代码块 单步进一步缩小了搜索范围。处理器清除了 生成调试异常时的BTF标志。调试器必须设置 在恢复程序执行之前继续BTF标志 单步踩树枝。
[1]从不导致任务切换的CALL,IRET和JMP的执行 导致单步调试异常(无论BTF的值如何 旗)。调试器需要在切换到任务时调试异常 应该在该任务的TSS中设置T标志(调试陷阱标志)。看到 第7.2.1节“任务状态段(TSS)。”
MTF位于VMCS中,在guest虚拟机中触发某些指令边界上的Monitor Trap Flag VMEXIT。
一般来说,只要guest虚拟机正在进行,就会发生退出,并且没有任何东西出现主机端,其优先级高于MTF VMEXIT。存在奇怪的边缘情况,例如REP MOV(可以被中断的指令)和SMI(对于主机OS是不可见的中断)。有关详细信息,请参阅SDM的Monitor Trap Flag部分(2016年4月25.5.2)。
为什么我们需要VMCS中的单独标志(虚拟Macine控件 结构)当架构中已经存在这样的标志时 (EFLAG)?
主持人和宾客州需要分开。如果您正在调试运行GDB的guest虚拟机,则主机需要能够触发VMEXIT,而不是guest虚拟机中的异常。请注意,设置陷阱标志时,默认设置是在当前上下文中触发异常(如果您在guest虚拟机中运行,则为guest虚拟机,如果您在主机中运行,则为guest虚拟机)。
主机可以尝试在不使用MTF的情况下进行调试,方法是使用VMCS中的异常位图强制设置guest虚拟机的TF并在调试异常上配置VMEXIT。遗憾的是,如果guest虚拟机还启用了调试异常,则主机无法知道调试异常属于谁(如果我没记错,则无法在写入RFLAGS时退出)。 MTF的存在使调试运行调试器的VM成为可能。
...任何人都可以让我知道如果有某种方法可以做同样的事情 用其他方法?
没有Branch Monitor Trap Flag。您可以通过查看来宾的RIP(应该在VMCS中)中的解码指令来实现等效的东西,但这需要一堆额外的VMEXITS。显然,这并不理想。
如果您在进入客人之前设置了BTF,事情会很快变得混乱。它将被视为客人的BTF,而不是与主机相关的BTF。如果您还在VMCS中设置MTF,则BTF不会延迟MTF VMEXIT。另一方面,它会延迟客户的下一个调试陷阱。
每当访客VMEXIT接下来,BTF将被破坏,如果它尚未被调试异常清除(IA32_DEBUGCTL在退出时被清除)。您可以使用MSR LOAD / STORE列表保存该值,但这并没有太大作用。