kvm: svm: Add kvm_fast_pio_in support
Update the I/O interception support to add the kvm_fast_pio_in function to speed up the in instruction similar to the out instruction. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Reviewed-by: Borislav Petkov <bp@suse.de> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
This commit is contained in:
parent
147277540b
commit
8370c3d08b
|
@ -1133,6 +1133,7 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr);
|
|||
struct x86_emulate_ctxt;
|
||||
|
||||
int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port);
|
||||
int kvm_fast_pio_in(struct kvm_vcpu *vcpu, int size, unsigned short port);
|
||||
void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
|
||||
int kvm_emulate_halt(struct kvm_vcpu *vcpu);
|
||||
int kvm_vcpu_halt(struct kvm_vcpu *vcpu);
|
||||
|
|
|
@ -2270,7 +2270,7 @@ static int io_interception(struct vcpu_svm *svm)
|
|||
++svm->vcpu.stat.io_exits;
|
||||
string = (io_info & SVM_IOIO_STR_MASK) != 0;
|
||||
in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
|
||||
if (string || in)
|
||||
if (string)
|
||||
return emulate_instruction(vcpu, 0) == EMULATE_DONE;
|
||||
|
||||
port = io_info >> 16;
|
||||
|
@ -2278,7 +2278,8 @@ static int io_interception(struct vcpu_svm *svm)
|
|||
svm->next_rip = svm->vmcb->control.exit_info_2;
|
||||
skip_emulated_instruction(&svm->vcpu);
|
||||
|
||||
return kvm_fast_pio_out(vcpu, size, port);
|
||||
return in ? kvm_fast_pio_in(vcpu, size, port)
|
||||
: kvm_fast_pio_out(vcpu, size, port);
|
||||
}
|
||||
|
||||
static int nmi_interception(struct vcpu_svm *svm)
|
||||
|
|
|
@ -5615,6 +5615,49 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
|
||||
|
||||
static int complete_fast_pio_in(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
unsigned long val;
|
||||
|
||||
/* We should only ever be called with arch.pio.count equal to 1 */
|
||||
BUG_ON(vcpu->arch.pio.count != 1);
|
||||
|
||||
/* For size less than 4 we merge, else we zero extend */
|
||||
val = (vcpu->arch.pio.size < 4) ? kvm_register_read(vcpu, VCPU_REGS_RAX)
|
||||
: 0;
|
||||
|
||||
/*
|
||||
* Since vcpu->arch.pio.count == 1 let emulator_pio_in_emulated perform
|
||||
* the copy and tracing
|
||||
*/
|
||||
emulator_pio_in_emulated(&vcpu->arch.emulate_ctxt, vcpu->arch.pio.size,
|
||||
vcpu->arch.pio.port, &val, 1);
|
||||
kvm_register_write(vcpu, VCPU_REGS_RAX, val);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kvm_fast_pio_in(struct kvm_vcpu *vcpu, int size, unsigned short port)
|
||||
{
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
/* For size less than 4 we merge, else we zero extend */
|
||||
val = (size < 4) ? kvm_register_read(vcpu, VCPU_REGS_RAX) : 0;
|
||||
|
||||
ret = emulator_pio_in_emulated(&vcpu->arch.emulate_ctxt, size, port,
|
||||
&val, 1);
|
||||
if (ret) {
|
||||
kvm_register_write(vcpu, VCPU_REGS_RAX, val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vcpu->arch.complete_userspace_io = complete_fast_pio_in;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_fast_pio_in);
|
||||
|
||||
static int kvmclock_cpu_down_prep(unsigned int cpu)
|
||||
{
|
||||
__this_cpu_write(cpu_tsc_khz, 0);
|
||||
|
|
Loading…
Reference in New Issue