// SPDX-License-Identifier: GPL-2.0
/*
 * guest access functions
 *
 * Copyright IBM Corp. 2014
 *
 */

#include <linux/vmalloc.h>
#include <linux/mm_types.h>
#include <linux/err.h>
#include <linux/pgtable.h>
#include <linux/bitfield.h>
#include <asm/access-regs.h>
#include <asm/fault.h>
#include <asm/gmap.h>
#include <asm/dat-bits.h>
#include "kvm-s390.h"
#include "gaccess.h"

/*
 * vaddress union in order to easily decode a virtual address into its
 * region first index, region second index etc. parts.
 */
union vaddress {
	unsigned long addr;
	struct {
		unsigned long rfx : 11;
		unsigned long rsx : 11;
		unsigned long rtx : 11;
		unsigned long sx  : 11;
		unsigned long px  : 8;
		unsigned long bx  : 12;
	};
	struct {
		unsigned long rfx01 : 2;
		unsigned long	    : 9;
		unsigned long rsx01 : 2;
		unsigned long	    : 9;
		unsigned long rtx01 : 2;
		unsigned long	    : 9;
		unsigned long sx01  : 2;
		unsigned long	    : 29;
	};
};

/*
 * raddress union which will contain the result (real or absolute address)
 * after a page table walk. The rfaa, sfaa and pfra members are used to
 * simply assign them the value of a region, segment or page table entry.
 */
union raddress {
	unsigned long addr;
	unsigned long rfaa : 33; /* Region-Frame Absolute Address */
	unsigned long sfaa : 44; /* Segment-Frame Absolute Address */
	unsigned long pfra : 52; /* Page-Frame Real Address */
};

union alet {
	u32 val;
	struct {
		u32 reserved : 7;
		u32 p        : 1;
		u32 alesn    : 8;
		u32 alen     : 16;
	};
};

union ald {
	u32 val;
	struct {
		u32     : 1;
		u32 alo : 24;
		u32 all : 7;
	};
};

struct ale {
	unsigned long i      : 1; /* ALEN-Invalid Bit */
	unsigned long        : 5;
	unsigned long fo     : 1; /* Fetch-Only Bit */
	unsigned long p      : 1; /* Private Bit */
	unsigned long alesn  : 8; /* Access-List-Entry Sequence Number */
	unsigned long aleax  : 16; /* Access-List-Entry Authorization Index */
	unsigned long        : 32;
	unsigned long        : 1;
	unsigned long asteo  : 25; /* ASN-Second-Table-Entry Origin */
	unsigned long        : 6;
	unsigned long astesn : 32; /* ASTE Sequence Number */
};

struct aste {
	unsigned long i      : 1; /* ASX-Invalid Bit */
	unsigned long ato    : 29; /* Authority-Table Origin */
	unsigned long        : 1;
	unsigned long b      : 1; /* Base-Space Bit */
	unsigned long ax     : 16; /* Authorization Index */
	unsigned long atl    : 12; /* Authority-Table Length */
	unsigned long        : 2;
	unsigned long ca     : 1; /* Controlled-ASN Bit */
	unsigned long ra     : 1; /* Reusable-ASN Bit */
	unsigned long asce   : 64; /* Address-Space-Control Element */
	unsigned long ald    : 32;
	unsigned long astesn : 32;
	/* .. more fields there */
};

int ipte_lock_held(struct kvm *kvm)
{
	if (sclp.has_siif) {
		int rc;

		read_lock(&kvm->arch.sca_lock);
		rc = kvm_s390_get_ipte_control(kvm)->kh != 0;
		read_unlock(&kvm->arch.sca_lock);
		return rc;
	}
	return kvm->arch.ipte_lock_count != 0;
}

static void ipte_lock_simple(struct kvm *kvm)
{
	union ipte_control old, new, *ic;

	mutex_lock(&kvm->arch.ipte_mutex);
	kvm->arch.ipte_lock_count++;
	if (kvm->arch.ipte_lock_count > 1)
		goto out;
retry:
	read_lock(&kvm->arch.sca_lock);
	ic = kvm_s390_get_ipte_control(kvm);
	do {
		old = READ_ONCE(*ic);
		if (old.k) {
			read_unlock(&kvm->arch.sca_lock);
			cond_resched();
			goto retry;
		}
		new = old;
		new.k = 1;
	} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
	read_unlock(&kvm->arch.sca_lock);
out:
	mutex_unlock(&kvm->arch.ipte_mutex);
}

static void ipte_unlock_simple(struct kvm *kvm)
{
	union ipte_control old, new, *ic;

	mutex_lock(&kvm->arch.ipte_mutex);
	kvm->arch.ipte_lock_count--;
	if (kvm->arch.ipte_lock_count)
		goto out;
	read_lock(&kvm->arch.sca_lock);
	ic = kvm_s390_get_ipte_control(kvm);
	do {
		old = READ_ONCE(*ic);
		new = old;
		new.k = 0;
	} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
	read_unlock(&kvm->arch.sca_lock);
	wake_up(&kvm->arch.ipte_wq);
out:
	mutex_unlock(&kvm->arch.ipte_mutex);
}

static void ipte_lock_siif(struct kvm *kvm)
{
	union ipte_control old, new, *ic;

retry:
	read_lock(&kvm->arch.sca_lock);
	ic = kvm_s390_get_ipte_control(kvm);
	do {
		old = READ_ONCE(*ic);
		if (old.kg) {
			read_unlock(&kvm->arch.sca_lock);
			cond_resched();
			goto retry;
		}
		new = old;
		new.k = 1;
		new.kh++;
	} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
	read_unlock(&kvm->arch.sca_lock);
}

static void ipte_unlock_siif(struct kvm *kvm)
{
	union ipte_control old, new, *ic;

	read_lock(&kvm->arch.sca_lock);
	ic = kvm_s390_get_ipte_control(kvm);
	do {
		old = READ_ONCE(*ic);
		new = old;
		new.kh--;
		if (!new.kh)
			new.k = 0;
	} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
	read_unlock(&kvm->arch.sca_lock);
	if (!new.kh)
		wake_up(&kvm->arch.ipte_wq);
}

void ipte_lock(struct kvm *kvm)
{
	if (sclp.has_siif)
		ipte_lock_siif(kvm);
	else
		ipte_lock_simple(kvm);
}

void ipte_unlock(struct kvm *kvm)
{
	if (sclp.has_siif)
		ipte_unlock_siif(kvm);
	else
		ipte_unlock_simple(kvm);
}

static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, u8 ar,
			  enum gacc_mode mode)
{
	union alet alet;
	struct ale ale;
	struct aste aste;
	unsigned long ald_addr, authority_table_addr;
	union ald ald;
	int eax, rc;
	u8 authority_table;

	if (ar >= NUM_ACRS)
		return -EINVAL;

	if (vcpu->arch.acrs_loaded)
		save_access_regs(vcpu->run->s.regs.acrs);
	alet.val = vcpu->run->s.regs.acrs[ar];

	if (ar == 0 || alet.val == 0) {
		asce->val = vcpu->arch.sie_block->gcr[1];
		return 0;
	} else if (alet.val == 1) {
		asce->val = vcpu->arch.sie_block->gcr[7];
		return 0;
	}

	if (alet.reserved)
		return PGM_ALET_SPECIFICATION;

	if (alet.p)
		ald_addr = vcpu->arch.sie_block->gcr[5];
	else
		ald_addr = vcpu->arch.sie_block->gcr[2];
	ald_addr &= 0x7fffffc0;

	rc = read_guest_real(vcpu, ald_addr + 16, &ald.val, sizeof(union ald));
	if (rc)
		return rc;

	if (alet.alen / 8 > ald.all)
		return PGM_ALEN_TRANSLATION;

	if (0x7fffffff - ald.alo * 128 < alet.alen * 16)
		return PGM_ADDRESSING;

	rc = read_guest_real(vcpu, ald.alo * 128 + alet.alen * 16, &ale,
			     sizeof(struct ale));
	if (rc)
		return rc;

	if (ale.i == 1)
		return PGM_ALEN_TRANSLATION;
	if (ale.alesn != alet.alesn)
		return PGM_ALE_SEQUENCE;

	rc = read_guest_real(vcpu, ale.asteo * 64, &aste, sizeof(struct aste));
	if (rc)
		return rc;

	if (aste.i)
		return PGM_ASTE_VALIDITY;
	if (aste.astesn != ale.astesn)
		return PGM_ASTE_SEQUENCE;

	if (ale.p == 1) {
		eax = (vcpu->arch.sie_block->gcr[8] >> 16) & 0xffff;
		if (ale.aleax != eax) {
			if (eax / 16 > aste.atl)
				return PGM_EXTENDED_AUTHORITY;

			authority_table_addr = aste.ato * 4 + eax / 4;

			rc = read_guest_real(vcpu, authority_table_addr,
					     &authority_table,
					     sizeof(u8));
			if (rc)
				return rc;

			if ((authority_table & (0x40 >> ((eax & 3) * 2))) == 0)
				return PGM_EXTENDED_AUTHORITY;
		}
	}

	if (ale.fo == 1 && mode == GACC_STORE)
		return PGM_PROTECTION;

	asce->val = aste.asce;
	return 0;
}

enum prot_type {
	PROT_TYPE_LA   = 0,
	PROT_TYPE_KEYC = 1,
	PROT_TYPE_ALC  = 2,
	PROT_TYPE_DAT  = 3,
	PROT_TYPE_IEP  = 4,
	/* Dummy value for passing an initialized value when code != PGM_PROTECTION */
	PROT_NONE,
};

static int trans_exc_ending(struct kvm_vcpu *vcpu, int code, unsigned long gva, u8 ar,
			    enum gacc_mode mode, enum prot_type prot, bool terminate)
{
	struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
	union teid *teid;

	memset(pgm, 0, sizeof(*pgm));
	pgm->code = code;
	teid = (union teid *)&pgm->trans_exc_code;

	switch (code) {
	case PGM_PROTECTION:
		switch (prot) {
		case PROT_NONE:
			/* We should never get here, acts like termination */
			WARN_ON_ONCE(1);
			break;
		case PROT_TYPE_IEP:
			teid->b61 = 1;
			fallthrough;
		case PROT_TYPE_LA:
			teid->b56 = 1;
			break;
		case PROT_TYPE_KEYC:
			teid->b60 = 1;
			break;
		case PROT_TYPE_ALC:
			teid->b60 = 1;
			fallthrough;
		case PROT_TYPE_DAT:
			teid->b61 = 1;
			break;
		}
		if (terminate) {
			teid->b56 = 0;
			teid->b60 = 0;
			teid->b61 = 0;
		}
		fallthrough;
	case PGM_ASCE_TYPE:
	case PGM_PAGE_TRANSLATION:
	case PGM_REGION_FIRST_TRANS:
	case PGM_REGION_SECOND_TRANS:
	case PGM_REGION_THIRD_TRANS:
	case PGM_SEGMENT_TRANSLATION:
		/*
		 * op_access_id only applies to MOVE_PAGE -> set bit 61
		 * exc_access_id has to be set to 0 for some instructions. Both
		 * cases have to be handled by the caller.
		 */
		teid->addr = gva >> PAGE_SHIFT;
		teid->fsi = mode == GACC_STORE ? TEID_FSI_STORE : TEID_FSI_FETCH;
		teid->as = psw_bits(vcpu->arch.sie_block->gpsw).as;
		fallthrough;
	case PGM_ALEN_TRANSLATION:
	case PGM_ALE_SEQUENCE:
	case PGM_ASTE_VALIDITY:
	case PGM_ASTE_SEQUENCE:
	case PGM_EXTENDED_AUTHORITY:
		/*
		 * We can always store exc_access_id, as it is
		 * undefined for non-ar cases. It is undefined for
		 * most DAT protection exceptions.
		 */
		pgm->exc_access_id = ar;
		break;
	}
	return code;
}

static int trans_exc(struct kvm_vcpu *vcpu, int code, unsigned long gva, u8 ar,
		     enum gacc_mode mode, enum prot_type prot)
{
	return trans_exc_ending(vcpu, code, gva, ar, mode, prot, false);
}

static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce,
			 unsigned long ga, u8 ar, enum gacc_mode mode)
{
	int rc;
	struct psw_bits psw = psw_bits(vcpu->arch.sie_block->gpsw);

	if (!psw.dat) {
		asce->val = 0;
		asce->r = 1;
		return 0;
	}

	if ((mode == GACC_IFETCH) && (psw.as != PSW_BITS_AS_HOME))
		psw.as = PSW_BITS_AS_PRIMARY;

	switch (psw.as) {
	case PSW_BITS_AS_PRIMARY:
		asce->val = vcpu->arch.sie_block->gcr[1];
		return 0;
	case PSW_BITS_AS_SECONDARY:
		asce->val = vcpu->arch.sie_block->gcr[7];
		return 0;
	case PSW_BITS_AS_HOME:
		asce->val = vcpu->arch.sie_block->gcr[13];
		return 0;
	case PSW_BITS_AS_ACCREG:
		rc = ar_translation(vcpu, asce, ar, mode);
		if (rc > 0)
			return trans_exc(vcpu, rc, ga, ar, mode, PROT_TYPE_ALC);
		return rc;
	}
	return 0;
}

static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val)
{
	return kvm_read_guest(kvm, gpa, val, sizeof(*val));
}

/**
 * guest_translate - translate a guest virtual into a guest absolute address
 * @vcpu: virtual cpu
 * @gva: guest virtual address
 * @gpa: points to where guest physical (absolute) address should be stored
 * @asce: effective asce
 * @mode: indicates the access mode to be used
 * @prot: returns the type for protection exceptions
 *
 * Translate a guest virtual address into a guest absolute address by means
 * of dynamic address translation as specified by the architecture.
 * If the resulting absolute address is not available in the configuration
 * an addressing exception is indicated and @gpa will not be changed.
 *
 * Returns: - zero on success; @gpa contains the resulting absolute address
 *	    - a negative value if guest access failed due to e.g. broken
 *	      guest mapping
 *	    - a positive value if an access exception happened. In this case
 *	      the returned value is the program interruption code as defined
 *	      by the architecture
 */
static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
				     unsigned long *gpa, const union asce asce,
				     enum gacc_mode mode, enum prot_type *prot)
{
	union vaddress vaddr = {.addr = gva};
	union raddress raddr = {.addr = gva};
	union page_table_entry pte;
	int dat_protection = 0;
	int iep_protection = 0;
	union ctlreg0 ctlreg0;
	unsigned long ptr;
	int edat1, edat2, iep;

	ctlreg0.val = vcpu->arch.sie_block->gcr[0];
	edat1 = ctlreg0.edat && test_kvm_facility(vcpu->kvm, 8);
	edat2 = edat1 && test_kvm_facility(vcpu->kvm, 78);
	iep = ctlreg0.iep && test_kvm_facility(vcpu->kvm, 130);
	if (asce.r)
		goto real_address;
	ptr = asce.rsto * PAGE_SIZE;
	switch (asce.dt) {
	case ASCE_TYPE_REGION1:
		if (vaddr.rfx01 > asce.tl)
			return PGM_REGION_FIRST_TRANS;
		ptr += vaddr.rfx * 8;
		break;
	case ASCE_TYPE_REGION2:
		if (vaddr.rfx)
			return PGM_ASCE_TYPE;
		if (vaddr.rsx01 > asce.tl)
			return PGM_REGION_SECOND_TRANS;
		ptr += vaddr.rsx * 8;
		break;
	case ASCE_TYPE_REGION3:
		if (vaddr.rfx || vaddr.rsx)
			return PGM_ASCE_TYPE;
		if (vaddr.rtx01 > asce.tl)
			return PGM_REGION_THIRD_TRANS;
		ptr += vaddr.rtx * 8;
		break;
	case ASCE_TYPE_SEGMENT:
		if (vaddr.rfx || vaddr.rsx || vaddr.rtx)
			return PGM_ASCE_TYPE;
		if (vaddr.sx01 > asce.tl)
			return PGM_SEGMENT_TRANSLATION;
		ptr += vaddr.sx * 8;
		break;
	}
	switch (asce.dt) {
	case ASCE_TYPE_REGION1:	{
		union region1_table_entry rfte;

		if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
			return PGM_ADDRESSING;
		if (deref_table(vcpu->kvm, ptr, &rfte.val))
			return -EFAULT;
		if (rfte.i)
			return PGM_REGION_FIRST_TRANS;
		if (rfte.tt != TABLE_TYPE_REGION1)
			return PGM_TRANSLATION_SPEC;
		if (vaddr.rsx01 < rfte.tf || vaddr.rsx01 > rfte.tl)
			return PGM_REGION_SECOND_TRANS;
		if (edat1)
			dat_protection |= rfte.p;
		ptr = rfte.rto * PAGE_SIZE + vaddr.rsx * 8;
	}
		fallthrough;
	case ASCE_TYPE_REGION2: {
		union region2_table_entry rste;

		if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
			return PGM_ADDRESSING;
		if (deref_table(vcpu->kvm, ptr, &rste.val))
			return -EFAULT;
		if (rste.i)
			return PGM_REGION_SECOND_TRANS;
		if (rste.tt != TABLE_TYPE_REGION2)
			return PGM_TRANSLATION_SPEC;
		if (vaddr.rtx01 < rste.tf || vaddr.rtx01 > rste.tl)
			return PGM_REGION_THIRD_TRANS;
		if (edat1)
			dat_protection |= rste.p;
		ptr = rste.rto * PAGE_SIZE + vaddr.rtx * 8;
	}
		fallthrough;
	case ASCE_TYPE_REGION3: {
		union region3_table_entry rtte;

		if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
			return PGM_ADDRESSING;
		if (deref_table(vcpu->kvm, ptr, &rtte.val))
			return -EFAULT;
		if (rtte.i)
			return PGM_REGION_THIRD_TRANS;
		if (rtte.tt != TABLE_TYPE_REGION3)
			return PGM_TRANSLATION_SPEC;
		if (rtte.cr && asce.p && edat2)
			return PGM_TRANSLATION_SPEC;
		if (rtte.fc && edat2) {
			dat_protection |= rtte.fc1.p;
			iep_protection = rtte.fc1.iep;
			raddr.rfaa = rtte.fc1.rfaa;
			goto absolute_address;
		}
		if (vaddr.sx01 < rtte.fc0.tf)
			return PGM_SEGMENT_TRANSLATION;
		if (vaddr.sx01 > rtte.fc0.tl)
			return PGM_SEGMENT_TRANSLATION;
		if (edat1)
			dat_protection |= rtte.fc0.p;
		ptr = rtte.fc0.sto * PAGE_SIZE + vaddr.sx * 8;
	}
		fallthrough;
	case ASCE_TYPE_SEGMENT: {
		union segment_table_entry ste;

		if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
			return PGM_ADDRESSING;
		if (deref_table(vcpu->kvm, ptr, &ste.val))
			return -EFAULT;
		if (ste.i)
			return PGM_SEGMENT_TRANSLATION;
		if (ste.tt != TABLE_TYPE_SEGMENT)
			return PGM_TRANSLATION_SPEC;
		if (ste.cs && asce.p)
			return PGM_TRANSLATION_SPEC;
		if (ste.fc && edat1) {
			dat_protection |= ste.fc1.p;
			iep_protection = ste.fc1.iep;
			raddr.sfaa = ste.fc1.sfaa;
			goto absolute_address;
		}
		dat_protection |= ste.fc0.p;
		ptr = ste.fc0.pto * (PAGE_SIZE / 2) + vaddr.px * 8;
	}
	}
	if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
		return PGM_ADDRESSING;
	if (deref_table(vcpu->kvm, ptr, &pte.val))
		return -EFAULT;
	if (pte.i)
		return PGM_PAGE_TRANSLATION;
	if (pte.z)
		return PGM_TRANSLATION_SPEC;
	dat_protection |= pte.p;
	iep_protection = pte.iep;
	raddr.pfra = pte.pfra;
real_address:
	raddr.addr = kvm_s390_real_to_abs(vcpu, raddr.addr);
absolute_address:
	if (mode == GACC_STORE && dat_protection) {
		*prot = PROT_TYPE_DAT;
		return PGM_PROTECTION;
	}
	if (mode == GACC_IFETCH && iep_protection && iep) {
		*prot = PROT_TYPE_IEP;
		return PGM_PROTECTION;
	}
	if (!kvm_is_gpa_in_memslot(vcpu->kvm, raddr.addr))
		return PGM_ADDRESSING;
	*gpa = raddr.addr;
	return 0;
}

static inline int is_low_address(unsigned long ga)
{
	/* Check for address ranges 0..511 and 4096..4607 */
	return (ga & ~0x11fful) == 0;
}

static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
					  const union asce asce)
{
	union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]};
	psw_t *psw = &vcpu->arch.sie_block->gpsw;

	if (!ctlreg0.lap)
		return 0;
	if (psw_bits(*psw).dat && asce.p)
		return 0;
	return 1;
}

static int vm_check_access_key(struct kvm *kvm, u8 access_key,
			       enum gacc_mode mode, gpa_t gpa)
{
	u8 storage_key, access_control;
	bool fetch_protected;
	unsigned long hva;
	int r;

	if (access_key == 0)
		return 0;

	hva = gfn_to_hva(kvm, gpa_to_gfn(gpa));
	if (kvm_is_error_hva(hva))
		return PGM_ADDRESSING;

	mmap_read_lock(current->mm);
	r = get_guest_storage_key(current->mm, hva, &storage_key);
	mmap_read_unlock(current->mm);
	if (r)
		return r;
	access_control = FIELD_GET(_PAGE_ACC_BITS, storage_key);
	if (access_control == access_key)
		return 0;
	fetch_protected = storage_key & _PAGE_FP_BIT;
	if ((mode == GACC_FETCH || mode == GACC_IFETCH) && !fetch_protected)
		return 0;
	return PGM_PROTECTION;
}

static bool fetch_prot_override_applicable(struct kvm_vcpu *vcpu, enum gacc_mode mode,
					   union asce asce)
{
	psw_t *psw = &vcpu->arch.sie_block->gpsw;
	unsigned long override;

	if (mode == GACC_FETCH || mode == GACC_IFETCH) {
		/* check if fetch protection override enabled */
		override = vcpu->arch.sie_block->gcr[0];
		override &= CR0_FETCH_PROTECTION_OVERRIDE;
		/* not applicable if subject to DAT && private space */
		override = override && !(psw_bits(*psw).dat && asce.p);
		return override;
	}
	return false;
}

static bool fetch_prot_override_applies(unsigned long ga, unsigned int len)
{
	return ga < 2048 && ga + len <= 2048;
}

static bool storage_prot_override_applicable(struct kvm_vcpu *vcpu)
{
	/* check if storage protection override enabled */
	return vcpu->arch.sie_block->gcr[0] & CR0_STORAGE_PROTECTION_OVERRIDE;
}

static bool storage_prot_override_applies(u8 access_control)
{
	/* matches special storage protection override key (9) -> allow */
	return access_control == PAGE_SPO_ACC;
}

static int vcpu_check_access_key(struct kvm_vcpu *vcpu, u8 access_key,
				 enum gacc_mode mode, union asce asce, gpa_t gpa,
				 unsigned long ga, unsigned int len)
{
	u8 storage_key, access_control;
	unsigned long hva;
	int r;

	/* access key 0 matches any storage key -> allow */
	if (access_key == 0)
		return 0;
	/*
	 * caller needs to ensure that gfn is accessible, so we can
	 * assume that this cannot fail
	 */
	hva = gfn_to_hva(vcpu->kvm, gpa_to_gfn(gpa));
	mmap_read_lock(current->mm);
	r = get_guest_storage_key(current->mm, hva, &storage_key);
	mmap_read_unlock(current->mm);
	if (r)
		return r;
	access_control = FIELD_GET(_PAGE_ACC_BITS, storage_key);
	/* access key matches storage key -> allow */
	if (access_control == access_key)
		return 0;
	if (mode == GACC_FETCH || mode == GACC_IFETCH) {
		/* it is a fetch and fetch protection is off -> allow */
		if (!(storage_key & _PAGE_FP_BIT))
			return 0;
		if (fetch_prot_override_applicable(vcpu, mode, asce) &&
		    fetch_prot_override_applies(ga, len))
			return 0;
	}
	if (storage_prot_override_applicable(vcpu) &&
	    storage_prot_override_applies(access_control))
		return 0;
	return PGM_PROTECTION;
}

/**
 * guest_range_to_gpas() - Calculate guest physical addresses of page fragments
 * covering a logical range
 * @vcpu: virtual cpu
 * @ga: guest address, start of range
 * @ar: access register
 * @gpas: output argument, may be NULL
 * @len: length of range in bytes
 * @asce: address-space-control element to use for translation
 * @mode: access mode
 * @access_key: access key to mach the range's storage keys against
 *
 * Translate a logical range to a series of guest absolute addresses,
 * such that the concatenation of page fragments starting at each gpa make up
 * the whole range.
 * The translation is performed as if done by the cpu for the given @asce, @ar,
 * @mode and state of the @vcpu.
 * If the translation causes an exception, its program interruption code is
 * returned and the &struct kvm_s390_pgm_info pgm member of @vcpu is modified
 * such that a subsequent call to kvm_s390_inject_prog_vcpu() will inject
 * a correct exception into the guest.
 * The resulting gpas are stored into @gpas, unless it is NULL.
 *
 * Note: All fragments except the first one start at the beginning of a page.
 *	 When deriving the boundaries of a fragment from a gpa, all but the last
 *	 fragment end at the end of the page.
 *
 * Return:
 * * 0		- success
 * * <0		- translation could not be performed, for example if  guest
 *		  memory could not be accessed
 * * >0		- an access exception occurred. In this case the returned value
 *		  is the program interruption code and the contents of pgm may
 *		  be used to inject an exception into the guest.
 */
static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
			       unsigned long *gpas, unsigned long len,
			       const union asce asce, enum gacc_mode mode,
			       u8 access_key)
{
	psw_t *psw = &vcpu->arch.sie_block->gpsw;
	unsigned int offset = offset_in_page(ga);
	unsigned int fragment_len;
	int lap_enabled, rc = 0;
	enum prot_type prot;
	unsigned long gpa;

	lap_enabled = low_address_protection_enabled(vcpu, asce);
	while (min(PAGE_SIZE - offset, len) > 0) {
		fragment_len = min(PAGE_SIZE - offset, len);
		ga = kvm_s390_logical_to_effective(vcpu, ga);
		if (mode == GACC_STORE && lap_enabled && is_low_address(ga))
			return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode,
					 PROT_TYPE_LA);
		if (psw_bits(*psw).dat) {
			rc = guest_translate(vcpu, ga, &gpa, asce, mode, &prot);
			if (rc < 0)
				return rc;
		} else {
			gpa = kvm_s390_real_to_abs(vcpu, ga);
			if (!kvm_is_gpa_in_memslot(vcpu->kvm, gpa)) {
				rc = PGM_ADDRESSING;
				prot = PROT_NONE;
			}
		}
		if (rc)
			return trans_exc(vcpu, rc, ga, ar, mode, prot);
		rc = vcpu_check_access_key(vcpu, access_key, mode, asce, gpa, ga,
					   fragment_len);
		if (rc)
			return trans_exc(vcpu, rc, ga, ar, mode, PROT_TYPE_KEYC);
		if (gpas)
			*gpas++ = gpa;
		offset = 0;
		ga += fragment_len;
		len -= fragment_len;
	}
	return 0;
}

static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa,
			     void *data, unsigned int len)
{
	const unsigned int offset = offset_in_page(gpa);
	const gfn_t gfn = gpa_to_gfn(gpa);
	int rc;

	if (mode == GACC_STORE)
		rc = kvm_write_guest_page(kvm, gfn, data, offset, len);
	else
		rc = kvm_read_guest_page(kvm, gfn, data, offset, len);
	return rc;
}

static int
access_guest_page_with_key(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa,
			   void *data, unsigned int len, u8 access_key)
{
	struct kvm_memory_slot *slot;
	bool writable;
	gfn_t gfn;
	hva_t hva;
	int rc;

	gfn = gpa >> PAGE_SHIFT;
	slot = gfn_to_memslot(kvm, gfn);
	hva = gfn_to_hva_memslot_prot(slot, gfn, &writable);

	if (kvm_is_error_hva(hva))
		return PGM_ADDRESSING;
	/*
	 * Check if it's a ro memslot, even tho that can't occur (they're unsupported).
	 * Don't try to actually handle that case.
	 */
	if (!writable && mode == GACC_STORE)
		return -EOPNOTSUPP;
	hva += offset_in_page(gpa);
	if (mode == GACC_STORE)
		rc = copy_to_user_key((void __user *)hva, data, len, access_key);
	else
		rc = copy_from_user_key(data, (void __user *)hva, len, access_key);
	if (rc)
		return PGM_PROTECTION;
	if (mode == GACC_STORE)
		mark_page_dirty_in_slot(kvm, slot, gfn);
	return 0;
}

int access_guest_abs_with_key(struct kvm *kvm, gpa_t gpa, void *data,
			      unsigned long len, enum gacc_mode mode, u8 access_key)
{
	int offset = offset_in_page(gpa);
	int fragment_len;
	int rc;

	while (min(PAGE_SIZE - offset, len) > 0) {
		fragment_len = min(PAGE_SIZE - offset, len);
		rc = access_guest_page_with_key(kvm, mode, gpa, data, fragment_len, access_key);
		if (rc)
			return rc;
		offset = 0;
		len -= fragment_len;
		data += fragment_len;
		gpa += fragment_len;
	}
	return 0;
}

int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
			  void *data, unsigned long len, enum gacc_mode mode,
			  u8 access_key)
{
	psw_t *psw = &vcpu->arch.sie_block->gpsw;
	unsigned long nr_pages, idx;
	unsigned long gpa_array[2];
	unsigned int fragment_len;
	unsigned long *gpas;
	enum prot_type prot;
	int need_ipte_lock;
	union asce asce;
	bool try_storage_prot_override;
	bool try_fetch_prot_override;
	int rc;

	if (!len)
		return 0;
	ga = kvm_s390_logical_to_effective(vcpu, ga);
	rc = get_vcpu_asce(vcpu, &asce, ga, ar, mode);
	if (rc)
		return rc;
	nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1;
	gpas = gpa_array;
	if (nr_pages > ARRAY_SIZE(gpa_array))
		gpas = vmalloc(array_size(nr_pages, sizeof(unsigned long)));
	if (!gpas)
		return -ENOMEM;
	try_fetch_prot_override = fetch_prot_override_applicable(vcpu, mode, asce);
	try_storage_prot_override = storage_prot_override_applicable(vcpu);
	need_ipte_lock = psw_bits(*psw).dat && !asce.r;
	if (need_ipte_lock)
		ipte_lock(vcpu->kvm);
	/*
	 * Since we do the access further down ultimately via a move instruction
	 * that does key checking and returns an error in case of a protection
	 * violation, we don't need to do the check during address translation.
	 * Skip it by passing access key 0, which matches any storage key,
	 * obviating the need for any further checks. As a result the check is
	 * handled entirely in hardware on access, we only need to take care to
	 * forego key protection checking if fetch protection override applies or
	 * retry with the special key 9 in case of storage protection override.
	 */
	rc = guest_range_to_gpas(vcpu, ga, ar, gpas, len, asce, mode, 0);
	if (rc)
		goto out_unlock;
	for (idx = 0; idx < nr_pages; idx++) {
		fragment_len = min(PAGE_SIZE - offset_in_page(gpas[idx]), len);
		if (try_fetch_prot_override && fetch_prot_override_applies(ga, fragment_len)) {
			rc = access_guest_page(vcpu->kvm, mode, gpas[idx],
					       data, fragment_len);
		} else {
			rc = access_guest_page_with_key(vcpu->kvm, mode, gpas[idx],
							data, fragment_len, access_key);
		}
		if (rc == PGM_PROTECTION && try_storage_prot_override)
			rc = access_guest_page_with_key(vcpu->kvm, mode, gpas[idx],
							data, fragment_len, PAGE_SPO_ACC);
		if (rc)
			break;
		len -= fragment_len;
		data += fragment_len;
		ga = kvm_s390_logical_to_effective(vcpu, ga + fragment_len);
	}
	if (rc > 0) {
		bool terminate = (mode == GACC_STORE) && (idx > 0);

		if (rc == PGM_PROTECTION)
			prot = PROT_TYPE_KEYC;
		else
			prot = PROT_NONE;
		rc = trans_exc_ending(vcpu, rc, ga, ar, mode, prot, terminate);
	}
out_unlock:
	if (need_ipte_lock)
		ipte_unlock(vcpu->kvm);
	if (nr_pages > ARRAY_SIZE(gpa_array))
		vfree(gpas);
	return rc;
}

int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
		      void *data, unsigned long len, enum gacc_mode mode)
{
	unsigned int fragment_len;
	unsigned long gpa;
	int rc = 0;

	while (len && !rc) {
		gpa = kvm_s390_real_to_abs(vcpu, gra);
		fragment_len = min(PAGE_SIZE - offset_in_page(gpa), len);
		rc = access_guest_page(vcpu->kvm, mode, gpa, data, fragment_len);
		len -= fragment_len;
		gra += fragment_len;
		data += fragment_len;
	}
	return rc;
}

/**
 * cmpxchg_guest_abs_with_key() - Perform cmpxchg on guest absolute address.
 * @kvm: Virtual machine instance.
 * @gpa: Absolute guest address of the location to be changed.
 * @len: Operand length of the cmpxchg, required: 1 <= len <= 16. Providing a
 *       non power of two will result in failure.
 * @old_addr: Pointer to old value. If the location at @gpa contains this value,
 *            the exchange will succeed. After calling cmpxchg_guest_abs_with_key()
 *            *@old_addr contains the value at @gpa before the attempt to
 *            exchange the value.
 * @new: The value to place at @gpa.
 * @access_key: The access key to use for the guest access.
 * @success: output value indicating if an exchange occurred.
 *
 * Atomically exchange the value at @gpa by @new, if it contains *@old.
 * Honors storage keys.
 *
 * Return: * 0: successful exchange
 *         * >0: a program interruption code indicating the reason cmpxchg could
 *               not be attempted
 *         * -EINVAL: address misaligned or len not power of two
 *         * -EAGAIN: transient failure (len 1 or 2)
 *         * -EOPNOTSUPP: read-only memslot (should never occur)
 */
int cmpxchg_guest_abs_with_key(struct kvm *kvm, gpa_t gpa, int len,
			       __uint128_t *old_addr, __uint128_t new,
			       u8 access_key, bool *success)
{
	gfn_t gfn = gpa_to_gfn(gpa);
	struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn);
	bool writable;
	hva_t hva;
	int ret;

	if (!IS_ALIGNED(gpa, len))
		return -EINVAL;

	hva = gfn_to_hva_memslot_prot(slot, gfn, &writable);
	if (kvm_is_error_hva(hva))
		return PGM_ADDRESSING;
	/*
	 * Check if it's a read-only memslot, even though that cannot occur
	 * since those are unsupported.
	 * Don't try to actually handle that case.
	 */
	if (!writable)
		return -EOPNOTSUPP;

	hva += offset_in_page(gpa);
	/*
	 * The cmpxchg_user_key macro depends on the type of "old", so we need
	 * a case for each valid length and get some code duplication as long
	 * as we don't introduce a new macro.
	 */
	switch (len) {
	case 1: {
		u8 old;

		ret = cmpxchg_user_key((u8 __user *)hva, &old, *old_addr, new, access_key);
		*success = !ret && old == *old_addr;
		*old_addr = old;
		break;
	}
	case 2: {
		u16 old;

		ret = cmpxchg_user_key((u16 __user *)hva, &old, *old_addr, new, access_key);
		*success = !ret && old == *old_addr;
		*old_addr = old;
		break;
	}
	case 4: {
		u32 old;

		ret = cmpxchg_user_key((u32 __user *)hva, &old, *old_addr, new, access_key);
		*success = !ret && old == *old_addr;
		*old_addr = old;
		break;
	}
	case 8: {
		u64 old;

		ret = cmpxchg_user_key((u64 __user *)hva, &old, *old_addr, new, access_key);
		*success = !ret && old == *old_addr;
		*old_addr = old;
		break;
	}
	case 16: {
		__uint128_t old;

		ret = cmpxchg_user_key((__uint128_t __user *)hva, &old, *old_addr, new, access_key);
		*success = !ret && old == *old_addr;
		*old_addr = old;
		break;
	}
	default:
		return -EINVAL;
	}
	if (*success)
		mark_page_dirty_in_slot(kvm, slot, gfn);
	/*
	 * Assume that the fault is caused by protection, either key protection
	 * or user page write protection.
	 */
	if (ret == -EFAULT)
		ret = PGM_PROTECTION;
	return ret;
}

