diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-04-28 12:15:37 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-08-01 03:35:34 -0400 |
commit | 8fe681e984b6505d4d12125c0776399304803ec7 (patch) | |
tree | dcd8b2a739541463cb1b93074bce5968bdb1a288 /arch/x86/kvm/emulate.c | |
parent | f181b96d4c769b8915849eb9070c18116fd8d44e (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.c | 12 |
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; |