diff options
author | Thomas Huth <thuth@linux.vnet.ibm.com> | 2014-03-03 17:34:42 -0500 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2014-04-29 09:01:52 -0400 |
commit | f8232c8cf720074c0eb0804202d424a2b7b4ee76 (patch) | |
tree | ee07bdda3663c68fad9cbeaff76935794f3f0286 /arch/s390/kvm/gaccess.c | |
parent | 9a558ee3ccb8afcf43c8d9d4d206ab6de4aa30a2 (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.c | 28 |
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 | */ | ||
656 | int 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 | } | ||