1 // SPDX-License-Identifier: GPL-2.0-only
3 * tests for KVM_CAP_X86_USER_SPACE_MSR and KVM_X86_SET_MSR_FILTER
5 * Copyright (C) 2020, Amazon Inc.
7 * This is a functional test to verify that we can deflect MSR events
10 #define _GNU_SOURCE /* for program_invocation_short_name */
15 #include <sys/ioctl.h>
17 #include "test_util.h"
20 #include "processor.h"
24 static u32 msr_reads, msr_writes;
26 static u8 bitmap_00000000[KVM_MSR_FILTER_MAX_BITMAP_SIZE];
27 static u8 bitmap_00000000_write[KVM_MSR_FILTER_MAX_BITMAP_SIZE];
28 static u8 bitmap_40000000[KVM_MSR_FILTER_MAX_BITMAP_SIZE];
29 static u8 bitmap_c0000000[KVM_MSR_FILTER_MAX_BITMAP_SIZE];
30 static u8 bitmap_c0000000_read[KVM_MSR_FILTER_MAX_BITMAP_SIZE];
31 static u8 bitmap_deadbeef[1] = { 0x1 };
33 static void deny_msr(uint8_t *bitmap, u32 msr)
35 u32 idx = msr & (KVM_MSR_FILTER_MAX_BITMAP_SIZE - 1);
37 bitmap[idx / 8] &= ~(1 << (idx % 8));
40 static void prepare_bitmaps(void)
42 memset(bitmap_00000000, 0xff, sizeof(bitmap_00000000));
43 memset(bitmap_00000000_write, 0xff, sizeof(bitmap_00000000_write));
44 memset(bitmap_40000000, 0xff, sizeof(bitmap_40000000));
45 memset(bitmap_c0000000, 0xff, sizeof(bitmap_c0000000));
46 memset(bitmap_c0000000_read, 0xff, sizeof(bitmap_c0000000_read));
48 deny_msr(bitmap_00000000_write, MSR_IA32_POWER_CTL);
49 deny_msr(bitmap_c0000000_read, MSR_SYSCALL_MASK);
50 deny_msr(bitmap_c0000000_read, MSR_GS_BASE);
53 struct kvm_msr_filter filter = {
54 .flags = KVM_MSR_FILTER_DEFAULT_DENY,
57 .flags = KVM_MSR_FILTER_READ,
59 .nmsrs = KVM_MSR_FILTER_MAX_BITMAP_SIZE * BITS_PER_BYTE,
60 .bitmap = bitmap_00000000,
62 .flags = KVM_MSR_FILTER_WRITE,
64 .nmsrs = KVM_MSR_FILTER_MAX_BITMAP_SIZE * BITS_PER_BYTE,
65 .bitmap = bitmap_00000000_write,
67 .flags = KVM_MSR_FILTER_READ | KVM_MSR_FILTER_WRITE,
69 .nmsrs = KVM_MSR_FILTER_MAX_BITMAP_SIZE * BITS_PER_BYTE,
70 .bitmap = bitmap_40000000,
72 .flags = KVM_MSR_FILTER_READ,
74 .nmsrs = KVM_MSR_FILTER_MAX_BITMAP_SIZE * BITS_PER_BYTE,
75 .bitmap = bitmap_c0000000_read,
77 .flags = KVM_MSR_FILTER_WRITE,
79 .nmsrs = KVM_MSR_FILTER_MAX_BITMAP_SIZE * BITS_PER_BYTE,
80 .bitmap = bitmap_c0000000,
82 .flags = KVM_MSR_FILTER_WRITE | KVM_MSR_FILTER_READ,
85 .bitmap = bitmap_deadbeef,
90 struct kvm_msr_filter no_filter = {
91 .flags = KVM_MSR_FILTER_DEFAULT_ALLOW,
94 static void guest_msr_calls(bool trapped)
96 /* This goes into the in-kernel emulation */
97 wrmsr(MSR_SYSCALL_MASK, 0);
100 /* This goes into user space emulation */
101 GUEST_ASSERT(rdmsr(MSR_SYSCALL_MASK) == MSR_SYSCALL_MASK);
102 GUEST_ASSERT(rdmsr(MSR_GS_BASE) == MSR_GS_BASE);
104 GUEST_ASSERT(rdmsr(MSR_SYSCALL_MASK) != MSR_SYSCALL_MASK);
105 GUEST_ASSERT(rdmsr(MSR_GS_BASE) != MSR_GS_BASE);
108 /* If trapped == true, this goes into user space emulation */
109 wrmsr(MSR_IA32_POWER_CTL, 0x1234);
111 /* This goes into the in-kernel emulation */
112 rdmsr(MSR_IA32_POWER_CTL);
114 /* Invalid MSR, should always be handled by user space exit */
115 GUEST_ASSERT(rdmsr(0xdeadbeef) == 0xdeadbeef);
116 wrmsr(0xdeadbeef, 0x1234);
119 static void guest_code(void)
121 guest_msr_calls(true);
124 * Disable msr filtering, so that the kernel
125 * handles everything in the next round
129 guest_msr_calls(false);
134 static int handle_ucall(struct kvm_vm *vm)
138 switch (get_ucall(vm, VCPU_ID, &uc)) {
140 TEST_FAIL("Guest assertion not met");
143 vm_ioctl(vm, KVM_X86_SET_MSR_FILTER, &no_filter);
148 TEST_FAIL("Unknown ucall %lu", uc.cmd);
154 static void handle_rdmsr(struct kvm_run *run)
156 run->msr.data = run->msr.index;
159 if (run->msr.index == MSR_SYSCALL_MASK ||
160 run->msr.index == MSR_GS_BASE) {
161 TEST_ASSERT(run->msr.reason == KVM_MSR_EXIT_REASON_FILTER,
162 "MSR read trap w/o access fault");
165 if (run->msr.index == 0xdeadbeef) {
166 TEST_ASSERT(run->msr.reason == KVM_MSR_EXIT_REASON_UNKNOWN,
167 "MSR deadbeef read trap w/o inval fault");
171 static void handle_wrmsr(struct kvm_run *run)
176 if (run->msr.index == MSR_IA32_POWER_CTL) {
177 TEST_ASSERT(run->msr.data == 0x1234,
178 "MSR data for MSR_IA32_POWER_CTL incorrect");
179 TEST_ASSERT(run->msr.reason == KVM_MSR_EXIT_REASON_FILTER,
180 "MSR_IA32_POWER_CTL trap w/o access fault");
183 if (run->msr.index == 0xdeadbeef) {
184 TEST_ASSERT(run->msr.data == 0x1234,
185 "MSR data for deadbeef incorrect");
186 TEST_ASSERT(run->msr.reason == KVM_MSR_EXIT_REASON_UNKNOWN,
187 "deadbeef trap w/o inval fault");
191 int main(int argc, char *argv[])
193 struct kvm_enable_cap cap = {
194 .cap = KVM_CAP_X86_USER_SPACE_MSR,
195 .args[0] = KVM_MSR_EXIT_REASON_INVAL |
196 KVM_MSR_EXIT_REASON_UNKNOWN |
197 KVM_MSR_EXIT_REASON_FILTER,
203 /* Tell stdout not to buffer its content */
204 setbuf(stdout, NULL);
207 vm = vm_create_default(VCPU_ID, 0, guest_code);
208 run = vcpu_state(vm, VCPU_ID);
210 rc = kvm_check_cap(KVM_CAP_X86_USER_SPACE_MSR);
212 print_skip("KVM_CAP_X86_USER_SPACE_MSR not supported");
216 vm_enable_cap(vm, &cap);
218 rc = kvm_check_cap(KVM_CAP_X86_MSR_FILTER);
219 TEST_ASSERT(rc, "KVM_CAP_X86_MSR_FILTER is available");
222 vm_ioctl(vm, KVM_X86_SET_MSR_FILTER, &filter);
225 rc = _vcpu_run(vm, VCPU_ID);
227 TEST_ASSERT(rc == 0, "vcpu_run failed: %d\n", rc);
229 switch (run->exit_reason) {
230 case KVM_EXIT_X86_RDMSR:
233 case KVM_EXIT_X86_WRMSR:
237 if (handle_ucall(vm))
245 TEST_ASSERT(msr_reads == 4, "Handled 4 rdmsr in user space");
246 TEST_ASSERT(msr_writes == 3, "Handled 3 wrmsr in user space");