diff mbox series

[kvm-unit-tests] x86: SEV-ES: add port string IO test case

Message ID 20211025052829.2062623-1-marcorr@google.com (mailing list archive)
State New, archived
Headers show
Series [kvm-unit-tests] x86: SEV-ES: add port string IO test case | expand

Commit Message

Marc Orr Oct. 25, 2021, 5:28 a.m. UTC
Add a test case to verify that string IO works as expected under SEV-ES.
This test case is based on the `test_stringio()` test case in emulator.c.
However, emulator.c does not currently run under UEFI.

Only the first half of the test case, which processes a string from
beginning to end, was taken for now. The second test case did not work
and is thus left out of the amd_sev.c setup for now.

Also, the first test case was modified to do port IO at word granularity
rather than byte granularity. The reason is to ensure that using the
port IO size in a calculation within the kernel does not multiply or
divide by 1. In particular, this tweak is useful to demonstrate that a
recent KVM patch [1] does not behave correctly.

* This patch is based on the `uefi` branch.

[1] https://patchwork.kernel.org/project/kvm/patch/20211013165616.19846-2-pbonzini@redhat.com/

Signed-off-by: Marc Orr <marcorr@google.com>
---
 x86/amd_sev.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

Comments

Paolo Bonzini Oct. 25, 2021, 5:09 p.m. UTC | #1
On 25/10/21 07:28, Marc Orr wrote:
> Add a test case to verify that string IO works as expected under SEV-ES.
> This test case is based on the `test_stringio()` test case in emulator.c.
> However, emulator.c does not currently run under UEFI.
> 
> Only the first half of the test case, which processes a string from
> beginning to end, was taken for now. The second test case did not work
> and is thus left out of the amd_sev.c setup for now.
> 
> Also, the first test case was modified to do port IO at word granularity
> rather than byte granularity. The reason is to ensure that using the
> port IO size in a calculation within the kernel does not multiply or
> divide by 1. In particular, this tweak is useful to demonstrate that a
> recent KVM patch [1] does not behave correctly.
> 
> * This patch is based on the `uefi` branch.
> 
> [1] https://patchwork.kernel.org/project/kvm/patch/20211013165616.19846-2-pbonzini@redhat.com/
> 
> Signed-off-by: Marc Orr <marcorr@google.com>
> ---
>   x86/amd_sev.c | 22 ++++++++++++++++++++++
>   1 file changed, 22 insertions(+)
> 
> diff --git a/x86/amd_sev.c b/x86/amd_sev.c
> index 061c50514545..7757d4f85b7a 100644
> --- a/x86/amd_sev.c
> +++ b/x86/amd_sev.c
> @@ -18,6 +18,10 @@
>   #define EXIT_SUCCESS 0
>   #define EXIT_FAILURE 1
>   
> +#define TESTDEV_IO_PORT 0xe0
> +
> +static char st1[] = "abcdefghijklmnop";
> +
>   static int test_sev_activation(void)
>   {
>   	struct cpuid cpuid_out;
> @@ -65,11 +69,29 @@ static void test_sev_es_activation(void)
>   	}
>   }
>   
> +static void test_stringio(void)
> +{
> +	int st1_len = sizeof(st1) - 1;
> +	u16 got;
> +
> +	asm volatile("cld \n\t"
> +		     "movw %0, %%dx \n\t"
> +		     "rep outsw \n\t"
> +		     : : "i"((short)TESTDEV_IO_PORT),
> +		         "S"(st1), "c"(st1_len / 2));
> +
> +	asm volatile("inw %1, %0\n\t" : "=a"(got) : "i"((short)TESTDEV_IO_PORT));
> +
> +	report((got & 0xff) == st1[sizeof(st1) - 3], "outsb nearly up");
> +	report((got & 0xff00) >> 8 == st1[sizeof(st1) - 2], "outsb up");
> +}
> +
>   int main(void)
>   {
>   	int rtn;
>   	rtn = test_sev_activation();
>   	report(rtn == EXIT_SUCCESS, "SEV activation test.");
>   	test_sev_es_activation();
> +	test_stringio();
>   	return report_summary();
>   }
> 

Applied to uefi branch, thanks (and tested both before and after the 
patch I've sent with subject "[PATCH] KVM: SEV-ES: fix another issue 
with string I/O VMGEXITs").

Paolo
diff mbox series

Patch

diff --git a/x86/amd_sev.c b/x86/amd_sev.c
index 061c50514545..7757d4f85b7a 100644
--- a/x86/amd_sev.c
+++ b/x86/amd_sev.c
@@ -18,6 +18,10 @@ 
 #define EXIT_SUCCESS 0
 #define EXIT_FAILURE 1
 
+#define TESTDEV_IO_PORT 0xe0
+
+static char st1[] = "abcdefghijklmnop";
+
 static int test_sev_activation(void)
 {
 	struct cpuid cpuid_out;
@@ -65,11 +69,29 @@  static void test_sev_es_activation(void)
 	}
 }
 
+static void test_stringio(void)
+{
+	int st1_len = sizeof(st1) - 1;
+	u16 got;
+
+	asm volatile("cld \n\t"
+		     "movw %0, %%dx \n\t"
+		     "rep outsw \n\t"
+		     : : "i"((short)TESTDEV_IO_PORT),
+		         "S"(st1), "c"(st1_len / 2));
+
+	asm volatile("inw %1, %0\n\t" : "=a"(got) : "i"((short)TESTDEV_IO_PORT));
+
+	report((got & 0xff) == st1[sizeof(st1) - 3], "outsb nearly up");
+	report((got & 0xff00) >> 8 == st1[sizeof(st1) - 2], "outsb up");
+}
+
 int main(void)
 {
 	int rtn;
 	rtn = test_sev_activation();
 	report(rtn == EXIT_SUCCESS, "SEV activation test.");
 	test_sev_es_activation();
+	test_stringio();
 	return report_summary();
 }