首页
社区
课程
招聘
[求助] 请教kvm虚拟机, 在guest用户态读写msr寄存器时, 为什么没有触发vm exit?
2021-4-27 16:15 6775

[求助] 请教kvm虚拟机, 在guest用户态读写msr寄存器时, 为什么没有触发vm exit?

2021-4-27 16:15
6775

我在kvm-intel.ko的vmx.c文件中的vmx_handle_exit函数添加了一行如下代码:

1
2
if(exit_reason == EXIT_REASON_MSR_WRITE)
    if(0x3000 == vcpu->arch.regs[VCPU_REGS_RCX]){asm(".byte 0xcc");}

用来检测是否触发了写msr 0x3000位置的操作. 然后编译加载.

 

然后我用qemu启动了一个centos虚拟机.
在虚拟机中, 我在用户态写了如下一个程序:

1
2
3
void main(){
asm("wrmsr"::"c"(0x3000),"a"(0xaa),"d"(0xdd));
}

用gcc编译运行后, guest里只出现了segment fault错误, 在双机调试的调试器里并没有捕捉到我的内核int3断点.

 

我在guest里用驱动编写类似的代码, 就可以触发我的int3断点.

 

我查了intel的说明文档, 它有提到msr 的bitmap过滤:

1
2
3
4
5
6
7
8
RDMSR. The RDMSR instruction causes a VM exit if any of the following are true:
 
 The "use MSR bitmaps" VM-execution control is 0.
 The value of ECX is not in the ranges 00000000H - 00001FFFH and C0000000H - C0001FFFH
 The value of ECX is in the range 00000000H - 00001FFFH and bit n in read bitmap for low MSRs is 1,
   where n is the value of ECX.
 The value of ECX is in the range C0000000H - C0001FFFH and bit n in read bitmap for high MSRs is 1,
   where n is the value of ECX & 00001FFFH.

从文中, 我的理解是, 只要写的不是0-0x1fff及0xc0000000-0xc0001fff范围的寄存器, 就应该会触发vm exit.

 

但是这与我的测试有不同, 我想请教下大佬, 是我忽略了什么说明吗?

 

还有一点我不太理解, 即使我在guest的用户态写0-0x1fff范围的寄存器, 且msr的bitmap也设置的1, 为什么也没有vm exit?


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2021-4-28 11:56 被音货得福编辑 ,原因:
收藏
点赞0
打赏
分享
最新回复 (13)
雪    币: 135
活跃值: (1240)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huojier 2021-4-27 16:24
2
0

没玩过KVM,我瞎猜的:
你设置了msr_bitmap没


等等,

你是用户态写的,用户态的会触发GP异常,自然不走你的msr vmexit了

#GP(0)If the current privilege level is not 0.
If the value in ECX specifies a reserved or unimplemented MSR address.
If the value in EDX:EAX sets bits that are reserved in the MSR specified by ECX.
If the source register contains a non-canonical address and ECX specifies one of the following MSRs: IA32_DS_AREA, IA32_FS_BASE, IA32_GS_BASE, IA32_KERNEL_GS_BASE, IA32_LSTAR, IA32_SYSENTER_EIP, IA32_SYSENTER_ESP.
#UDIf the LOCK prefix is used.


最后于 2021-4-27 16:36 被huojier编辑 ,原因:
雪    币: 3842
活跃值: (1830)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
音货得福 1 2021-4-27 17:24
3
0

这个...我不确定受不受这个的影响, 以我的理解, 这个属于特权指令, 应该归vmm管理, 判断是否有必要交给内核处理?

最后于 2021-4-27 17:26 被音货得福编辑 ,原因:
雪    币: 3842
活跃值: (1830)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
音货得福 1 2021-4-27 18:05
4
0
不知道发这个区, 有没有大佬能看到
雪    币: 135
活跃值: (1240)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huojier 2021-4-27 18:37
5
0
音货得福 这个...我不确定受不受这个的影响, 以我的理解, 这个属于特权指令, 应该归vmm管理, 判断是否有必要交给内核处理?
我认为一般是先检查异常,前置检查跑完了再给VMCS的
不相信的你可以试验一下,捕获PG异常 看看
雪    币: 3842
活跃值: (1830)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
音货得福 1 2021-4-28 10:49
6
0
huojier 我认为一般是先检查异常,前置检查跑完了再给VMCS的 不相信的你可以试验一下,捕获PG异常 看看

我测试了dr寄存器相关的mov指令:

asm("movq %0,%%dr0"::"r"(0xaabbccddaa));


参照官方说明:

MOV — Move to/from Debug Registers

MOV—Move to/from Debug Registers

