aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-03-29 19:23:41 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-03-29 19:23:41 +0100
commit61e7893dafdfa84717d362986c8328effd1a2320 (patch)
treef4dddc42536c9ede261501d527b3d485aa122795
parenta9214a8feef1f35d2b852443c158221e60b90195 (diff)
downloadxen-61e7893dafdfa84717d362986c8328effd1a2320.tar.gz
xen-61e7893dafdfa84717d362986c8328effd1a2320.tar.bz2
xen-61e7893dafdfa84717d362986c8328effd1a2320.zip
hvm: Fix the assert on size in HVM MMIO flag-setting functions
Signed-off-by: Xin Li <xin.b.li@intel.com> Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--xen/arch/x86/hvm/io.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index b9f0a39c2c..605a42978b 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -287,13 +287,15 @@ static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *r
}
#endif
-extern long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs);
+long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs);
static inline void set_eflags_CF(int size, unsigned long v1,
unsigned long v2, struct cpu_user_regs *regs)
{
unsigned long mask;
-
+
+ if ( size == BYTE_64 )
+ size = BYTE;
ASSERT((size <= sizeof(mask)) && (size > 0));
mask = ~0UL >> (8 * (sizeof(mask) - size));
@@ -305,20 +307,24 @@ static inline void set_eflags_CF(int size, unsigned long v1,
}
static inline void set_eflags_OF(int size, unsigned long v1,
- unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
+ unsigned long v2, unsigned long v3,
+ struct cpu_user_regs *regs)
{
unsigned long mask;
+ if ( size == BYTE_64 )
+ size = BYTE;
ASSERT((size <= sizeof(mask)) && (size > 0));
mask = ~0UL >> (8 * (sizeof(mask) - size));
-
+
if ((v3 ^ v2) & (v3 ^ v1) & mask)
regs->eflags |= X86_EFLAGS_OF;
}
static inline void set_eflags_AF(int size, unsigned long v1,
- unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
+ unsigned long v2, unsigned long v3,
+ struct cpu_user_regs *regs)
{
if ((v1 ^ v2 ^ v3) & 0x10)
regs->eflags |= X86_EFLAGS_AF;
@@ -328,7 +334,9 @@ static inline void set_eflags_ZF(int size, unsigned long v1,
struct cpu_user_regs *regs)
{
unsigned long mask;
-
+
+ if ( size == BYTE_64 )
+ size = BYTE;
ASSERT((size <= sizeof(mask)) && (size > 0));
mask = ~0UL >> (8 * (sizeof(mask) - size));
@@ -341,7 +349,9 @@ static inline void set_eflags_SF(int size, unsigned long v1,
struct cpu_user_regs *regs)
{
unsigned long mask;
-
+
+ if ( size == BYTE_64 )
+ size = BYTE;
ASSERT((size <= sizeof(mask)) && (size > 0));
mask = ~0UL >> (8 * (sizeof(mask) - size));
@@ -395,14 +405,14 @@ static void hvm_pio_assist(struct cpu_user_regs *regs, ioreq_t *p,
if ( hvm_paging_enabled(current) )
{
int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size);
- if ( rv != 0 )
+ if ( rv != 0 )
{
/* Failed on the page-spanning copy. Inject PF into
* the guest for the address where we failed. */
addr += p->size - rv;
gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side "
"of a page-spanning PIO: va=%#lx\n", addr);
- hvm_inject_exception(TRAP_page_fault,
+ hvm_inject_exception(TRAP_page_fault,
PFEC_write_access, addr);
return;
}
@@ -525,14 +535,14 @@ static void hvm_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p,
if (hvm_paging_enabled(current))
{
int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size);
- if ( rv != 0 )
+ if ( rv != 0 )
{
/* Failed on the page-spanning copy. Inject PF into
* the guest for the address where we failed. */
addr += p->size - rv;
gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side of "
"a page-spanning MMIO: va=%#lx\n", addr);
- hvm_inject_exception(TRAP_page_fault,
+ hvm_inject_exception(TRAP_page_fault,
PFEC_write_access, addr);
return;
}
@@ -738,14 +748,14 @@ static void hvm_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p,
case INSTR_PUSH:
mmio_opp->addr += hvm_get_segment_base(current, x86_seg_ss);
- {
+ {
unsigned long addr = mmio_opp->addr;
int rv = hvm_copy_to_guest_virt(addr, &p->data, size);
- if ( rv != 0 )
+ if ( rv != 0 )
{
addr += p->size - rv;
- gdprintk(XENLOG_DEBUG, "Pagefault emulating PUSH from MMIO: "
- "va=%#lx\n", addr);
+ gdprintk(XENLOG_DEBUG, "Pagefault emulating PUSH from MMIO:"
+ " va=%#lx\n", addr);
hvm_inject_exception(TRAP_page_fault, PFEC_write_access, addr);
return;
}
@@ -787,7 +797,7 @@ void hvm_io_assist(struct vcpu *v)
memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
/* Has memory been dirtied? */
- if ( p->dir == IOREQ_READ && p->data_is_ptr )
+ if ( p->dir == IOREQ_READ && p->data_is_ptr )
{
gmfn = get_mfn_from_gpfn(paging_gva_to_gfn(v, p->data));
mark_dirty(v->domain, gmfn);