11a7b0521SNico Boehr /* SPDX-License-Identifier: GPL-2.0-only */ 21a7b0521SNico Boehr /* 31a7b0521SNico Boehr * Storage Key migration tests 41a7b0521SNico Boehr * 51a7b0521SNico Boehr * Copyright IBM Corp. 2022 61a7b0521SNico Boehr * 71a7b0521SNico Boehr * Authors: 81a7b0521SNico Boehr * Nico Boehr <nrb@linux.ibm.com> 91a7b0521SNico Boehr */ 101a7b0521SNico Boehr 111a7b0521SNico Boehr #include <libcflat.h> 12*eef2cdb5SNico Boehr #include <migrate.h> 131a7b0521SNico Boehr #include <asm/facility.h> 141a7b0521SNico Boehr #include <asm/page.h> 151a7b0521SNico Boehr #include <asm/mem.h> 161a7b0521SNico Boehr #include <asm/interrupt.h> 171a7b0521SNico Boehr #include <hardware.h> 181a7b0521SNico Boehr 191a7b0521SNico Boehr #define NUM_PAGES 128 201a7b0521SNico Boehr static uint8_t pagebuf[NUM_PAGES][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); 211a7b0521SNico Boehr 221a7b0521SNico Boehr static void test_migration(void) 231a7b0521SNico Boehr { 241a7b0521SNico Boehr union skey expected_key, actual_key; 251a7b0521SNico Boehr int i, key_to_set, key_mismatches = 0; 261a7b0521SNico Boehr 271a7b0521SNico Boehr for (i = 0; i < NUM_PAGES; i++) { 281a7b0521SNico Boehr /* 291a7b0521SNico Boehr * Storage keys are 7 bit, lowest bit is always returned as zero 301a7b0521SNico Boehr * by iske. 311a7b0521SNico Boehr * This loop will set all 7 bits which means we set fetch 321a7b0521SNico Boehr * protection as well as reference and change indication for 331a7b0521SNico Boehr * some keys. 341a7b0521SNico Boehr */ 351a7b0521SNico Boehr key_to_set = i * 2; 361a7b0521SNico Boehr set_storage_key(pagebuf[i], key_to_set, 1); 371a7b0521SNico Boehr } 381a7b0521SNico Boehr 39*eef2cdb5SNico Boehr migrate_once(); 401a7b0521SNico Boehr 411a7b0521SNico Boehr for (i = 0; i < NUM_PAGES; i++) { 421a7b0521SNico Boehr actual_key.val = get_storage_key(pagebuf[i]); 431a7b0521SNico Boehr expected_key.val = i * 2; 441a7b0521SNico Boehr 451a7b0521SNico Boehr /* 461a7b0521SNico Boehr * The PoP neither gives a guarantee that the reference bit is 471a7b0521SNico Boehr * accurate nor that it won't be cleared by hardware. Hence we 481a7b0521SNico Boehr * don't rely on it and just clear the bits to avoid compare 491a7b0521SNico Boehr * errors. 501a7b0521SNico Boehr */ 511a7b0521SNico Boehr actual_key.str.rf = 0; 521a7b0521SNico Boehr expected_key.str.rf = 0; 531a7b0521SNico Boehr 541a7b0521SNico Boehr /* don't log anything when key matches to avoid spamming the log */ 551a7b0521SNico Boehr if (actual_key.val != expected_key.val) { 561a7b0521SNico Boehr key_mismatches++; 571a7b0521SNico Boehr report_fail("page %d expected_key=0x%x actual_key=0x%x", i, expected_key.val, actual_key.val); 581a7b0521SNico Boehr } 591a7b0521SNico Boehr } 601a7b0521SNico Boehr 611a7b0521SNico Boehr report(!key_mismatches, "skeys after migration match"); 621a7b0521SNico Boehr } 631a7b0521SNico Boehr 641a7b0521SNico Boehr int main(void) 651a7b0521SNico Boehr { 661a7b0521SNico Boehr report_prefix_push("migration-skey"); 671a7b0521SNico Boehr 68*eef2cdb5SNico Boehr if (test_facility(169)) 69*eef2cdb5SNico Boehr report_skip("storage key removal facility is active"); 70*eef2cdb5SNico Boehr else 711a7b0521SNico Boehr test_migration(); 72*eef2cdb5SNico Boehr 73*eef2cdb5SNico Boehr migrate_once(); 741a7b0521SNico Boehr 751a7b0521SNico Boehr report_prefix_pop(); 761a7b0521SNico Boehr return report_summary(); 771a7b0521SNico Boehr } 78