From: Andre Przywara <andre.przywara@amd.com>
To: avi@redhat.com
Cc: kvm@vger.kernel.org, Andre Przywara <andre.przywara@amd.com>,
Christoph Egger <christoph.egger@amd.com>,
Amit Shah <amit.shah@redhat.com>
Subject: [PATCH 6/6] add sysexit emulation
Date: Wed, 17 Jun 2009 15:50:36 +0200 [thread overview]
Message-ID: <1245246636-30760-7-git-send-email-andre.przywara@amd.com> (raw)
In-Reply-To: <1245246636-30760-1-git-send-email-andre.przywara@amd.com>
Handle #UD intercept of the sysexit instruction in 64bit mode returning to
32bit compat mode on an AMD host.
Setup the segment descriptors for CS and SS and the EIP/ESP registers
according to the manual.
Signed-off-by: Christoph Egger <christoph.egger@amd.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
arch/x86/kvm/x86_emulate.c | 79 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 78 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index 2f62aaa..7df05cc 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -1548,6 +1548,80 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt)
return 0;
}
+static int
+emulate_sysexit(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+ struct kvm_segment cs, ss;
+ u64 msr_data;
+ int usermode;
+
+ /* inject #UD if LOCK prefix is used */
+ if (c->lock_prefix)
+ return -1;
+
+ /* inject #GP if in real mode or paging is disabled */
+ if (ctxt->mode == X86EMUL_MODE_REAL
+ || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ return -1;
+ }
+
+ /* sysexit must be called from CPL 0 */
+ if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ return -1;
+ }
+
+ setup_syscalls_segments(ctxt, &cs, &ss);
+
+ if ((c->rex_prefix & 0x8) != 0x0)
+ usermode = X86EMUL_MODE_PROT64;
+ else
+ usermode = X86EMUL_MODE_PROT32;
+
+ /* We don't care about cs.g/ss.g bits
+ * (= 4kb granularity) so we have to set the effective
+ * limit here or we get a #GP in the guest, otherwise.
+ */
+ cs.limit = 0xffffffff;
+ ss.limit = 0xffffffff;
+
+ cs.dpl = 3;
+ ss.dpl = 3;
+ kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
+ switch (usermode) {
+ case X86EMUL_MODE_PROT32:
+ cs.selector = (u16)(msr_data + 16);
+ if ((msr_data & 0xfffc) == 0x0) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ return -1;
+ }
+ ss.selector = (u16)(msr_data + 24);
+ break;
+ case X86EMUL_MODE_PROT64:
+ cs.selector = (u16)(msr_data + 32);
+ if (msr_data == 0x0) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ return -1;
+ }
+ ss.selector = cs.selector + 8;
+ cs.db = 0;
+ cs.l = 1;
+ break;
+ }
+ cs.selector |= SELECTOR_RPL_MASK;
+ ss.selector |= SELECTOR_RPL_MASK;
+
+ kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS);
+ kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS);
+
+ c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX];
+ c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX];
+
+ return 0;
+}
+
int
x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
{
@@ -2222,7 +2296,10 @@ twobyte_insn:
goto writeback;
break;
case 0x35: /* sysexit */
- goto cannot_emulate;
+ if (emulate_sysexit(ctxt) == -1)
+ goto cannot_emulate;
+ else
+ goto writeback;
break;
case 0x40 ... 0x4f: /* cmov */
c->dst.val = c->dst.orig_val = c->src.val;
--
1.6.1.3
next prev parent reply other threads:[~2009-06-17 13:47 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-17 13:50 [PATCH 0/6] add sysenter/syscall emulation for 32bit compat mode Andre Przywara
2009-06-17 13:50 ` [PATCH 1/6] allow emulation of syscalls instructions on #UD Andre Przywara
2009-06-17 13:50 ` [PATCH 2/6] add missing EFLAGS bit definitions Andre Przywara
2009-06-17 13:50 ` [PATCH 3/6] prepare for emulation of syscall instructions Andre Przywara
2009-06-17 13:50 ` [PATCH 4/6] add syscall emulation Andre Przywara
2009-06-18 8:47 ` Avi Kivity
2009-06-18 10:27 ` Andre Przywara
2009-06-22 8:43 ` Avi Kivity
2009-06-17 13:50 ` [PATCH 5/6] add sysenter emulation Andre Przywara
2009-06-17 13:50 ` Andre Przywara [this message]
2009-06-18 8:48 ` [PATCH 0/6] add sysenter/syscall emulation for 32bit compat mode Avi Kivity
2009-06-18 10:56 ` [PATCH 4/6 v2] add syscall emulation Andre Przywara
2009-06-18 10:56 ` [PATCH 5/6 v2] add sysenter emulation Andre Przywara
2009-06-18 10:56 ` [PATCH 6/6 v2] add sysexit emulation Andre Przywara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1245246636-30760-7-git-send-email-andre.przywara@amd.com \
--to=andre.przywara@amd.com \
--cc=amit.shah@redhat.com \
--cc=avi@redhat.com \
--cc=christoph.egger@amd.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox