aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/gaccess.c
diff options
context:
space:
mode:
authorThomas Huth <thuth@linux.vnet.ibm.com>2014-03-03 17:34:42 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-04-29 09:01:52 -0400
commitf8232c8cf720074c0eb0804202d424a2b7b4ee76 (patch)
treeee07bdda3663c68fad9cbeaff76935794f3f0286 /arch/s390/kvm/gaccess.c
parent9a558ee3ccb8afcf43c8d9d4d206ab6de4aa30a2 (diff)
KVM: s390: Add a function for checking the low-address protection
The s390 architecture has a special protection mechanism that can be used to prevent write access to the vital data in the low-core memory area. This patch adds a new helper function that can be used to check for such write accesses and in case of protection, it also sets up the exception data accordingly. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm/gaccess.c')
-rw-r--r--arch/s390/kvm/gaccess.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index 691fdb776c90..db608c3f9303 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -643,3 +643,31 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
643 } 643 }
644 return rc; 644 return rc;
645} 645}
646
647/**
648 * kvm_s390_check_low_addr_protection - check for low-address protection
649 * @ga: Guest address
650 *
651 * Checks whether an address is subject to low-address protection and set
652 * up vcpu->arch.pgm accordingly if necessary.
653 *
654 * Return: 0 if no protection exception, or PGM_PROTECTION if protected.
655 */
656int kvm_s390_check_low_addr_protection(struct kvm_vcpu *vcpu, unsigned long ga)
657{
658 struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
659 psw_t *psw = &vcpu->arch.sie_block->gpsw;
660 struct trans_exc_code_bits *tec_bits;
661
662 if (!is_low_address(ga) || !low_address_protection_enabled(vcpu))
663 return 0;
664
665 memset(pgm, 0, sizeof(*pgm));
666 tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
667 tec_bits->fsi = FSI_STORE;
668 tec_bits->as = psw_bits(*psw).as;
669 tec_bits->addr = ga >> PAGE_SHIFT;
670 pgm->code = PGM_PROTECTION;
671
672 return pgm->code;
673}