xref: /kvm-unit-tests/lib/s390x/sie.c (revision b4667f4ca26aea926a2ddecfcb5669e0e4e7cbf4)
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 <libcflat.h>
13 #include <sie.h>
14 #include <asm/page.h>
15 #include <libcflat.h>
16 #include <alloc_page.h>
17 
18 static bool validity_expected;
19 static uint16_t vir;		/* Validity interception reason */
20 
21 void sie_expect_validity(void)
22 {
23 	validity_expected = true;
24 	vir = 0;
25 }
26 
27 void sie_check_validity(uint16_t vir_exp)
28 {
29 	report(vir_exp == vir, "VALIDITY: %x", vir);
30 	vir = 0;
31 }
32 
33 void sie_handle_validity(struct vm *vm)
34 {
35 	if (vm->sblk->icptcode != ICPT_VALIDITY)
36 		return;
37 
38 	vir = vm->sblk->ipb >> 16;
39 
40 	if (!validity_expected)
41 		report_abort("VALIDITY: %x", vir);
42 	validity_expected = false;
43 }
44 
45 void sie(struct vm *vm)
46 {
47 	/* Reset icptcode so we don't trip over it below */
48 	vm->sblk->icptcode = 0;
49 
50 	while (vm->sblk->icptcode == 0) {
51 		sie64a(vm->sblk, &vm->save_area);
52 		sie_handle_validity(vm);
53 	}
54 	vm->save_area.guest.grs[14] = vm->sblk->gg14;
55 	vm->save_area.guest.grs[15] = vm->sblk->gg15;
56 }
57 
58 /* Initializes the struct vm members like the SIE control block. */
59 void sie_guest_create(struct vm *vm, uint64_t guest_mem, uint64_t guest_mem_len)
60 {
61 	vm->sblk = alloc_page();
62 	memset(vm->sblk, 0, PAGE_SIZE);
63 	vm->sblk->cpuflags = CPUSTAT_ZARCH | CPUSTAT_RUNNING;
64 	vm->sblk->ihcpu = 0xffff;
65 	vm->sblk->prefix = 0;
66 
67 	/* Guest memory chunks are always 1MB */
68 	assert(!(guest_mem_len & ~HPAGE_MASK));
69 	/* Currently MSO/MSL is the easiest option */
70 	vm->sblk->mso = (uint64_t)guest_mem;
71 	vm->sblk->msl = (uint64_t)guest_mem + ((guest_mem_len - 1) & HPAGE_MASK);
72 
73 	/* CRYCB needs to be in the first 2GB */
74 	vm->crycb = alloc_pages_flags(0, AREA_DMA31);
75 	vm->sblk->crycbd = (uint32_t)(uintptr_t)vm->crycb;
76 }
77 
78 /* Frees the memory that was gathered on initialization */
79 void sie_guest_destroy(struct vm *vm)
80 {
81 	free_page(vm->crycb);
82 	free_page(vm->sblk);
83 }
84