aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-04-28 12:15:37 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:35:34 -0400
commit8fe681e984b6505d4d12125c0776399304803ec7 (patch)
treedcd8b2a739541463cb1b93074bce5968bdb1a288 /arch/x86/kvm/emulate.c
parentf181b96d4c769b8915849eb9070c18116fd8d44e (diff)
KVM: do not inject #PF in (read|write)_emulated() callbacks
Return error to x86 emulator instead of injection exception behind its back. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index d5979ecc2521..d7a18a0f80a2 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1277,6 +1277,7 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt,
1277{ 1277{
1278 int rc; 1278 int rc;
1279 struct read_cache *mc = &ctxt->decode.mem_read; 1279 struct read_cache *mc = &ctxt->decode.mem_read;
1280 u32 err;
1280 1281
1281 while (size) { 1282 while (size) {
1282 int n = min(size, 8u); 1283 int n = min(size, 8u);
@@ -1284,7 +1285,10 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt,
1284 if (mc->pos < mc->end) 1285 if (mc->pos < mc->end)
1285 goto read_cached; 1286 goto read_cached;
1286 1287
1287 rc = ops->read_emulated(addr, mc->data + mc->end, n, ctxt->vcpu); 1288 rc = ops->read_emulated(addr, mc->data + mc->end, n, &err,
1289 ctxt->vcpu);
1290 if (rc == X86EMUL_PROPAGATE_FAULT)
1291 kvm_inject_page_fault(ctxt->vcpu, addr, err);
1288 if (rc != X86EMUL_CONTINUE) 1292 if (rc != X86EMUL_CONTINUE)
1289 return rc; 1293 return rc;
1290 mc->end += n; 1294 mc->end += n;
@@ -1789,6 +1793,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
1789{ 1793{
1790 int rc; 1794 int rc;
1791 struct decode_cache *c = &ctxt->decode; 1795 struct decode_cache *c = &ctxt->decode;
1796 u32 err;
1792 1797
1793 switch (c->dst.type) { 1798 switch (c->dst.type) {
1794 case OP_REG: 1799 case OP_REG:
@@ -1817,13 +1822,18 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
1817 &c->dst.orig_val, 1822 &c->dst.orig_val,
1818 &c->dst.val, 1823 &c->dst.val,
1819 c->dst.bytes, 1824 c->dst.bytes,
1825 &err,
1820 ctxt->vcpu); 1826 ctxt->vcpu);
1821 else 1827 else
1822 rc = ops->write_emulated( 1828 rc = ops->write_emulated(
1823 (unsigned long)c->dst.ptr, 1829 (unsigned long)c->dst.ptr,
1824 &c->dst.val, 1830 &c->dst.val,
1825 c->dst.bytes, 1831 c->dst.bytes,
1832 &err,
1826 ctxt->vcpu); 1833 ctxt->vcpu);
1834 if (rc == X86EMUL_PROPAGATE_FAULT)
1835 kvm_inject_page_fault(ctxt->vcpu,
1836 (unsigned long)c->dst.ptr, err);
1827 if (rc != X86EMUL_CONTINUE) 1837 if (rc != X86EMUL_CONTINUE)
1828 return rc; 1838 return rc;
1829 break; 1839 break;