aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/gaccess.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kvm/gaccess.h')
-rw-r--r--arch/s390/kvm/gaccess.h21
1 files changed, 14 insertions, 7 deletions
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index 99d789e8a018..374a439ccc60 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -18,20 +18,27 @@
18#include <asm/uaccess.h> 18#include <asm/uaccess.h>
19#include "kvm-s390.h" 19#include "kvm-s390.h"
20 20
21/* Convert real to absolute address by applying the prefix of the CPU */
22static inline unsigned long kvm_s390_real_to_abs(struct kvm_vcpu *vcpu,
23 unsigned long gaddr)
24{
25 unsigned long prefix = vcpu->arch.sie_block->prefix;
26 if (gaddr < 2 * PAGE_SIZE)
27 gaddr += prefix;
28 else if (gaddr >= prefix && gaddr < prefix + 2 * PAGE_SIZE)
29 gaddr -= prefix;
30 return gaddr;
31}
32
21static inline void __user *__gptr_to_uptr(struct kvm_vcpu *vcpu, 33static inline void __user *__gptr_to_uptr(struct kvm_vcpu *vcpu,
22 void __user *gptr, 34 void __user *gptr,
23 int prefixing) 35 int prefixing)
24{ 36{
25 unsigned long prefix = vcpu->arch.sie_block->prefix;
26 unsigned long gaddr = (unsigned long) gptr; 37 unsigned long gaddr = (unsigned long) gptr;
27 unsigned long uaddr; 38 unsigned long uaddr;
28 39
29 if (prefixing) { 40 if (prefixing)
30 if (gaddr < 2 * PAGE_SIZE) 41 gaddr = kvm_s390_real_to_abs(vcpu, gaddr);
31 gaddr += prefix;
32 else if ((gaddr >= prefix) && (gaddr < prefix + 2 * PAGE_SIZE))
33 gaddr -= prefix;
34 }
35 uaddr = gmap_fault(gaddr, vcpu->arch.gmap); 42 uaddr = gmap_fault(gaddr, vcpu->arch.gmap);
36 if (IS_ERR_VALUE(uaddr)) 43 if (IS_ERR_VALUE(uaddr))
37 uaddr = -EFAULT; 44 uaddr = -EFAULT;