KVM: s390: Add a function for checking the low-address protection
authorThomas Huth <thuth@linux.vnet.ibm.com>
Mon, 3 Mar 2014 22:34:42 +0000 (23:34 +0100)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Tue, 29 Apr 2014 13:01:52 +0000 (15:01 +0200)
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>
arch/s390/kvm/gaccess.c
arch/s390/kvm/gaccess.h

index 691fdb7..db608c3 100644 (file)
@@ -643,3 +643,31 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
        }
        return rc;
 }
+
+/**
+ * kvm_s390_check_low_addr_protection - check for low-address protection
+ * @ga: Guest 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_protection(struct kvm_vcpu *vcpu, unsigned long ga)
+{
+       struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
+       psw_t *psw = &vcpu->arch.sie_block->gpsw;
+       struct trans_exc_code_bits *tec_bits;
+
+       if (!is_low_address(ga) || !low_address_protection_enabled(vcpu))
+               return 0;
+
+       memset(pgm, 0, sizeof(*pgm));
+       tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
+       tec_bits->fsi = FSI_STORE;
+       tec_bits->as = psw_bits(*psw).as;
+       tec_bits->addr = ga >> PAGE_SHIFT;
+       pgm->code = PGM_PROTECTION;
+
+       return pgm->code;
+}
index 1079c8f..68db43e 100644 (file)
@@ -325,5 +325,6 @@ int read_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
 }
 
 int ipte_lock_held(struct kvm_vcpu *vcpu);
+int kvm_s390_check_low_addr_protection(struct kvm_vcpu *vcpu, unsigned long ga);
 
 #endif /* __KVM_S390_GACCESS_H */