|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.7] x86/HVM: suppress I/O completion for port output
commit 5c81317a54703a1a2d4a8ae7e49f7444ea17e1b9
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Apr 18 16:55:18 2018 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Apr 18 16:55:18 2018 +0200
x86/HVM: suppress I/O completion for port output
We don't break up port requests in case they cross emulation entity
boundaries, and a write to an I/O port is necessarily the last
operation of an instruction instance, so there's no need to re-invoke
the full emulation path upon receiving the result from an external
emulator.
In case we want to properly split port accesses in the future, this
change will need to be reverted, as it would prevent things working
correctly when e.g. the first part needs to go to an external emulator,
while the second part is to be handled internally.
While this addresses the reported problem of Windows paging out the
buffer underneath an in-process REP OUTS, it does not address the wider
problem of the re-issued insn (to the insn emulator) being prone to
raise an exception (#PF) during a replayed, previously successful memory
access (we only record prior MMIO accesses).
Leaving aside the problem tried to be worked around here, I think the
performance aspect alone is a good reason to change the behavior.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
master commit: 91afb8139f954a06e564d4915bc7d6a8575e2812
master date: 2018-04-11 10:42:24 +0200
---
xen/arch/x86/hvm/emulate.c | 6 +++++-
xen/include/asm-x86/hvm/vcpu.h | 4 +++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index f84ab5a0bf..a835e14c98 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -192,7 +192,11 @@ static int hvmemul_do_io(
rc = hvm_send_ioreq(s, &p, 0);
if ( rc != X86EMUL_RETRY || curr->domain->is_shutting_down )
vio->io_req.state = STATE_IOREQ_NONE;
- else if ( data_is_addr )
+ /*
+ * This effectively is !hvm_vcpu_io_need_completion(vio), slightly
+ * optimized and using local variables we have available.
+ */
+ else if ( data_is_addr || (!is_mmio && dir == IOREQ_WRITE) )
rc = X86EMUL_OKAY;
}
break;
diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
index 8a4a92f4be..c1183bbb6f 100644
--- a/xen/include/asm-x86/hvm/vcpu.h
+++ b/xen/include/asm-x86/hvm/vcpu.h
@@ -94,7 +94,9 @@ struct hvm_vcpu_io {
static inline bool_t hvm_vcpu_io_need_completion(const struct hvm_vcpu_io *vio)
{
return (vio->io_req.state == STATE_IOREQ_READY) &&
- !vio->io_req.data_is_ptr;
+ !vio->io_req.data_is_ptr &&
+ (vio->io_req.type != IOREQ_TYPE_PIO ||
+ vio->io_req.dir != IOREQ_WRITE);
}
#define VMCX_EADDR (~0ULL)
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.7
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |