1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Library for managing various aspects of guests 4 * 5 * Copyright (c) 2021 IBM Corp 6 * 7 * Authors: 8 * Janosch Frank <frankja@linux.ibm.com> 9 */ 10 11 #include <asm/barrier.h> 12 #include <bitops.h> 13 #include <libcflat.h> 14 #include <sie.h> 15 #include <asm/page.h> 16 #include <asm/interrupt.h> 17 #include <libcflat.h> 18 #include <alloc_page.h> 19 #include <vmalloc.h> 20 #include <sclp.h> 21 22 void sie_expect_validity(struct vm *vm) 23 { 24 vm->validity_expected = true; 25 } 26 27 uint16_t sie_get_validity(struct vm *vm) 28 { 29 /* 30 * 0xffff will never be returned by SIE, so we can indicate a 31 * missing validity via this value. 32 */ 33 if (vm->sblk->icptcode != ICPT_VALIDITY) 34 return 0xffff; 35 36 return vm->sblk->ipb >> 16; 37 } 38 39 void sie_check_validity(struct vm *vm, uint16_t vir_exp) 40 { 41 uint16_t vir = sie_get_validity(vm); 42 43 report(vir_exp == vir, "VALIDITY: %x", vir); 44 } 45 46 void sie_handle_validity(struct vm *vm) 47 { 48 if (vm->sblk->icptcode != ICPT_VALIDITY) 49 return; 50 51 if (!vm->validity_expected) 52 report_abort("VALIDITY: %x", sie_get_validity(vm)); 53 vm->validity_expected = false; 54 } 55 56 void sie(struct vm *vm) 57 { 58 uint64_t old_cr13; 59 60 /* When a pgm int code is set, we'll never enter SIE below. */ 61 assert(!read_pgm_int_code()); 62 63 if (vm->sblk->sdf == 2) 64 memcpy(vm->sblk->pv_grregs, vm->save_area.guest.grs, 65 sizeof(vm->save_area.guest.grs)); 66 67 /* Reset icptcode so we don't trip over it below */ 68 vm->sblk->icptcode = 0; 69 70 /* 71 * Set up home address space to match primary space. Instead of running 72 * in home space all the time, we switch every time in sie() because: 73 * - tests that depend on running in primary space mode don't need to be 74 * touched 75 * - it avoids regressions in tests 76 * - switching every time makes it easier to extend this in the future, 77 * for example to allow tests to run in whatever space they want 78 */ 79 old_cr13 = stctg(13); 80 lctlg(13, stctg(1)); 81 82 /* switch to home space so guest tables can be different from host */ 83 psw_mask_set_bits(PSW_MASK_HOME); 84 85 /* also handle all interruptions in home space while in SIE */ 86 irq_set_dat_mode(true, AS_HOME); 87 88 /* leave SIE when we have an intercept or an interrupt so the test can react to it */ 89 while (vm->sblk->icptcode == 0 && !read_pgm_int_code()) { 90 sie64a(vm->sblk, &vm->save_area); 91 sie_handle_validity(vm); 92 } 93 vm->save_area.guest.grs[14] = vm->sblk->gg14; 94 vm->save_area.guest.grs[15] = vm->sblk->gg15; 95 96 irq_set_dat_mode(true, AS_PRIM); 97 psw_mask_clear_bits(PSW_MASK_HOME); 98 99 /* restore the old CR 13 */ 100 lctlg(13, old_cr13); 101 102 if (vm->sblk->sdf == 2) 103 memcpy(vm->save_area.guest.grs, vm->sblk->pv_grregs, 104 sizeof(vm->save_area.guest.grs)); 105 } 106 107 void sie_guest_sca_create(struct vm *vm) 108 { 109 vm->sca = (struct esca_block *)alloc_page(); 110 111 /* Let's start out with one page of ESCA for now */ 112 vm->sblk->scaoh = ((uint64_t)vm->sca >> 32); 113 vm->sblk->scaol = (uint64_t)vm->sca & ~0x3fU; 114 vm->sblk->ecb2 |= ECB2_ESCA; 115 116 /* Enable SIGP sense running interpretation */ 117 vm->sblk->ecb |= ECB_SRSI; 118 119 /* We assume that cpu 0 is always part of the vm */ 120 vm->sca->mcn[0] = BIT(63); 121 vm->sca->cpu[0].sda = (uint64_t)vm->sblk; 122 } 123 124 /* Initializes the struct vm members like the SIE control block. */ 125 void sie_guest_create(struct vm *vm, uint64_t guest_mem, uint64_t guest_mem_len) 126 { 127 vm->sblk = alloc_page(); 128 memset(vm->sblk, 0, PAGE_SIZE); 129 vm->sblk->cpuflags = CPUSTAT_ZARCH | CPUSTAT_RUNNING; 130 vm->sblk->ihcpu = 0xffff; 131 vm->sblk->prefix = 0; 132 133 /* Guest memory chunks are always 1MB */ 134 assert(!(guest_mem_len & ~HPAGE_MASK)); 135 vm->guest_mem = (uint8_t *)guest_mem; 136 /* For non-PV guests we re-use the host's ASCE for ease of use */ 137 vm->save_area.guest.asce = stctg(1); 138 /* Currently MSO/MSL is the easiest option */ 139 vm->sblk->mso = (uint64_t)guest_mem; 140 vm->sblk->msl = (uint64_t)guest_mem + ((guest_mem_len - 1) & HPAGE_MASK); 141 142 /* CRYCB needs to be in the first 2GB */ 143 vm->crycb = alloc_pages_flags(0, AREA_DMA31); 144 vm->sblk->crycbd = (uint32_t)(uintptr_t)vm->crycb; 145 } 146 147 /** 148 * sie_guest_alloc() - Allocate memory for a guest and map it in virtual address 149 * space such that it is properly aligned. 150 * @guest_size: the desired size of the guest in bytes. 151 */ 152 uint8_t *sie_guest_alloc(uint64_t guest_size) 153 { 154 static unsigned long guest_counter = 1; 155 u8 *guest_phys, *guest_virt; 156 unsigned long i; 157 pgd_t *root; 158 159 setup_vm(); 160 root = (pgd_t *)(stctg(1) & PAGE_MASK); 161 162 /* 163 * Start of guest memory in host virtual space needs to be aligned to 164 * 2GB for some environments. It also can't be at 2GB since the memory 165 * allocator stores its page_states metadata there. 166 * Thus we use the next multiple of 4GB after the end of physical 167 * mapping. This also leaves space after end of physical memory so the 168 * page immediately after physical memory is guaranteed not to be 169 * present. 170 */ 171 guest_virt = (uint8_t *)ALIGN(get_ram_size() + guest_counter * 4UL * SZ_1G, SZ_2G); 172 guest_counter++; 173 174 guest_phys = alloc_pages(get_order(guest_size) - 12); 175 /* 176 * Establish a new mapping of the guest memory so it can be 2GB aligned 177 * without actually requiring 2GB physical memory. 178 */ 179 for (i = 0; i < guest_size; i += PAGE_SIZE) { 180 install_page(root, __pa(guest_phys + i), guest_virt + i); 181 } 182 memset(guest_virt, 0, guest_size); 183 184 return guest_virt; 185 } 186 187 /* Frees the memory that was gathered on initialization */ 188 void sie_guest_destroy(struct vm *vm) 189 { 190 free_page(vm->crycb); 191 free_page(vm->sblk); 192 if (vm->sblk->ecb2 & ECB2_ESCA) 193 free_page(vm->sca); 194 } 195