18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * access guest memory
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2008, 2014
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *    Author(s): Carsten Otte <cotte@de.ibm.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef __KVM_S390_GACCESS_H
118c2ecf20Sopenharmony_ci#define __KVM_S390_GACCESS_H
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/compiler.h>
148c2ecf20Sopenharmony_ci#include <linux/kvm_host.h>
158c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
168c2ecf20Sopenharmony_ci#include <linux/ptrace.h>
178c2ecf20Sopenharmony_ci#include "kvm-s390.h"
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/**
208c2ecf20Sopenharmony_ci * kvm_s390_real_to_abs - convert guest real address to guest absolute address
218c2ecf20Sopenharmony_ci * @prefix - guest prefix
228c2ecf20Sopenharmony_ci * @gra - guest real address
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * Returns the guest absolute address that corresponds to the passed guest real
258c2ecf20Sopenharmony_ci * address @gra of by applying the given prefix.
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_cistatic inline unsigned long _kvm_s390_real_to_abs(u32 prefix, unsigned long gra)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	if (gra < 2 * PAGE_SIZE)
308c2ecf20Sopenharmony_ci		gra += prefix;
318c2ecf20Sopenharmony_ci	else if (gra >= prefix && gra < prefix + 2 * PAGE_SIZE)
328c2ecf20Sopenharmony_ci		gra -= prefix;
338c2ecf20Sopenharmony_ci	return gra;
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/**
378c2ecf20Sopenharmony_ci * kvm_s390_real_to_abs - convert guest real address to guest absolute address
388c2ecf20Sopenharmony_ci * @vcpu - guest virtual cpu
398c2ecf20Sopenharmony_ci * @gra - guest real address
408c2ecf20Sopenharmony_ci *
418c2ecf20Sopenharmony_ci * Returns the guest absolute address that corresponds to the passed guest real
428c2ecf20Sopenharmony_ci * address @gra of a virtual guest cpu by applying its prefix.
438c2ecf20Sopenharmony_ci */
448c2ecf20Sopenharmony_cistatic inline unsigned long kvm_s390_real_to_abs(struct kvm_vcpu *vcpu,
458c2ecf20Sopenharmony_ci						 unsigned long gra)
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	return _kvm_s390_real_to_abs(kvm_s390_get_prefix(vcpu), gra);
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/**
518c2ecf20Sopenharmony_ci * _kvm_s390_logical_to_effective - convert guest logical to effective address
528c2ecf20Sopenharmony_ci * @psw: psw of the guest
538c2ecf20Sopenharmony_ci * @ga: guest logical address
548c2ecf20Sopenharmony_ci *
558c2ecf20Sopenharmony_ci * Convert a guest logical address to an effective address by applying the
568c2ecf20Sopenharmony_ci * rules of the addressing mode defined by bits 31 and 32 of the given PSW
578c2ecf20Sopenharmony_ci * (extendended/basic addressing mode).
588c2ecf20Sopenharmony_ci *
598c2ecf20Sopenharmony_ci * Depending on the addressing mode, the upper 40 bits (24 bit addressing
608c2ecf20Sopenharmony_ci * mode), 33 bits (31 bit addressing mode) or no bits (64 bit addressing
618c2ecf20Sopenharmony_ci * mode) of @ga will be zeroed and the remaining bits will be returned.
628c2ecf20Sopenharmony_ci */
638c2ecf20Sopenharmony_cistatic inline unsigned long _kvm_s390_logical_to_effective(psw_t *psw,
648c2ecf20Sopenharmony_ci							   unsigned long ga)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	if (psw_bits(*psw).eaba == PSW_BITS_AMODE_64BIT)
678c2ecf20Sopenharmony_ci		return ga;
688c2ecf20Sopenharmony_ci	if (psw_bits(*psw).eaba == PSW_BITS_AMODE_31BIT)
698c2ecf20Sopenharmony_ci		return ga & ((1UL << 31) - 1);
708c2ecf20Sopenharmony_ci	return ga & ((1UL << 24) - 1);
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/**
748c2ecf20Sopenharmony_ci * kvm_s390_logical_to_effective - convert guest logical to effective address
758c2ecf20Sopenharmony_ci * @vcpu: guest virtual cpu
768c2ecf20Sopenharmony_ci * @ga: guest logical address
778c2ecf20Sopenharmony_ci *
788c2ecf20Sopenharmony_ci * Convert a guest vcpu logical address to a guest vcpu effective address by
798c2ecf20Sopenharmony_ci * applying the rules of the vcpu's addressing mode defined by PSW bits 31
808c2ecf20Sopenharmony_ci * and 32 (extendended/basic addressing mode).
818c2ecf20Sopenharmony_ci *
828c2ecf20Sopenharmony_ci * Depending on the vcpu's addressing mode the upper 40 bits (24 bit addressing
838c2ecf20Sopenharmony_ci * mode), 33 bits (31 bit addressing mode) or no bits (64 bit addressing mode)
848c2ecf20Sopenharmony_ci * of @ga will be zeroed and the remaining bits will be returned.
858c2ecf20Sopenharmony_ci */
868c2ecf20Sopenharmony_cistatic inline unsigned long kvm_s390_logical_to_effective(struct kvm_vcpu *vcpu,
878c2ecf20Sopenharmony_ci							  unsigned long ga)
888c2ecf20Sopenharmony_ci{
898c2ecf20Sopenharmony_ci	return _kvm_s390_logical_to_effective(&vcpu->arch.sie_block->gpsw, ga);
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/*
938c2ecf20Sopenharmony_ci * put_guest_lc, read_guest_lc and write_guest_lc are guest access functions
948c2ecf20Sopenharmony_ci * which shall only be used to access the lowcore of a vcpu.
958c2ecf20Sopenharmony_ci * These functions should be used for e.g. interrupt handlers where no
968c2ecf20Sopenharmony_ci * guest memory access protection facilities, like key or low address
978c2ecf20Sopenharmony_ci * protection, are applicable.
988c2ecf20Sopenharmony_ci * At a later point guest vcpu lowcore access should happen via pinned
998c2ecf20Sopenharmony_ci * prefix pages, so that these pages can be accessed directly via the
1008c2ecf20Sopenharmony_ci * kernel mapping. All of these *_lc functions can be removed then.
1018c2ecf20Sopenharmony_ci */
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci/**
1048c2ecf20Sopenharmony_ci * put_guest_lc - write a simple variable to a guest vcpu's lowcore
1058c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
1068c2ecf20Sopenharmony_ci * @x: value to copy to guest
1078c2ecf20Sopenharmony_ci * @gra: vcpu's destination guest real address
1088c2ecf20Sopenharmony_ci *
1098c2ecf20Sopenharmony_ci * Copies a simple value from kernel space to a guest vcpu's lowcore.
1108c2ecf20Sopenharmony_ci * The size of the variable may be 1, 2, 4 or 8 bytes. The destination
1118c2ecf20Sopenharmony_ci * must be located in the vcpu's lowcore. Otherwise the result is undefined.
1128c2ecf20Sopenharmony_ci *
1138c2ecf20Sopenharmony_ci * Returns zero on success or -EFAULT on error.
1148c2ecf20Sopenharmony_ci *
1158c2ecf20Sopenharmony_ci * Note: an error indicates that either the kernel is out of memory or
1168c2ecf20Sopenharmony_ci *	 the guest memory mapping is broken. In any case the best solution
1178c2ecf20Sopenharmony_ci *	 would be to terminate the guest.
1188c2ecf20Sopenharmony_ci *	 It is wrong to inject a guest exception.
1198c2ecf20Sopenharmony_ci */
1208c2ecf20Sopenharmony_ci#define put_guest_lc(vcpu, x, gra)				\
1218c2ecf20Sopenharmony_ci({								\
1228c2ecf20Sopenharmony_ci	struct kvm_vcpu *__vcpu = (vcpu);			\
1238c2ecf20Sopenharmony_ci	__typeof__(*(gra)) __x = (x);				\
1248c2ecf20Sopenharmony_ci	unsigned long __gpa;					\
1258c2ecf20Sopenharmony_ci								\
1268c2ecf20Sopenharmony_ci	__gpa = (unsigned long)(gra);				\
1278c2ecf20Sopenharmony_ci	__gpa += kvm_s390_get_prefix(__vcpu);			\
1288c2ecf20Sopenharmony_ci	kvm_write_guest(__vcpu->kvm, __gpa, &__x, sizeof(__x));	\
1298c2ecf20Sopenharmony_ci})
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci/**
1328c2ecf20Sopenharmony_ci * write_guest_lc - copy data from kernel space to guest vcpu's lowcore
1338c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
1348c2ecf20Sopenharmony_ci * @gra: vcpu's source guest real address
1358c2ecf20Sopenharmony_ci * @data: source address in kernel space
1368c2ecf20Sopenharmony_ci * @len: number of bytes to copy
1378c2ecf20Sopenharmony_ci *
1388c2ecf20Sopenharmony_ci * Copy data from kernel space to guest vcpu's lowcore. The entire range must
1398c2ecf20Sopenharmony_ci * be located within the vcpu's lowcore, otherwise the result is undefined.
1408c2ecf20Sopenharmony_ci *
1418c2ecf20Sopenharmony_ci * Returns zero on success or -EFAULT on error.
1428c2ecf20Sopenharmony_ci *
1438c2ecf20Sopenharmony_ci * Note: an error indicates that either the kernel is out of memory or
1448c2ecf20Sopenharmony_ci *	 the guest memory mapping is broken. In any case the best solution
1458c2ecf20Sopenharmony_ci *	 would be to terminate the guest.
1468c2ecf20Sopenharmony_ci *	 It is wrong to inject a guest exception.
1478c2ecf20Sopenharmony_ci */
1488c2ecf20Sopenharmony_cistatic inline __must_check
1498c2ecf20Sopenharmony_ciint write_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
1508c2ecf20Sopenharmony_ci		   unsigned long len)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	unsigned long gpa = gra + kvm_s390_get_prefix(vcpu);
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	return kvm_write_guest(vcpu->kvm, gpa, data, len);
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci/**
1588c2ecf20Sopenharmony_ci * read_guest_lc - copy data from guest vcpu's lowcore to kernel space
1598c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
1608c2ecf20Sopenharmony_ci * @gra: vcpu's source guest real address
1618c2ecf20Sopenharmony_ci * @data: destination address in kernel space
1628c2ecf20Sopenharmony_ci * @len: number of bytes to copy
1638c2ecf20Sopenharmony_ci *
1648c2ecf20Sopenharmony_ci * Copy data from guest vcpu's lowcore to kernel space. The entire range must
1658c2ecf20Sopenharmony_ci * be located within the vcpu's lowcore, otherwise the result is undefined.
1668c2ecf20Sopenharmony_ci *
1678c2ecf20Sopenharmony_ci * Returns zero on success or -EFAULT on error.
1688c2ecf20Sopenharmony_ci *
1698c2ecf20Sopenharmony_ci * Note: an error indicates that either the kernel is out of memory or
1708c2ecf20Sopenharmony_ci *	 the guest memory mapping is broken. In any case the best solution
1718c2ecf20Sopenharmony_ci *	 would be to terminate the guest.
1728c2ecf20Sopenharmony_ci *	 It is wrong to inject a guest exception.
1738c2ecf20Sopenharmony_ci */
1748c2ecf20Sopenharmony_cistatic inline __must_check
1758c2ecf20Sopenharmony_ciint read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
1768c2ecf20Sopenharmony_ci		  unsigned long len)
1778c2ecf20Sopenharmony_ci{
1788c2ecf20Sopenharmony_ci	unsigned long gpa = gra + kvm_s390_get_prefix(vcpu);
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	return kvm_read_guest(vcpu->kvm, gpa, data, len);
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_cienum gacc_mode {
1848c2ecf20Sopenharmony_ci	GACC_FETCH,
1858c2ecf20Sopenharmony_ci	GACC_STORE,
1868c2ecf20Sopenharmony_ci	GACC_IFETCH,
1878c2ecf20Sopenharmony_ci};
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ciint guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva,
1908c2ecf20Sopenharmony_ci			    u8 ar, unsigned long *gpa, enum gacc_mode mode);
1918c2ecf20Sopenharmony_ciint check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
1928c2ecf20Sopenharmony_ci		    unsigned long length, enum gacc_mode mode);
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ciint access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
1958c2ecf20Sopenharmony_ci		 unsigned long len, enum gacc_mode mode);
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ciint access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
1988c2ecf20Sopenharmony_ci		      void *data, unsigned long len, enum gacc_mode mode);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci/**
2018c2ecf20Sopenharmony_ci * write_guest - copy data from kernel space to guest space
2028c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
2038c2ecf20Sopenharmony_ci * @ga: guest address
2048c2ecf20Sopenharmony_ci * @ar: access register
2058c2ecf20Sopenharmony_ci * @data: source address in kernel space
2068c2ecf20Sopenharmony_ci * @len: number of bytes to copy
2078c2ecf20Sopenharmony_ci *
2088c2ecf20Sopenharmony_ci * Copy @len bytes from @data (kernel space) to @ga (guest address).
2098c2ecf20Sopenharmony_ci * In order to copy data to guest space the PSW of the vcpu is inspected:
2108c2ecf20Sopenharmony_ci * If DAT is off data will be copied to guest real or absolute memory.
2118c2ecf20Sopenharmony_ci * If DAT is on data will be copied to the address space as specified by
2128c2ecf20Sopenharmony_ci * the address space bits of the PSW:
2138c2ecf20Sopenharmony_ci * Primary, secondary, home space or access register mode.
2148c2ecf20Sopenharmony_ci * The addressing mode of the PSW is also inspected, so that address wrap
2158c2ecf20Sopenharmony_ci * around is taken into account for 24-, 31- and 64-bit addressing mode,
2168c2ecf20Sopenharmony_ci * if the to be copied data crosses page boundaries in guest address space.
2178c2ecf20Sopenharmony_ci * In addition also low address and DAT protection are inspected before
2188c2ecf20Sopenharmony_ci * copying any data (key protection is currently not implemented).
2198c2ecf20Sopenharmony_ci *
2208c2ecf20Sopenharmony_ci * This function modifies the 'struct kvm_s390_pgm_info pgm' member of @vcpu.
2218c2ecf20Sopenharmony_ci * In case of an access exception (e.g. protection exception) pgm will contain
2228c2ecf20Sopenharmony_ci * all data necessary so that a subsequent call to 'kvm_s390_inject_prog_vcpu()'
2238c2ecf20Sopenharmony_ci * will inject a correct exception into the guest.
2248c2ecf20Sopenharmony_ci * If no access exception happened, the contents of pgm are undefined when
2258c2ecf20Sopenharmony_ci * this function returns.
2268c2ecf20Sopenharmony_ci *
2278c2ecf20Sopenharmony_ci * Returns:  - zero on success
2288c2ecf20Sopenharmony_ci *	     - a negative value if e.g. the guest mapping is broken or in
2298c2ecf20Sopenharmony_ci *	       case of out-of-memory. In this case the contents of pgm are
2308c2ecf20Sopenharmony_ci *	       undefined. Also parts of @data may have been copied to guest
2318c2ecf20Sopenharmony_ci *	       space.
2328c2ecf20Sopenharmony_ci *	     - a positive value if an access exception happened. In this case
2338c2ecf20Sopenharmony_ci *	       the returned value is the program interruption code and the
2348c2ecf20Sopenharmony_ci *	       contents of pgm may be used to inject an exception into the
2358c2ecf20Sopenharmony_ci *	       guest. No data has been copied to guest space.
2368c2ecf20Sopenharmony_ci *
2378c2ecf20Sopenharmony_ci * Note: in case an access exception is recognized no data has been copied to
2388c2ecf20Sopenharmony_ci *	 guest space (this is also true, if the to be copied data would cross
2398c2ecf20Sopenharmony_ci *	 one or more page boundaries in guest space).
2408c2ecf20Sopenharmony_ci *	 Therefore this function may be used for nullifying and suppressing
2418c2ecf20Sopenharmony_ci *	 instruction emulation.
2428c2ecf20Sopenharmony_ci *	 It may also be used for terminating instructions, if it is undefined
2438c2ecf20Sopenharmony_ci *	 if data has been changed in guest space in case of an exception.
2448c2ecf20Sopenharmony_ci */
2458c2ecf20Sopenharmony_cistatic inline __must_check
2468c2ecf20Sopenharmony_ciint write_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
2478c2ecf20Sopenharmony_ci		unsigned long len)
2488c2ecf20Sopenharmony_ci{
2498c2ecf20Sopenharmony_ci	return access_guest(vcpu, ga, ar, data, len, GACC_STORE);
2508c2ecf20Sopenharmony_ci}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci/**
2538c2ecf20Sopenharmony_ci * read_guest - copy data from guest space to kernel space
2548c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
2558c2ecf20Sopenharmony_ci * @ga: guest address
2568c2ecf20Sopenharmony_ci * @ar: access register
2578c2ecf20Sopenharmony_ci * @data: destination address in kernel space
2588c2ecf20Sopenharmony_ci * @len: number of bytes to copy
2598c2ecf20Sopenharmony_ci *
2608c2ecf20Sopenharmony_ci * Copy @len bytes from @ga (guest address) to @data (kernel space).
2618c2ecf20Sopenharmony_ci *
2628c2ecf20Sopenharmony_ci * The behaviour of read_guest is identical to write_guest, except that
2638c2ecf20Sopenharmony_ci * data will be copied from guest space to kernel space.
2648c2ecf20Sopenharmony_ci */
2658c2ecf20Sopenharmony_cistatic inline __must_check
2668c2ecf20Sopenharmony_ciint read_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
2678c2ecf20Sopenharmony_ci	       unsigned long len)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	return access_guest(vcpu, ga, ar, data, len, GACC_FETCH);
2708c2ecf20Sopenharmony_ci}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci/**
2738c2ecf20Sopenharmony_ci * read_guest_instr - copy instruction data from guest space to kernel space
2748c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
2758c2ecf20Sopenharmony_ci * @ga: guest address
2768c2ecf20Sopenharmony_ci * @data: destination address in kernel space
2778c2ecf20Sopenharmony_ci * @len: number of bytes to copy
2788c2ecf20Sopenharmony_ci *
2798c2ecf20Sopenharmony_ci * Copy @len bytes from the given address (guest space) to @data (kernel
2808c2ecf20Sopenharmony_ci * space).
2818c2ecf20Sopenharmony_ci *
2828c2ecf20Sopenharmony_ci * The behaviour of read_guest_instr is identical to read_guest, except that
2838c2ecf20Sopenharmony_ci * instruction data will be read from primary space when in home-space or
2848c2ecf20Sopenharmony_ci * address-space mode.
2858c2ecf20Sopenharmony_ci */
2868c2ecf20Sopenharmony_cistatic inline __must_check
2878c2ecf20Sopenharmony_ciint read_guest_instr(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
2888c2ecf20Sopenharmony_ci		     unsigned long len)
2898c2ecf20Sopenharmony_ci{
2908c2ecf20Sopenharmony_ci	return access_guest(vcpu, ga, 0, data, len, GACC_IFETCH);
2918c2ecf20Sopenharmony_ci}
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci/**
2948c2ecf20Sopenharmony_ci * write_guest_abs - copy data from kernel space to guest space absolute
2958c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
2968c2ecf20Sopenharmony_ci * @gpa: guest physical (absolute) address
2978c2ecf20Sopenharmony_ci * @data: source address in kernel space
2988c2ecf20Sopenharmony_ci * @len: number of bytes to copy
2998c2ecf20Sopenharmony_ci *
3008c2ecf20Sopenharmony_ci * Copy @len bytes from @data (kernel space) to @gpa (guest absolute address).
3018c2ecf20Sopenharmony_ci * It is up to the caller to ensure that the entire guest memory range is
3028c2ecf20Sopenharmony_ci * valid memory before calling this function.
3038c2ecf20Sopenharmony_ci * Guest low address and key protection are not checked.
3048c2ecf20Sopenharmony_ci *
3058c2ecf20Sopenharmony_ci * Returns zero on success or -EFAULT on error.
3068c2ecf20Sopenharmony_ci *
3078c2ecf20Sopenharmony_ci * If an error occurs data may have been copied partially to guest memory.
3088c2ecf20Sopenharmony_ci */
3098c2ecf20Sopenharmony_cistatic inline __must_check
3108c2ecf20Sopenharmony_ciint write_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
3118c2ecf20Sopenharmony_ci		    unsigned long len)
3128c2ecf20Sopenharmony_ci{
3138c2ecf20Sopenharmony_ci	return kvm_write_guest(vcpu->kvm, gpa, data, len);
3148c2ecf20Sopenharmony_ci}
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci/**
3178c2ecf20Sopenharmony_ci * read_guest_abs - copy data from guest space absolute to kernel space
3188c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
3198c2ecf20Sopenharmony_ci * @gpa: guest physical (absolute) address
3208c2ecf20Sopenharmony_ci * @data: destination address in kernel space
3218c2ecf20Sopenharmony_ci * @len: number of bytes to copy
3228c2ecf20Sopenharmony_ci *
3238c2ecf20Sopenharmony_ci * Copy @len bytes from @gpa (guest absolute address) to @data (kernel space).
3248c2ecf20Sopenharmony_ci * It is up to the caller to ensure that the entire guest memory range is
3258c2ecf20Sopenharmony_ci * valid memory before calling this function.
3268c2ecf20Sopenharmony_ci * Guest key protection is not checked.
3278c2ecf20Sopenharmony_ci *
3288c2ecf20Sopenharmony_ci * Returns zero on success or -EFAULT on error.
3298c2ecf20Sopenharmony_ci *
3308c2ecf20Sopenharmony_ci * If an error occurs data may have been copied partially to kernel space.
3318c2ecf20Sopenharmony_ci */
3328c2ecf20Sopenharmony_cistatic inline __must_check
3338c2ecf20Sopenharmony_ciint read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
3348c2ecf20Sopenharmony_ci		   unsigned long len)
3358c2ecf20Sopenharmony_ci{
3368c2ecf20Sopenharmony_ci	return kvm_read_guest(vcpu->kvm, gpa, data, len);
3378c2ecf20Sopenharmony_ci}
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci/**
3408c2ecf20Sopenharmony_ci * write_guest_real - copy data from kernel space to guest space real
3418c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
3428c2ecf20Sopenharmony_ci * @gra: guest real address
3438c2ecf20Sopenharmony_ci * @data: source address in kernel space
3448c2ecf20Sopenharmony_ci * @len: number of bytes to copy
3458c2ecf20Sopenharmony_ci *
3468c2ecf20Sopenharmony_ci * Copy @len bytes from @data (kernel space) to @gra (guest real address).
3478c2ecf20Sopenharmony_ci * It is up to the caller to ensure that the entire guest memory range is
3488c2ecf20Sopenharmony_ci * valid memory before calling this function.
3498c2ecf20Sopenharmony_ci * Guest low address and key protection are not checked.
3508c2ecf20Sopenharmony_ci *
3518c2ecf20Sopenharmony_ci * Returns zero on success or -EFAULT on error.
3528c2ecf20Sopenharmony_ci *
3538c2ecf20Sopenharmony_ci * If an error occurs data may have been copied partially to guest memory.
3548c2ecf20Sopenharmony_ci */
3558c2ecf20Sopenharmony_cistatic inline __must_check
3568c2ecf20Sopenharmony_ciint write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
3578c2ecf20Sopenharmony_ci		     unsigned long len)
3588c2ecf20Sopenharmony_ci{
3598c2ecf20Sopenharmony_ci	return access_guest_real(vcpu, gra, data, len, 1);
3608c2ecf20Sopenharmony_ci}
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci/**
3638c2ecf20Sopenharmony_ci * read_guest_real - copy data from guest space real to kernel space
3648c2ecf20Sopenharmony_ci * @vcpu: virtual cpu
3658c2ecf20Sopenharmony_ci * @gra: guest real address
3668c2ecf20Sopenharmony_ci * @data: destination address in kernel space
3678c2ecf20Sopenharmony_ci * @len: number of bytes to copy
3688c2ecf20Sopenharmony_ci *
3698c2ecf20Sopenharmony_ci * Copy @len bytes from @gra (guest real address) to @data (kernel space).
3708c2ecf20Sopenharmony_ci * It is up to the caller to ensure that the entire guest memory range is
3718c2ecf20Sopenharmony_ci * valid memory before calling this function.
3728c2ecf20Sopenharmony_ci * Guest key protection is not checked.
3738c2ecf20Sopenharmony_ci *
3748c2ecf20Sopenharmony_ci * Returns zero on success or -EFAULT on error.
3758c2ecf20Sopenharmony_ci *
3768c2ecf20Sopenharmony_ci * If an error occurs data may have been copied partially to kernel space.
3778c2ecf20Sopenharmony_ci */
3788c2ecf20Sopenharmony_cistatic inline __must_check
3798c2ecf20Sopenharmony_ciint read_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
3808c2ecf20Sopenharmony_ci		    unsigned long len)
3818c2ecf20Sopenharmony_ci{
3828c2ecf20Sopenharmony_ci	return access_guest_real(vcpu, gra, data, len, 0);
3838c2ecf20Sopenharmony_ci}
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_civoid ipte_lock(struct kvm_vcpu *vcpu);
3868c2ecf20Sopenharmony_civoid ipte_unlock(struct kvm_vcpu *vcpu);
3878c2ecf20Sopenharmony_ciint ipte_lock_held(struct kvm_vcpu *vcpu);
3888c2ecf20Sopenharmony_ciint kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra);
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci/* MVPG PEI indication bits */
3918c2ecf20Sopenharmony_ci#define PEI_DAT_PROT 2
3928c2ecf20Sopenharmony_ci#define PEI_NOT_PTE 4
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_ciint kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *shadow,
3958c2ecf20Sopenharmony_ci			  unsigned long saddr, unsigned long *datptr);
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci#endif /* __KVM_S390_GACCESS_H */
398