aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-03-18 09:20:27 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:16:31 -0400
commit7b262e90fc20a49fddf3dad94c8cead1f0439751 (patch)
treec64306065ff392590cf89808807fb82a65499650 /arch/x86/kvm/emulate.c
parent5cd21917da245fbe98bd443de2c7f519b3df6814 (diff)
KVM: x86 emulator: introduce pio in string read ahead.
To optimize "rep ins" instruction do IO in big chunks ahead of time instead of doing it only when required during instruction emulation. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 6de6ad1610d8..ab3fff5bf7c4 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1257,6 +1257,36 @@ done:
1257 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; 1257 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
1258} 1258}
1259 1259
1260static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
1261 struct x86_emulate_ops *ops,
1262 unsigned int size, unsigned short port,
1263 void *dest)
1264{
1265 struct read_cache *rc = &ctxt->decode.io_read;
1266
1267 if (rc->pos == rc->end) { /* refill pio read ahead */
1268 struct decode_cache *c = &ctxt->decode;
1269 unsigned int in_page, n;
1270 unsigned int count = c->rep_prefix ?
1271 address_mask(c, c->regs[VCPU_REGS_RCX]) : 1;
1272 in_page = (ctxt->eflags & EFLG_DF) ?
1273 offset_in_page(c->regs[VCPU_REGS_RDI]) :
1274 PAGE_SIZE - offset_in_page(c->regs[VCPU_REGS_RDI]);
1275 n = min(min(in_page, (unsigned int)sizeof(rc->data)) / size,
1276 count);
1277 if (n == 0)
1278 n = 1;
1279 rc->pos = rc->end = 0;
1280 if (!ops->pio_in_emulated(size, port, rc->data, n, ctxt->vcpu))
1281 return 0;
1282 rc->end = n * size;
1283 }
1284
1285 memcpy(dest, rc->data + rc->pos, size);
1286 rc->pos += size;
1287 return 1;
1288}
1289
1260static u32 desc_limit_scaled(struct desc_struct *desc) 1290static u32 desc_limit_scaled(struct desc_struct *desc)
1261{ 1291{
1262 u32 limit = get_desc_limit(desc); 1292 u32 limit = get_desc_limit(desc);
@@ -2622,8 +2652,8 @@ special_insn:
2622 kvm_inject_gp(ctxt->vcpu, 0); 2652 kvm_inject_gp(ctxt->vcpu, 0);
2623 goto done; 2653 goto done;
2624 } 2654 }
2625 if (!ops->pio_in_emulated(c->dst.bytes, c->regs[VCPU_REGS_RDX], 2655 if (!pio_in_emulated(ctxt, ops, c->dst.bytes,
2626 &c->dst.val, 1, ctxt->vcpu)) 2656 c->regs[VCPU_REGS_RDX], &c->dst.val))
2627 goto done; /* IO is needed, skip writeback */ 2657 goto done; /* IO is needed, skip writeback */
2628 break; 2658 break;
2629 case 0x6e: /* outsb */ 2659 case 0x6e: /* outsb */
@@ -2839,8 +2869,8 @@ special_insn:
2839 kvm_inject_gp(ctxt->vcpu, 0); 2869 kvm_inject_gp(ctxt->vcpu, 0);
2840 goto done; 2870 goto done;
2841 } 2871 }
2842 if (!ops->pio_in_emulated(c->dst.bytes, c->src.val, 2872 if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val,
2843 &c->dst.val, 1, ctxt->vcpu)) 2873 &c->dst.val))
2844 goto done; /* IO is needed */ 2874 goto done; /* IO is needed */
2845 break; 2875 break;
2846 case 0xee: /* out al,dx */ 2876 case 0xee: /* out al,dx */
@@ -2928,8 +2958,14 @@ writeback:
2928 string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, &c->dst); 2958 string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, &c->dst);
2929 2959
2930 if (c->rep_prefix && (c->d & String)) { 2960 if (c->rep_prefix && (c->d & String)) {
2961 struct read_cache *rc = &ctxt->decode.io_read;
2931 register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); 2962 register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
2932 if (!(c->regs[VCPU_REGS_RCX] & 0x3ff)) 2963 /*
2964 * Re-enter guest when pio read ahead buffer is empty or,
2965 * if it is not used, after each 1024 iteration.
2966 */
2967 if ((rc->end == 0 && !(c->regs[VCPU_REGS_RCX] & 0x3ff)) ||
2968 (rc->end != 0 && rc->end == rc->pos))
2933 ctxt->restart = false; 2969 ctxt->restart = false;
2934 } 2970 }
2935 2971