aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-03-31 10:21:19 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-03-31 10:21:19 +0100
commit147808b8b8022419497c0ab754848060b6a1dbd8 (patch)
tree66a530789936193bc8bfea3b765bf97595a632f5 /xen/include
parent75cc04fb6808d5cb1b98b36ecd8568d1bd3b0991 (diff)
downloadxen-147808b8b8022419497c0ab754848060b6a1dbd8.tar.gz
xen-147808b8b8022419497c0ab754848060b6a1dbd8.tar.bz2
xen-147808b8b8022419497c0ab754848060b6a1dbd8.zip
x86/hvm: accelerate I/O intercept handling
currently we go through the emulator every time a HVM guest does an I/O port access (in/out). This is unnecessary most of the times, as both VMX and SVM provide all the necessary information already in the VMCS/VMCB. String instructions are not covered by this shortcut, but they are quite rare and we would need to access the guest memory anyway. This patch decodes the information from VMCB/VMCS and calls a simple handle_mmio wrapper. In handle_mmio() itself the emulation part will simply be skipped, this approach avoids code duplication. Since the vendor specific part is quite trivial, I implemented both the VMX and SVM part, please check the VMX part for sanity. I boot-tested both versions and ran some simple benchmarks. A micro benchmark (hammering an I/O port in a tight loop) shows a significant performance improvement (down to 66% of the time needed to handle the intercept on an AMD K8, measured in the guest with TSC). Even with reading a 1GB file from an emulated IDE harddisk (Dom0 cached) I could get a 4-5% improvement. Some guest code (e.g. the TCP stack in some Windows version) exercises the PM-Timer I/O port (0x1F48) very often (multiple 10,000 times per second), these workloads also benefit with up to 5% improvement from this patch. Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Diffstat (limited to 'xen/include')
-rw-r--r--xen/include/asm-x86/hvm/emulate.h4
-rw-r--r--xen/include/asm-x86/hvm/io.h1
-rw-r--r--xen/include/asm-x86/hvm/vcpu.h4
3 files changed, 9 insertions, 0 deletions
diff --git a/xen/include/asm-x86/hvm/emulate.h b/xen/include/asm-x86/hvm/emulate.h
index c46ffb0706..2bb0a98ae9 100644
--- a/xen/include/asm-x86/hvm/emulate.h
+++ b/xen/include/asm-x86/hvm/emulate.h
@@ -46,4 +46,8 @@ struct segment_register *hvmemul_get_seg_reg(
enum x86_segment seg,
struct hvm_emulate_ctxt *hvmemul_ctxt);
+int hvmemul_do_io(
+ int is_mmio, paddr_t addr, unsigned long *reps, int size,
+ paddr_t ram_gpa, int dir, int df, void *p_data);
+
#endif /* __ASM_X86_HVM_EMULATE_H__ */
diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h
index f9ae0f9d0c..4d5e8b1294 100644
--- a/xen/include/asm-x86/hvm/io.h
+++ b/xen/include/asm-x86/hvm/io.h
@@ -100,6 +100,7 @@ void send_timeoffset_req(unsigned long timeoff);
void send_invalidate_req(void);
int handle_mmio(void);
int handle_mmio_with_translation(unsigned long gva, unsigned long gpfn);
+int handle_mmio_decoded(uint16_t port, int size, int dir);
void hvm_interrupt_post(struct vcpu *v, int vector, int type);
void hvm_io_assist(void);
void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq,
diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
index 80c4d5b073..840625040f 100644
--- a/xen/include/asm-x86/hvm/vcpu.h
+++ b/xen/include/asm-x86/hvm/vcpu.h
@@ -103,6 +103,10 @@ struct hvm_vcpu {
*/
unsigned long mmio_gva;
unsigned long mmio_gpfn;
+ uint16_t io_port;
+ int io_size;
+ unsigned io_dir;
+
/* Callback into x86_emulate when emulating FPU/MMX/XMM instructions. */
void (*fpu_exception_callback)(void *, struct cpu_user_regs *);
void *fpu_exception_callback_arg;