diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-02-10 07:21:33 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:36:11 -0500 |
commit | f850e2e603bf5a05b0aee7901857cf85715aa694 (patch) | |
tree | d3c841530a11187bbe70b36bf4b9bca97bf7dd64 /arch/x86/kvm/x86.c | |
parent | 1871c6020d7308afb99127bba51f04548e7ca84e (diff) |
KVM: x86 emulator: Check IOPL level during io instruction emulation
Make emulator check that vcpu is allowed to execute IN, INS, OUT,
OUTS, CLI, STI.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Cc: stable@kernel.org
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ea3a8af8a478..86b739f8f173 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3599,6 +3599,8 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port) | |||
3599 | { | 3599 | { |
3600 | unsigned long val; | 3600 | unsigned long val; |
3601 | 3601 | ||
3602 | trace_kvm_pio(!in, port, size, 1); | ||
3603 | |||
3602 | vcpu->run->exit_reason = KVM_EXIT_IO; | 3604 | vcpu->run->exit_reason = KVM_EXIT_IO; |
3603 | vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; | 3605 | vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; |
3604 | vcpu->run->io.size = vcpu->arch.pio.size = size; | 3606 | vcpu->run->io.size = vcpu->arch.pio.size = size; |
@@ -3610,9 +3612,6 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port) | |||
3610 | vcpu->arch.pio.down = 0; | 3612 | vcpu->arch.pio.down = 0; |
3611 | vcpu->arch.pio.rep = 0; | 3613 | vcpu->arch.pio.rep = 0; |
3612 | 3614 | ||
3613 | trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port, | ||
3614 | size, 1); | ||
3615 | |||
3616 | if (!vcpu->arch.pio.in) { | 3615 | if (!vcpu->arch.pio.in) { |
3617 | val = kvm_register_read(vcpu, VCPU_REGS_RAX); | 3616 | val = kvm_register_read(vcpu, VCPU_REGS_RAX); |
3618 | memcpy(vcpu->arch.pio_data, &val, 4); | 3617 | memcpy(vcpu->arch.pio_data, &val, 4); |
@@ -3633,6 +3632,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, | |||
3633 | unsigned now, in_page; | 3632 | unsigned now, in_page; |
3634 | int ret = 0; | 3633 | int ret = 0; |
3635 | 3634 | ||
3635 | trace_kvm_pio(!in, port, size, count); | ||
3636 | |||
3636 | vcpu->run->exit_reason = KVM_EXIT_IO; | 3637 | vcpu->run->exit_reason = KVM_EXIT_IO; |
3637 | vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; | 3638 | vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; |
3638 | vcpu->run->io.size = vcpu->arch.pio.size = size; | 3639 | vcpu->run->io.size = vcpu->arch.pio.size = size; |
@@ -3644,9 +3645,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, | |||
3644 | vcpu->arch.pio.down = down; | 3645 | vcpu->arch.pio.down = down; |
3645 | vcpu->arch.pio.rep = rep; | 3646 | vcpu->arch.pio.rep = rep; |
3646 | 3647 | ||
3647 | trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port, | ||
3648 | size, count); | ||
3649 | |||
3650 | if (!count) { | 3648 | if (!count) { |
3651 | kvm_x86_ops->skip_emulated_instruction(vcpu); | 3649 | kvm_x86_ops->skip_emulated_instruction(vcpu); |
3652 | return 1; | 3650 | return 1; |