gaccess.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * access guest memory
  3. *
  4. * Copyright IBM Corp. 2008, 2009
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License (version 2 only)
  8. * as published by the Free Software Foundation.
  9. *
  10. * Author(s): Carsten Otte <cotte@de.ibm.com>
  11. */
  12. #ifndef __KVM_S390_GACCESS_H
  13. #define __KVM_S390_GACCESS_H
  14. #include <linux/compiler.h>
  15. #include <linux/kvm_host.h>
  16. #include <asm/uaccess.h>
  17. #include "kvm-s390.h"
  18. static inline void __user *__gptr_to_uptr(struct kvm_vcpu *vcpu,
  19. void __user *gptr,
  20. int prefixing)
  21. {
  22. unsigned long prefix = vcpu->arch.sie_block->prefix;
  23. unsigned long gaddr = (unsigned long) gptr;
  24. unsigned long uaddr;
  25. if (prefixing) {
  26. if (gaddr < 2 * PAGE_SIZE)
  27. gaddr += prefix;
  28. else if ((gaddr >= prefix) && (gaddr < prefix + 2 * PAGE_SIZE))
  29. gaddr -= prefix;
  30. }
  31. uaddr = gmap_fault(gaddr, vcpu->arch.gmap);
  32. if (IS_ERR_VALUE(uaddr))
  33. uaddr = -EFAULT;
  34. return (void __user *)uaddr;
  35. }
  36. #define get_guest(vcpu, x, gptr) \
  37. ({ \
  38. __typeof__(gptr) __uptr = __gptr_to_uptr(vcpu, gptr, 1);\
  39. int __mask = sizeof(__typeof__(*(gptr))) - 1; \
  40. int __ret; \
  41. \
  42. if (IS_ERR((void __force *)__uptr)) { \
  43. __ret = PTR_ERR((void __force *)__uptr); \
  44. } else { \
  45. BUG_ON((unsigned long)__uptr & __mask); \
  46. __ret = get_user(x, __uptr); \
  47. } \
  48. __ret; \
  49. })
  50. #define put_guest(vcpu, x, gptr) \
  51. ({ \
  52. __typeof__(gptr) __uptr = __gptr_to_uptr(vcpu, gptr, 1);\
  53. int __mask = sizeof(__typeof__(*(gptr))) - 1; \
  54. int __ret; \
  55. \
  56. if (IS_ERR((void __force *)__uptr)) { \
  57. __ret = PTR_ERR((void __force *)__uptr); \
  58. } else { \
  59. BUG_ON((unsigned long)__uptr & __mask); \
  60. __ret = put_user(x, __uptr); \
  61. } \
  62. __ret; \
  63. })
  64. static inline int __copy_guest(struct kvm_vcpu *vcpu, unsigned long to,
  65. unsigned long from, unsigned long len,
  66. int to_guest, int prefixing)
  67. {
  68. unsigned long _len, rc;
  69. void __user *uptr;
  70. while (len) {
  71. uptr = to_guest ? (void __user *)to : (void __user *)from;
  72. uptr = __gptr_to_uptr(vcpu, uptr, prefixing);
  73. if (IS_ERR((void __force *)uptr))
  74. return -EFAULT;
  75. _len = PAGE_SIZE - ((unsigned long)uptr & (PAGE_SIZE - 1));
  76. _len = min(_len, len);
  77. if (to_guest)
  78. rc = copy_to_user((void __user *) uptr, (void *)from, _len);
  79. else
  80. rc = copy_from_user((void *)to, (void __user *)uptr, _len);
  81. if (rc)
  82. return -EFAULT;
  83. len -= _len;
  84. from += _len;
  85. to += _len;
  86. }
  87. return 0;
  88. }
  89. #define copy_to_guest(vcpu, to, from, size) \
  90. __copy_guest(vcpu, to, (unsigned long)from, size, 1, 1)
  91. #define copy_from_guest(vcpu, to, from, size) \
  92. __copy_guest(vcpu, (unsigned long)to, from, size, 0, 1)
  93. #define copy_to_guest_absolute(vcpu, to, from, size) \
  94. __copy_guest(vcpu, to, (unsigned long)from, size, 1, 0)
  95. #define copy_from_guest_absolute(vcpu, to, from, size) \
  96. __copy_guest(vcpu, (unsigned long)to, from, size, 0, 0)
  97. #endif /* __KVM_S390_GACCESS_H */