/**
 * guest_translate_address_with_key - translate guest logical into guest absolute address
 * @vcpu: virtual cpu
 * @gva: Guest virtual address
 * @ar: Access register
 * @gpa: Guest physical address
 * @mode: Translation access mode
 * @access_key: access key to mach the storage key with
 *
 * Parameter semantics are the same as the ones from guest_translate.
 * The memory contents at the guest address are not changed.
 *
 * Note: The IPTE lock is not taken during this function, so the caller
 * has to take care of this.
 */
int guest_translate_address_with_key(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
				     unsigned long *gpa, enum gacc_mode mode,
				     u8 access_key)
{
	union asce asce;
	int rc;

	gva = kvm_s390_logical_to_effective(vcpu, gva);
	rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
	if (rc)
		return rc;
	return guest_range_to_gpas(vcpu, gva, ar, gpa, 1, asce, mode,
				   access_key);
}

/**
 * check_gva_range - test a range of guest virtual addresses for accessibility
 * @vcpu: virtual cpu
 * @gva: Guest virtual address
 * @ar: Access register
 * @length: Length of test range
 * @mode: Translation access mode
 * @access_key: access key to mach the storage keys with
 */
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
		    unsigned long length, enum gacc_mode mode, u8 access_key)
{
	union asce asce;
	int rc = 0;

	rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
	if (rc)
		return rc;
	ipte_lock(vcpu->kvm);
	rc = guest_range_to_gpas(vcpu, gva, ar, NULL, length, asce, mode,
				 access_key);
	ipte_unlock(vcpu->kvm);

	return rc;
}

/**
 * check_gpa_range - test a range of guest physical addresses for accessibility
 * @kvm: virtual machine instance
 * @gpa: guest physical address
 * @length: length of test range
 * @mode: access mode to test, relevant for storage keys
 * @access_key: access key to mach the storage keys with
 */
int check_gpa_range(struct kvm *kvm, unsigned long gpa, unsigned long length,
		    enum gacc_mode mode, u8 access_key)
{
	unsigned int fragment_len;
	int rc = 0;

	while (length && !rc) {
		fragment_len = min(PAGE_SIZE - offset_in_page(gpa), length);
		rc = vm_check_access_key(kvm, access_key, mode, gpa);
		length -= fragment_len;
		gpa += fragment_len;
	}
	return rc;
}

/**
 * kvm_s390_check_low_addr_prot_real - check for low-address protection
 * @vcpu: virtual cpu
 * @gra: Guest real address
 *
 * Checks whether an address is subject to low-address protection and set
 * up vcpu->arch.pgm accordingly if necessary.
 *
 * Return: 0 if no protection exception, or PGM_PROTECTION if protected.
 */
int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra)
{
	union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]};

	if (!ctlreg0.lap || !is_low_address(gra))
		return 0;
	return trans_exc(vcpu, PGM_PROTECTION, gra, 0, GACC_STORE, PROT_TYPE_LA);
}

/**
 * kvm_s390_shadow_tables - walk the guest page table and create shadow tables
 * @sg: pointer to the shadow guest address space structure
 * @saddr: faulting address in the shadow gmap
 * @pgt: pointer to the beginning of the page table for the given address if
 *	 successful (return value 0), or to the first invalid DAT entry in
 *	 case of exceptions (return value > 0)
 * @dat_protection: referenced memory is write protected
 * @fake: pgt references contiguous guest memory block, not a pgtable
 */
