aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-09-15 10:34:36 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:29 -0400
commit0967b7bf1c22b55777aba46ff616547feed0b141 (patch)
treef855d1f25943dfd8cb6e40f0e81744f1e32d98e0
parent535eabcf0e55804b53d27fe45217d874b19bcfa9 (diff)
KVM: Skip pio instruction when it is emulated, not executed
If we defer updating rip until pio instructions are executed, we have a problem with reset: a pio reset updates rip, and when the instruction completes we skip the emulated instruction, pointing rip somewhere completely unrelated. Fix by updating rip when we see decode the instruction, not after emulation. Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--drivers/kvm/kvm_main.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 3b046507ebc6..353e58527d15 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1815,8 +1815,6 @@ static int complete_pio(struct kvm_vcpu *vcpu)
1815 io->count -= io->cur_count; 1815 io->count -= io->cur_count;
1816 io->cur_count = 0; 1816 io->cur_count = 0;
1817 1817
1818 if (!io->count)
1819 kvm_x86_ops->skip_emulated_instruction(vcpu);
1820 return 0; 1818 return 0;
1821} 1819}
1822 1820
@@ -1876,6 +1874,8 @@ int kvm_emulate_pio (struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1876 memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4); 1874 memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);
1877 kvm_x86_ops->decache_regs(vcpu); 1875 kvm_x86_ops->decache_regs(vcpu);
1878 1876
1877 kvm_x86_ops->skip_emulated_instruction(vcpu);
1878
1879 pio_dev = vcpu_find_pio_dev(vcpu, port); 1879 pio_dev = vcpu_find_pio_dev(vcpu, port);
1880 if (pio_dev) { 1880 if (pio_dev) {
1881 kernel_pio(pio_dev, vcpu, vcpu->pio_data); 1881 kernel_pio(pio_dev, vcpu, vcpu->pio_data);
@@ -1938,6 +1938,9 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
1938 vcpu->run->io.count = now; 1938 vcpu->run->io.count = now;
1939 vcpu->pio.cur_count = now; 1939 vcpu->pio.cur_count = now;
1940 1940
1941 if (vcpu->pio.cur_count == vcpu->pio.count)
1942 kvm_x86_ops->skip_emulated_instruction(vcpu);
1943
1941 for (i = 0; i < nr_pages; ++i) { 1944 for (i = 0; i < nr_pages; ++i) {
1942 mutex_lock(&vcpu->kvm->lock); 1945 mutex_lock(&vcpu->kvm->lock);
1943 page = gva_to_page(vcpu, address + i * PAGE_SIZE); 1946 page = gva_to_page(vcpu, address + i * PAGE_SIZE);