1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Storage Key migration tests 4 * 5 * Copyright IBM Corp. 2022 6 * 7 * Authors: 8 * Nico Boehr <nrb@linux.ibm.com> 9 */ 10 11 #include <libcflat.h> 12 #include <migrate.h> 13 #include <asm/facility.h> 14 #include <asm/page.h> 15 #include <asm/mem.h> 16 #include <asm/interrupt.h> 17 #include <hardware.h> 18 19 #define NUM_PAGES 128 20 static uint8_t pagebuf[NUM_PAGES][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); 21 22 static void test_migration(void) 23 { 24 union skey expected_key, actual_key; 25 int i, key_to_set, key_mismatches = 0; 26 27 for (i = 0; i < NUM_PAGES; i++) { 28 /* 29 * Storage keys are 7 bit, lowest bit is always returned as zero 30 * by iske. 31 * This loop will set all 7 bits which means we set fetch 32 * protection as well as reference and change indication for 33 * some keys. 34 */ 35 key_to_set = i * 2; 36 set_storage_key(pagebuf[i], key_to_set, 1); 37 } 38 39 migrate_once(); 40 41 for (i = 0; i < NUM_PAGES; i++) { 42 actual_key.val = get_storage_key(pagebuf[i]); 43 expected_key.val = i * 2; 44 45 /* 46 * The PoP neither gives a guarantee that the reference bit is 47 * accurate nor that it won't be cleared by hardware. Hence we 48 * don't rely on it and just clear the bits to avoid compare 49 * errors. 50 */ 51 actual_key.str.rf = 0; 52 expected_key.str.rf = 0; 53 54 /* don't log anything when key matches to avoid spamming the log */ 55 if (actual_key.val != expected_key.val) { 56 key_mismatches++; 57 report_fail("page %d expected_key=0x%x actual_key=0x%x", i, expected_key.val, actual_key.val); 58 } 59 } 60 61 report(!key_mismatches, "skeys after migration match"); 62 } 63 64 int main(void) 65 { 66 report_prefix_push("migration-skey"); 67 68 if (test_facility(169)) 69 report_skip("storage key removal facility is active"); 70 else 71 test_migration(); 72 73 migrate_once(); 74 75 report_prefix_pop(); 76 return report_summary(); 77 } 78