1 /* 2 * Instruction Execution Prevention (IEP) DAT test. 3 * 4 * Copyright (c) 2018 IBM Corp 5 * 6 * Authors: 7 * Janosch Frank <frankja@de.ibm.com> 8 * 9 * This code is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU Library General Public License version 2. 11 */ 12 #include <libcflat.h> 13 #include <vmalloc.h> 14 #include <asm/facility.h> 15 #include <asm/interrupt.h> 16 #include <mmu.h> 17 #include <asm/pgtable.h> 18 #include <asm-generic/barrier.h> 19 20 static void test_iep(void) 21 { 22 uint16_t *code; 23 uint8_t *iepbuf = NULL; 24 void (*fn)(void); 25 26 /* Enable IEP */ 27 ctl_set_bit(0, 20); 28 29 /* Get and protect a page with the IEP bit */ 30 iepbuf = alloc_page(); 31 protect_page(iepbuf, PAGE_ENTRY_IEP); 32 33 /* Code branches into r14 which contains the return address. */ 34 code = (uint16_t *)iepbuf; 35 *code = 0x07fe; 36 fn = (void *)code; 37 38 report_prefix_push("iep protection"); 39 expect_pgm_int(); 40 /* Jump into protected page */ 41 fn(); 42 check_pgm_int_code(PGM_INT_CODE_PROTECTION); 43 report_prefix_pop(); 44 unprotect_page(iepbuf, PAGE_ENTRY_IEP); 45 ctl_clear_bit(0, 20); 46 free_page(iepbuf); 47 } 48 49 int main(void) 50 { 51 bool has_iep = test_facility(130); 52 53 report_prefix_push("iep"); 54 if (!has_iep) { 55 report_skip("DAT IEP is not available"); 56 goto done; 57 } 58 59 /* Setup DAT 1:1 mapping and memory management */ 60 setup_vm(); 61 test_iep(); 62 63 done: 64 report_prefix_pop(); 65 return report_summary(); 66 } 67