1 /* 2 * Release pages hypercall tests (DIAG 10) 3 * 4 * Copyright (c) 2018 IBM Corp 5 * 6 * Authors: 7 * Janosch Frank <frankja@linux.vnet.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 13 #include <libcflat.h> 14 #include <asm/asm-offsets.h> 15 #include <asm/interrupt.h> 16 #include <asm/page.h> 17 18 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2))); 19 const unsigned long page0 = (unsigned long)pagebuf; 20 const unsigned long page1 = (unsigned long)(pagebuf + PAGE_SIZE); 21 22 /* Tells the host to release pages from guest real addresses start to 23 * end. Parameters have to be page aligned, instruction is privileged. 24 */ 25 static inline void diag10(unsigned long start, unsigned long end) 26 { 27 asm volatile ( 28 "diag %0,%1,0x10\n" 29 : : "a" (start), "a" (end)); 30 } 31 32 /* Try freeing the prefix */ 33 static void test_prefix(void) 34 { 35 expect_pgm_int(); 36 diag10(0, 0); 37 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 38 39 expect_pgm_int(); 40 diag10(0x1000, 0x1000); 41 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 42 43 expect_pgm_int(); 44 diag10(0, 0x1000); 45 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 46 } 47 48 static void test_params(void) 49 { 50 /* end < start */ 51 expect_pgm_int(); 52 diag10(page1, page0); 53 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 54 55 /* Unaligned start */ 56 expect_pgm_int(); 57 diag10((unsigned long) pagebuf + 42, page1); 58 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 59 60 /* Unaligned end */ 61 expect_pgm_int(); 62 diag10(page0, (unsigned long) pagebuf + PAGE_SIZE + 42); 63 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 64 } 65 66 static void test_priv(void) 67 { 68 expect_pgm_int(); 69 enter_pstate(); 70 diag10(page0, page0); 71 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); 72 } 73 74 int main(void) 75 { 76 report_prefix_push("diag10"); 77 test_prefix(); 78 test_params(); 79 test_priv(); 80 return report_summary(); 81 } 82