aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2015-11-16 09:48:59 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2016-02-10 07:12:51 -0500
commit34346b9a9388b28c3b4a865f8b4f98863f05df81 (patch)
treea58ffbb94c94f85fd5b5763582229cd5994f83aa
parent92c9632119b67f3e201240f6813cd0343bfb0141 (diff)
KVM: s390: gaccess: implement instruction fetching mode
When an instruction is to be fetched, special handling applies to secondary-space mode and access-register mode. The instruction is to be fetched from primary space. We can easily support this by selecting the right asce for translation. Access registers will never be used during translation, so don't include them in the interface. As we only want to read from the current PSW address for now, let's also hide that detail. 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.c11
-rw-r--r--arch/s390/kvm/gaccess.h21
2 files changed, 28 insertions, 4 deletions
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index c72ad9157414..66938d283b77 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -480,22 +480,25 @@ static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce,
480 ar_t ar, enum gacc_mode mode) 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 struct psw_bits psw = psw_bits(vcpu->arch.sie_block->gpsw);
484 struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; 484 struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
485 struct trans_exc_code_bits *tec_bits; 485 struct trans_exc_code_bits *tec_bits;
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 = mode == GACC_STORE ? 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.as;
491 491
492 if (!psw_bits(*psw).t) { 492 if (!psw.t) {
493 asce->val = 0; 493 asce->val = 0;
494 asce->r = 1; 494 asce->r = 1;
495 return 0; 495 return 0;
496 } 496 }
497 497
498 switch (psw_bits(vcpu->arch.sie_block->gpsw).as) { 498 if (mode == GACC_IFETCH)
499 psw.as = psw.as == PSW_AS_HOME ? PSW_AS_HOME : PSW_AS_PRIMARY;
500
501 switch (psw.as) {
499 case PSW_AS_PRIMARY: 502 case PSW_AS_PRIMARY:
500 asce->val = vcpu->arch.sie_block->gcr[1]; 503 asce->val = vcpu->arch.sie_block->gcr[1];
501 return 0; 504 return 0;
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index 2a6f8bfd22f8..df0a79dd8159 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -158,6 +158,7 @@ int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
158enum gacc_mode { 158enum gacc_mode {
159 GACC_FETCH, 159 GACC_FETCH,
160 GACC_STORE, 160 GACC_STORE,
161 GACC_IFETCH,
161}; 162};
162 163
163int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, 164int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva,
@@ -244,6 +245,26 @@ int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
244} 245}
245 246
246/** 247/**
248 * read_guest_instr - copy instruction data from guest space to kernel space
249 * @vcpu: virtual cpu
250 * @data: destination address in kernel space
251 * @len: number of bytes to copy
252 *
253 * Copy @len bytes from the current psw address (guest space) to @data (kernel
254 * space).
255 *
256 * The behaviour of read_guest_instr is identical to read_guest, except that
257 * instruction data will be read from primary space when in home-space or
258 * address-space mode.
259 */
260static inline __must_check
261int read_guest_instr(struct kvm_vcpu *vcpu, void *data, unsigned long len)
262{
263 return access_guest(vcpu, vcpu->arch.sie_block->gpsw.addr, 0, data, len,
264 GACC_IFETCH);
265}
266
267/**
247 * write_guest_abs - copy data from kernel space to guest space absolute 268 * write_guest_abs - copy data from kernel space to guest space absolute
248 * @vcpu: virtual cpu 269 * @vcpu: virtual cpu
249 * @gpa: guest physical (absolute) address 270 * @gpa: guest physical (absolute) address