diff mbox

[kvm-unit-tests,4/8] s390x: Add diag10 tests

Message ID 1520942503-6163-5-git-send-email-frankja@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Janosch Frank March 13, 2018, 12:01 p.m. UTC
Let's add some tests for the diag10 "Release pages" instruction.

Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
---
 s390x/Makefile      |  1 +
 s390x/diag10.c      | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 s390x/unittests.cfg |  3 ++
 3 files changed, 85 insertions(+)
 create mode 100644 s390x/diag10.c

Comments

Thomas Huth March 13, 2018, 7:27 p.m. UTC | #1
On 13.03.2018 13:01, Janosch Frank wrote:
> Let's add some tests for the diag10 "Release pages" instruction.
> 
> Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
> ---
>  s390x/Makefile      |  1 +
>  s390x/diag10.c      | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  s390x/unittests.cfg |  3 ++
>  3 files changed, 85 insertions(+)
>  create mode 100644 s390x/diag10.c
> 
> diff --git a/s390x/Makefile b/s390x/Makefile
> index b73031d..bc5dd91 100644
> --- a/s390x/Makefile
> +++ b/s390x/Makefile
> @@ -4,6 +4,7 @@ tests += $(TEST_DIR)/emulator.elf
>  tests += $(TEST_DIR)/sieve.elf
>  tests += $(TEST_DIR)/sthyi.elf
>  tests += $(TEST_DIR)/skey.elf
> +tests += $(TEST_DIR)/diag10.elf
>  
>  all: directories test_cases
>  
> diff --git a/s390x/diag10.c b/s390x/diag10.c
> new file mode 100644
> index 0000000..ed94ffd
> --- /dev/null
> +++ b/s390x/diag10.c
> @@ -0,0 +1,81 @@
> +/*
> + * Release pages hypercall tests (DIAG 10)
> + *
> + * Copyright (c) 2017 IBM Corp
> + *
> + * Authors:
> + *  Janosch Frank <frankja@linux.vnet.ibm.com>
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Library General Public License version 2.
> + */
> +
> +#include <libcflat.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/interrupt.h>
> +#include <asm/page.h>
> +
> +static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
> +const unsigned long page0 = (unsigned long)pagebuf;
> +const unsigned long page1 = (unsigned long)(pagebuf + PAGE_SIZE);
> +
> +/* Tells the host to release pages from guest real addresses start to
> + * end. Parameters have to be page aligned, instruction is privileged.
> + */
> +static inline void diag10(unsigned long start, unsigned long end)
> +{
> +	asm volatile (
> +		"diag	%0,%1,0x10\n"
> +		: : "a" (start), "a" (end));
> +}
> +
> +/* Try freeing the prefix */
> +static void test_prefix(void)
> +{
> +	expect_pgm_int();
> +	diag10(0, 0);
> +	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
> +
> +	expect_pgm_int();
> +	diag10(0x1000, 0x1000);
> +	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
> +
> +	expect_pgm_int();
> +	diag10(0, 0x1000);
> +	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
> +}
> +
> +static void test_params(void)
> +{
> +	/* end < start */
> +	expect_pgm_int();
> +	diag10(page1, page0);
> +	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
> +
> +	/* Unaligned start */
> +	expect_pgm_int();
> +	diag10((unsigned long) pagebuf + 42, page1);
> +	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
> +
> +	/* Unaligned end */
> +	expect_pgm_int();
> +	diag10(page0, (unsigned long) pagebuf + PAGE_SIZE + 42);
> +	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
> +}
> +
> +static void test_priv(void)
> +{
> +	expect_pgm_int();
> +	enter_pstate();
> +	diag10(page0, page0);
> +	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
> +}
> +
> +int main(void)
> +{
> +	report_prefix_push("diag10");
> +	test_prefix();
> +	test_params();
> +	test_priv();
> +	return report_summary();
> +}
> diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
> index 8321e9b..5531590 100644
> --- a/s390x/unittests.cfg
> +++ b/s390x/unittests.cfg
> @@ -41,3 +41,6 @@ accel = kvm
>  
>  [skey]
>  file = skey.elf
> +
> +[diag10]
> +file = diag10.elf
> 

Looks good to me!

Reviewed-by: Thomas Huth <thuth@redhat.com>

FWIW, the spec lists some more exceptions that could occur:

Addressing exception  The designated storage area includes discontiguous
                      storage.

Protection exception  The designated storage area includes read-only
                      storage.

Worth a try to check them, too?
Janosch Frank March 14, 2018, 7:02 a.m. UTC | #2
On 13.03.2018 20:27, Thomas Huth wrote:
> On 13.03.2018 13:01, Janosch Frank wrote:
>> Let's add some tests for the diag10 "Release pages" instruction.
>>
[...]
>> +int main(void)
>> +{
>> +	report_prefix_push("diag10");
>> +	test_prefix();
>> +	test_params();
>> +	test_priv();
>> +	return report_summary();
>> +}
>> diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
>> index 8321e9b..5531590 100644
>> --- a/s390x/unittests.cfg
>> +++ b/s390x/unittests.cfg
>> @@ -41,3 +41,6 @@ accel = kvm
>>  
>>  [skey]
>>  file = skey.elf
>> +
>> +[diag10]
>> +file = diag10.elf
>>
> 
> Looks good to me!
> 
> Reviewed-by: Thomas Huth <thuth@redhat.com>

