diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-03-29 19:23:41 +0100 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-03-29 19:23:41 +0100 |
commit | 61e7893dafdfa84717d362986c8328effd1a2320 (patch) | |
tree | f4dddc42536c9ede261501d527b3d485aa122795 | |
parent | a9214a8feef1f35d2b852443c158221e60b90195 (diff) | |
download | xen-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.c | 42 |
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); |