KVM: s390: convert __sigp_set_prefix()/handle_set_prefix()
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Wed, 1 Jan 2014 15:47:12 +0000 (16:47 +0100)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Tue, 22 Apr 2014 11:24:42 +0000 (13:24 +0200)
Convert __sigp_set_prefix() and handle_set_prefix() to new guest
access functions.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
arch/s390/kvm/priv.c
arch/s390/kvm/sigp.c

index 7066fc5bf48a64632c970dd5346ec6d9ab9179bb..dd6ad8445608db0e001a0b41e6e4f7d3b3d895da 100644 (file)
@@ -65,8 +65,8 @@ static int handle_set_clock(struct kvm_vcpu *vcpu)
 static int handle_set_prefix(struct kvm_vcpu *vcpu)
 {
        u64 operand2;
-       u32 address = 0;
-       u8 tmp;
+       u32 address;
+       int rc;
 
        vcpu->stat.instruction_spx++;
 
@@ -80,14 +80,18 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu)
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
 
        /* get the value */
-       if (get_guest(vcpu, address, (u32 __user *) operand2))
-               return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+       rc = read_guest(vcpu, operand2, &address, sizeof(address));
+       if (rc)
+               return kvm_s390_inject_prog_cond(vcpu, rc);
 
-       address = address & 0x7fffe000u;
+       address &= 0x7fffe000u;
 
-       /* make sure that the new value is valid memory */
-       if (copy_from_guest_absolute(vcpu, &tmp, address, 1) ||
-          (copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1)))
+       /*
+        * Make sure the new value is valid memory. We only need to check the
+        * first page, since address is 8k aligned and memory pieces are always
+        * at least 1MB aligned and have at least a size of 1MB.
+        */
+       if (kvm_is_error_gpa(vcpu->kvm, address))
                return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
 
        kvm_s390_set_prefix(vcpu, address);
index 26caeb530a7829f6688a31e8ecaa84203b2496bb..c0b99e0f6b63a52bcf0d037da403319878c6817a 100644 (file)
@@ -235,7 +235,6 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
        struct kvm_vcpu *dst_vcpu = NULL;
        struct kvm_s390_interrupt_info *inti;
        int rc;
-       u8 tmp;
 
        if (cpu_addr < KVM_MAX_VCPUS)
                dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
@@ -243,10 +242,13 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
                return SIGP_CC_NOT_OPERATIONAL;
        li = &dst_vcpu->arch.local_int;
 
-       /* make sure that the new value is valid memory */
-       address = address & 0x7fffe000u;
-       if (copy_from_guest_absolute(vcpu, &tmp, address, 1) ||
-          copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1)) {
+       /*
+        * Make sure the new value is valid memory. We only need to check the
+        * first page, since address is 8k aligned and memory pieces are always
+        * at least 1MB aligned and have at least a size of 1MB.
+        */
+       address &= 0x7fffe000u;
+       if (kvm_is_error_gpa(vcpu->kvm, address)) {
                *reg &= 0xffffffff00000000UL;
                *reg |= SIGP_STATUS_INVALID_PARAMETER;
                return SIGP_CC_STATUS_STORED;