aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/svm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/svm.c')
-rw-r--r--drivers/kvm/svm.c40
1 files changed, 19 insertions, 21 deletions
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 2396ada23777..64afc5cf890d 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -984,7 +984,7 @@ static int io_get_override(struct kvm_vcpu *vcpu,
984 return 0; 984 return 0;
985} 985}
986 986
987static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, u64 *address) 987static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, gva_t *address)
988{ 988{
989 unsigned long addr_mask; 989 unsigned long addr_mask;
990 unsigned long *reg; 990 unsigned long *reg;
@@ -1028,40 +1028,38 @@ static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, u64 *address)
1028static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1028static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1029{ 1029{
1030 u32 io_info = vcpu->svm->vmcb->control.exit_info_1; //address size bug? 1030 u32 io_info = vcpu->svm->vmcb->control.exit_info_1; //address size bug?
1031 int _in = io_info & SVM_IOIO_TYPE_MASK; 1031 int size, down, in, string, rep;
1032 unsigned port;
1033 unsigned long count;
1034 gva_t address = 0;
1032 1035
1033 ++kvm_stat.io_exits; 1036 ++kvm_stat.io_exits;
1034 1037
1035 vcpu->svm->next_rip = vcpu->svm->vmcb->control.exit_info_2; 1038 vcpu->svm->next_rip = vcpu->svm->vmcb->control.exit_info_2;
1036 1039
1037 kvm_run->exit_reason = KVM_EXIT_IO; 1040 in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
1038 kvm_run->io.port = io_info >> 16; 1041 port = io_info >> 16;
1039 kvm_run->io.direction = (_in) ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; 1042 size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
1040 kvm_run->io.size = ((io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT); 1043 string = (io_info & SVM_IOIO_STR_MASK) != 0;
1041 kvm_run->io.string = (io_info & SVM_IOIO_STR_MASK) != 0; 1044 rep = (io_info & SVM_IOIO_REP_MASK) != 0;
1042 kvm_run->io.rep = (io_info & SVM_IOIO_REP_MASK) != 0; 1045 count = 1;
1043 kvm_run->io.count = 1; 1046 down = (vcpu->svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
1044 1047
1045 if (kvm_run->io.string) { 1048 if (string) {
1046 unsigned addr_mask; 1049 unsigned addr_mask;
1047 1050
1048 addr_mask = io_adress(vcpu, _in, &kvm_run->io.address); 1051 addr_mask = io_adress(vcpu, in, &address);
1049 if (!addr_mask) { 1052 if (!addr_mask) {
1050 printk(KERN_DEBUG "%s: get io address failed\n", 1053 printk(KERN_DEBUG "%s: get io address failed\n",
1051 __FUNCTION__); 1054 __FUNCTION__);
1052 return 1; 1055 return 1;
1053 } 1056 }
1054 1057
1055 if (kvm_run->io.rep) { 1058 if (rep)
1056 kvm_run->io.count 1059 count = vcpu->regs[VCPU_REGS_RCX] & addr_mask;
1057 = vcpu->regs[VCPU_REGS_RCX] & addr_mask; 1060 }
1058 kvm_run->io.string_down = (vcpu->svm->vmcb->save.rflags 1061 return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down,
1059 & X86_EFLAGS_DF) != 0; 1062 address, rep, port);
1060 }
1061 } else
1062 kvm_run->io.value = vcpu->svm->vmcb->save.rax;
1063 vcpu->pio_pending = 1;
1064 return 0;
1065} 1063}
1066 1064
1067static int nop_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1065static int nop_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)