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.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index bc969722a293..44ff22007052 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -755,32 +755,31 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu)
755{ 755{
756 int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; 756 int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
757 int reg3 = vcpu->arch.sie_block->ipa & 0x000f; 757 int reg3 = vcpu->arch.sie_block->ipa & 0x000f;
758 u64 useraddr;
759 u32 val = 0; 758 u32 val = 0;
760 int reg, rc; 759 int reg, rc;
760 u64 ga;
761 761
762 vcpu->stat.instruction_lctl++; 762 vcpu->stat.instruction_lctl++;
763 763
764 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 764 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
765 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 765 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
766 766
767 useraddr = kvm_s390_get_base_disp_rs(vcpu); 767 ga = kvm_s390_get_base_disp_rs(vcpu);
768 768
769 if (useraddr & 3) 769 if (ga & 3)
770 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 770 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
771 771
772 VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x, addr:%llx", reg1, reg3, 772 VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x, addr:%llx", reg1, reg3, ga);
773 useraddr); 773 trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, ga);
774 trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, useraddr);
775 774
776 reg = reg1; 775 reg = reg1;
777 do { 776 do {
778 rc = get_guest(vcpu, val, (u32 __user *) useraddr); 777 rc = read_guest(vcpu, ga, &val, sizeof(val));
779 if (rc) 778 if (rc)
780 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 779 return kvm_s390_inject_prog_cond(vcpu, rc);
781 vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul; 780 vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul;
782 vcpu->arch.sie_block->gcr[reg] |= val; 781 vcpu->arch.sie_block->gcr[reg] |= val;
783 useraddr += 4; 782 ga += 4;
784 if (reg == reg3) 783 if (reg == reg3)
785 break; 784 break;
786 reg = (reg + 1) % 16; 785 reg = (reg + 1) % 16;
@@ -793,7 +792,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
793{ 792{
794 int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; 793 int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
795 int reg3 = vcpu->arch.sie_block->ipa & 0x000f; 794 int reg3 = vcpu->arch.sie_block->ipa & 0x000f;
796 u64 useraddr; 795 u64 ga, val;
797 int reg, rc; 796 int reg, rc;
798 797
799 vcpu->stat.instruction_lctlg++; 798 vcpu->stat.instruction_lctlg++;
@@ -801,23 +800,22 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
801 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 800 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
802 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 801 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
803 802
804 useraddr = kvm_s390_get_base_disp_rsy(vcpu); 803 ga = kvm_s390_get_base_disp_rsy(vcpu);
805 804
806 if (useraddr & 7) 805 if (ga & 7)
807 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 806 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
808 807
809 reg = reg1; 808 reg = reg1;
810 809
811 VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x, addr:%llx", reg1, reg3, 810 VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x, addr:%llx", reg1, reg3, ga);
812 useraddr); 811 trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, ga);
813 trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, useraddr);
814 812
815 do { 813 do {
816 rc = get_guest(vcpu, vcpu->arch.sie_block->gcr[reg], 814 rc = read_guest(vcpu, ga, &val, sizeof(val));
817 (u64 __user *) useraddr);
818 if (rc) 815 if (rc)
819 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 816 return kvm_s390_inject_prog_cond(vcpu, rc);
820 useraddr += 8; 817 vcpu->arch.sie_block->gcr[reg] = val;
818 ga += 8;
821 if (reg == reg3) 819 if (reg == reg3)
822 break; 820 break;
823 reg = (reg + 1) % 16; 821 reg = (reg + 1) % 16;