* [PATCH kvm-unit-tests] svm: add a test for exception injection
@ 2020-04-09 9:43 Paolo Bonzini
2020-04-11 0:24 ` Krish Sadhukhan
0 siblings, 1 reply; 3+ messages in thread
From: Paolo Bonzini @ 2020-04-09 9:43 UTC (permalink / raw)
To: kvm
Cover VMRUN's testing whether EVENTINJ.TYPE = 3 (exception) has been specified with
a vector that does not correspond to an exception.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
x86/svm.h | 7 +++++
x86/svm_tests.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+)
diff --git a/x86/svm.h b/x86/svm.h
index 645deb7..bb5c552 100644
--- a/x86/svm.h
+++ b/x86/svm.h
@@ -324,6 +324,13 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
+#define SVM_EVENT_INJ_HWINT (0 << 8)
+#define SVM_EVENT_INJ_NMI (2 << 8)
+#define SVM_EVENT_INJ_EXC (3 << 8)
+#define SVM_EVENT_INJ_SWINT (4 << 8)
+#define SVM_EVENT_INJ_ERRCODE (1 << 11)
+#define SVM_EVENT_INJ_VALID (1 << 31)
+
#define MSR_BITMAP_SIZE 8192
struct svm_test {
diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 16b9dfd..6292e68 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -1340,6 +1340,73 @@ static bool interrupt_check(struct svm_test *test)
return get_test_stage(test) == 5;
}
+static volatile int count_exc = 0;
+
+static void my_isr(struct ex_regs *r)
+{
+ count_exc++;
+}
+
+static void exc_inject_prepare(struct svm_test *test)
+{
+ handle_exception(DE_VECTOR, my_isr);
+ handle_exception(NMI_VECTOR, my_isr);
+}
+
+
+static void exc_inject_test(struct svm_test *test)
+{
+ asm volatile ("vmmcall\n\tvmmcall\n\t");
+}
+
+static bool exc_inject_finished(struct svm_test *test)
+{
+ vmcb->save.rip += 3;
+
+ switch (get_test_stage(test)) {
+ case 0:
+ if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
+ report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
+ vmcb->control.exit_code);
+ return true;
+ }
+ vmcb->control.event_inj = NMI_VECTOR | SVM_EVENT_INJ_EXC | SVM_EVENT_INJ_VALID;
+ break;
+
+ case 1:
+ if (vmcb->control.exit_code != SVM_EXIT_ERR) {
+ report(false, "VMEXIT not due to error. Exit reason 0x%x",
+ vmcb->control.exit_code);
+ return true;
+ }
+ report(count_exc == 0, "exception with vector 2 not injected");
+ vmcb->control.event_inj = DE_VECTOR | SVM_EVENT_INJ_EXC | SVM_EVENT_INJ_VALID;
+ break;
+
+ case 2:
+ if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
+ report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
+ vmcb->control.exit_code);
+ return true;
+ }
+ report(count_exc == 1, "divide overflow exception injected");
+ report(!(vmcb->control.event_inj & SVM_EVENT_INJ_VALID), "eventinj.VALID cleared");
+ break;
+
+ default:
+ return true;
+ }
+
+ inc_test_stage(test);
+
+ return get_test_stage(test) == 3;
+}
+
+static bool exc_inject_check(struct svm_test *test)
+{
+ return count_exc == 1 && get_test_stage(test) == 3;
+}
+
#define TEST(name) { #name, .v2 = name }
/*
@@ -1446,6 +1513,9 @@ struct svm_test svm_tests[] = {
{ "interrupt", default_supported, interrupt_prepare,
default_prepare_gif_clear, interrupt_test,
interrupt_finished, interrupt_check },
+ { "exc_inject", default_supported, exc_inject_prepare,
+ default_prepare_gif_clear, exc_inject_test,
+ exc_inject_finished, exc_inject_check },
TEST(svm_guest_state_test),
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
--
2.18.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH kvm-unit-tests] svm: add a test for exception injection
2020-04-09 9:43 [PATCH kvm-unit-tests] svm: add a test for exception injection Paolo Bonzini
@ 2020-04-11 0:24 ` Krish Sadhukhan
2020-04-15 14:56 ` Paolo Bonzini
0 siblings, 1 reply; 3+ messages in thread
From: Krish Sadhukhan @ 2020-04-11 0:24 UTC (permalink / raw)
To: Paolo Bonzini, kvm
On 4/9/20 2:43 AM, Paolo Bonzini wrote:
> Cover VMRUN's testing whether EVENTINJ.TYPE = 3 (exception) has been specified with
> a vector that does not correspond to an exception.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> x86/svm.h | 7 +++++
> x86/svm_tests.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 77 insertions(+)
>
> diff --git a/x86/svm.h b/x86/svm.h
> index 645deb7..bb5c552 100644
> --- a/x86/svm.h
> +++ b/x86/svm.h
> @@ -324,6 +324,13 @@ struct __attribute__ ((__packed__)) vmcb {
>
> #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
>
> +#define SVM_EVENT_INJ_HWINT (0 << 8)
> +#define SVM_EVENT_INJ_NMI (2 << 8)
> +#define SVM_EVENT_INJ_EXC (3 << 8)
> +#define SVM_EVENT_INJ_SWINT (4 << 8)
> +#define SVM_EVENT_INJ_ERRCODE (1 << 11)
> +#define SVM_EVENT_INJ_VALID (1 << 31)
I see existing #defines in svm.h:
#define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
#define SVM_EVTINJ_VALID (1 << 31)
#define SVM_EVTINJ_VALID_ERR (1 << 11)
> +
> #define MSR_BITMAP_SIZE 8192
>
> struct svm_test {
> diff --git a/x86/svm_tests.c b/x86/svm_tests.c
> index 16b9dfd..6292e68 100644
> --- a/x86/svm_tests.c
> +++ b/x86/svm_tests.c
> @@ -1340,6 +1340,73 @@ static bool interrupt_check(struct svm_test *test)
> return get_test_stage(test) == 5;
> }
>
> +static volatile int count_exc = 0;
> +
> +static void my_isr(struct ex_regs *r)
> +{
> + count_exc++;
> +}
> +
> +static void exc_inject_prepare(struct svm_test *test)
> +{
> + handle_exception(DE_VECTOR, my_isr);
> + handle_exception(NMI_VECTOR, my_isr);
> +}
> +
> +
> +static void exc_inject_test(struct svm_test *test)
> +{
> + asm volatile ("vmmcall\n\tvmmcall\n\t");
> +}
> +
> +static bool exc_inject_finished(struct svm_test *test)
> +{
> + vmcb->save.rip += 3;
> +
> + switch (get_test_stage(test)) {
> + case 0:
> + if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
> + report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
> + vmcb->control.exit_code);
> + return true;
> + }
> + vmcb->control.event_inj = NMI_VECTOR | SVM_EVENT_INJ_EXC | SVM_EVENT_INJ_VALID;
> + break;
> +
> + case 1:
> + if (vmcb->control.exit_code != SVM_EXIT_ERR) {
> + report(false, "VMEXIT not due to error. Exit reason 0x%x",
> + vmcb->control.exit_code);
> + return true;
> + }
> + report(count_exc == 0, "exception with vector 2 not injected");
> + vmcb->control.event_inj = DE_VECTOR | SVM_EVENT_INJ_EXC | SVM_EVENT_INJ_VALID;
> + break;
> +
> + case 2:
> + if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
> + report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
> + vmcb->control.exit_code);
> + return true;
> + }
> + report(count_exc == 1, "divide overflow exception injected");
> + report(!(vmcb->control.event_inj & SVM_EVENT_INJ_VALID), "eventinj.VALID cleared");
> + break;
> +
> + default:
> + return true;
> + }
> +
> + inc_test_stage(test);
> +
> + return get_test_stage(test) == 3;
> +}
> +
> +static bool exc_inject_check(struct svm_test *test)
> +{
> + return count_exc == 1 && get_test_stage(test) == 3;
> +}
> +
> #define TEST(name) { #name, .v2 = name }
>
> /*
> @@ -1446,6 +1513,9 @@ struct svm_test svm_tests[] = {
> { "interrupt", default_supported, interrupt_prepare,
> default_prepare_gif_clear, interrupt_test,
> interrupt_finished, interrupt_check },
> + { "exc_inject", default_supported, exc_inject_prepare,
> + default_prepare_gif_clear, exc_inject_test,
> + exc_inject_finished, exc_inject_check },
> TEST(svm_guest_state_test),
> { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
> };
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH kvm-unit-tests] svm: add a test for exception injection
2020-04-11 0:24 ` Krish Sadhukhan
@ 2020-04-15 14:56 ` Paolo Bonzini
0 siblings, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2020-04-15 14:56 UTC (permalink / raw)
To: Krish Sadhukhan, kvm
On 11/04/20 02:24, Krish Sadhukhan wrote:
>
> On 4/9/20 2:43 AM, Paolo Bonzini wrote:
>> Cover VMRUN's testing whether EVENTINJ.TYPE = 3 (exception) has been
>> specified with
>> a vector that does not correspond to an exception.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>> x86/svm.h | 7 +++++
>> x86/svm_tests.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 77 insertions(+)
>>
>> diff --git a/x86/svm.h b/x86/svm.h
>> index 645deb7..bb5c552 100644
>> --- a/x86/svm.h
>> +++ b/x86/svm.h
>> @@ -324,6 +324,13 @@ struct __attribute__ ((__packed__)) vmcb {
>> #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
>> +#define SVM_EVENT_INJ_HWINT (0 << 8)
>> +#define SVM_EVENT_INJ_NMI (2 << 8)
>> +#define SVM_EVENT_INJ_EXC (3 << 8)
>> +#define SVM_EVENT_INJ_SWINT (4 << 8)
>> +#define SVM_EVENT_INJ_ERRCODE (1 << 11)
>> +#define SVM_EVENT_INJ_VALID (1 << 31)
>
>
> I see existing #defines in svm.h:
>
> #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
> #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
> #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
> #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
> #define SVM_EVTINJ_VALID (1 << 31)
> #define SVM_EVTINJ_VALID_ERR (1 << 11)
Indeed. I queued the patch with these defines instead.
Paolo
>> +
>> #define MSR_BITMAP_SIZE 8192
>> struct svm_test {
>> diff --git a/x86/svm_tests.c b/x86/svm_tests.c
>> index 16b9dfd..6292e68 100644
>> --- a/x86/svm_tests.c
>> +++ b/x86/svm_tests.c
>> @@ -1340,6 +1340,73 @@ static bool interrupt_check(struct svm_test *test)
>> return get_test_stage(test) == 5;
>> }
>> +static volatile int count_exc = 0;
>> +
>> +static void my_isr(struct ex_regs *r)
>> +{
>> + count_exc++;
>> +}
>> +
>> +static void exc_inject_prepare(struct svm_test *test)
>> +{
>> + handle_exception(DE_VECTOR, my_isr);
>> + handle_exception(NMI_VECTOR, my_isr);
>> +}
>> +
>> +
>> +static void exc_inject_test(struct svm_test *test)
>> +{
>> + asm volatile ("vmmcall\n\tvmmcall\n\t");
>> +}
>> +
>> +static bool exc_inject_finished(struct svm_test *test)
>> +{
>> + vmcb->save.rip += 3;
>> +
>> + switch (get_test_stage(test)) {
>> + case 0:
>> + if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
>> + report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
>> + vmcb->control.exit_code);
>> + return true;
>> + }
>> + vmcb->control.event_inj = NMI_VECTOR | SVM_EVENT_INJ_EXC |
>> SVM_EVENT_INJ_VALID;
>> + break;
>> +
>> + case 1:
>> + if (vmcb->control.exit_code != SVM_EXIT_ERR) {
>> + report(false, "VMEXIT not due to error. Exit reason 0x%x",
>> + vmcb->control.exit_code);
>> + return true;
>> + }
>> + report(count_exc == 0, "exception with vector 2 not injected");
>> + vmcb->control.event_inj = DE_VECTOR | SVM_EVENT_INJ_EXC |
>> SVM_EVENT_INJ_VALID;
>> + break;
>> +
>> + case 2:
>> + if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
>> + report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
>> + vmcb->control.exit_code);
>> + return true;
>> + }
>> + report(count_exc == 1, "divide overflow exception injected");
>> + report(!(vmcb->control.event_inj & SVM_EVENT_INJ_VALID),
>> "eventinj.VALID cleared");
>> + break;
>> +
>> + default:
>> + return true;
>> + }
>> +
>> + inc_test_stage(test);
>> +
>> + return get_test_stage(test) == 3;
>> +}
>> +
>> +static bool exc_inject_check(struct svm_test *test)
>> +{
>> + return count_exc == 1 && get_test_stage(test) == 3;
>> +}
>> +
>> #define TEST(name) { #name, .v2 = name }
>> /*
>> @@ -1446,6 +1513,9 @@ struct svm_test svm_tests[] = {
>> { "interrupt", default_supported, interrupt_prepare,
>> default_prepare_gif_clear, interrupt_test,
>> interrupt_finished, interrupt_check },
>> + { "exc_inject", default_supported, exc_inject_prepare,
>> + default_prepare_gif_clear, exc_inject_test,
>> + exc_inject_finished, exc_inject_check },
>> TEST(svm_guest_state_test),
>> { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
>> };
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-04-15 14:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-09 9:43 [PATCH kvm-unit-tests] svm: add a test for exception injection Paolo Bonzini
2020-04-11 0:24 ` Krish Sadhukhan
2020-04-15 14:56 ` 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).