aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/kvm/kvm.h8
-rw-r--r--drivers/kvm/kvm_main.c63
-rw-r--r--drivers/kvm/svm.c3
-rw-r--r--drivers/kvm/vmx.c3
-rw-r--r--drivers/kvm/x86_emulate.c6
5 files changed, 48 insertions, 35 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 6d258261891e..2245baeeb022 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -539,9 +539,11 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
539 539
540struct x86_emulate_ctxt; 540struct x86_emulate_ctxt;
541 541
542int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, 542int kvm_emulate_pio (struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
543 int size, unsigned long count, int string, int down, 543 int size, unsigned port);
544 gva_t address, int rep, unsigned port); 544int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
545 int size, unsigned long count, int down,
546 gva_t address, int rep, unsigned port);
545void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); 547void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
546int kvm_emulate_halt(struct kvm_vcpu *vcpu); 548int kvm_emulate_halt(struct kvm_vcpu *vcpu);
547int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); 549int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 661d065fd866..d154487b7729 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1735,8 +1735,39 @@ static void pio_string_write(struct kvm_io_device *pio_dev,
1735 } 1735 }
1736} 1736}
1737 1737
1738int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, 1738int kvm_emulate_pio (struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1739 int size, unsigned long count, int string, int down, 1739 int size, unsigned port)
1740{
1741 struct kvm_io_device *pio_dev;
1742
1743 vcpu->run->exit_reason = KVM_EXIT_IO;
1744 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
1745 vcpu->run->io.size = vcpu->pio.size = size;
1746 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
1747 vcpu->run->io.count = vcpu->pio.count = vcpu->pio.cur_count = 1;
1748 vcpu->run->io.port = vcpu->pio.port = port;
1749 vcpu->pio.in = in;
1750 vcpu->pio.string = 0;
1751 vcpu->pio.down = 0;
1752 vcpu->pio.guest_page_offset = 0;
1753 vcpu->pio.rep = 0;
1754
1755 kvm_arch_ops->cache_regs(vcpu);
1756 memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);
1757 kvm_arch_ops->decache_regs(vcpu);
1758
1759 pio_dev = vcpu_find_pio_dev(vcpu, port);
1760 if (pio_dev) {
1761 kernel_pio(pio_dev, vcpu, vcpu->pio_data);
1762 complete_pio(vcpu);
1763 return 1;
1764 }
1765 return 0;
1766}
1767EXPORT_SYMBOL_GPL(kvm_emulate_pio);
1768
1769int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1770 int size, unsigned long count, int down,
1740 gva_t address, int rep, unsigned port) 1771 gva_t address, int rep, unsigned port)
1741{ 1772{
1742 unsigned now, in_page; 1773 unsigned now, in_page;
@@ -1747,33 +1778,16 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1747 1778
1748 vcpu->run->exit_reason = KVM_EXIT_IO; 1779 vcpu->run->exit_reason = KVM_EXIT_IO;
1749 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; 1780 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
1750 vcpu->run->io.size = size; 1781 vcpu->run->io.size = vcpu->pio.size = size;
1751 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; 1782 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
1752 vcpu->run->io.count = count; 1783 vcpu->run->io.count = vcpu->pio.count = vcpu->pio.cur_count = count;
1753 vcpu->run->io.port = port; 1784 vcpu->run->io.port = vcpu->pio.port = port;
1754 vcpu->pio.count = count;
1755 vcpu->pio.cur_count = count;
1756 vcpu->pio.size = size;
1757 vcpu->pio.in = in; 1785 vcpu->pio.in = in;
1758 vcpu->pio.port = port; 1786 vcpu->pio.string = 1;
1759 vcpu->pio.string = string;
1760 vcpu->pio.down = down; 1787 vcpu->pio.down = down;
1761 vcpu->pio.guest_page_offset = offset_in_page(address); 1788 vcpu->pio.guest_page_offset = offset_in_page(address);
1762 vcpu->pio.rep = rep; 1789 vcpu->pio.rep = rep;
1763 1790
1764 pio_dev = vcpu_find_pio_dev(vcpu, port);
1765 if (!string) {
1766 kvm_arch_ops->cache_regs(vcpu);
1767 memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);
1768 kvm_arch_ops->decache_regs(vcpu);
1769 if (pio_dev) {
1770 kernel_pio(pio_dev, vcpu, vcpu->pio_data);
1771 complete_pio(vcpu);
1772 return 1;
1773 }
1774 return 0;
1775 }
1776
1777 if (!count) { 1791 if (!count) {
1778 kvm_arch_ops->skip_emulated_instruction(vcpu); 1792 kvm_arch_ops->skip_emulated_instruction(vcpu);
1779 return 1; 1793 return 1;
@@ -1818,6 +1832,7 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1818 } 1832 }
1819 } 1833 }
1820 1834
1835 pio_dev = vcpu_find_pio_dev(vcpu, port);
1821 if (!vcpu->pio.in) { 1836 if (!vcpu->pio.in) {
1822 /* string PIO write */ 1837 /* string PIO write */
1823 ret = pio_copy_data(vcpu); 1838 ret = pio_copy_data(vcpu);
@@ -1834,7 +1849,7 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1834 1849
1835 return ret; 1850 return ret;
1836} 1851}
1837EXPORT_SYMBOL_GPL(kvm_setup_pio); 1852EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
1838 1853
1839static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1854static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1840{ 1855{
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index a83ff01bb014..e3c6d891326b 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1005,8 +1005,7 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1005 rep = (io_info & SVM_IOIO_REP_MASK) != 0; 1005 rep = (io_info & SVM_IOIO_REP_MASK) != 0;
1006 down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0; 1006 down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
1007 1007
1008 return kvm_setup_pio(&svm->vcpu, kvm_run, in, size, 1, 0, 1008 return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port);
1009 down, 0, rep, port);
1010} 1009}
1011 1010
1012static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1011static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 044722bc1a7f..906d4fa13d10 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1785,8 +1785,7 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1785 rep = (exit_qualification & 32) != 0; 1785 rep = (exit_qualification & 32) != 0;
1786 port = exit_qualification >> 16; 1786 port = exit_qualification >> 16;
1787 1787
1788 return kvm_setup_pio(vcpu, kvm_run, in, size, 1, 0, down, 1788 return kvm_emulate_pio(vcpu, kvm_run, in, size, port);
1789 0, rep, port);
1790} 1789}
1791 1790
1792static void 1791static void
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index d553719fc4cb..b4f439cfc66e 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1123,12 +1123,11 @@ special_insn:
1123 switch(b) { 1123 switch(b) {
1124 case 0x6c: /* insb */ 1124 case 0x6c: /* insb */
1125 case 0x6d: /* insw/insd */ 1125 case 0x6d: /* insw/insd */
1126 if (kvm_setup_pio(ctxt->vcpu, NULL, 1126 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
1127 1, /* in */ 1127 1, /* in */
1128 (d & ByteOp) ? 1 : op_bytes, /* size */ 1128 (d & ByteOp) ? 1 : op_bytes, /* size */
1129 rep_prefix ? 1129 rep_prefix ?
1130 address_mask(_regs[VCPU_REGS_RCX]) : 1, /* count */ 1130 address_mask(_regs[VCPU_REGS_RCX]) : 1, /* count */
1131 1, /* strings */
1132 (_eflags & EFLG_DF), /* down */ 1131 (_eflags & EFLG_DF), /* down */
1133 register_address(ctxt->es_base, 1132 register_address(ctxt->es_base,
1134 _regs[VCPU_REGS_RDI]), /* address */ 1133 _regs[VCPU_REGS_RDI]), /* address */
@@ -1139,12 +1138,11 @@ special_insn:
1139 return 0; 1138 return 0;
1140 case 0x6e: /* outsb */ 1139 case 0x6e: /* outsb */
1141 case 0x6f: /* outsw/outsd */ 1140 case 0x6f: /* outsw/outsd */
1142 if (kvm_setup_pio(ctxt->vcpu, NULL, 1141 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
1143 0, /* in */ 1142 0, /* in */
1144 (d & ByteOp) ? 1 : op_bytes, /* size */ 1143 (d & ByteOp) ? 1 : op_bytes, /* size */
1145 rep_prefix ? 1144 rep_prefix ?
1146 address_mask(_regs[VCPU_REGS_RCX]) : 1, /* count */ 1145 address_mask(_regs[VCPU_REGS_RCX]) : 1, /* count */
1147 1, /* strings */
1148 (_eflags & EFLG_DF), /* down */ 1146 (_eflags & EFLG_DF), /* down */
1149 register_address(override_base ? 1147 register_address(override_base ?
1150 *override_base : ctxt->ds_base, 1148 *override_base : ctxt->ds_base,