Commit | Line | Data |
---|---|---|
b0c632db | 1 | /* |
a53c8fab | 2 | * access guest memory |
b0c632db | 3 | * |
d95fb12f | 4 | * Copyright IBM Corp. 2008, 2014 |
b0c632db HC |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License (version 2 only) | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | |
11 | */ | |
12 | ||
13 | #ifndef __KVM_S390_GACCESS_H | |
14 | #define __KVM_S390_GACCESS_H | |
15 | ||
16 | #include <linux/compiler.h> | |
17 | #include <linux/kvm_host.h> | |
d95fb12f HC |
18 | #include <linux/uaccess.h> |
19 | #include <linux/ptrace.h> | |
628eb9b8 | 20 | #include "kvm-s390.h" |
b0c632db | 21 | |
e497a96a HC |
22 | /** |
23 | * kvm_s390_real_to_abs - convert guest real address to guest absolute address | |
24 | * @vcpu - guest virtual cpu | |
25 | * @gra - guest real address | |
26 | * | |
27 | * Returns the guest absolute address that corresponds to the passed guest real | |
28 | * address @gra of a virtual guest cpu by applying its prefix. | |
29 | */ | |
732e5633 | 30 | static inline unsigned long kvm_s390_real_to_abs(struct kvm_vcpu *vcpu, |
e497a96a | 31 | unsigned long gra) |
732e5633 | 32 | { |
fda902cb | 33 | unsigned long prefix = kvm_s390_get_prefix(vcpu); |
e497a96a HC |
34 | |
35 | if (gra < 2 * PAGE_SIZE) | |
36 | gra += prefix; | |
37 | else if (gra >= prefix && gra < prefix + 2 * PAGE_SIZE) | |
38 | gra -= prefix; | |
39 | return gra; | |
732e5633 TH |
40 | } |
41 | ||
072c9878 HC |
42 | /** |
43 | * kvm_s390_logical_to_effective - convert guest logical to effective address | |
44 | * @vcpu: guest virtual cpu | |
45 | * @ga: guest logical address | |
46 | * | |
47 | * Convert a guest vcpu logical address to a guest vcpu effective address by | |
48 | * applying the rules of the vcpu's addressing mode defined by PSW bits 31 | |
49 | * and 32 (extendended/basic addressing mode). | |
50 | * | |
51 | * Depending on the vcpu's addressing mode the upper 40 bits (24 bit addressing | |
52 | * mode), 33 bits (31 bit addressing mode) or no bits (64 bit addressing mode) | |
53 | * of @ga will be zeroed and the remaining bits will be returned. | |
54 | */ | |
55 | static inline unsigned long kvm_s390_logical_to_effective(struct kvm_vcpu *vcpu, | |
56 | unsigned long ga) | |
57 | { | |
58 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | |
59 | ||
60 | if (psw_bits(*psw).eaba == PSW_AMODE_64BIT) | |
61 | return ga; | |
62 | if (psw_bits(*psw).eaba == PSW_AMODE_31BIT) | |
63 | return ga & ((1UL << 31) - 1); | |
64 | return ga & ((1UL << 24) - 1); | |
65 | } | |
66 | ||
d95fb12f HC |
67 | /* |
68 | * put_guest_lc, read_guest_lc and write_guest_lc are guest access functions | |
69 | * which shall only be used to access the lowcore of a vcpu. | |
70 | * These functions should be used for e.g. interrupt handlers where no | |
71 | * guest memory access protection facilities, like key or low address | |
72 | * protection, are applicable. | |
73 | * At a later point guest vcpu lowcore access should happen via pinned | |
74 | * prefix pages, so that these pages can be accessed directly via the | |
75 | * kernel mapping. All of these *_lc functions can be removed then. | |
76 | */ | |
77 | ||
78 | /** | |
79 | * put_guest_lc - write a simple variable to a guest vcpu's lowcore | |
80 | * @vcpu: virtual cpu | |
81 | * @x: value to copy to guest | |
82 | * @gra: vcpu's destination guest real address | |
83 | * | |
84 | * Copies a simple value from kernel space to a guest vcpu's lowcore. | |
85 | * The size of the variable may be 1, 2, 4 or 8 bytes. The destination | |
86 | * must be located in the vcpu's lowcore. Otherwise the result is undefined. | |
87 | * | |
88 | * Returns zero on success or -EFAULT on error. | |
89 | * | |
90 | * Note: an error indicates that either the kernel is out of memory or | |
91 | * the guest memory mapping is broken. In any case the best solution | |
92 | * would be to terminate the guest. | |
93 | * It is wrong to inject a guest exception. | |
94 | */ | |
95 | #define put_guest_lc(vcpu, x, gra) \ | |
96 | ({ \ | |
97 | struct kvm_vcpu *__vcpu = (vcpu); \ | |
98 | __typeof__(*(gra)) __x = (x); \ | |
99 | unsigned long __gpa; \ | |
100 | \ | |
101 | __gpa = (unsigned long)(gra); \ | |
fda902cb | 102 | __gpa += kvm_s390_get_prefix(__vcpu); \ |
d95fb12f HC |
103 | kvm_write_guest(__vcpu->kvm, __gpa, &__x, sizeof(__x)); \ |
104 | }) | |
105 | ||
106 | /** | |
107 | * write_guest_lc - copy data from kernel space to guest vcpu's lowcore | |
108 | * @vcpu: virtual cpu | |
109 | * @gra: vcpu's source guest real address | |
110 | * @data: source address in kernel space | |
111 | * @len: number of bytes to copy | |
112 | * | |
113 | * Copy data from kernel space to guest vcpu's lowcore. The entire range must | |
114 | * be located within the vcpu's lowcore, otherwise the result is undefined. | |
115 | * | |
116 | * Returns zero on success or -EFAULT on error. | |
117 | * | |
118 | * Note: an error indicates that either the kernel is out of memory or | |
119 | * the guest memory mapping is broken. In any case the best solution | |
120 | * would be to terminate the guest. | |
121 | * It is wrong to inject a guest exception. | |
122 | */ | |
123 | static inline __must_check | |
124 | int write_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data, | |
125 | unsigned long len) | |
126 | { | |
fda902cb | 127 | unsigned long gpa = gra + kvm_s390_get_prefix(vcpu); |
d95fb12f HC |
128 | |
129 | return kvm_write_guest(vcpu->kvm, gpa, data, len); | |
130 | } | |
131 | ||
132 | /** | |
133 | * read_guest_lc - copy data from guest vcpu's lowcore to kernel space | |
134 | * @vcpu: virtual cpu | |
135 | * @gra: vcpu's source guest real address | |
136 | * @data: destination address in kernel space | |
137 | * @len: number of bytes to copy | |
138 | * | |
139 | * Copy data from guest vcpu's lowcore to kernel space. The entire range must | |
140 | * be located within the vcpu's lowcore, otherwise the result is undefined. | |
141 | * | |
142 | * Returns zero on success or -EFAULT on error. | |
143 | * | |
144 | * Note: an error indicates that either the kernel is out of memory or | |
145 | * the guest memory mapping is broken. In any case the best solution | |
146 | * would be to terminate the guest. | |
147 | * It is wrong to inject a guest exception. | |
148 | */ | |
149 | static inline __must_check | |
150 | int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data, | |
151 | unsigned long len) | |
152 | { | |
fda902cb | 153 | unsigned long gpa = gra + kvm_s390_get_prefix(vcpu); |
d95fb12f HC |
154 | |
155 | return kvm_read_guest(vcpu->kvm, gpa, data, len); | |
156 | } | |
22938978 | 157 | |
92c96321 DH |
158 | enum gacc_mode { |
159 | GACC_FETCH, | |
160 | GACC_STORE, | |
34346b9a | 161 | GACC_IFETCH, |
92c96321 DH |
162 | }; |
163 | ||
9fbc0276 | 164 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, |
92c96321 | 165 | ar_t ar, unsigned long *gpa, enum gacc_mode mode); |
41408c28 | 166 | int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, |
92c96321 | 167 | unsigned long length, enum gacc_mode mode); |
9fbc0276 | 168 | |
8ae04b8f | 169 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
92c96321 | 170 | unsigned long len, enum gacc_mode mode); |
22938978 HC |
171 | |
172 | int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | |
92c96321 | 173 | void *data, unsigned long len, enum gacc_mode mode); |
22938978 HC |
174 | |
175 | /** | |
176 | * write_guest - copy data from kernel space to guest space | |
177 | * @vcpu: virtual cpu | |
178 | * @ga: guest address | |
8ae04b8f | 179 | * @ar: access register |
22938978 HC |
180 | * @data: source address in kernel space |
181 | * @len: number of bytes to copy | |
182 | * | |
183 | * Copy @len bytes from @data (kernel space) to @ga (guest address). | |
184 | * In order to copy data to guest space the PSW of the vcpu is inspected: | |
185 | * If DAT is off data will be copied to guest real or absolute memory. | |
186 | * If DAT is on data will be copied to the address space as specified by | |
187 | * the address space bits of the PSW: | |
664b4973 | 188 | * Primary, secondary, home space or access register mode. |
22938978 HC |
189 | * The addressing mode of the PSW is also inspected, so that address wrap |
190 | * around is taken into account for 24-, 31- and 64-bit addressing mode, | |
191 | * if the to be copied data crosses page boundaries in guest address space. | |
192 | * In addition also low address and DAT protection are inspected before | |
193 | * copying any data (key protection is currently not implemented). | |
194 | * | |
195 | * This function modifies the 'struct kvm_s390_pgm_info pgm' member of @vcpu. | |
196 | * In case of an access exception (e.g. protection exception) pgm will contain | |
197 | * all data necessary so that a subsequent call to 'kvm_s390_inject_prog_vcpu()' | |
198 | * will inject a correct exception into the guest. | |
199 | * If no access exception happened, the contents of pgm are undefined when | |
200 | * this function returns. | |
201 | * | |
202 | * Returns: - zero on success | |
203 | * - a negative value if e.g. the guest mapping is broken or in | |
204 | * case of out-of-memory. In this case the contents of pgm are | |
205 | * undefined. Also parts of @data may have been copied to guest | |
206 | * space. | |
207 | * - a positive value if an access exception happened. In this case | |
208 | * the returned value is the program interruption code and the | |
209 | * contents of pgm may be used to inject an exception into the | |
210 | * guest. No data has been copied to guest space. | |
211 | * | |
212 | * Note: in case an access exception is recognized no data has been copied to | |
213 | * guest space (this is also true, if the to be copied data would cross | |
214 | * one or more page boundaries in guest space). | |
215 | * Therefore this function may be used for nullifying and suppressing | |
216 | * instruction emulation. | |
217 | * It may also be used for terminating instructions, if it is undefined | |
218 | * if data has been changed in guest space in case of an exception. | |
219 | */ | |
220 | static inline __must_check | |
8ae04b8f | 221 | int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
22938978 HC |
222 | unsigned long len) |
223 | { | |
92c96321 | 224 | return access_guest(vcpu, ga, ar, data, len, GACC_STORE); |
22938978 HC |
225 | } |
226 | ||
227 | /** | |
228 | * read_guest - copy data from guest space to kernel space | |
229 | * @vcpu: virtual cpu | |
230 | * @ga: guest address | |
8ae04b8f | 231 | * @ar: access register |
22938978 HC |
232 | * @data: destination address in kernel space |
233 | * @len: number of bytes to copy | |
234 | * | |
235 | * Copy @len bytes from @ga (guest address) to @data (kernel space). | |
236 | * | |
237 | * The behaviour of read_guest is identical to write_guest, except that | |
238 | * data will be copied from guest space to kernel space. | |
239 | */ | |
240 | static inline __must_check | |
8ae04b8f | 241 | int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
22938978 HC |
242 | unsigned long len) |
243 | { | |
92c96321 | 244 | return access_guest(vcpu, ga, ar, data, len, GACC_FETCH); |
22938978 HC |
245 | } |
246 | ||
34346b9a DH |
247 | /** |
248 | * read_guest_instr - copy instruction data from guest space to kernel space | |
249 | * @vcpu: virtual cpu | |
250 | * @data: destination address in kernel space | |
251 | * @len: number of bytes to copy | |
252 | * | |
253 | * Copy @len bytes from the current psw address (guest space) to @data (kernel | |
254 | * space). | |
255 | * | |
256 | * The behaviour of read_guest_instr is identical to read_guest, except that | |
257 | * instruction data will be read from primary space when in home-space or | |
258 | * address-space mode. | |
259 | */ | |
260 | static inline __must_check | |
261 | int read_guest_instr(struct kvm_vcpu *vcpu, void *data, unsigned long len) | |
262 | { | |
263 | return access_guest(vcpu, vcpu->arch.sie_block->gpsw.addr, 0, data, len, | |
264 | GACC_IFETCH); | |
265 | } | |
266 | ||
22938978 HC |
267 | /** |
268 | * write_guest_abs - copy data from kernel space to guest space absolute | |
269 | * @vcpu: virtual cpu | |
270 | * @gpa: guest physical (absolute) address | |
271 | * @data: source address in kernel space | |
272 | * @len: number of bytes to copy | |
273 | * | |
274 | * Copy @len bytes from @data (kernel space) to @gpa (guest absolute address). | |
275 | * It is up to the caller to ensure that the entire guest memory range is | |
276 | * valid memory before calling this function. | |
277 | * Guest low address and key protection are not checked. | |
278 | * | |
279 | * Returns zero on success or -EFAULT on error. | |
280 | * | |
281 | * If an error occurs data may have been copied partially to guest memory. | |
282 | */ | |
283 | static inline __must_check | |
284 | int write_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data, | |
285 | unsigned long len) | |
286 | { | |
287 | return kvm_write_guest(vcpu->kvm, gpa, data, len); | |
288 | } | |
289 | ||
290 | /** | |
291 | * read_guest_abs - copy data from guest space absolute to kernel space | |
292 | * @vcpu: virtual cpu | |
293 | * @gpa: guest physical (absolute) address | |
294 | * @data: destination address in kernel space | |
295 | * @len: number of bytes to copy | |
296 | * | |
297 | * Copy @len bytes from @gpa (guest absolute address) to @data (kernel space). | |
298 | * It is up to the caller to ensure that the entire guest memory range is | |
299 | * valid memory before calling this function. | |
300 | * Guest key protection is not checked. | |
301 | * | |
302 | * Returns zero on success or -EFAULT on error. | |
303 | * | |
304 | * If an error occurs data may have been copied partially to kernel space. | |
305 | */ | |
306 | static inline __must_check | |
307 | int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data, | |
308 | unsigned long len) | |
309 | { | |
310 | return kvm_read_guest(vcpu->kvm, gpa, data, len); | |
311 | } | |
312 | ||
313 | /** | |
314 | * write_guest_real - copy data from kernel space to guest space real | |
315 | * @vcpu: virtual cpu | |
316 | * @gra: guest real address | |
317 | * @data: source address in kernel space | |
318 | * @len: number of bytes to copy | |
319 | * | |
320 | * Copy @len bytes from @data (kernel space) to @gra (guest real address). | |
321 | * It is up to the caller to ensure that the entire guest memory range is | |
322 | * valid memory before calling this function. | |
323 | * Guest low address and key protection are not checked. | |
324 | * | |
325 | * Returns zero on success or -EFAULT on error. | |
326 | * | |
327 | * If an error occurs data may have been copied partially to guest memory. | |
328 | */ | |
329 | static inline __must_check | |
330 | int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data, | |
331 | unsigned long len) | |
332 | { | |
333 | return access_guest_real(vcpu, gra, data, len, 1); | |
334 | } | |
335 | ||
336 | /** | |
337 | * read_guest_real - copy data from guest space real to kernel space | |
338 | * @vcpu: virtual cpu | |
339 | * @gra: guest real address | |
340 | * @data: destination address in kernel space | |
341 | * @len: number of bytes to copy | |
342 | * | |
343 | * Copy @len bytes from @gra (guest real address) to @data (kernel space). | |
344 | * It is up to the caller to ensure that the entire guest memory range is | |
345 | * valid memory before calling this function. | |
346 | * Guest key protection is not checked. | |
347 | * | |
348 | * Returns zero on success or -EFAULT on error. | |
349 | * | |
350 | * If an error occurs data may have been copied partially to kernel space. | |
351 | */ | |
352 | static inline __must_check | |
353 | int read_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data, | |
354 | unsigned long len) | |
355 | { | |
356 | return access_guest_real(vcpu, gra, data, len, 0); | |
357 | } | |
358 | ||
a0465f9a TH |
359 | void ipte_lock(struct kvm_vcpu *vcpu); |
360 | void ipte_unlock(struct kvm_vcpu *vcpu); | |
8a242234 | 361 | int ipte_lock_held(struct kvm_vcpu *vcpu); |
dd9e5b7b | 362 | int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra); |
8a242234 | 363 | |
f4debb40 DH |
364 | int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *shadow, |
365 | unsigned long saddr); | |
aa17aa57 | 366 | |
f9dc72e8 | 367 | #endif /* __KVM_S390_GACCESS_H */ |