aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_emulate.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2007-11-25 11:43:53 +0000
committerKeir Fraser <keir.fraser@citrix.com>2007-11-25 11:43:53 +0000
commita2b5673b0018f0184b4833f65a453538cf84f6f5 (patch)
tree3db44cdf515f059f4c2ddfe28a0137ff8a840d6c /xen/arch/x86/x86_emulate.c
parent727f3fd5fa194bb03e9e478b2fd1760f38a43546 (diff)
downloadxen-a2b5673b0018f0184b4833f65a453538cf84f6f5.tar.gz
xen-a2b5673b0018f0184b4833f65a453538cf84f6f5.tar.bz2
xen-a2b5673b0018f0184b4833f65a453538cf84f6f5.zip
vmx realmode: Plumb through I/O port accesses in emulated realmode.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/arch/x86/x86_emulate.c')
-rw-r--r--xen/arch/x86/x86_emulate.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index 48325f92fc..3ff12f8112 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -264,6 +264,7 @@ struct operand {
};
/* EFLAGS bit definitions. */
+#define EFLG_VM (1<<17)
#define EFLG_RF (1<<16)
#define EFLG_OF (1<<11)
#define EFLG_DF (1<<10)
@@ -478,10 +479,6 @@ do { \
/* In future we will be able to generate arbitrary exceptions. */
#define generate_exception_if(p, e) fail_if(p)
-/* To be done... */
-#define mode_ring0() (0)
-#define mode_iopl() (0)
-
/* Given byte has even parity (even number of 1s)? */
static int even_parity(uint8_t v)
{
@@ -680,6 +677,35 @@ test_cc(
}
static int
+get_cpl(
+ struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops)
+{
+ struct segment_register reg;
+
+ if ( ctxt->regs->eflags & EFLG_VM )
+ return 3;
+
+ if ( (ops->read_segment == NULL) ||
+ ops->read_segment(x86_seg_ss, &reg, ctxt) )
+ return -1;
+
+ return reg.attr.fields.dpl;
+}
+
+static int
+_mode_iopl(
+ struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops)
+{
+ int cpl = get_cpl(ctxt, ops);
+ return ((cpl >= 0) && (cpl <= ((ctxt->regs->eflags >> 12) & 3)));
+}
+
+#define mode_ring0() (get_cpl(ctxt, ops) == 0)
+#define mode_iopl() _mode_iopl(ctxt, ops)
+
+static int
in_realmode(
struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)