Moves the contents of a debug register (DR0, DR1, DR2, DR3, DR4, DR5, DR6, or DR7) to a general-purpose register or vice versa. The operand size for these instructions is always 32 bits in non-64-bit modes, regardless of the operand-size attribute. (See Section 17.2, “Debug Registers”, of the Intel® 64 and IA-32 Architectures Soft-ware Developer’s Manual, Volume 3A, for a detailed description of the flags and fields in the debug registers.)

The instructions must be executed at privilege level 0 or in real-address mode.

When the debug extension (DE) flag in register CR4 is clear, these instructions operate on debug registers in a manner that is compatible with Intel386 and Intel486 processors. In this mode, references to DR4 and DR5 refer to DR6 and DR7, respectively. When the DE flag in CR4 is set, attempts to reference DR4 and DR5 result in an undefined opcode (#UD) exception. (The CR4 register was added to the IA-32 Architecture beginning with the Pentium processor.)

At the opcode level, the reg field within the ModR/M byte specifies which of the debug registers is loaded or read. The two bits in the mod field are ignored. The r/m field specifies the general-purpose register loaded or read.

In 64-bit mode, the instruction’s default operation size is 64 bits. Use of the REX.B prefix permits access to addi-tional registers (R8–R15). Use of the REX.W or 66H prefix is ignored. Use of the REX.R prefix causes an invalid-opcode exception. See the summary chart at the beginning of this section for encoding data and limits.

64-Bit Mode Exceptions
#GP(0)
    If the current privilege level is not 0.
    If an attempt is made to write a 1 to any of bits 63:32 in DR6.
    If an attempt is made to write a 1 to any of bits 63:32 in DR7

如果GP异常的优先级高于vm exit, 此处应该不会触发vm exit. 但是我在guest用户态确实触发了vm exit. 

并且在kvm的exit handler函数"handle_dr"中有如下检查代码:

static int handle_dr(struct kvm_vcpu *vcpu)
{
        unsigned long exit_qualification;
        int dr, reg;
        /* Do not handle if the CPL > 0, will trigger GP on re-entry */
        if (!kvm_require_cpl(vcpu, 0))// 此处检查了调用方是否来自ring0
                return 1;
...


我理解的是, 这个应该是交给kvm来决定的. 不知道我这个论证是否存在问题?

最后于 2021-4-28 10:53 被音货得福编辑 ,原因:
雪    币: 135
活跃值: (1240)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huojier 2021-4-28 12:16
7
0
不是的,因为DR寄存器R3是可以控制的,但是MSR寄存器R3权限不能控制.
所以才会有你说的用户态触发VMEXIT的情况
雪    币: 3842
活跃值: (1830)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
音货得福 1 2021-4-28 13:39
8
0
huojier 不是的,因为DR寄存器R3是可以控制的,但是MSR寄存器R3权限不能控制. 所以才会有你说的用户态触发VMEXIT的情况
可是这个说明不是说必须是privilege level 0吗?
雪    币: 39
活跃值: (4157)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
ookkaa 2021-4-28 15:57
9
0

雪    币: 39
活跃值: (4157)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
ookkaa 2021-4-28 15:59
10
0
huojier 不是的,因为DR寄存器R3是可以控制的,但是MSR寄存器R3权限不能控制. 所以才会有你说的用户态触发VMEXIT的情况
那个白帽网站是你开的不,进去是有个鸭子走来走去的那个
雪    币: 3842
活跃值: (1830)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
音货得福 1 2021-4-28 18:05
11
0
ookkaa

我找到 《处理器虚拟化技术》看了, 确实存在这种说明, 但没在 《Intel® 64 and IA-32 ArchitecturesSoftware Developer’s Manual》找到类似说明,不知道这个说法有没有出处。另外我还关注到exception bitmap好像蛮重要,它也决定了一些情况下是否需要触发vm exit。

感谢大佬的解答

最后于 2021-4-28 18:07 被音货得福编辑 ,原因:
雪    币: 3842
活跃值: (1830)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
音货得福 1 2021-4-28 18:07
12
0
huojier 不是的,因为DR寄存器R3是可以控制的,但是MSR寄存器R3权限不能控制. 所以才会有你说的用户态触发VMEXIT的情况
也感谢大佬的解答
雪    币: 3842
活跃值: (1830)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
音货得福 1 2021-5-7 17:01
13
0

哈哈, 终于找到原文了, 这里明确说了用户态读写msr寄存器不会产生vm exit, 而 dr就会产生. 我也是真的刚好碰上到两个特例 -_-"" , 把我给绕晕了.

雪    币: 5291
活跃值: (11715)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
一半人生 5 2021-6-3 15:47
14
0

VMCS如果设置了Msr域相关的处理,Guest内核态Msr操作会触发vmexit。

Guest r3陷入由Guest r0处理, Guest r0陷入由VMM处理

最后于 2021-6-3 15:48 被一半人生编辑 ,原因:
游客
登录 | 注册 方可回帖
返回