| From stable-bounces@linux.kernel.org Sun Dec 2 03:19:00 2007 |
| From: Avi Kivity <avi@qumranet.com> |
| Date: Sun, 2 Dec 2007 13:18:45 +0200 |
| Subject: KVM: Skip pio instruction when it is emulated, not executed |
| To: stable@kernel.org |
| Cc: kvm-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, Avi Kivity <avi@qumranet.com> |
| Message-ID: <11965943273087-git-send-email-avi@qumranet.com> |
| |
| From: Avi Kivity <avi@qumranet.com> |
| |
| patch 0967b7bf1c22b55777aba46ff616547feed0b141 in mainline. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/kvm/kvm_main.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/kvm/kvm_main.c |
| +++ b/drivers/kvm/kvm_main.c |
| @@ -1757,8 +1757,6 @@ static int complete_pio(struct kvm_vcpu |
| io->count -= io->cur_count; |
| io->cur_count = 0; |
| |
| - if (!io->count) |
| - kvm_arch_ops->skip_emulated_instruction(vcpu); |
| return 0; |
| } |
| |
| @@ -1804,6 +1802,7 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, |
| |
| pio_dev = vcpu_find_pio_dev(vcpu, port); |
| if (!string) { |
| + kvm_arch_ops->skip_emulated_instruction(vcpu); |
| kvm_arch_ops->cache_regs(vcpu); |
| memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4); |
| kvm_arch_ops->decache_regs(vcpu); |
| @@ -1850,6 +1849,9 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, |
| vcpu->run->io.count = now; |
| vcpu->pio.cur_count = now; |
| |
| + if (now == count) |
| + kvm_arch_ops->skip_emulated_instruction(vcpu); |
| + |
| for (i = 0; i < nr_pages; ++i) { |
| spin_lock(&vcpu->kvm->lock); |
| page = gva_to_page(vcpu, address + i * PAGE_SIZE); |