aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/priv.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kvm/priv.c')
-rw-r--r--arch/s390/kvm/priv.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 7066fc5bf48a..dd6ad8445608 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -65,8 +65,8 @@ static int handle_set_clock(struct kvm_vcpu *vcpu)
65static int handle_set_prefix(struct kvm_vcpu *vcpu) 65static int handle_set_prefix(struct kvm_vcpu *vcpu)
66{ 66{
67 u64 operand2; 67 u64 operand2;
68 u32 address = 0; 68 u32 address;
69 u8 tmp; 69 int rc;
70 70
71 vcpu->stat.instruction_spx++; 71 vcpu->stat.instruction_spx++;
72 72
@@ -80,14 +80,18 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu)
80 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 80 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
81 81
82 /* get the value */ 82 /* get the value */
83 if (get_guest(vcpu, address, (u32 __user *) operand2)) 83 rc = read_guest(vcpu, operand2, &address, sizeof(address));
84 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 84 if (rc)
85 return kvm_s390_inject_prog_cond(vcpu, rc);
85 86
86 address = address & 0x7fffe000u; 87 address &= 0x7fffe000u;
87 88
88 /* make sure that the new value is valid memory */ 89 /*
89 if (copy_from_guest_absolute(vcpu, &tmp, address, 1) || 90 * Make sure the new value is valid memory. We only need to check the
90 (copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1))) 91 * first page, since address is 8k aligned and memory pieces are always
92 * at least 1MB aligned and have at least a size of 1MB.
93 */
94 if (kvm_is_error_gpa(vcpu->kvm, address))
91 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 95 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
92 96
93 kvm_s390_set_prefix(vcpu, address); 97 kvm_s390_set_prefix(vcpu, address);