Thanks!

> 
> FWIW, the spec lists some more exceptions that could occur:
> 
> Addressing exception  The designated storage area includes discontinuous
>                       storage.
> 
> Protection exception  The designated storage area includes read-only
>                       storage.
> 
> Worth a try to check them, too?

Any idea on how to do that?
I guess the diag10.elf will have a readonly area that I could try to free.
Thomas Huth March 14, 2018, 7:11 a.m. UTC | #3
On 14.03.2018 08:02, Janosch Frank wrote:
> On 13.03.2018 20:27, Thomas Huth wrote:
>> On 13.03.2018 13:01, Janosch Frank wrote:
>>> Let's add some tests for the diag10 "Release pages" instruction.
>>>
> [...]
>>> +int main(void)
>>> +{
>>> +	report_prefix_push("diag10");
>>> +	test_prefix();
>>> +	test_params();
>>> +	test_priv();
>>> +	return report_summary();
>>> +}
>>> diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
>>> index 8321e9b..5531590 100644
>>> --- a/s390x/unittests.cfg
>>> +++ b/s390x/unittests.cfg
>>> @@ -41,3 +41,6 @@ accel = kvm
>>>  
>>>  [skey]
>>>  file = skey.elf
>>> +
>>> +[diag10]
>>> +file = diag10.elf
>>>
>>
>> Looks good to me!
>>
>> Reviewed-by: Thomas Huth <thuth@redhat.com>
> 
> Thanks!
> 
>>
>> FWIW, the spec lists some more exceptions that could occur:
>>
>> Addressing exception  The designated storage area includes discontinuous
>>                       storage.
>>
>> Protection exception  The designated storage area includes read-only
>>                       storage.
>>
>> Worth a try to check them, too?
> 
> Any idea on how to do that?

For the addressing exception, I guess you could try something like
diag10(0x7fffffffffffe000, 0x7ffffffffffff000) ?

> I guess the diag10.elf will have a readonly area that I could try to free.

I don't think that any ELF section will be marked as readonly in the
page tables, since the ELF loading is done by QEMU, not by our kernel.
So you'd likely need to mess with the page tables on your own... I guess
that's rather something for a later patch...

 Thomas
diff mbox

Patch

diff --git a/s390x/Makefile b/s390x/Makefile
index b73031d..bc5dd91 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -4,6 +4,7 @@  tests += $(TEST_DIR)/emulator.elf
 tests += $(TEST_DIR)/sieve.elf
 tests += $(TEST_DIR)/sthyi.elf
 tests += $(TEST_DIR)/skey.elf
+tests += $(TEST_DIR)/diag10.elf
 
 all: directories test_cases
 
diff --git a/s390x/diag10.c b/s390x/diag10.c
new file mode 100644
index 0000000..ed94ffd
--- /dev/null
+++ b/s390x/diag10.c
@@ -0,0 +1,81 @@ 
+/*
+ * Release pages hypercall tests (DIAG 10)
+ *
+ * Copyright (c) 2017 IBM Corp
+ *
+ * Authors:
+ *  Janosch Frank <frankja@linux.vnet.ibm.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+
+#include <libcflat.h>
+#include <asm/asm-offsets.h>
+#include <asm/interrupt.h>
+#include <asm/page.h>
+
+static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
+const unsigned long page0 = (unsigned long)pagebuf;
+const unsigned long page1 = (unsigned long)(pagebuf + PAGE_SIZE);
+
+/* Tells the host to release pages from guest real addresses start to
+ * end. Parameters have to be page aligned, instruction is privileged.
+ */
+static inline void diag10(unsigned long start, unsigned long end)
+{
+	asm volatile (
+		"diag	%0,%1,0x10\n"
+		: : "a" (start), "a" (end));
+}
+
+/* Try freeing the prefix */
+static void test_prefix(void)
+{
+	expect_pgm_int();
+	diag10(0, 0);
+	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
+
+	expect_pgm_int();
+	diag10(0x1000, 0x1000);
+	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
+
+	expect_pgm_int();
+	diag10(0, 0x1000);
+	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
+}
+
+static void test_params(void)
+{
+	/* end < start */
+	expect_pgm_int();
+	diag10(page1, page0);
+	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
+
+	/* Unaligned start */
+	expect_pgm_int();
+	diag10((unsigned long) pagebuf + 42, page1);
+	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
+
+	/* Unaligned end */
+	expect_pgm_int();
+	diag10(page0, (unsigned long) pagebuf + PAGE_SIZE + 42);
+	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
+}
+
+static void test_priv(void)
+{
+	expect_pgm_int();
+	enter_pstate();
+	diag10(page0, page0);
+	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
+}
+
+int main(void)
+{
+	report_prefix_push("diag10");
+	test_prefix();
+	test_params();
+	test_priv();
+	return report_summary();
+}
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index 8321e9b..5531590 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -41,3 +41,6 @@  accel = kvm
 
 [skey]
 file = skey.elf
+
+[diag10]
+file = diag10.elf