xref: /kvm-unit-tests/lib/s390x/sie.h (revision dbd3800490429358367c717669aab76678429ef1)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef _S390X_SIE_H_
3 #define _S390X_SIE_H_
4 
5 #include <stdint.h>
6 #include <asm/arch_def.h>
7 
8 #define CPUSTAT_STOPPED    0x80000000
9 #define CPUSTAT_WAIT       0x10000000
10 #define CPUSTAT_ECALL_PEND 0x08000000
11 #define CPUSTAT_STOP_INT   0x04000000
12 #define CPUSTAT_IO_INT     0x02000000
13 #define CPUSTAT_EXT_INT    0x01000000
14 #define CPUSTAT_RUNNING    0x00800000
15 #define CPUSTAT_RETAINED   0x00400000
16 #define CPUSTAT_TIMING_SUB 0x00020000
17 #define CPUSTAT_SIE_SUB    0x00010000
18 #define CPUSTAT_RRF        0x00008000
19 #define CPUSTAT_SLSV       0x00004000
20 #define CPUSTAT_SLSR       0x00002000
21 #define CPUSTAT_ZARCH      0x00000800
22 #define CPUSTAT_MCDS       0x00000100
23 #define CPUSTAT_KSS        0x00000200
24 #define CPUSTAT_SM         0x00000080
25 #define CPUSTAT_IBS        0x00000040
26 #define CPUSTAT_GED2       0x00000010
27 #define CPUSTAT_G          0x00000008
28 #define CPUSTAT_GED        0x00000004
29 #define CPUSTAT_J          0x00000002
30 #define CPUSTAT_P          0x00000001
31 
32 struct kvm_s390_sie_block {
33 	uint32_t 	cpuflags;		/* 0x0000 */
34 	uint32_t : 1;			/* 0x0004 */
35 	uint32_t 	prefix : 18;
36 	uint32_t : 1;
37 	uint32_t 	ibc : 12;
38 	uint8_t		reserved08[4];		/* 0x0008 */
39 #define PROG_IN_SIE (1<<0)
40 	uint32_t	prog0c;			/* 0x000c */
41 	uint8_t		reserved10[16];		/* 0x0010 */
42 #define PROG_BLOCK_SIE	(1<<0)
43 #define PROG_REQUEST	(1<<1)
44 	uint32_t 	prog20;		/* 0x0020 */
45 	uint8_t		reserved24[4];		/* 0x0024 */
46 	uint64_t	cputm;			/* 0x0028 */
47 	uint64_t	ckc;			/* 0x0030 */
48 	uint64_t	epoch;			/* 0x0038 */
49 	uint32_t	svcc;			/* 0x0040 */
50 #define LCTL_CR0	0x8000
51 #define LCTL_CR6	0x0200
52 #define LCTL_CR9	0x0040
53 #define LCTL_CR10	0x0020
54 #define LCTL_CR11	0x0010
55 #define LCTL_CR14	0x0002
56 	uint16_t   	lctl;			/* 0x0044 */
57 	int16_t		icpua;			/* 0x0046 */
58 #define ICTL_OPEREXC	0x80000000
59 #define ICTL_PINT	0x20000000
60 #define ICTL_LPSW	0x00400000
61 #define ICTL_STCTL	0x00040000
62 #define ICTL_ISKE	0x00004000
63 #define ICTL_SSKE	0x00002000
64 #define ICTL_RRBE	0x00001000
65 #define ICTL_TPROT	0x00000200
66 	uint32_t	ictl;			/* 0x0048 */
67 #define ECA_CEI		0x80000000
68 #define ECA_IB		0x40000000
69 #define ECA_SIGPI	0x10000000
70 #define ECA_MVPGI	0x01000000
71 #define ECA_AIV		0x00200000
72 #define ECA_VX		0x00020000
73 #define ECA_PROTEXCI	0x00002000
74 #define ECA_APIE	0x00000008
75 #define ECA_SII		0x00000001
76 	uint32_t	eca;			/* 0x004c */
77 #define ICPT_INST	0x04
78 #define ICPT_PROGI	0x08
79 #define ICPT_INSTPROGI	0x0C
80 #define ICPT_EXTREQ	0x10
81 #define ICPT_EXTINT	0x14
82 #define ICPT_IOREQ	0x18
83 #define ICPT_WAIT	0x1c
84 #define ICPT_VALIDITY	0x20
85 #define ICPT_STOP	0x28
86 #define ICPT_OPEREXC	0x2C
87 #define ICPT_PARTEXEC	0x38
88 #define ICPT_IOINST	0x40
89 #define ICPT_KSS	0x5c
90 	uint8_t		icptcode;		/* 0x0050 */
91 	uint8_t		icptstatus;		/* 0x0051 */
92 	uint16_t	ihcpu;			/* 0x0052 */
93 	uint8_t		reserved54[2];		/* 0x0054 */
94 	uint16_t	ipa;			/* 0x0056 */
95 	uint32_t	ipb;			/* 0x0058 */
96 	uint32_t	scaoh;			/* 0x005c */
97 #define FPF_BPBC 	0x20
98 	uint8_t		fpf;			/* 0x0060 */
99 #define ECB_GS		0x40
100 #define ECB_TE		0x10
101 #define ECB_SRSI	0x04
102 #define ECB_HOSTPROTINT	0x02
103 	uint8_t		ecb;			/* 0x0061 */
104 #define ECB2_CMMA	0x80
105 #define ECB2_IEP	0x20
106 #define ECB2_PFMFI	0x08
107 #define ECB2_ESCA	0x04
108 	uint8_t    	ecb2;                   /* 0x0062 */
109 #define ECB3_DEA 0x08
110 #define ECB3_AES 0x04
111 #define ECB3_RI  0x01
112 	uint8_t    	ecb3;			/* 0x0063 */
113 	uint32_t	scaol;			/* 0x0064 */
114 	uint8_t		reserved68;		/* 0x0068 */
115 	uint8_t    	epdx;			/* 0x0069 */
116 	uint8_t    	reserved6a[2];		/* 0x006a */
117 	uint32_t	todpr;			/* 0x006c */
118 #define GISA_FORMAT1 0x00000001
119 	uint32_t	gd;			/* 0x0070 */
120 	uint8_t		reserved74[12];		/* 0x0074 */
121 	uint64_t	mso;			/* 0x0080 */
122 	uint64_t	msl;			/* 0x0088 */
123 	struct psw	gpsw;			/* 0x0090 */
124 	uint64_t	gg14;			/* 0x00a0 */
125 	uint64_t	gg15;			/* 0x00a8 */
126 	uint8_t		reservedb0[8];		/* 0x00b0 */
127 #define HPID_KVM	0x4
128 #define HPID_VSIE	0x5
129 	uint8_t		hpid;			/* 0x00b8 */
130 	uint8_t		reservedb9[11];		/* 0x00b9 */
131 	uint16_t	extcpuaddr;		/* 0x00c4 */
132 	uint16_t	eic;			/* 0x00c6 */
133 	uint32_t	reservedc8;		/* 0x00c8 */
134 	uint16_t	pgmilc;			/* 0x00cc */
135 	uint16_t	iprcc;			/* 0x00ce */
136 	uint32_t	dxc;			/* 0x00d0 */
137 	uint16_t	mcn;			/* 0x00d4 */
138 	uint8_t		perc;			/* 0x00d6 */
139 	uint8_t		peratmid;		/* 0x00d7 */
140 	uint64_t	peraddr;		/* 0x00d8 */
141 	uint8_t		eai;			/* 0x00e0 */
142 	uint8_t		peraid;			/* 0x00e1 */
143 	uint8_t		oai;			/* 0x00e2 */
144 	uint8_t		armid;			/* 0x00e3 */
145 	uint8_t		reservede4[4];		/* 0x00e4 */
146 	uint64_t	tecmc;			/* 0x00e8 */
147 	uint8_t		reservedf0[12];		/* 0x00f0 */
148 #define CRYCB_FORMAT_MASK 0x00000003
149 #define CRYCB_FORMAT0 0x00000000
150 #define CRYCB_FORMAT1 0x00000001
151 #define CRYCB_FORMAT2 0x00000003
152 	uint32_t	crycbd;			/* 0x00fc */
153 	uint64_t	gcr[16];		/* 0x0100 */
154 	uint64_t	gbea;			/* 0x0180 */
155 	uint8_t		reserved188[8];		/* 0x0188 */
156 	uint64_t   	sdnxo;			/* 0x0190 */
157 	uint8_t    	reserved198[8];		/* 0x0198 */
158 	uint32_t	fac;			/* 0x01a0 */
159 	uint8_t		reserved1a4[20];	/* 0x01a4 */
160 	uint64_t	cbrlo;			/* 0x01b8 */
161 	uint8_t		reserved1c0[8];		/* 0x01c0 */
162 #define ECD_HOSTREGMGMT	0x20000000
163 #define ECD_MEF		0x08000000
164 #define ECD_ETOKENF	0x02000000
165 #define ECD_ECC		0x00200000
166 	uint32_t	ecd;			/* 0x01c8 */
167 	uint8_t		reserved1cc[18];	/* 0x01cc */
168 	uint64_t	pp;			/* 0x01de */
169 	uint8_t		reserved1e6[2];		/* 0x01e6 */
170 	uint64_t	itdba;			/* 0x01e8 */
171 	uint64_t   	riccbd;			/* 0x01f0 */
172 	uint64_t	gvrd;			/* 0x01f8 */
173 } __attribute__((packed));
174 
175 struct vm_save_regs {
176 	uint64_t grs[16];
177 	uint64_t fprs[16];
178 	uint32_t fpc;
179 };
180 
181 /* We might be able to nestle all of this into the stack frame. But
182  * having a dedicated save area that saves more than the s390 ELF ABI
183  * defines leaves us more freedom in the implementation.
184 */
185 struct vm_save_area {
186 	struct vm_save_regs guest;
187 	struct vm_save_regs host;
188 };
189 
190 struct vm {
191 	struct kvm_s390_sie_block *sblk;
192 	struct vm_save_area save_area;
193 	uint8_t *crycb;				/* Crypto Control Block */
194 	/* Ptr to first guest page */
195 	uint8_t *guest_mem;
196 };
197 
198 extern void sie_entry(void);
199 extern void sie_exit(void);
200 extern void sie64a(struct kvm_s390_sie_block *sblk, struct vm_save_area *save_area);
201 void sie(struct vm *vm);
202 void sie_expect_validity(void);
203 void sie_check_validity(uint16_t vir_exp);
204 void sie_handle_validity(struct vm *vm);
205 void sie_guest_create(struct vm *vm, uint64_t guest_mem, uint64_t guest_mem_len);
206 void sie_guest_destroy(struct vm *vm);
207 
208 #endif /* _S390X_SIE_H_ */
209