* [PATCH kvm-unit-tests 0/2] svm: make preparation more flexible
@ 2019-12-18 17:33 Paolo Bonzini
2019-12-18 17:33 ` [PATCH kvm-unit-tests 1/2] svm: introduce prepare_gif_clear callback Paolo Bonzini
2019-12-18 17:33 ` [PATCH kvm-unit-tests 2/2] svm: replace set_host_if with " Paolo Bonzini
0 siblings, 2 replies; 3+ messages in thread
From: Paolo Bonzini @ 2019-12-18 17:33 UTC (permalink / raw)
To: kvm; +Cc: cavery
In the future we may want tests that inject events while GIF=0 (this is
nice to cover check_nested_events or lack thereof). Adjust the SVM
test harness to make this easy and not ad hoc.
Paolo
Paolo Bonzini (2):
svm: introduce prepare_gif_clear callback
svm: replace set_host_if with prepare_gif_clear callback
x86/svm.c | 132 +++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 84 insertions(+), 48 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH kvm-unit-tests 1/2] svm: introduce prepare_gif_clear callback
2019-12-18 17:33 [PATCH kvm-unit-tests 0/2] svm: make preparation more flexible Paolo Bonzini
@ 2019-12-18 17:33 ` Paolo Bonzini
2019-12-18 17:33 ` [PATCH kvm-unit-tests 2/2] svm: replace set_host_if with " Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2019-12-18 17:33 UTC (permalink / raw)
To: kvm; +Cc: cavery
Generalize the set_host_if flag that was added recently, by introducing
a new callback that is called with GIF=0 && IF=1. This is useful to
inject events that will trigger right after VMRUN.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
x86/svm.c | 124 ++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 81 insertions(+), 43 deletions(-)
diff --git a/x86/svm.c b/x86/svm.c
index 99b1d71..63fda65 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -192,6 +192,7 @@ struct test {
const char *name;
bool (*supported)(void);
void (*prepare)(struct test *test);
+ void (*prepare_gif_clear)(struct test *test);
void (*guest_func)(struct test *test);
bool (*finished)(struct test *test);
bool (*succeeded)(struct test *test);
@@ -266,31 +267,37 @@ static void test_run(struct test *test, struct vmcb *vmcb)
vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack));
regs.rdi = (ulong)test;
do {
+ struct test *the_test = test;
+ u64 the_vmcb = vmcb_phys;
tsc_start = rdtsc();
asm volatile (
"clgi;\n\t" // semi-colon needed for LLVM compatibility
- "cmpb $0, set_host_if\n\t"
- "jz 1f\n\t"
"sti \n\t"
- "1: \n\t"
+ "call *%c[PREPARE_GIF_CLEAR](%[test]) \n \t"
+ "mov %[vmcb_phys], %%rax \n\t"
"vmload \n\t"
"vmload %0\n\t"
"mov regs+0x80, %%r15\n\t" // rflags
- "mov %%r15, 0x170(%0)\n\t"
+ "mov %%r15, 0x170(%%rax)\n\t"
"mov regs, %%r15\n\t" // rax
- "mov %%r15, 0x1f8(%0)\n\t"
+ "mov %%r15, 0x1f8(%%rax)\n\t"
LOAD_GPR_C
"vmrun %0\n\t"
SAVE_GPR_C
- "mov 0x170(%0), %%r15\n\t" // rflags
+ "mov 0x170(%%rax), %%r15\n\t" // rflags
"mov %%r15, regs+0x80\n\t"
- "mov 0x1f8(%0), %%r15\n\t" // rax
+ "mov 0x1f8(%%rax), %%r15\n\t" // rax
"mov %%r15, regs\n\t"
"vmsave %0\n\t"
"cli \n\t"
"stgi"
- : : "a"(vmcb_phys)
- : "rbx", "rcx", "rdx", "rsi",
+ : // inputs clobbered by the guest:
+ "+D" (the_test), // first argument register
+ "+b" (the_vmcb) // callee save register!
+ : [test] "0" (the_test),
+ [vmcb_phys] "1"(the_vmcb),
+ [PREPARE_GIF_CLEAR] "i" (offsetof(struct test, prepare_gif_clear))
+ : "rax", "rcx", "rdx", "rsi",
"r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15",
"memory");
tsc_end = rdtsc();
@@ -316,6 +323,12 @@ static void default_prepare(struct test *test)
vmcb_ident(test->vmcb);
}
+static void default_prepare_gif_clear(struct test *test)
+{
+ if (!set_host_if)
+ asm("cli");
+}
+
static bool default_finished(struct test *test)
{
return true; /* one vmexit */
@@ -1486,58 +1499,83 @@ static bool pending_event_check_vmask(struct test *test)
}
static struct test tests[] = {
- { "null", default_supported, default_prepare, null_test,
+ { "null", default_supported, default_prepare,
+ default_prepare_gif_clear, null_test,
default_finished, null_check },
- { "vmrun", default_supported, default_prepare, test_vmrun,
+ { "vmrun", default_supported, default_prepare,
+ default_prepare_gif_clear, test_vmrun,
default_finished, check_vmrun },
- { "ioio", default_supported, prepare_ioio, test_ioio,
+ { "ioio", default_supported, prepare_ioio,
+ default_prepare_gif_clear, test_ioio,
ioio_finished, check_ioio },
{ "vmrun intercept check", default_supported, prepare_no_vmrun_int,
- null_test, default_finished, check_no_vmrun_int },
- { "cr3 read intercept", default_supported, prepare_cr3_intercept,
+ default_prepare_gif_clear, null_test, default_finished,
+ check_no_vmrun_int },
+ { "cr3 read intercept", default_supported,
+ prepare_cr3_intercept, default_prepare_gif_clear,
test_cr3_intercept, default_finished, check_cr3_intercept },
{ "cr3 read nointercept", default_supported, default_prepare,
- test_cr3_intercept, default_finished, check_cr3_nointercept },
+ default_prepare_gif_clear, test_cr3_intercept, default_finished,
+ check_cr3_nointercept },
{ "cr3 read intercept emulate", smp_supported,
- prepare_cr3_intercept_bypass, test_cr3_intercept_bypass,
- default_finished, check_cr3_intercept },
+ prepare_cr3_intercept_bypass, default_prepare_gif_clear,
+ test_cr3_intercept_bypass, default_finished, check_cr3_intercept },
{ "dr intercept check", default_supported, prepare_dr_intercept,
- test_dr_intercept, dr_intercept_finished, check_dr_intercept },
- { "next_rip", next_rip_supported, prepare_next_rip, test_next_rip,
+ default_prepare_gif_clear, test_dr_intercept, dr_intercept_finished,
+ check_dr_intercept },
+ { "next_rip", next_rip_supported, prepare_next_rip,
+ default_prepare_gif_clear, test_next_rip,
default_finished, check_next_rip },
{ "msr intercept check", default_supported, prepare_msr_intercept,
- test_msr_intercept, msr_intercept_finished, check_msr_intercept },
- { "mode_switch", default_supported, prepare_mode_switch, test_mode_switch,
+ default_prepare_gif_clear, test_msr_intercept,
+ msr_intercept_finished, check_msr_intercept },
+ { "mode_switch", default_supported, prepare_mode_switch,
+ default_prepare_gif_clear, test_mode_switch,
mode_switch_finished, check_mode_switch },
- { "asid_zero", default_supported, prepare_asid_zero, test_asid_zero,
+ { "asid_zero", default_supported, prepare_asid_zero,
+ default_prepare_gif_clear, test_asid_zero,
default_finished, check_asid_zero },
- { "sel_cr0_bug", default_supported, sel_cr0_bug_prepare, sel_cr0_bug_test,
+ { "sel_cr0_bug", default_supported, sel_cr0_bug_prepare,
+ default_prepare_gif_clear, sel_cr0_bug_test,
sel_cr0_bug_finished, sel_cr0_bug_check },
- { "npt_nx", npt_supported, npt_nx_prepare, null_test,
- default_finished, npt_nx_check },
- { "npt_us", npt_supported, npt_us_prepare, npt_us_test,
- default_finished, npt_us_check },
- { "npt_rsvd", npt_supported, npt_rsvd_prepare, null_test,
- default_finished, npt_rsvd_check },
- { "npt_rw", npt_supported, npt_rw_prepare, npt_rw_test,
- default_finished, npt_rw_check },
- { "npt_rsvd_pfwalk", npt_supported, npt_rsvd_pfwalk_prepare, null_test,
- default_finished, npt_rsvd_pfwalk_check },
- { "npt_rw_pfwalk", npt_supported, npt_rw_pfwalk_prepare, null_test,
- default_finished, npt_rw_pfwalk_check },
- { "npt_l1mmio", npt_supported, npt_l1mmio_prepare, npt_l1mmio_test,
- default_finished, npt_l1mmio_check },
- { "npt_rw_l1mmio", npt_supported, npt_rw_l1mmio_prepare, npt_rw_l1mmio_test,
- default_finished, npt_rw_l1mmio_check },
- { "tsc_adjust", default_supported, tsc_adjust_prepare, tsc_adjust_test,
- default_finished, tsc_adjust_check },
- { "latency_run_exit", default_supported, latency_prepare, latency_test,
+ { "npt_nx", npt_supported, npt_nx_prepare,
+ default_prepare_gif_clear, null_test,
+ default_finished, npt_nx_check },
+ { "npt_us", npt_supported, npt_us_prepare,
+ default_prepare_gif_clear, npt_us_test,
+ default_finished, npt_us_check },
+ { "npt_rsvd", npt_supported, npt_rsvd_prepare,
+ default_prepare_gif_clear, null_test,
+ default_finished, npt_rsvd_check },
+ { "npt_rw", npt_supported, npt_rw_prepare,
+ default_prepare_gif_clear, npt_rw_test,
+ default_finished, npt_rw_check },
+ { "npt_rsvd_pfwalk", npt_supported, npt_rsvd_pfwalk_prepare,
+ default_prepare_gif_clear, null_test,
+ default_finished, npt_rsvd_pfwalk_check },
+ { "npt_rw_pfwalk", npt_supported, npt_rw_pfwalk_prepare,
+ default_prepare_gif_clear, null_test,
+ default_finished, npt_rw_pfwalk_check },
+ { "npt_l1mmio", npt_supported, npt_l1mmio_prepare,
+ default_prepare_gif_clear, npt_l1mmio_test,
+ default_finished, npt_l1mmio_check },
+ { "npt_rw_l1mmio", npt_supported, npt_rw_l1mmio_prepare,
+ default_prepare_gif_clear, npt_rw_l1mmio_test,
+ default_finished, npt_rw_l1mmio_check },
+ { "tsc_adjust", default_supported, tsc_adjust_prepare,
+ default_prepare_gif_clear, tsc_adjust_test,
+ default_finished, tsc_adjust_check },
+ { "latency_run_exit", default_supported, latency_prepare,
+ default_prepare_gif_clear, latency_test,
latency_finished, latency_check },
- { "latency_svm_insn", default_supported, lat_svm_insn_prepare, null_test,
+ { "latency_svm_insn", default_supported, lat_svm_insn_prepare,
+ default_prepare_gif_clear, null_test,
lat_svm_insn_finished, lat_svm_insn_check },
{ "pending_event", default_supported, pending_event_prepare,
+ default_prepare_gif_clear,
pending_event_test, pending_event_finished, pending_event_check },
{ "pending_event_vmask", default_supported, pending_event_prepare_vmask,
+ default_prepare_gif_clear,
pending_event_test_vmask, pending_event_finished_vmask,
pending_event_check_vmask },
};
--
1.8.3.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH kvm-unit-tests 2/2] svm: replace set_host_if with prepare_gif_clear callback
2019-12-18 17:33 [PATCH kvm-unit-tests 0/2] svm: make preparation more flexible Paolo Bonzini
2019-12-18 17:33 ` [PATCH kvm-unit-tests 1/2] svm: introduce prepare_gif_clear callback Paolo Bonzini
@ 2019-12-18 17:33 ` Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2019-12-18 17:33 UTC (permalink / raw)
To: kvm; +Cc: cavery
Instead of setting a flag in the prepare callback, override the
default value of the host IF flag in the prepare_gif_clear
callback.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
x86/svm.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/x86/svm.c b/x86/svm.c
index 63fda65..2cbd9fd 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -44,8 +44,6 @@ u64 runs;
u8 *io_bitmap;
u8 io_bitmap_area[16384];
-u8 set_host_if;
-
#define MSR_BITMAP_SIZE 8192
u8 *msr_bitmap;
@@ -261,7 +259,6 @@ static void test_run(struct test *test, struct vmcb *vmcb)
irq_disable();
test->vmcb = vmcb;
- set_host_if = 1;
test->prepare(test);
vmcb->save.rip = (ulong)test_thunk;
vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack));
@@ -325,8 +322,6 @@ static void default_prepare(struct test *test)
static void default_prepare_gif_clear(struct test *test)
{
- if (!set_host_if)
- asm("cli");
}
static bool default_finished(struct test *test)
@@ -1412,8 +1407,6 @@ static void pending_event_prepare_vmask(struct test *test)
pending_event_ipi_fired = false;
- set_host_if = 0;
-
handle_irq(0xf1, pending_event_ipi_isr);
apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL |
@@ -1422,6 +1415,11 @@ static void pending_event_prepare_vmask(struct test *test)
set_test_stage(test, 0);
}
+static void pending_event_prepare_gif_clear_vmask(struct test *test)
+{
+ asm("cli");
+}
+
static void pending_event_test_vmask(struct test *test)
{
if (pending_event_ipi_fired == true) {
@@ -1575,7 +1573,7 @@ static struct test tests[] = {
default_prepare_gif_clear,
pending_event_test, pending_event_finished, pending_event_check },
{ "pending_event_vmask", default_supported, pending_event_prepare_vmask,
- default_prepare_gif_clear,
+ pending_event_prepare_gif_clear_vmask,
pending_event_test_vmask, pending_event_finished_vmask,
pending_event_check_vmask },
};
--
1.8.3.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-12-18 17:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-18 17:33 [PATCH kvm-unit-tests 0/2] svm: make preparation more flexible Paolo Bonzini
2019-12-18 17:33 ` [PATCH kvm-unit-tests 1/2] svm: introduce prepare_gif_clear callback Paolo Bonzini
2019-12-18 17:33 ` [PATCH kvm-unit-tests 2/2] svm: replace set_host_if with " Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).