diff options
author | Thomas Huth <thuth@linux.vnet.ibm.com> | 2013-09-12 04:33:48 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-09-24 13:12:21 -0400 |
commit | aca84241b576044de68da9ca7e5cfa9c9bf9867b (patch) | |
tree | 057f12b7d19a58d23b38e1d5ffacc1e43b7417a1 /arch/s390/kvm | |
parent | 732e563373ffc57d38a8a3b6d55f2de865182117 (diff) |
KVM: s390: Implement TEST BLOCK
This patch provides a simple version for the mandatory TEST BLOCK
instruction interception, so that guests that use this instruction
do not crash anymore.
Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/priv.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 59200ee275e5..6f9599416bae 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -128,6 +128,33 @@ static int handle_skey(struct kvm_vcpu *vcpu) | |||
128 | return 0; | 128 | return 0; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int handle_test_block(struct kvm_vcpu *vcpu) | ||
132 | { | ||
133 | unsigned long hva; | ||
134 | gpa_t addr; | ||
135 | int reg2; | ||
136 | |||
137 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | ||
138 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | ||
139 | |||
140 | kvm_s390_get_regs_rre(vcpu, NULL, ®2); | ||
141 | addr = vcpu->run->s.regs.gprs[reg2] & PAGE_MASK; | ||
142 | addr = kvm_s390_real_to_abs(vcpu, addr); | ||
143 | |||
144 | hva = gfn_to_hva(vcpu->kvm, gpa_to_gfn(addr)); | ||
145 | if (kvm_is_error_hva(hva)) | ||
146 | return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | ||
147 | /* | ||
148 | * We don't expect errors on modern systems, and do not care | ||
149 | * about storage keys (yet), so let's just clear the page. | ||
150 | */ | ||
151 | if (clear_user((void __user *)hva, PAGE_SIZE) != 0) | ||
152 | return -EFAULT; | ||
153 | kvm_s390_set_psw_cc(vcpu, 0); | ||
154 | vcpu->run->s.regs.gprs[0] = 0; | ||
155 | return 0; | ||
156 | } | ||
157 | |||
131 | static int handle_tpi(struct kvm_vcpu *vcpu) | 158 | static int handle_tpi(struct kvm_vcpu *vcpu) |
132 | { | 159 | { |
133 | struct kvm_s390_interrupt_info *inti; | 160 | struct kvm_s390_interrupt_info *inti; |
@@ -444,6 +471,7 @@ static const intercept_handler_t b2_handlers[256] = { | |||
444 | [0x29] = handle_skey, | 471 | [0x29] = handle_skey, |
445 | [0x2a] = handle_skey, | 472 | [0x2a] = handle_skey, |
446 | [0x2b] = handle_skey, | 473 | [0x2b] = handle_skey, |
474 | [0x2c] = handle_test_block, | ||
447 | [0x30] = handle_io_inst, | 475 | [0x30] = handle_io_inst, |
448 | [0x31] = handle_io_inst, | 476 | [0x31] = handle_io_inst, |
449 | [0x32] = handle_io_inst, | 477 | [0x32] = handle_io_inst, |