diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2007-11-25 11:43:53 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2007-11-25 11:43:53 +0000 |
commit | a2b5673b0018f0184b4833f65a453538cf84f6f5 (patch) | |
tree | 3db44cdf515f059f4c2ddfe28a0137ff8a840d6c /xen/arch/x86/x86_emulate.c | |
parent | 727f3fd5fa194bb03e9e478b2fd1760f38a43546 (diff) | |
download | xen-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.c | 34 |
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, ®, 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) |