aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/gaccess.h
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2014-01-01 10:26:52 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-04-22 07:24:38 -0400
commit2293897805c2fea69e45aca31b3589d4590af89d (patch)
tree21fc9661bc2936bca9ba3054f02613859c53d663 /arch/s390/kvm/gaccess.h
parentd95fb12ff4d73e897126043bb5d03a068997a2ef (diff)
KVM: s390: add architecture compliant guest access functions
The new guest memory access function write_guest() and read_guest() can be used to access guest memory in an architecture compliant way. These functions will look at the vcpu's PSW and select the correct address space for memory access and also perform correct address wrap around. In case DAT is turned on, page tables will be walked otherwise access will happen to real or absolute memory. Any access exception will be recognized and exception data will be stored in the vcpu's kvm_vcpu_arch.pgm member. Subsequently an exception can be injected if necessary. Missing are: - key protection checks - access register mode support - program event recording support This patch also adds write_guest_real(), read_guest_real(), write_guest_absolute() and read_guest_absolute() guest functions which can be used to access real and absolute storage. These functions currently do not perform any access checks, since there is no use case (yet?). Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm/gaccess.h')
-rw-r--r--arch/s390/kvm/gaccess.h170
1 files changed, 170 insertions, 0 deletions
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index 917aeaa04fff..21ee62cd948e 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -227,4 +227,174 @@ int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
227 227
228 return kvm_read_guest(vcpu->kvm, gpa, data, len); 228 return kvm_read_guest(vcpu->kvm, gpa, data, len);
229} 229}
230
231int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
232 unsigned long len, int write);
233
234int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
235 void *data, unsigned long len, int write);
236
237/**
238 * write_guest - copy data from kernel space to guest space
239 * @vcpu: virtual cpu
240 * @ga: guest address
241 * @data: source address in kernel space
242 * @len: number of bytes to copy
243 *
244 * Copy @len bytes from @data (kernel space) to @ga (guest address).
245 * In order to copy data to guest space the PSW of the vcpu is inspected:
246 * If DAT is off data will be copied to guest real or absolute memory.
247 * If DAT is on data will be copied to the address space as specified by
248 * the address space bits of the PSW:
249 * Primary, secondory or home space (access register mode is currently not
250 * implemented).
251 * The addressing mode of the PSW is also inspected, so that address wrap
252 * around is taken into account for 24-, 31- and 64-bit addressing mode,
253 * if the to be copied data crosses page boundaries in guest address space.
254 * In addition also low address and DAT protection are inspected before
255 * copying any data (key protection is currently not implemented).
256 *
257 * This function modifies the 'struct kvm_s390_pgm_info pgm' member of @vcpu.
258 * In case of an access exception (e.g. protection exception) pgm will contain
259 * all data necessary so that a subsequent call to 'kvm_s390_inject_prog_vcpu()'
260 * will inject a correct exception into the guest.
261 * If no access exception happened, the contents of pgm are undefined when
262 * this function returns.
263 *
264 * Returns: - zero on success
265 * - a negative value if e.g. the guest mapping is broken or in
266 * case of out-of-memory. In this case the contents of pgm are
267 * undefined. Also parts of @data may have been copied to guest
268 * space.
269 * - a positive value if an access exception happened. In this case
270 * the returned value is the program interruption code and the
271 * contents of pgm may be used to inject an exception into the
272 * guest. No data has been copied to guest space.
273 *
274 * Note: in case an access exception is recognized no data has been copied to
275 * guest space (this is also true, if the to be copied data would cross
276 * one or more page boundaries in guest space).
277 * Therefore this function may be used for nullifying and suppressing
278 * instruction emulation.
279 * It may also be used for terminating instructions, if it is undefined
280 * if data has been changed in guest space in case of an exception.
281 */
282static inline __must_check
283int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
284 unsigned long len)
285{
286 return access_guest(vcpu, ga, data, len, 1);
287}
288
289/**
290 * read_guest - copy data from guest space to kernel space
291 * @vcpu: virtual cpu
292 * @ga: guest address
293 * @data: destination address in kernel space
294 * @len: number of bytes to copy
295 *
296 * Copy @len bytes from @ga (guest address) to @data (kernel space).
297 *
298 * The behaviour of read_guest is identical to write_guest, except that
299 * data will be copied from guest space to kernel space.
300 */
301static inline __must_check
302int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
303 unsigned long len)
304{
305 return access_guest(vcpu, ga, data, len, 0);
306}
307
308/**
309 * write_guest_abs - copy data from kernel space to guest space absolute
310 * @vcpu: virtual cpu
311 * @gpa: guest physical (absolute) address
312 * @data: source address in kernel space
313 * @len: number of bytes to copy
314 *
315 * Copy @len bytes from @data (kernel space) to @gpa (guest absolute address).
316 * It is up to the caller to ensure that the entire guest memory range is
317 * valid memory before calling this function.
318 * Guest low address and key protection are not checked.
319 *
320 * Returns zero on success or -EFAULT on error.
321 *
322 * If an error occurs data may have been copied partially to guest memory.
323 */
324static inline __must_check
325int write_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
326 unsigned long len)
327{
328 return kvm_write_guest(vcpu->kvm, gpa, data, len);
329}
330
331/**
332 * read_guest_abs - copy data from guest space absolute to kernel space
333 * @vcpu: virtual cpu
334 * @gpa: guest physical (absolute) address
335 * @data: destination address in kernel space
336 * @len: number of bytes to copy
337 *
338 * Copy @len bytes from @gpa (guest absolute address) to @data (kernel space).
339 * It is up to the caller to ensure that the entire guest memory range is
340 * valid memory before calling this function.
341 * Guest key protection is not checked.
342 *
343 * Returns zero on success or -EFAULT on error.
344 *
345 * If an error occurs data may have been copied partially to kernel space.
346 */
347static inline __must_check
348int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
349 unsigned long len)
350{
351 return kvm_read_guest(vcpu->kvm, gpa, data, len);
352}
353
354/**
355 * write_guest_real - copy data from kernel space to guest space real
356 * @vcpu: virtual cpu
357 * @gra: guest real address
358 * @data: source address in kernel space
359 * @len: number of bytes to copy
360 *
361 * Copy @len bytes from @data (kernel space) to @gra (guest real address).
362 * It is up to the caller to ensure that the entire guest memory range is
363 * valid memory before calling this function.
364 * Guest low address and key protection are not checked.
365 *
366 * Returns zero on success or -EFAULT on error.
367 *
368 * If an error occurs data may have been copied partially to guest memory.
369 */
370static inline __must_check
371int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
372 unsigned long len)
373{
374 return access_guest_real(vcpu, gra, data, len, 1);
375}
376
377/**
378 * read_guest_real - copy data from guest space real to kernel space
379 * @vcpu: virtual cpu
380 * @gra: guest real address
381 * @data: destination address in kernel space
382 * @len: number of bytes to copy
383 *
384 * Copy @len bytes from @gra (guest real address) to @data (kernel space).
385 * It is up to the caller to ensure that the entire guest memory range is
386 * valid memory before calling this function.
387 * Guest key protection is not checked.
388 *
389 * Returns zero on success or -EFAULT on error.
390 *
391 * If an error occurs data may have been copied partially to kernel space.
392 */
393static inline __must_check
394int read_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
395 unsigned long len)
396{
397 return access_guest_real(vcpu, gra, data, len, 0);
398}
399
230#endif /* __KVM_S390_GACCESS_H */ 400#endif /* __KVM_S390_GACCESS_H */