aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2015-11-16 09:42:11 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2016-02-10 07:12:50 -0500
commit92c9632119b67f3e201240f6813cd0343bfb0141 (patch)
tree3ff5116af2531962e9686cb8b1214f907aff105c
parent634790b82759c98ee57c80966d859083fa2fcd8c (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.c46
-rw-r--r--arch/s390/kvm/gaccess.h17
-rw-r--r--arch/s390/kvm/intercept.c4
-rw-r--r--arch/s390/kvm/kvm-s390.c6
-rw-r--r--arch/s390/kvm/priv.c5
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
375static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, ar_t ar, 375static 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
479static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce, 479static 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 */
555static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, 555static 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,
699real_address: 699real_address:
700 raddr.addr = kvm_s390_real_to_abs(vcpu, raddr.addr); 700 raddr.addr = kvm_s390_real_to_abs(vcpu, raddr.addr);
701absolute_address: 701absolute_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
729static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, 729static 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
770int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, 770int 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
814int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, 814int 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 */
843int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, 843int 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 */
885int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, 885int 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
158enum gacc_mode {
159 GACC_FETCH,
160 GACC_STORE,
161};
162
158int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, 163int 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);
160int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, 165int 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
163int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, 168int 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
166int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, 171int 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
215int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, 220int 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
235int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, 240int 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) {