diff options
author | David Hildenbrand <dahi@linux.vnet.ibm.com> | 2015-11-16 09:42:11 -0500 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2016-02-10 07:12:50 -0500 |
commit | 92c9632119b67f3e201240f6813cd0343bfb0141 (patch) | |
tree | 3ff5116af2531962e9686cb8b1214f907aff105c | |
parent | 634790b82759c98ee57c80966d859083fa2fcd8c (diff) |
KVM: s390: gaccess: introduce access modes
We will need special handling when fetching instructions, so let's
introduce new guest access modes GACC_FETCH and GACC_STORE instead
of a write flag. An additional patch will then introduce GACC_IFETCH.
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r-- | arch/s390/kvm/gaccess.c | 46 | ||||
-rw-r--r-- | arch/s390/kvm/gaccess.h | 17 | ||||
-rw-r--r-- | arch/s390/kvm/intercept.c | 4 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 6 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 5 |
5 files changed, 43 insertions, 35 deletions
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index d30db40437dc..c72ad9157414 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c | |||
@@ -373,7 +373,7 @@ void ipte_unlock(struct kvm_vcpu *vcpu) | |||
373 | } | 373 | } |
374 | 374 | ||
375 | static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, ar_t ar, | 375 | static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, ar_t ar, |
376 | int write) | 376 | enum gacc_mode mode) |
377 | { | 377 | { |
378 | union alet alet; | 378 | union alet alet; |
379 | struct ale ale; | 379 | struct ale ale; |
@@ -454,7 +454,7 @@ static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, ar_t ar, | |||
454 | } | 454 | } |
455 | } | 455 | } |
456 | 456 | ||
457 | if (ale.fo == 1 && write) | 457 | if (ale.fo == 1 && mode == GACC_STORE) |
458 | return PGM_PROTECTION; | 458 | return PGM_PROTECTION; |
459 | 459 | ||
460 | asce->val = aste.asce; | 460 | asce->val = aste.asce; |
@@ -477,7 +477,7 @@ enum { | |||
477 | }; | 477 | }; |
478 | 478 | ||
479 | static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce, | 479 | static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce, |
480 | ar_t ar, int write) | 480 | ar_t ar, enum gacc_mode mode) |
481 | { | 481 | { |
482 | int rc; | 482 | int rc; |
483 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | 483 | psw_t *psw = &vcpu->arch.sie_block->gpsw; |
@@ -486,7 +486,7 @@ static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce, | |||
486 | 486 | ||
487 | memset(pgm, 0, sizeof(*pgm)); | 487 | memset(pgm, 0, sizeof(*pgm)); |
488 | tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code; | 488 | tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code; |
489 | tec_bits->fsi = write ? FSI_STORE : FSI_FETCH; | 489 | tec_bits->fsi = mode == GACC_STORE ? FSI_STORE : FSI_FETCH; |
490 | tec_bits->as = psw_bits(*psw).as; | 490 | tec_bits->as = psw_bits(*psw).as; |
491 | 491 | ||
492 | if (!psw_bits(*psw).t) { | 492 | if (!psw_bits(*psw).t) { |
@@ -506,7 +506,7 @@ static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce, | |||
506 | asce->val = vcpu->arch.sie_block->gcr[13]; | 506 | asce->val = vcpu->arch.sie_block->gcr[13]; |
507 | return 0; | 507 | return 0; |
508 | case PSW_AS_ACCREG: | 508 | case PSW_AS_ACCREG: |
509 | rc = ar_translation(vcpu, asce, ar, write); | 509 | rc = ar_translation(vcpu, asce, ar, mode); |
510 | switch (rc) { | 510 | switch (rc) { |
511 | case PGM_ALEN_TRANSLATION: | 511 | case PGM_ALEN_TRANSLATION: |
512 | case PGM_ALE_SEQUENCE: | 512 | case PGM_ALE_SEQUENCE: |
@@ -538,7 +538,7 @@ static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val) | |||
538 | * @gva: guest virtual address | 538 | * @gva: guest virtual address |
539 | * @gpa: points to where guest physical (absolute) address should be stored | 539 | * @gpa: points to where guest physical (absolute) address should be stored |
540 | * @asce: effective asce | 540 | * @asce: effective asce |
541 | * @write: indicates if access is a write access | 541 | * @mode: indicates the access mode to be used |
542 | * | 542 | * |
543 | * Translate a guest virtual address into a guest absolute address by means | 543 | * Translate a guest virtual address into a guest absolute address by means |
544 | * of dynamic address translation as specified by the architecture. | 544 | * of dynamic address translation as specified by the architecture. |
@@ -554,7 +554,7 @@ static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val) | |||
554 | */ | 554 | */ |
555 | static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, | 555 | static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, |
556 | unsigned long *gpa, const union asce asce, | 556 | unsigned long *gpa, const union asce asce, |
557 | int write) | 557 | enum gacc_mode mode) |
558 | { | 558 | { |
559 | union vaddress vaddr = {.addr = gva}; | 559 | union vaddress vaddr = {.addr = gva}; |
560 | union raddress raddr = {.addr = gva}; | 560 | union raddress raddr = {.addr = gva}; |
@@ -699,7 +699,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, | |||
699 | real_address: | 699 | real_address: |
700 | raddr.addr = kvm_s390_real_to_abs(vcpu, raddr.addr); | 700 | raddr.addr = kvm_s390_real_to_abs(vcpu, raddr.addr); |
701 | absolute_address: | 701 | absolute_address: |
702 | if (write && dat_protection) | 702 | if (mode == GACC_STORE && dat_protection) |
703 | return PGM_PROTECTION; | 703 | return PGM_PROTECTION; |
704 | if (kvm_is_error_gpa(vcpu->kvm, raddr.addr)) | 704 | if (kvm_is_error_gpa(vcpu->kvm, raddr.addr)) |
705 | return PGM_ADDRESSING; | 705 | return PGM_ADDRESSING; |
@@ -728,7 +728,7 @@ static int low_address_protection_enabled(struct kvm_vcpu *vcpu, | |||
728 | 728 | ||
729 | static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, | 729 | static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, |
730 | unsigned long *pages, unsigned long nr_pages, | 730 | unsigned long *pages, unsigned long nr_pages, |
731 | const union asce asce, int write) | 731 | const union asce asce, enum gacc_mode mode) |
732 | { | 732 | { |
733 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; | 733 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; |
734 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | 734 | psw_t *psw = &vcpu->arch.sie_block->gpsw; |
@@ -740,13 +740,13 @@ static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, | |||
740 | while (nr_pages) { | 740 | while (nr_pages) { |
741 | ga = kvm_s390_logical_to_effective(vcpu, ga); | 741 | ga = kvm_s390_logical_to_effective(vcpu, ga); |
742 | tec_bits->addr = ga >> PAGE_SHIFT; | 742 | tec_bits->addr = ga >> PAGE_SHIFT; |
743 | if (write && lap_enabled && is_low_address(ga)) { | 743 | if (mode == GACC_STORE && lap_enabled && is_low_address(ga)) { |
744 | pgm->code = PGM_PROTECTION; | 744 | pgm->code = PGM_PROTECTION; |
745 | return pgm->code; | 745 | return pgm->code; |
746 | } | 746 | } |
747 | ga &= PAGE_MASK; | 747 | ga &= PAGE_MASK; |
748 | if (psw_bits(*psw).t) { | 748 | if (psw_bits(*psw).t) { |
749 | rc = guest_translate(vcpu, ga, pages, asce, write); | 749 | rc = guest_translate(vcpu, ga, pages, asce, mode); |
750 | if (rc < 0) | 750 | if (rc < 0) |
751 | return rc; | 751 | return rc; |
752 | if (rc == PGM_PROTECTION) | 752 | if (rc == PGM_PROTECTION) |
@@ -768,7 +768,7 @@ static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, | |||
768 | } | 768 | } |
769 | 769 | ||
770 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, | 770 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
771 | unsigned long len, int write) | 771 | unsigned long len, enum gacc_mode mode) |
772 | { | 772 | { |
773 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | 773 | psw_t *psw = &vcpu->arch.sie_block->gpsw; |
774 | unsigned long _len, nr_pages, gpa, idx; | 774 | unsigned long _len, nr_pages, gpa, idx; |
@@ -780,7 +780,7 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, | |||
780 | 780 | ||
781 | if (!len) | 781 | if (!len) |
782 | return 0; | 782 | return 0; |
783 | rc = get_vcpu_asce(vcpu, &asce, ar, write); | 783 | rc = get_vcpu_asce(vcpu, &asce, ar, mode); |
784 | if (rc) | 784 | if (rc) |
785 | return rc; | 785 | return rc; |
786 | nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1; | 786 | nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1; |
@@ -792,11 +792,11 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, | |||
792 | need_ipte_lock = psw_bits(*psw).t && !asce.r; | 792 | need_ipte_lock = psw_bits(*psw).t && !asce.r; |
793 | if (need_ipte_lock) | 793 | if (need_ipte_lock) |
794 | ipte_lock(vcpu); | 794 | ipte_lock(vcpu); |
795 | rc = guest_page_range(vcpu, ga, pages, nr_pages, asce, write); | 795 | rc = guest_page_range(vcpu, ga, pages, nr_pages, asce, mode); |
796 | for (idx = 0; idx < nr_pages && !rc; idx++) { | 796 | for (idx = 0; idx < nr_pages && !rc; idx++) { |
797 | gpa = *(pages + idx) + (ga & ~PAGE_MASK); | 797 | gpa = *(pages + idx) + (ga & ~PAGE_MASK); |
798 | _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); | 798 | _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); |
799 | if (write) | 799 | if (mode == GACC_STORE) |
800 | rc = kvm_write_guest(vcpu->kvm, gpa, data, _len); | 800 | rc = kvm_write_guest(vcpu->kvm, gpa, data, _len); |
801 | else | 801 | else |
802 | rc = kvm_read_guest(vcpu->kvm, gpa, data, _len); | 802 | rc = kvm_read_guest(vcpu->kvm, gpa, data, _len); |
@@ -812,7 +812,7 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, | |||
812 | } | 812 | } |
813 | 813 | ||
814 | int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | 814 | int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, |
815 | void *data, unsigned long len, int write) | 815 | void *data, unsigned long len, enum gacc_mode mode) |
816 | { | 816 | { |
817 | unsigned long _len, gpa; | 817 | unsigned long _len, gpa; |
818 | int rc = 0; | 818 | int rc = 0; |
@@ -820,7 +820,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | |||
820 | while (len && !rc) { | 820 | while (len && !rc) { |
821 | gpa = kvm_s390_real_to_abs(vcpu, gra); | 821 | gpa = kvm_s390_real_to_abs(vcpu, gra); |
822 | _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); | 822 | _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); |
823 | if (write) | 823 | if (mode) |
824 | rc = write_guest_abs(vcpu, gpa, data, _len); | 824 | rc = write_guest_abs(vcpu, gpa, data, _len); |
825 | else | 825 | else |
826 | rc = read_guest_abs(vcpu, gpa, data, _len); | 826 | rc = read_guest_abs(vcpu, gpa, data, _len); |
@@ -841,7 +841,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | |||
841 | * has to take care of this. | 841 | * has to take care of this. |
842 | */ | 842 | */ |
843 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, | 843 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, |
844 | unsigned long *gpa, int write) | 844 | unsigned long *gpa, enum gacc_mode mode) |
845 | { | 845 | { |
846 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; | 846 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; |
847 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | 847 | psw_t *psw = &vcpu->arch.sie_block->gpsw; |
@@ -851,19 +851,19 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, | |||
851 | 851 | ||
852 | gva = kvm_s390_logical_to_effective(vcpu, gva); | 852 | gva = kvm_s390_logical_to_effective(vcpu, gva); |
853 | tec = (struct trans_exc_code_bits *)&pgm->trans_exc_code; | 853 | tec = (struct trans_exc_code_bits *)&pgm->trans_exc_code; |
854 | rc = get_vcpu_asce(vcpu, &asce, ar, write); | 854 | rc = get_vcpu_asce(vcpu, &asce, ar, mode); |
855 | tec->addr = gva >> PAGE_SHIFT; | 855 | tec->addr = gva >> PAGE_SHIFT; |
856 | if (rc) | 856 | if (rc) |
857 | return rc; | 857 | return rc; |
858 | if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) { | 858 | if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) { |
859 | if (write) { | 859 | if (mode == GACC_STORE) { |
860 | rc = pgm->code = PGM_PROTECTION; | 860 | rc = pgm->code = PGM_PROTECTION; |
861 | return rc; | 861 | return rc; |
862 | } | 862 | } |
863 | } | 863 | } |
864 | 864 | ||
865 | if (psw_bits(*psw).t && !asce.r) { /* Use DAT? */ | 865 | if (psw_bits(*psw).t && !asce.r) { /* Use DAT? */ |
866 | rc = guest_translate(vcpu, gva, gpa, asce, write); | 866 | rc = guest_translate(vcpu, gva, gpa, asce, mode); |
867 | if (rc > 0) { | 867 | if (rc > 0) { |
868 | if (rc == PGM_PROTECTION) | 868 | if (rc == PGM_PROTECTION) |
869 | tec->b61 = 1; | 869 | tec->b61 = 1; |
@@ -883,7 +883,7 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, | |||
883 | * check_gva_range - test a range of guest virtual addresses for accessibility | 883 | * check_gva_range - test a range of guest virtual addresses for accessibility |
884 | */ | 884 | */ |
885 | int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, | 885 | int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, |
886 | unsigned long length, int is_write) | 886 | unsigned long length, enum gacc_mode mode) |
887 | { | 887 | { |
888 | unsigned long gpa; | 888 | unsigned long gpa; |
889 | unsigned long currlen; | 889 | unsigned long currlen; |
@@ -892,7 +892,7 @@ int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, | |||
892 | ipte_lock(vcpu); | 892 | ipte_lock(vcpu); |
893 | while (length > 0 && !rc) { | 893 | while (length > 0 && !rc) { |
894 | currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE)); | 894 | currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE)); |
895 | rc = guest_translate_address(vcpu, gva, ar, &gpa, is_write); | 895 | rc = guest_translate_address(vcpu, gva, ar, &gpa, mode); |
896 | gva += currlen; | 896 | gva += currlen; |
897 | length -= currlen; | 897 | length -= currlen; |
898 | } | 898 | } |
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index ef03726cc661..2a6f8bfd22f8 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h | |||
@@ -155,16 +155,21 @@ int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data, | |||
155 | return kvm_read_guest(vcpu->kvm, gpa, data, len); | 155 | return kvm_read_guest(vcpu->kvm, gpa, data, len); |
156 | } | 156 | } |
157 | 157 | ||
158 | enum gacc_mode { | ||
159 | GACC_FETCH, | ||
160 | GACC_STORE, | ||
161 | }; | ||
162 | |||
158 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, | 163 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, |
159 | ar_t ar, unsigned long *gpa, int write); | 164 | ar_t ar, unsigned long *gpa, enum gacc_mode mode); |
160 | int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, | 165 | int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, |
161 | unsigned long length, int is_write); | 166 | unsigned long length, enum gacc_mode mode); |
162 | 167 | ||
163 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, | 168 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
164 | unsigned long len, int write); | 169 | unsigned long len, enum gacc_mode mode); |
165 | 170 | ||
166 | int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | 171 | int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, |
167 | void *data, unsigned long len, int write); | 172 | void *data, unsigned long len, enum gacc_mode mode); |
168 | 173 | ||
169 | /** | 174 | /** |
170 | * write_guest - copy data from kernel space to guest space | 175 | * write_guest - copy data from kernel space to guest space |
@@ -215,7 +220,7 @@ static inline __must_check | |||
215 | int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, | 220 | int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
216 | unsigned long len) | 221 | unsigned long len) |
217 | { | 222 | { |
218 | return access_guest(vcpu, ga, ar, data, len, 1); | 223 | return access_guest(vcpu, ga, ar, data, len, GACC_STORE); |
219 | } | 224 | } |
220 | 225 | ||
221 | /** | 226 | /** |
@@ -235,7 +240,7 @@ static inline __must_check | |||
235 | int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, | 240 | int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
236 | unsigned long len) | 241 | unsigned long len) |
237 | { | 242 | { |
238 | return access_guest(vcpu, ga, ar, data, len, 0); | 243 | return access_guest(vcpu, ga, ar, data, len, GACC_FETCH); |
239 | } | 244 | } |
240 | 245 | ||
241 | /** | 246 | /** |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 7f992e02124a..44bb923a6482 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -317,7 +317,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu) | |||
317 | 317 | ||
318 | /* Make sure that the source is paged-in */ | 318 | /* Make sure that the source is paged-in */ |
319 | rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2], | 319 | rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2], |
320 | reg2, &srcaddr, 0); | 320 | reg2, &srcaddr, GACC_FETCH); |
321 | if (rc) | 321 | if (rc) |
322 | return kvm_s390_inject_prog_cond(vcpu, rc); | 322 | return kvm_s390_inject_prog_cond(vcpu, rc); |
323 | rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0); | 323 | rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0); |
@@ -326,7 +326,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu) | |||
326 | 326 | ||
327 | /* Make sure that the destination is paged-in */ | 327 | /* Make sure that the destination is paged-in */ |
328 | rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1], | 328 | rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1], |
329 | reg1, &dstaddr, 1); | 329 | reg1, &dstaddr, GACC_STORE); |
330 | if (rc) | 330 | if (rc) |
331 | return kvm_s390_inject_prog_cond(vcpu, rc); | 331 | return kvm_s390_inject_prog_cond(vcpu, rc); |
332 | rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1); | 332 | rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1); |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index cd84a3eeb214..85e169b8e90d 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -2610,7 +2610,8 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu, | |||
2610 | switch (mop->op) { | 2610 | switch (mop->op) { |
2611 | case KVM_S390_MEMOP_LOGICAL_READ: | 2611 | case KVM_S390_MEMOP_LOGICAL_READ: |
2612 | if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { | 2612 | if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { |
2613 | r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, false); | 2613 | r = check_gva_range(vcpu, mop->gaddr, mop->ar, |
2614 | mop->size, GACC_FETCH); | ||
2614 | break; | 2615 | break; |
2615 | } | 2616 | } |
2616 | r = read_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size); | 2617 | r = read_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size); |
@@ -2621,7 +2622,8 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu, | |||
2621 | break; | 2622 | break; |
2622 | case KVM_S390_MEMOP_LOGICAL_WRITE: | 2623 | case KVM_S390_MEMOP_LOGICAL_WRITE: |
2623 | if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { | 2624 | if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { |
2624 | r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, true); | 2625 | r = check_gva_range(vcpu, mop->gaddr, mop->ar, |
2626 | mop->size, GACC_STORE); | ||
2625 | break; | 2627 | break; |
2626 | } | 2628 | } |
2627 | if (copy_from_user(tmpbuf, uaddr, mop->size)) { | 2629 | if (copy_from_user(tmpbuf, uaddr, mop->size)) { |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index d58cbe9813db..add990945986 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -981,11 +981,12 @@ static int handle_tprot(struct kvm_vcpu *vcpu) | |||
981 | return -EOPNOTSUPP; | 981 | return -EOPNOTSUPP; |
982 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT) | 982 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT) |
983 | ipte_lock(vcpu); | 983 | ipte_lock(vcpu); |
984 | ret = guest_translate_address(vcpu, address1, ar, &gpa, 1); | 984 | ret = guest_translate_address(vcpu, address1, ar, &gpa, GACC_STORE); |
985 | if (ret == PGM_PROTECTION) { | 985 | if (ret == PGM_PROTECTION) { |
986 | /* Write protected? Try again with read-only... */ | 986 | /* Write protected? Try again with read-only... */ |
987 | cc = 1; | 987 | cc = 1; |
988 | ret = guest_translate_address(vcpu, address1, ar, &gpa, 0); | 988 | ret = guest_translate_address(vcpu, address1, ar, &gpa, |
989 | GACC_FETCH); | ||
989 | } | 990 | } |
990 | if (ret) { | 991 | if (ret) { |
991 | if (ret == PGM_ADDRESSING || ret == PGM_TRANSLATION_SPEC) { | 992 | if (ret == PGM_ADDRESSING || ret == PGM_TRANSLATION_SPEC) { |