aboutsummaryrefslogtreecommitdiff
path: root/emulators/kqemu-kmod-devel/files/extra-patch-jk-200905-04
diff options
context:
space:
mode:
Diffstat (limited to 'emulators/kqemu-kmod-devel/files/extra-patch-jk-200905-04')
-rw-r--r--emulators/kqemu-kmod-devel/files/extra-patch-jk-200905-04108
1 files changed, 108 insertions, 0 deletions
diff --git a/emulators/kqemu-kmod-devel/files/extra-patch-jk-200905-04 b/emulators/kqemu-kmod-devel/files/extra-patch-jk-200905-04
new file mode 100644
index 000000000000..57ab6d9f5cfd
--- /dev/null
+++ b/emulators/kqemu-kmod-devel/files/extra-patch-jk-200905-04
@@ -0,0 +1,108 @@
+From: jan.kiszka@siemens.com (Jan Kiszka)
+Subject: [Qemu-devel] [PATCH 4/5] kqemu: Implement verr/verw in the monitor
+ code interpreter
+Date: Fri, 29 May 2009 19:18:31 +0200
+Message-ID: <20090529171831.14265.57241.stgit@mchn012c.ww002.siemens.net>
+To: qemu-devel@nongnu.org
+
+This avoids user space for handling verr/verw via TCG.
+
+Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
+---
+
+ common/interp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 files changed, 70 insertions(+), 1 deletions(-)
+
+diff --git a/common/interp.c b/common/interp.c
+index 4c042e9..4f93bc3 100644
+Index: common/interp.c
+--- a/common/interp.c
++++ b/common/interp.c
+@@ -1720,6 +1720,65 @@ void helper_lldt(struct kqemu_state *s, int selector)
+ env->ldt.selector = selector;
+ }
+
++static void helper_verr(struct kqemu_state *s, int selector)
++{
++ uint32_t e1, e2;
++ int rpl, dpl, cpl;
++
++ if ((selector & 0xfffc) == 0)
++ goto fail;
++ if (load_segment(s, &e1, &e2, selector) != 0)
++ goto fail;
++ if (!(e2 & DESC_S_MASK))
++ goto fail;
++ rpl = selector & 3;
++ dpl = (e2 >> DESC_DPL_SHIFT) & 3;
++ cpl = s->cpu_state.cpl;
++ if (e2 & DESC_CS_MASK) {
++ if (!(e2 & DESC_R_MASK))
++ goto fail;
++ if (!(e2 & DESC_C_MASK)) {
++ if (dpl < cpl || dpl < rpl)
++ goto fail;
++ }
++ } else {
++ if (dpl < cpl || dpl < rpl) {
++ fail:
++ set_reset_eflags(s, 0, CC_Z);
++ return;
++ }
++ }
++ set_reset_eflags(s, CC_Z, 0);
++}
++
++static void helper_verw(struct kqemu_state *s, int selector)
++{
++ uint32_t e1, e2;
++ int rpl, dpl, cpl;
++
++ if ((selector & 0xfffc) == 0)
++ goto fail;
++ if (load_segment(s, &e1, &e2, selector) != 0)
++ goto fail;
++ if (!(e2 & DESC_S_MASK))
++ goto fail;
++ rpl = selector & 3;
++ dpl = (e2 >> DESC_DPL_SHIFT) & 3;
++ cpl = s->cpu_state.cpl;
++ if (e2 & DESC_CS_MASK) {
++ goto fail;
++ } else {
++ if (dpl < cpl || dpl < rpl)
++ goto fail;
++ if (!(e2 & DESC_W_MASK)) {
++ fail:
++ set_reset_eflags(s, 0, CC_Z);
++ return;
++ }
++ }
++ set_reset_eflags(s, CC_Z, 0);
++}
++
+ static void helper_wrmsr(struct kqemu_state *s)
+ {
+ #ifdef __x86_64__
+@@ -4479,7 +4538,17 @@ QO( case OT_LONG | 8:\
+ case 5: /* verw */
+ if (!(s->cpu_state.cr0 & CR0_PE_MASK) || get_eflags_vm(s))
+ goto illegal_op;
+- raise_exception(s, KQEMU_RET_SOFTMMU);
++ if (mod == 3) {
++ rm = (modrm & 7) | REX_B(s);
++ val = get_regS(s, OT_WORD, rm) & 0xffff;
++ } else {
++ addr = get_modrm(s, modrm);
++ val = ldS(s, OT_WORD, addr);
++ }
++ if (op == 4)
++ helper_verr(s, val);
++ else
++ helper_verw(s, val);
+ break;
+ default:
+ goto illegal_op;
+
+
+