static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
				  unsigned long *pgt, int *dat_protection,
				  int *fake)
{
	struct kvm *kvm;
	struct gmap *parent;
	union asce asce;
	union vaddress vaddr;
	unsigned long ptr;
	int rc;

	*fake = 0;
	*dat_protection = 0;
	kvm = sg->private;
	parent = sg->parent;
	vaddr.addr = saddr;
	asce.val = sg->orig_asce;
	ptr = asce.rsto * PAGE_SIZE;
	if (asce.r) {
		*fake = 1;
		ptr = 0;
		asce.dt = ASCE_TYPE_REGION1;
	}
	switch (asce.dt) {
	case ASCE_TYPE_REGION1:
		if (vaddr.rfx01 > asce.tl && !*fake)
			return PGM_REGION_FIRST_TRANS;
		break;
	case ASCE_TYPE_REGION2:
		if (vaddr.rfx)
			return PGM_ASCE_TYPE;
		if (vaddr.rsx01 > asce.tl)
			return PGM_REGION_SECOND_TRANS;
		break;
	case ASCE_TYPE_REGION3:
		if (vaddr.rfx || vaddr.rsx)
			return PGM_ASCE_TYPE;
		if (vaddr.rtx01 > asce.tl)
			return PGM_REGION_THIRD_TRANS;
		break;
	case ASCE_TYPE_SEGMENT:
		if (vaddr.rfx || vaddr.rsx || vaddr.rtx)
			return PGM_ASCE_TYPE;
		if (vaddr.sx01 > asce.tl)
			return PGM_SEGMENT_TRANSLATION;
		break;
	}

	switch (asce.dt) {
	case ASCE_TYPE_REGION1: {
		union region1_table_entry rfte;

		if (*fake) {
			ptr += vaddr.rfx * _REGION1_SIZE;
			rfte.val = ptr;
			goto shadow_r2t;
		}
		*pgt = ptr + vaddr.rfx * 8;
		rc = gmap_read_table(parent, ptr + vaddr.rfx * 8, &rfte.val);
		if (rc)
			return rc;
		if (rfte.i)
			return PGM_REGION_FIRST_TRANS;
		if (rfte.tt != TABLE_TYPE_REGION1)
			return PGM_TRANSLATION_SPEC;
		if (vaddr.rsx01 < rfte.tf || vaddr.rsx01 > rfte.tl)
			return PGM_REGION_SECOND_TRANS;
		if (sg->edat_level >= 1)
			*dat_protection |= rfte.p;
		ptr = rfte.rto * PAGE_SIZE;
shadow_r2t:
		rc = gmap_shadow_r2t(sg, saddr, rfte.val, *fake);
		if (rc)
			return rc;
		kvm->stat.gmap_shadow_r1_entry++;
	}
		fallthrough;
	case ASCE_TYPE_REGION2: {
		union region2_table_entry rste;

		if (*fake) {
			ptr += vaddr.rsx * _REGION2_SIZE;
			rste.val = ptr;
			goto shadow_r3t;
		}
		*pgt = ptr + vaddr.rsx * 8;
		rc = gmap_read_table(parent, ptr + vaddr.rsx * 8, &rste.val);
		if (rc)
			return rc;
		if (rste.i)
			return PGM_REGION_SECOND_TRANS;
		if (rste.tt != TABLE_TYPE_REGION2)
			return PGM_TRANSLATION_SPEC;
		if (vaddr.rtx01 < rste.tf || vaddr.rtx01 > rste.tl)
			return PGM_REGION_THIRD_TRANS;
		if (sg->edat_level >= 1)
			*dat_protection |= rste.p;
		ptr = rste.rto * PAGE_SIZE;
shadow_r3t:
		rste.p |= *dat_protection;
		rc = gmap_shadow_r3t(sg, saddr, rste.val, *fake);
		if (rc)
			return rc;
		kvm->stat.gmap_shadow_r2_entry++;
	}
		fallthrough;
	case ASCE_TYPE_REGION3: {
		union region3_table_entry rtte;

		if (*fake) {
			ptr += vaddr.rtx * _REGION3_SIZE;
			rtte.val = ptr;
			goto shadow_sgt;
		}
		*pgt = ptr + vaddr.rtx * 8;
		rc = gmap_read_table(parent, ptr + vaddr.rtx * 8, &rtte.val);
		if (rc)
			return rc;
		if (rtte.i)
			return PGM_REGION_THIRD_TRANS;
		if (rtte.tt != TABLE_TYPE_REGION3)
			return PGM_TRANSLATION_SPEC;
		if (rtte.cr && asce.p && sg->edat_level >= 2)
			return PGM_TRANSLATION_SPEC;
		if (rtte.fc && sg->edat_level >= 2) {
			*dat_protection |= rtte.fc0.p;
			*fake = 1;
			ptr = rtte.fc1.rfaa * _REGION3_SIZE;
			rtte.val = ptr;
			goto shadow_sgt;
		}
		if (vaddr.sx01 < rtte.fc0.tf || vaddr.sx01 > rtte.fc0.tl)
			return PGM_SEGMENT_TRANSLATION;
		if (sg->edat_level >= 1)
			*dat_protection |= rtte.fc0.p;
		ptr = rtte.fc0.sto * PAGE_SIZE;
shadow_sgt:
		rtte.fc0.p |= *dat_protection;
		rc = gmap_shadow_sgt(sg, saddr, rtte.val, *fake);
		if (rc)
			return rc;
		kvm->stat.gmap_shadow_r3_entry++;
	}
		fallthrough;
	case ASCE_TYPE_SEGMENT: {
		union segment_table_entry ste;

		if (*fake) {
			ptr += vaddr.sx * _SEGMENT_SIZE;
			ste.val = ptr;
			goto shadow_pgt;
		}
		*pgt = ptr + vaddr.sx * 8;
		rc = gmap_read_table(parent, ptr + vaddr.sx * 8, &ste.val);
		if (rc)
			return rc;
		if (ste.i)
			return PGM_SEGMENT_TRANSLATION;
		if (ste.tt != TABLE_TYPE_SEGMENT)
			return PGM_TRANSLATION_SPEC;
		if (ste.cs && asce.p)
			return PGM_TRANSLATION_SPEC;
		*dat_protection |= ste.fc0.p;
		if (ste.fc && sg->edat_level >= 1) {
			*fake = 1;
			ptr = ste.fc1.sfaa * _SEGMENT_SIZE;
			ste.val = ptr;
			goto shadow_pgt;
		}
		ptr = ste.fc0.pto * (PAGE_SIZE / 2);
shadow_pgt:
		ste.fc0.p |= *dat_protection;
		rc = gmap_shadow_pgt(sg, saddr, ste.val, *fake);
		if (rc)
			return rc;
		kvm->stat.gmap_shadow_sg_entry++;
	}
	}
	/* Return the parent address of the page table */
	*pgt = ptr;
	return 0;
}

/**
 * kvm_s390_shadow_fault - handle fault on a shadow page table
 * @vcpu: virtual cpu
 * @sg: pointer to the shadow guest address space structure
 * @saddr: faulting address in the shadow gmap
 * @datptr: will contain the address of the faulting DAT table entry, or of
 *	    the valid leaf, plus some flags
 *
 * Returns: - 0 if the shadow fault was successfully resolved
 *	    - > 0 (pgm exception code) on exceptions while faulting
 *	    - -EAGAIN if the caller can retry immediately
 *	    - -EFAULT when accessing invalid guest addresses
 *	    - -ENOMEM if out of memory
 */
int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg,
			  unsigned long saddr, unsigned long *datptr)
{
	union vaddress vaddr;
	union page_table_entry pte;
	unsigned long pgt = 0;
	int dat_protection, fake;
	int rc;

	mmap_read_lock(sg->mm);
	/*
	 * We don't want any guest-2 tables to change - so the parent
	 * tables/pointers we read stay valid - unshadowing is however
	 * always possible - only guest_table_lock protects us.
	 */
	ipte_lock(vcpu->kvm);

	rc = gmap_shadow_pgt_lookup(sg, saddr, &pgt, &dat_protection, &fake);
	if (rc)
		rc = kvm_s390_shadow_tables(sg, saddr, &pgt, &dat_protection,
					    &fake);

	vaddr.addr = saddr;
	if (fake) {
		pte.val = pgt + vaddr.px * PAGE_SIZE;
		goto shadow_page;
	}

	switch (rc) {
	case PGM_SEGMENT_TRANSLATION:
	case PGM_REGION_THIRD_TRANS:
	case PGM_REGION_SECOND_TRANS:
	case PGM_REGION_FIRST_TRANS:
		pgt |= PEI_NOT_PTE;
		break;
	case 0:
		pgt += vaddr.px * 8;
		rc = gmap_read_table(sg->parent, pgt, &pte.val);
	}
	if (datptr)
		*datptr = pgt | dat_protection * PEI_DAT_PROT;
	if (!rc && pte.i)
		rc = PGM_PAGE_TRANSLATION;
	if (!rc && pte.z)
		rc = PGM_TRANSLATION_SPEC;
shadow_page:
	pte.p |= dat_protection;
	if (!rc)
		rc = gmap_shadow_page(sg, saddr, __pte(pte.val));
	vcpu->kvm->stat.gmap_shadow_pg_entry++;
	ipte_unlock(vcpu->kvm);
	mmap_read_unlock(sg->mm);
	return rc;
}
