If you combined them you'd have to have an extra argument to say if it was in or out. You'd then have to have code to parse that. I prefer this way.
return emulate_instruction(vcpu, 0) == EMULATE_DONE;(kvm_fast_pio() comes to mind.)
port = io_info >> 16;
@@ -1907,6 +1907,8 @@ static int io_interception(struct vcpu_svm *svm)
svm->next_rip = svm->vmcb->control.exit_info_2;
skip_emulated_instruction(&svm->vcpu);
+ if (in)
+ return kvm_fast_pio_in(vcpu, size, port);
return kvm_fast_pio_out(vcpu, size, port);
Good call. I'll use unsigned long like kvm_fast_pio_out() uses.
}u64.
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bd7a70b..089247c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5463,6 +5463,39 @@ 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(struct kvm_vcpu *vcpu)
+{
+ u32 new_rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
arch/x86/kvm/x86.cAgreed on both counts.
+sizeof(new_rax). (safer and easier to understand)
+ if (!vcpu->arch.pio.count)
+ return 0;
+ if (vcpu->arch.pio.count * vcpu->arch.pio.size > 8)
+ return 0;
Both should never happen in KVM code, BUG_ON().
I looked at pulling this out, it was a painful. I'll add the trace hook.
+Use emulator_pio_in_emulated() here, for code sharing.
+ memcpy(&new_rax, vcpu->arch.pio_data,
+ vcpu->arch.pio.count * vcpu->arch.pio.size);
(We want to trace the read here too; it could be better to split
the path from emulator_pio_in_emulated() first.)
will remove = 0 line
+ kvm_register_write(vcpu, VCPU_REGS_RAX, new_rax);(emulator_pio_in_emulated() sets count to zero if it returns true.)
+
+ vcpu->arch.pio.count = 0;
+ return 1;
+}
+
+int kvm_fast_pio_in(struct kvm_vcpu *vcpu, int size, unsigned short port)
+{
+ unsigned long val;
+ int ret = emulator_pio_in_emulated(&vcpu->arch.emulate_ctxt, size,
+ port, &val, 1);
+
+ if (ret) {
+ kvm_register_write(vcpu, VCPU_REGS_RAX, val);
+ vcpu->arch.pio.count = 0;