/* * Perform Frame Management Function (pfmf) tests * * Copyright (c) 2018 IBM * * Authors: * Janosch Frank * * 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 #include #include #include #include #include static uint8_t pagebuf[PAGE_SIZE * 256] __attribute__((aligned(PAGE_SIZE * 256))); static void test_priv(void) { report_prefix_push("privileged"); expect_pgm_int(); enter_pstate(); pfmf(0, pagebuf); check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); report_prefix_pop(); } static void test_4k_key(void) { union pfmf_r1 r1; union skey skey; report_prefix_push("4K"); if (test_facility(169)) { report_skip("storage key removal facility is active"); goto out; } r1.val = 0; r1.reg.sk = 1; r1.reg.fsc = PFMF_FSC_4K; r1.reg.key = 0x30; pfmf(r1.val, pagebuf); skey.val = get_storage_key(pagebuf); skey.val &= SKEY_ACC | SKEY_FP; report("set storage keys", skey.val == 0x30); out: report_prefix_pop(); } static void test_1m_key(void) { int i; bool rp = true; union pfmf_r1 r1; union skey skey; report_prefix_push("1M"); if (test_facility(169)) { report_skip("storage key removal facility is active"); goto out; } r1.val = 0; r1.reg.sk = 1; r1.reg.fsc = PFMF_FSC_1M; r1.reg.key = 0x30; pfmf(r1.val, pagebuf); for (i = 0; i < 256; i++) { skey.val = get_storage_key(pagebuf + i * PAGE_SIZE); skey.val &= SKEY_ACC | SKEY_FP; if (skey.val != 0x30) { rp = false; break; } } report("set storage keys", rp); out: report_prefix_pop(); } static void test_4k_clear(void) { union pfmf_r1 r1; r1.val = 0; r1.reg.cf = 1; r1.reg.fsc = PFMF_FSC_4K; report_prefix_push("4K"); memset(pagebuf, 42, PAGE_SIZE); pfmf(r1.val, pagebuf); report("clear memory", !memcmp(pagebuf, pagebuf + PAGE_SIZE, PAGE_SIZE)); report_prefix_pop(); } static void test_1m_clear(void) { int i; union pfmf_r1 r1; unsigned long sum = 0; r1.val = 0; r1.reg.cf = 1; r1.reg.fsc = PFMF_FSC_1M; report_prefix_push("1M"); memset(pagebuf, 42, PAGE_SIZE * 256); pfmf(r1.val, pagebuf); for (i = 0; i < PAGE_SIZE * 256; i++) sum |= pagebuf[i]; report("clear memory", !sum); report_prefix_pop(); } int main(void) { bool has_edat = test_facility(8); report_prefix_push("pfmf"); if (!has_edat) { report_skip("PFMF is not available"); goto done; } test_priv(); /* Force the buffer pages in */ memset(pagebuf, 0, PAGE_SIZE * 256); test_4k_key(); test_4k_clear(); test_1m_key(); test_1m_clear(); done: report_prefix_pop(); return report_summary(); }