blob: aa1305292ee8b4eb96bf80116397bcb67bd162d7 [file] [log] [blame]
Janosch Frankfa624cc2020-12-07 04:38:46 -05001/* SPDX-License-Identifier: GPL-2.0-only */
Janosch Frankffdfc622018-03-27 13:55:17 +02002/*
3 * Perform Frame Management Function (pfmf) tests
4 *
5 * Copyright (c) 2018 IBM
6 *
7 * Authors:
8 * Janosch Frank <frankja@linux.vnet.ibm.com>
Janosch Frankffdfc622018-03-27 13:55:17 +02009 */
10#include <libcflat.h>
11#include <asm/asm-offsets.h>
12#include <asm/interrupt.h>
13#include <asm/page.h>
14#include <asm/facility.h>
15#include <asm/mem.h>
16
Janosch Frankffdfc622018-03-27 13:55:17 +020017static uint8_t pagebuf[PAGE_SIZE * 256] __attribute__((aligned(PAGE_SIZE * 256)));
18
Janosch Frankffdfc622018-03-27 13:55:17 +020019static void test_priv(void)
20{
Janosch Franke4654a12018-09-19 15:14:14 +020021 report_prefix_push("privileged");
Janosch Frankffdfc622018-03-27 13:55:17 +020022 expect_pgm_int();
23 enter_pstate();
Janosch Frank6f9a99f2019-08-28 13:36:12 +020024 pfmf(0, pagebuf);
Janosch Frankffdfc622018-03-27 13:55:17 +020025 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
Janosch Franke4654a12018-09-19 15:14:14 +020026 report_prefix_pop();
Janosch Frankffdfc622018-03-27 13:55:17 +020027}
28
29static void test_4k_key(void)
30{
Janosch Frank6f9a99f2019-08-28 13:36:12 +020031 union pfmf_r1 r1;
Janosch Frankffdfc622018-03-27 13:55:17 +020032 union skey skey;
33
Janosch Frankc952b3d2019-02-28 09:35:38 +010034 report_prefix_push("4K");
Janosch Frank47df95c2019-08-28 13:36:15 +020035 if (test_facility(169)) {
36 report_skip("storage key removal facility is active");
37 goto out;
38 }
Janosch Frankffdfc622018-03-27 13:55:17 +020039 r1.val = 0;
40 r1.reg.sk = 1;
Janosch Frank6f9a99f2019-08-28 13:36:12 +020041 r1.reg.fsc = PFMF_FSC_4K;
Janosch Frankffdfc622018-03-27 13:55:17 +020042 r1.reg.key = 0x30;
Janosch Frank6f9a99f2019-08-28 13:36:12 +020043 pfmf(r1.val, pagebuf);
Janosch Frank7b9ca992019-08-28 13:36:13 +020044 skey.val = get_storage_key(pagebuf);
Janosch Frankd0bfafd2019-02-06 09:46:56 +010045 skey.val &= SKEY_ACC | SKEY_FP;
Thomas Hutha2998952019-12-06 12:31:02 +010046 report(skey.val == 0x30, "set storage keys");
Janosch Frank47df95c2019-08-28 13:36:15 +020047out:
Janosch Frankc952b3d2019-02-28 09:35:38 +010048 report_prefix_pop();
Janosch Frankffdfc622018-03-27 13:55:17 +020049}
50
51static void test_1m_key(void)
52{
53 int i;
Janosch Frankc952b3d2019-02-28 09:35:38 +010054 bool rp = true;
Janosch Frank6f9a99f2019-08-28 13:36:12 +020055 union pfmf_r1 r1;
Janosch Frankd0bfafd2019-02-06 09:46:56 +010056 union skey skey;
Janosch Frankffdfc622018-03-27 13:55:17 +020057
Janosch Frankc952b3d2019-02-28 09:35:38 +010058 report_prefix_push("1M");
Janosch Frank47df95c2019-08-28 13:36:15 +020059 if (test_facility(169)) {
60 report_skip("storage key removal facility is active");
61 goto out;
62 }
Janosch Frankffdfc622018-03-27 13:55:17 +020063 r1.val = 0;
64 r1.reg.sk = 1;
Janosch Frank6f9a99f2019-08-28 13:36:12 +020065 r1.reg.fsc = PFMF_FSC_1M;
Janosch Frankffdfc622018-03-27 13:55:17 +020066 r1.reg.key = 0x30;
Janosch Frank6f9a99f2019-08-28 13:36:12 +020067 pfmf(r1.val, pagebuf);
Janosch Frankffdfc622018-03-27 13:55:17 +020068 for (i = 0; i < 256; i++) {
Janosch Frank7b9ca992019-08-28 13:36:13 +020069 skey.val = get_storage_key(pagebuf + i * PAGE_SIZE);
Janosch Frankd0bfafd2019-02-06 09:46:56 +010070 skey.val &= SKEY_ACC | SKEY_FP;
71 if (skey.val != 0x30) {
Janosch Frankc952b3d2019-02-28 09:35:38 +010072 rp = false;
73 break;
Janosch Frankffdfc622018-03-27 13:55:17 +020074 }
75 }
Thomas Hutha2998952019-12-06 12:31:02 +010076 report(rp, "set storage keys");
Janosch Frank47df95c2019-08-28 13:36:15 +020077out:
Janosch Frankc952b3d2019-02-28 09:35:38 +010078 report_prefix_pop();
Janosch Frankffdfc622018-03-27 13:55:17 +020079}
80
81static void test_4k_clear(void)
82{
Janosch Frank6f9a99f2019-08-28 13:36:12 +020083 union pfmf_r1 r1;
Janosch Frankffdfc622018-03-27 13:55:17 +020084
85 r1.val = 0;
86 r1.reg.cf = 1;
Janosch Frank6f9a99f2019-08-28 13:36:12 +020087 r1.reg.fsc = PFMF_FSC_4K;
Janosch Frankffdfc622018-03-27 13:55:17 +020088
Janosch Frankc952b3d2019-02-28 09:35:38 +010089 report_prefix_push("4K");
Janosch Frankffdfc622018-03-27 13:55:17 +020090 memset(pagebuf, 42, PAGE_SIZE);
Janosch Frank6f9a99f2019-08-28 13:36:12 +020091 pfmf(r1.val, pagebuf);
Thomas Hutha2998952019-12-06 12:31:02 +010092 report(!memcmp(pagebuf, pagebuf + PAGE_SIZE, PAGE_SIZE),
93 "clear memory");
Janosch Frankc952b3d2019-02-28 09:35:38 +010094 report_prefix_pop();
Janosch Frankffdfc622018-03-27 13:55:17 +020095}
96
97static void test_1m_clear(void)
98{
99 int i;
Janosch Frank6f9a99f2019-08-28 13:36:12 +0200100 union pfmf_r1 r1;
Janosch Frankffdfc622018-03-27 13:55:17 +0200101 unsigned long sum = 0;
102
103 r1.val = 0;
104 r1.reg.cf = 1;
Janosch Frank6f9a99f2019-08-28 13:36:12 +0200105 r1.reg.fsc = PFMF_FSC_1M;
Janosch Frankffdfc622018-03-27 13:55:17 +0200106
Janosch Frankc952b3d2019-02-28 09:35:38 +0100107 report_prefix_push("1M");
Janosch Frankffdfc622018-03-27 13:55:17 +0200108 memset(pagebuf, 42, PAGE_SIZE * 256);
Janosch Frank6f9a99f2019-08-28 13:36:12 +0200109 pfmf(r1.val, pagebuf);
Janosch Frankffdfc622018-03-27 13:55:17 +0200110 for (i = 0; i < PAGE_SIZE * 256; i++)
111 sum |= pagebuf[i];
Thomas Hutha2998952019-12-06 12:31:02 +0100112 report(!sum, "clear memory");
Janosch Frankc952b3d2019-02-28 09:35:38 +0100113 report_prefix_pop();
Janosch Frankffdfc622018-03-27 13:55:17 +0200114}
115
Nico Boehr36b3a892022-02-24 16:43:30 +0100116static void test_low_addr_prot(void)
117{
118 union pfmf_r1 r1 = {
119 .reg.cf = 1,
120 .reg.fsc = PFMF_FSC_4K
121 };
122
123 report_prefix_push("low-address protection");
124
125 report_prefix_push("0x1000");
126 expect_pgm_int();
127 low_prot_enable();
128 pfmf(r1.val, (void *)0x1000);
129 low_prot_disable();
130 check_pgm_int_code(PGM_INT_CODE_PROTECTION);
131 report_prefix_pop();
132
133 report_prefix_push("0x0");
134 expect_pgm_int();
135 low_prot_enable();
136 pfmf(r1.val, 0);
137 low_prot_disable();
138 check_pgm_int_code(PGM_INT_CODE_PROTECTION);
139 report_prefix_pop();
140
141 report_prefix_pop();
142}
143
Janosch Frankffdfc622018-03-27 13:55:17 +0200144int main(void)
145{
146 bool has_edat = test_facility(8);
147
148 report_prefix_push("pfmf");
Thomas Huth90016cc2018-06-14 20:25:15 +0200149 if (!has_edat) {
150 report_skip("PFMF is not available");
Janosch Frankffdfc622018-03-27 13:55:17 +0200151 goto done;
Thomas Huth90016cc2018-06-14 20:25:15 +0200152 }
Janosch Frankffdfc622018-03-27 13:55:17 +0200153
154 test_priv();
Nico Boehr36b3a892022-02-24 16:43:30 +0100155 test_low_addr_prot();
Janosch Frankffdfc622018-03-27 13:55:17 +0200156 /* Force the buffer pages in */
157 memset(pagebuf, 0, PAGE_SIZE * 256);
158
159 test_4k_key();
Janosch Frankffdfc622018-03-27 13:55:17 +0200160 test_4k_clear();
Janosch Frankc952b3d2019-02-28 09:35:38 +0100161 test_1m_key();
Janosch Frankffdfc622018-03-27 13:55:17 +0200162 test_1m_clear();
163
164done:
165 report_prefix_pop();
166 return report_summary();
167}