在QEMU对MSR的处理(一)中,我们介绍了qemu中有kvm_get_supported_msrs()函数。该函数会调用kvm_ioctl(KVM_GET_MSR_INDEX_LIST),kvm会向qemu返回其定义的msr_to_save[]和emulated_msrs[]数组。
之后qemu就可以调用vcpu_ioctl(KVM_GET_MSRS)和vcpu_ioctl(KVM_SET_MSRS)来get/set之前获取到的suppoted_msrs[]。
kvm对KVM_GET_MSRS, KVM_SET_MSRS的处理
1 | case KVM_GET_MSRS: { |
可以看到会调用do_get_msr()和do_set_msr()函数。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24static int do_get_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
{
struct msr_data msr;
int r;
msr.index = index;
msr.host_initiated = true;
r = kvm_get_msr(vcpu, &msr);
if (r)
return r;
*data = msr.data;
return 0;
}
static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
{
struct msr_data msr;
msr.data = *data;
msr.index = index;
msr.host_initiated = true;
return kvm_set_msr(vcpu, &msr);
}
对应的,又会调用kvm_get_msr()和kvm_set_msr()函数。
这两个函数干了什么,具体地可以参考kvm中handle_rdmsr和kvm中handle_wrmsr这两篇文章。
总结:QEMU和KVM调用get/set msr的区别
QEMU和KVM都可以get/set guest的msr。
QEMU调用get msr是主动查询guest中相应的msr的值,set_msr是修改guest中msr的值。
KVM是对rdmsr和wrmsr指令的模拟(如果这两条指令会vm exit)。
具体地,QEMU和KVM最后调用的函数是一样的,都是vmx_get/set_msr(),唯一的区别就是:
QEMU将msr.host_initiated = true;
KVM将msr.host_initiated = false;