4 * Copyright (C) 2019, Google LLC.
6 * This work is licensed under the terms of the GNU GPL, version 2.
8 * Test that we don't get a kernel warning when we call KVM_RUN after a
9 * triple fault occurs. To get the triple fault to occur we call KVM_RUN
10 * on a VCPU that hasn't been properly setup.
17 #include <linux/kvm.h>
18 #include <processor.h>
23 #include <sys/ioctl.h>
26 #include <sys/types.h>
28 #include <test_util.h>
34 struct thread_context
{
41 struct thread_context
*tc
= (struct thread_context
*)arg
;
43 int kvmcpu
= tc
->kvmcpu
;
44 struct kvm_run
*run
= tc
->run
;
46 res
= ioctl(kvmcpu
, KVM_RUN
, 0);
47 pr_info("ret1=%d exit_reason=%d suberror=%d\n",
48 res
, run
->exit_reason
, run
->internal
.suberror
);
55 int i
, kvm
, kvmvm
, kvmcpu
;
56 pthread_t th
[NTHREAD
];
58 struct thread_context tc
;
60 kvm
= open("/dev/kvm", O_RDWR
);
61 TEST_ASSERT(kvm
!= -1, "failed to open /dev/kvm");
62 kvmvm
= ioctl(kvm
, KVM_CREATE_VM
, 0);
63 TEST_ASSERT(kvmvm
!= -1, "KVM_CREATE_VM failed");
64 kvmcpu
= ioctl(kvmvm
, KVM_CREATE_VCPU
, 0);
65 TEST_ASSERT(kvmcpu
!= -1, "KVM_CREATE_VCPU failed");
66 run
= (struct kvm_run
*)mmap(0, 4096, PROT_READ
|PROT_WRITE
, MAP_SHARED
,
71 for (i
= 0; i
< NTHREAD
; i
++) {
72 pthread_create(&th
[i
], NULL
, thr
, (void *)(uintptr_t)&tc
);
73 usleep(rand() % 10000);
75 for (i
= 0; i
< NTHREAD
; i
++)
76 pthread_join(th
[i
], NULL
);
79 int get_warnings_count(void)
84 f
= popen("dmesg | grep \"WARNING:\" | wc -l", "r");
85 fscanf(f
, "%d", &warnings
);
93 int warnings_before
, warnings_after
;
95 if (!is_intel_cpu()) {
96 print_skip("Must be run on an Intel CPU");
100 if (vm_is_unrestricted_guest(NULL
)) {
101 print_skip("Unrestricted guest must be disabled");
105 warnings_before
= get_warnings_count();
107 for (int i
= 0; i
< NPROCESS
; ++i
) {
117 while (waitpid(pid
, &status
, __WALL
) != pid
)
121 warnings_after
= get_warnings_count();
122 TEST_ASSERT(warnings_before
== warnings_after
,
123 "Warnings found in kernel. Run 'dmesg' to inspect them.");