All of lore.kernel.org
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH v5] s390x: Test effect of storage keys on some instructions
@ 2022-04-25 16:17 Janis Schoetterl-Glausch
  2022-04-26  7:53 ` Janosch Frank
  2022-04-26  9:19 ` Thomas Huth
  0 siblings, 2 replies; 4+ messages in thread
From: Janis Schoetterl-Glausch @ 2022-04-25 16:17 UTC (permalink / raw)
  To: Thomas Huth, Janosch Frank, Claudio Imbrenda
  Cc: Janis Schoetterl-Glausch, David Hildenbrand, kvm, linux-s390

Some instructions are emulated by KVM. Test that KVM correctly emulates
storage key checking for two of those instructions (STORE CPU ADDRESS,
SET PREFIX).
Test success and error conditions, including coverage of storage and
fetch protection override.
Also add test for TEST PROTECTION, even if that instruction will not be
emulated by KVM under normal conditions.

Signed-off-by: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
---
Range-diff against v4:
1:  a9af3e08 ! 1:  89e59626 s390x: Test effect of storage keys on some instructions
    @@ s390x/skey.c: static void test_invalid_address(void)
     +	load_psw_mask(psw_mask);
     +}
     +
    ++#define PREFIX_AREA_SIZE (PAGE_SIZE * 2)
    ++static char lowcore_tmp[PREFIX_AREA_SIZE] __attribute__((aligned(PREFIX_AREA_SIZE)));
    ++
     +static void test_set_prefix(void)
     +{
    -+	char lowcore_tmp[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
     +	uint32_t *prefix_ptr = (uint32_t *)pagebuf;
    ++	uint32_t *no_override_prefix_ptr;
     +	uint32_t old_prefix;
     +	pgd_t *root;
     +
     +	report_prefix_push("SET PREFIX");
     +	root = (pgd_t *)(stctg(1) & PAGE_MASK);
     +	old_prefix = get_prefix();
    -+	memcpy(lowcore_tmp, 0, PAGE_SIZE * 2);
    ++	memcpy(lowcore_tmp, 0, sizeof(lowcore_tmp));
     +	assert(((uint64_t)&lowcore_tmp >> 31) == 0);
     +	*prefix_ptr = (uint32_t)(uint64_t)&lowcore_tmp;
     +
    @@ s390x/skey.c: static void test_invalid_address(void)
     +	expect_pgm_int();
     +	set_prefix_key_1(prefix_ptr);
     +	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
    -+	report(get_prefix() != *prefix_ptr, "did not set prefix");
    ++	report(get_prefix() == old_prefix, "did not set prefix");
     +	report_prefix_pop();
     +
     +	register_pgm_cleanup_func(dat_fixup_pgm_int);
    @@ s390x/skey.c: static void test_invalid_address(void)
     +	set_prefix_key_1((uint32_t *)0);
     +	install_page(root, 0, 0);
     +	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
    -+	report(get_prefix() != *prefix_ptr, "did not set prefix");
    ++	report(get_prefix() == old_prefix, "did not set prefix");
     +	report_prefix_pop();
     +
     +	ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
    @@ s390x/skey.c: static void test_invalid_address(void)
     +	report(get_prefix() == *prefix_ptr, "set prefix");
     +	report_prefix_pop();
     +
    -+	{
    -+		uint32_t *prefix_ptr = (uint32_t *)(pagebuf + 2048);
    -+
    -+		WRITE_ONCE(*prefix_ptr, (uint32_t)(uint64_t)&lowcore_tmp);
    -+		report_prefix_push("fetch protection override does not apply");
    -+		set_prefix(old_prefix);
    -+		set_storage_key(pagebuf, 0x28, 0);
    -+		expect_pgm_int();
    -+		install_page(root, virt_to_pte_phys(root, pagebuf), 0);
    -+		set_prefix_key_1((uint32_t *)2048);
    -+		install_page(root, 0, 0);
    -+		check_pgm_int_code(PGM_INT_CODE_PROTECTION);
    -+		report(get_prefix() != *prefix_ptr, "did not set prefix");
    -+		report_prefix_pop();
    -+	}
    ++	no_override_prefix_ptr = (uint32_t *)(pagebuf + 2048);
    ++	WRITE_ONCE(*no_override_prefix_ptr, (uint32_t)(uint64_t)&lowcore_tmp);
    ++	report_prefix_push("fetch protection override does not apply");
    ++	set_prefix(old_prefix);
    ++	set_storage_key(pagebuf, 0x28, 0);
    ++	expect_pgm_int();
    ++	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
    ++	set_prefix_key_1((uint32_t *)2048);
    ++	install_page(root, 0, 0);
    ++	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
    ++	report(get_prefix() == old_prefix, "did not set prefix");
    ++	report_prefix_pop();
     +
     +	ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
     +	register_pgm_cleanup_func(NULL);

 lib/s390x/asm/arch_def.h |  20 ++--
 s390x/skey.c             | 227 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 238 insertions(+), 9 deletions(-)

diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
index bab3c374..676a2753 100644
--- a/lib/s390x/asm/arch_def.h
+++ b/lib/s390x/asm/arch_def.h
@@ -55,15 +55,17 @@ struct psw {
 #define PSW_MASK_BA			0x0000000080000000UL
 #define PSW_MASK_64			(PSW_MASK_BA | PSW_MASK_EA)
 
-#define CTL0_LOW_ADDR_PROT		(63 - 35)
-#define CTL0_EDAT			(63 - 40)
-#define CTL0_IEP			(63 - 43)
-#define CTL0_AFP			(63 - 45)
-#define CTL0_VECTOR			(63 - 46)
-#define CTL0_EMERGENCY_SIGNAL		(63 - 49)
-#define CTL0_EXTERNAL_CALL		(63 - 50)
-#define CTL0_CLOCK_COMPARATOR		(63 - 52)
-#define CTL0_SERVICE_SIGNAL		(63 - 54)
+#define CTL0_LOW_ADDR_PROT			(63 - 35)
+#define CTL0_EDAT				(63 - 40)
+#define CTL0_FETCH_PROTECTION_OVERRIDE		(63 - 38)
+#define CTL0_STORAGE_PROTECTION_OVERRIDE	(63 - 39)
+#define CTL0_IEP				(63 - 43)
+#define CTL0_AFP				(63 - 45)
+#define CTL0_VECTOR				(63 - 46)
+#define CTL0_EMERGENCY_SIGNAL			(63 - 49)
+#define CTL0_EXTERNAL_CALL			(63 - 50)
+#define CTL0_CLOCK_COMPARATOR			(63 - 52)
+#define CTL0_SERVICE_SIGNAL			(63 - 54)
 #define CR0_EXTM_MASK			0x0000000000006200UL /* Combined external masks */
 
 #define CTL2_GUARDED_STORAGE		(63 - 59)
diff --git a/s390x/skey.c b/s390x/skey.c
index edad53e9..39429960 100644
--- a/s390x/skey.c
+++ b/s390x/skey.c
@@ -10,6 +10,7 @@
 #include <libcflat.h>
 #include <asm/asm-offsets.h>
 #include <asm/interrupt.h>
+#include <vmalloc.h>
 #include <asm/page.h>
 #include <asm/facility.h>
 #include <asm/mem.h>
@@ -118,6 +119,227 @@ static void test_invalid_address(void)
 	report_prefix_pop();
 }
 
+static void test_test_protection(void)
+{
+	unsigned long addr = (unsigned long)pagebuf;
+
+	report_prefix_push("TPROT");
+
+	set_storage_key(pagebuf, 0x10, 0);
+	report(tprot(addr, 0) == 0, "access key 0 -> no protection");
+	report(tprot(addr, 1) == 0, "access key matches -> no protection");
+	report(tprot(addr, 2) == 1, "access key mismatches, no fetch protection -> store protection");
+
+	set_storage_key(pagebuf, 0x18, 0);
+	report(tprot(addr, 2) == 2, "access key mismatches, fetch protection -> fetch & store protection");
+
+	ctl_set_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
+	set_storage_key(pagebuf, 0x90, 0);
+	report(tprot(addr, 2) == 0, "access key mismatches, storage protection override -> no protection");
+	ctl_clear_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
+
+	set_storage_key(pagebuf, 0x00, 0);
+	report_prefix_pop();
+}
+
+/*
+ * Perform STORE CPU ADDRESS (STAP) instruction while temporarily executing
+ * with access key 1.
+ */
+static void store_cpu_address_key_1(uint16_t *out)
+{
+	asm volatile (
+		"spka	0x10\n\t"
+		"stap	%0\n\t"
+		"spka	0\n"
+	     : "+Q" (*out) /* exception: old value remains in out -> + constraint */
+	);
+}
+
+static void test_store_cpu_address(void)
+{
+	uint16_t *out = (uint16_t *)pagebuf;
+	uint16_t cpu_addr;
+
+	report_prefix_push("STORE CPU ADDRESS");
+	asm ("stap %0" : "=Q" (cpu_addr));
+
+	report_prefix_push("zero key");
+	set_storage_key(pagebuf, 0x20, 0);
+	WRITE_ONCE(*out, 0xbeef);
+	asm ("stap %0" : "=Q" (*out));
+	report(*out == cpu_addr, "store occurred");
+	report_prefix_pop();
+
+	report_prefix_push("matching key");
+	set_storage_key(pagebuf, 0x10, 0);
+	*out = 0xbeef;
+	store_cpu_address_key_1(out);
+	report(*out == cpu_addr, "store occurred");
+	report_prefix_pop();
+
+	report_prefix_push("mismatching key");
+	set_storage_key(pagebuf, 0x20, 0);
+	expect_pgm_int();
+	*out = 0xbeef;
+	store_cpu_address_key_1(out);
+	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
+	report(*out == 0xbeef, "no store occurred");
+	report_prefix_pop();
+
+	ctl_set_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
+
+	report_prefix_push("storage-protection override, invalid key");
+	set_storage_key(pagebuf, 0x20, 0);
+	expect_pgm_int();
+	*out = 0xbeef;
+	store_cpu_address_key_1(out);
+	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
+	report(*out == 0xbeef, "no store occurred");
+	report_prefix_pop();
+
+	report_prefix_push("storage-protection override, override key");
+	set_storage_key(pagebuf, 0x90, 0);
+	*out = 0xbeef;
+	store_cpu_address_key_1(out);
+	report(*out == cpu_addr, "override occurred");
+	report_prefix_pop();
+
+	ctl_clear_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
+
+	report_prefix_push("storage-protection override disabled, override key");
+	set_storage_key(pagebuf, 0x90, 0);
+	expect_pgm_int();
+	*out = 0xbeef;
+	store_cpu_address_key_1(out);
+	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
+	report(*out == 0xbeef, "no store occurred");
+	report_prefix_pop();
+
+	set_storage_key(pagebuf, 0x00, 0);
+	report_prefix_pop();
+}
+
+/*
+ * Perform SET PREFIX (SPX) instruction while temporarily executing
+ * with access key 1.
+ */
+static void set_prefix_key_1(uint32_t *prefix_ptr)
+{
+	asm volatile (
+		"spka	0x10\n\t"
+		"spx	%0\n\t"
+		"spka	0\n"
+	     :: "Q" (*prefix_ptr)
+	);
+}
+
+/*
+ * We remapped page 0, making the lowcore inaccessible, which breaks the normal
+ * handler and breaks skipping the faulting instruction.
+ * Just disable dynamic address translation to make things work.
+ */
+static void dat_fixup_pgm_int(void)
+{
+	uint64_t psw_mask = extract_psw_mask();
+
+	psw_mask &= ~PSW_MASK_DAT;
+	load_psw_mask(psw_mask);
+}
+
+#define PREFIX_AREA_SIZE (PAGE_SIZE * 2)
+static char lowcore_tmp[PREFIX_AREA_SIZE] __attribute__((aligned(PREFIX_AREA_SIZE)));
+
+static void test_set_prefix(void)
+{
+	uint32_t *prefix_ptr = (uint32_t *)pagebuf;
+	uint32_t *no_override_prefix_ptr;
+	uint32_t old_prefix;
+	pgd_t *root;
+
+	report_prefix_push("SET PREFIX");
+	root = (pgd_t *)(stctg(1) & PAGE_MASK);
+	old_prefix = get_prefix();
+	memcpy(lowcore_tmp, 0, sizeof(lowcore_tmp));
+	assert(((uint64_t)&lowcore_tmp >> 31) == 0);
+	*prefix_ptr = (uint32_t)(uint64_t)&lowcore_tmp;
+
+	report_prefix_push("zero key");
+	set_prefix(old_prefix);
+	set_storage_key(prefix_ptr, 0x20, 0);
+	set_prefix(*prefix_ptr);
+	report(get_prefix() == *prefix_ptr, "set prefix");
+	report_prefix_pop();
+
+	report_prefix_push("matching key");
+	set_prefix(old_prefix);
+	set_storage_key(pagebuf, 0x10, 0);
+	set_prefix_key_1(prefix_ptr);
+	report(get_prefix() == *prefix_ptr, "set prefix");
+	report_prefix_pop();
+
+	report_prefix_push("mismatching key");
+
+	report_prefix_push("no fetch protection");
+	set_prefix(old_prefix);
+	set_storage_key(pagebuf, 0x20, 0);
+	set_prefix_key_1(prefix_ptr);
+	report(get_prefix() == *prefix_ptr, "set prefix");
+	report_prefix_pop();
+
+	report_prefix_push("fetch protection");
+	set_prefix(old_prefix);
+	set_storage_key(pagebuf, 0x28, 0);
+	expect_pgm_int();
+	set_prefix_key_1(prefix_ptr);
+	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
+	report(get_prefix() == old_prefix, "did not set prefix");
+	report_prefix_pop();
+
+	register_pgm_cleanup_func(dat_fixup_pgm_int);
+
+	report_prefix_push("remapped page, fetch protection");
+	set_prefix(old_prefix);
+	set_storage_key(pagebuf, 0x28, 0);
+	expect_pgm_int();
+	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
+	set_prefix_key_1((uint32_t *)0);
+	install_page(root, 0, 0);
+	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
+	report(get_prefix() == old_prefix, "did not set prefix");
+	report_prefix_pop();
+
+	ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
+
+	report_prefix_push("fetch protection override applies");
+	set_prefix(old_prefix);
+	set_storage_key(pagebuf, 0x28, 0);
+	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
+	set_prefix_key_1((uint32_t *)0);
+	install_page(root, 0, 0);
+	report(get_prefix() == *prefix_ptr, "set prefix");
+	report_prefix_pop();
+
+	no_override_prefix_ptr = (uint32_t *)(pagebuf + 2048);
+	WRITE_ONCE(*no_override_prefix_ptr, (uint32_t)(uint64_t)&lowcore_tmp);
+	report_prefix_push("fetch protection override does not apply");
+	set_prefix(old_prefix);
+	set_storage_key(pagebuf, 0x28, 0);
+	expect_pgm_int();
+	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
+	set_prefix_key_1((uint32_t *)2048);
+	install_page(root, 0, 0);
+	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
+	report(get_prefix() == old_prefix, "did not set prefix");
+	report_prefix_pop();
+
+	ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
+	register_pgm_cleanup_func(NULL);
+	report_prefix_pop();
+	set_storage_key(pagebuf, 0x00, 0);
+	report_prefix_pop();
+}
+
 int main(void)
 {
 	report_prefix_push("skey");
@@ -130,6 +352,11 @@ int main(void)
 	test_set();
 	test_set_mb();
 	test_chg();
+	test_test_protection();
+	test_store_cpu_address();
+
+	setup_vm();
+	test_set_prefix();
 done:
 	report_prefix_pop();
 	return report_summary();

base-commit: 6a7a83ed106211fc0ee530a3a05f171f6a4c4e66
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [kvm-unit-tests PATCH v5] s390x: Test effect of storage keys on some instructions
  2022-04-25 16:17 [kvm-unit-tests PATCH v5] s390x: Test effect of storage keys on some instructions Janis Schoetterl-Glausch
@ 2022-04-26  7:53 ` Janosch Frank
  2022-04-26  8:48   ` Janosch Frank
  2022-04-26  9:19 ` Thomas Huth
  1 sibling, 1 reply; 4+ messages in thread
From: Janosch Frank @ 2022-04-26  7:53 UTC (permalink / raw)
  To: Janis Schoetterl-Glausch, Thomas Huth, Claudio Imbrenda
  Cc: David Hildenbrand, kvm, linux-s390

On 4/25/22 18:17, Janis Schoetterl-Glausch wrote:
> Some instructions are emulated by KVM. Test that KVM correctly emulates
> storage key checking for two of those instructions (STORE CPU ADDRESS,
> SET PREFIX).
> Test success and error conditions, including coverage of storage and
> fetch protection override.
> Also add test for TEST PROTECTION, even if that instruction will not be
> emulated by KVM under normal conditions.
> 
> Signed-off-by: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
> ---
[...]
>   lib/s390x/asm/arch_def.h |  20 ++--
>   s390x/skey.c             | 227 +++++++++++++++++++++++++++++++++++++++
>   2 files changed, 238 insertions(+), 9 deletions(-)
> 
> diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
> index bab3c374..676a2753 100644
> --- a/lib/s390x/asm/arch_def.h
> +++ b/lib/s390x/asm/arch_def.h
> @@ -55,15 +55,17 @@ struct psw {
>   #define PSW_MASK_BA			0x0000000080000000UL
>   #define PSW_MASK_64			(PSW_MASK_BA | PSW_MASK_EA)
>   
> -#define CTL0_LOW_ADDR_PROT		(63 - 35)
> -#define CTL0_EDAT			(63 - 40)
> -#define CTL0_IEP			(63 - 43)
> -#define CTL0_AFP			(63 - 45)
> -#define CTL0_VECTOR			(63 - 46)
> -#define CTL0_EMERGENCY_SIGNAL		(63 - 49)
> -#define CTL0_EXTERNAL_CALL		(63 - 50)
> -#define CTL0_CLOCK_COMPARATOR		(63 - 52)
> -#define CTL0_SERVICE_SIGNAL		(63 - 54)
> +#define CTL0_LOW_ADDR_PROT			(63 - 35)
> +#define CTL0_EDAT				(63 - 40)
> +#define CTL0_FETCH_PROTECTION_OVERRIDE		(63 - 38)
> +#define CTL0_STORAGE_PROTECTION_OVERRIDE	(63 - 39)
> +#define CTL0_IEP				(63 - 43)
> +#define CTL0_AFP				(63 - 45)
> +#define CTL0_VECTOR				(63 - 46)
> +#define CTL0_EMERGENCY_SIGNAL			(63 - 49)
> +#define CTL0_EXTERNAL_CALL			(63 - 50)
> +#define CTL0_CLOCK_COMPARATOR			(63 - 52)
> +#define CTL0_SERVICE_SIGNAL			(63 - 54)
>   #define CR0_EXTM_MASK			0x0000000000006200UL /* Combined external masks */
>   
>   #define CTL2_GUARDED_STORAGE		(63 - 59)
> diff --git a/s390x/skey.c b/s390x/skey.c
> index edad53e9..39429960 100644
> --- a/s390x/skey.c
> +++ b/s390x/skey.c
> @@ -10,6 +10,7 @@
>   #include <libcflat.h>
>   #include <asm/asm-offsets.h>
>   #include <asm/interrupt.h>
> +#include <vmalloc.h>
>   #include <asm/page.h>
>   #include <asm/facility.h>
>   #include <asm/mem.h>
> @@ -118,6 +119,227 @@ static void test_invalid_address(void)
>   	report_prefix_pop();
>   }
>   
> +static void test_test_protection(void)
> +{
> +	unsigned long addr = (unsigned long)pagebuf;
> +
> +	report_prefix_push("TPROT");
> +
> +	set_storage_key(pagebuf, 0x10, 0);
> +	report(tprot(addr, 0) == 0, "access key 0 -> no protection");
> +	report(tprot(addr, 1) == 0, "access key matches -> no protection");
> +	report(tprot(addr, 2) == 1, "access key mismatches, no fetch protection -> store protection");

I'd love to see these numerical constants replaced with named constants 
in the future so I don't have to look up the tprot CCs every time :)

> +
> +	set_storage_key(pagebuf, 0x18, 0);
> +	report(tprot(addr, 2) == 2, "access key mismatches, fetch protection -> fetch & store protection");
> +
> +	ctl_set_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
> +	set_storage_key(pagebuf, 0x90, 0);
> +	report(tprot(addr, 2) == 0, "access key mismatches, storage protection override -> no protection");
> +	ctl_clear_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
> +
> +	set_storage_key(pagebuf, 0x00, 0);
> +	report_prefix_pop();
> +}

[...]

> +/*
> + * Perform SET PREFIX (SPX) instruction while temporarily executing
> + * with access key 1.
> + */
> +static void set_prefix_key_1(uint32_t *prefix_ptr)
> +{
> +	asm volatile (
> +		"spka	0x10\n\t"
> +		"spx	%0\n\t"
> +		"spka	0\n"
> +	     :: "Q" (*prefix_ptr)
> +	);
> +}
> +
> +/*
> + * We remapped page 0, making the lowcore inaccessible, which breaks the normal
> + * handler and breaks skipping the faulting instruction.
> + * Just disable dynamic address translation to make things work.
> + */
> +static void dat_fixup_pgm_int(void)
> +{
> +	uint64_t psw_mask = extract_psw_mask();
> +
> +	psw_mask &= ~PSW_MASK_DAT;
> +	load_psw_mask(psw_mask);
> +}
> +
> +#define PREFIX_AREA_SIZE (PAGE_SIZE * 2)
> +static char lowcore_tmp[PREFIX_AREA_SIZE] __attribute__((aligned(PREFIX_AREA_SIZE)));
> +

Please add a comment that we're testing the fetch access of the operand 
since the prefix is only checked for addressing.

> +static void test_set_prefix(void)
> +{
> +	uint32_t *prefix_ptr = (uint32_t *)pagebuf;
> +	uint32_t *no_override_prefix_ptr;
> +	uint32_t old_prefix;
> +	pgd_t *root;
> +
> +	report_prefix_push("SET PREFIX");
> +	root = (pgd_t *)(stctg(1) & PAGE_MASK);
> +	old_prefix = get_prefix();
> +	memcpy(lowcore_tmp, 0, sizeof(lowcore_tmp));
> +	assert(((uint64_t)&lowcore_tmp >> 31) == 0);
> +	*prefix_ptr = (uint32_t)(uint64_t)&lowcore_tmp;
> +
> +	report_prefix_push("zero key");
> +	set_prefix(old_prefix);
> +	set_storage_key(prefix_ptr, 0x20, 0);
> +	set_prefix(*prefix_ptr);
> +	report(get_prefix() == *prefix_ptr, "set prefix");
> +	report_prefix_pop();
> +
> +	report_prefix_push("matching key");
> +	set_prefix(old_prefix);
> +	set_storage_key(pagebuf, 0x10, 0);
> +	set_prefix_key_1(prefix_ptr);
> +	report(get_prefix() == *prefix_ptr, "set prefix");
> +	report_prefix_pop();
> +
> +	report_prefix_push("mismatching key");
> +
> +	report_prefix_push("no fetch protection");
> +	set_prefix(old_prefix);
> +	set_storage_key(pagebuf, 0x20, 0);
> +	set_prefix_key_1(prefix_ptr);
> +	report(get_prefix() == *prefix_ptr, "set prefix");
> +	report_prefix_pop();
> +
> +	report_prefix_push("fetch protection");
> +	set_prefix(old_prefix);
> +	set_storage_key(pagebuf, 0x28, 0);
> +	expect_pgm_int();
> +	set_prefix_key_1(prefix_ptr);
> +	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
> +	report(get_prefix() == old_prefix, "did not set prefix");
> +	report_prefix_pop();
> +
> +	register_pgm_cleanup_func(dat_fixup_pgm_int);
> +
> +	report_prefix_push("remapped page, fetch protection");
> +	set_prefix(old_prefix);
> +	set_storage_key(pagebuf, 0x28, 0);
> +	expect_pgm_int();
> +	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
> +	set_prefix_key_1((uint32_t *)0);
> +	install_page(root, 0, 0);
> +	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
> +	report(get_prefix() == old_prefix, "did not set prefix");
> +	report_prefix_pop();
> +
> +	ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
> +
> +	report_prefix_push("fetch protection override applies");
> +	set_prefix(old_prefix);
> +	set_storage_key(pagebuf, 0x28, 0);
> +	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
> +	set_prefix_key_1((uint32_t *)0);
> +	install_page(root, 0, 0);
> +	report(get_prefix() == *prefix_ptr, "set prefix");
> +	report_prefix_pop();
> +
> +	no_override_prefix_ptr = (uint32_t *)(pagebuf + 2048);
> +	WRITE_ONCE(*no_override_prefix_ptr, (uint32_t)(uint64_t)&lowcore_tmp);
> +	report_prefix_push("fetch protection override does not apply");
> +	set_prefix(old_prefix);
> +	set_storage_key(pagebuf, 0x28, 0);
> +	expect_pgm_int();
> +	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
> +	set_prefix_key_1((uint32_t *)2048);
> +	install_page(root, 0, 0);
> +	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
> +	report(get_prefix() == old_prefix, "did not set prefix");
> +	report_prefix_pop();
> +
> +	ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
> +	register_pgm_cleanup_func(NULL);
> +	report_prefix_pop();
> +	set_storage_key(pagebuf, 0x00, 0);
> +	report_prefix_pop();
> +}
> +
>   int main(void)
>   {
>   	report_prefix_push("skey");
> @@ -130,6 +352,11 @@ int main(void)
>   	test_set();
>   	test_set_mb();
>   	test_chg();
> +	test_test_protection();
> +	test_store_cpu_address();
> +
> +	setup_vm();
> +	test_set_prefix();
>   done:
>   	report_prefix_pop();
>   	return report_summary();
> 
> base-commit: 6a7a83ed106211fc0ee530a3a05f171f6a4c4e66


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [kvm-unit-tests PATCH v5] s390x: Test effect of storage keys on some instructions
  2022-04-26  7:53 ` Janosch Frank
@ 2022-04-26  8:48   ` Janosch Frank
  0 siblings, 0 replies; 4+ messages in thread
From: Janosch Frank @ 2022-04-26  8:48 UTC (permalink / raw)
  To: Janis Schoetterl-Glausch, Thomas Huth, Claudio Imbrenda
  Cc: David Hildenbrand, kvm, linux-s390

On 4/26/22 09:53, Janosch Frank wrote:
> On 4/25/22 18:17, Janis Schoetterl-Glausch wrote:
>> Some instructions are emulated by KVM. Test that KVM correctly emulates
>> storage key checking for two of those instructions (STORE CPU ADDRESS,
>> SET PREFIX).
>> Test success and error conditions, including coverage of storage and
>> fetch protection override.
>> Also add test for TEST PROTECTION, even if that instruction will not be
>> emulated by KVM under normal conditions.
>>
>> Signed-off-by: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
[...]

We need to:
a) Fence this in our CI environments
b) Fence this for the gitlab ci s390x kvm entry

Could you please add a patch that removes the skey test from 
.gitlab-ci.yml? It's at the very end of that file.

If the nit below is fixed:
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>


> Please add a comment that we're testing the fetch access of the operand
> since the prefix is only checked for addressing.
> 
>> +static void test_set_prefix(void)
>> +{
>> +	uint32_t *prefix_ptr = (uint32_t *)pagebuf;
>> +	uint32_t *no_override_prefix_ptr;
>> +	uint32_t old_prefix;
>> +	pgd_t *root;
>> +
>> +	report_prefix_push("SET PREFIX");
>> +	root = (pgd_t *)(stctg(1) & PAGE_MASK);
>> +	old_prefix = get_prefix();
>> +	memcpy(lowcore_tmp, 0, sizeof(lowcore_tmp));
>> +	assert(((uint64_t)&lowcore_tmp >> 31) == 0);
>> +	*prefix_ptr = (uint32_t)(uint64_t)&lowcore_tmp;
>> +
>> +	report_prefix_push("zero key");
>> +	set_prefix(old_prefix);
>> +	set_storage_key(prefix_ptr, 0x20, 0);
>> +	set_prefix(*prefix_ptr);
>> +	report(get_prefix() == *prefix_ptr, "set prefix");
>> +	report_prefix_pop();
>> +
>> +	report_prefix_push("matching key");
>> +	set_prefix(old_prefix);
>> +	set_storage_key(pagebuf, 0x10, 0);
>> +	set_prefix_key_1(prefix_ptr);
>> +	report(get_prefix() == *prefix_ptr, "set prefix");
>> +	report_prefix_pop();
>> +
>> +	report_prefix_push("mismatching key");
>> +
>> +	report_prefix_push("no fetch protection");
>> +	set_prefix(old_prefix);
>> +	set_storage_key(pagebuf, 0x20, 0);
>> +	set_prefix_key_1(prefix_ptr);
>> +	report(get_prefix() == *prefix_ptr, "set prefix");
>> +	report_prefix_pop();
>> +
>> +	report_prefix_push("fetch protection");
>> +	set_prefix(old_prefix);
>> +	set_storage_key(pagebuf, 0x28, 0);
>> +	expect_pgm_int();
>> +	set_prefix_key_1(prefix_ptr);
>> +	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
>> +	report(get_prefix() == old_prefix, "did not set prefix");
>> +	report_prefix_pop();
>> +
>> +	register_pgm_cleanup_func(dat_fixup_pgm_int);
>> +
>> +	report_prefix_push("remapped page, fetch protection");
>> +	set_prefix(old_prefix);
>> +	set_storage_key(pagebuf, 0x28, 0);
>> +	expect_pgm_int();
>> +	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
>> +	set_prefix_key_1((uint32_t *)0);
>> +	install_page(root, 0, 0);
>> +	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
>> +	report(get_prefix() == old_prefix, "did not set prefix");
>> +	report_prefix_pop();
>> +
>> +	ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
>> +
>> +	report_prefix_push("fetch protection override applies");
>> +	set_prefix(old_prefix);
>> +	set_storage_key(pagebuf, 0x28, 0);
>> +	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
>> +	set_prefix_key_1((uint32_t *)0);
>> +	install_page(root, 0, 0);
>> +	report(get_prefix() == *prefix_ptr, "set prefix");
>> +	report_prefix_pop();
>> +
>> +	no_override_prefix_ptr = (uint32_t *)(pagebuf + 2048);
>> +	WRITE_ONCE(*no_override_prefix_ptr, (uint32_t)(uint64_t)&lowcore_tmp);
>> +	report_prefix_push("fetch protection override does not apply");
>> +	set_prefix(old_prefix);
>> +	set_storage_key(pagebuf, 0x28, 0);
>> +	expect_pgm_int();
>> +	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
>> +	set_prefix_key_1((uint32_t *)2048);
>> +	install_page(root, 0, 0);
>> +	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
>> +	report(get_prefix() == old_prefix, "did not set prefix");
>> +	report_prefix_pop();
>> +
>> +	ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
>> +	register_pgm_cleanup_func(NULL);
>> +	report_prefix_pop();
>> +	set_storage_key(pagebuf, 0x00, 0);
>> +	report_prefix_pop();
>> +}
>> +
>>    int main(void)
>>    {
>>    	report_prefix_push("skey");
>> @@ -130,6 +352,11 @@ int main(void)
>>    	test_set();
>>    	test_set_mb();
>>    	test_chg();
>> +	test_test_protection();
>> +	test_store_cpu_address();
>> +
>> +	setup_vm();
>> +	test_set_prefix();
>>    done:
>>    	report_prefix_pop();
>>    	return report_summary();
>>
>> base-commit: 6a7a83ed106211fc0ee530a3a05f171f6a4c4e66
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [kvm-unit-tests PATCH v5] s390x: Test effect of storage keys on some instructions
  2022-04-25 16:17 [kvm-unit-tests PATCH v5] s390x: Test effect of storage keys on some instructions Janis Schoetterl-Glausch
  2022-04-26  7:53 ` Janosch Frank
@ 2022-04-26  9:19 ` Thomas Huth
  1 sibling, 0 replies; 4+ messages in thread
From: Thomas Huth @ 2022-04-26  9:19 UTC (permalink / raw)
  To: Janis Schoetterl-Glausch, Janosch Frank, Claudio Imbrenda
  Cc: David Hildenbrand, kvm, linux-s390

On 25/04/2022 18.17, Janis Schoetterl-Glausch wrote:
> Some instructions are emulated by KVM. Test that KVM correctly emulates
> storage key checking for two of those instructions (STORE CPU ADDRESS,
> SET PREFIX).
> Test success and error conditions, including coverage of storage and
> fetch protection override.
> Also add test for TEST PROTECTION, even if that instruction will not be
> emulated by KVM under normal conditions.
> 
> Signed-off-by: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
>
Reviewed-by: Thomas Huth <thuth@redhat.com>


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-04-26  9:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-25 16:17 [kvm-unit-tests PATCH v5] s390x: Test effect of storage keys on some instructions Janis Schoetterl-Glausch
2022-04-26  7:53 ` Janosch Frank
2022-04-26  8:48   ` Janosch Frank
2022-04-26  9:19 ` Thomas Huth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.