[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] add support for XCHG instruction accessing APIC
32-bit SMP Linux uses xchg instruction to access APIC (see apic_write_atomic()). Attached is patch that adds support for this instruction. The patch also fixes missed dependencies (in xen/Rules.mk) on header files in include/asm-x86/hvm. -boris # # Add support for XCHG instruction accessing APIC # Signed-off-by: Boris Ostrovsky <bostrovsky@xxxxxxxxxxxxxxx> diff -r d0d3fef37685 xen/Rules.mk --- a/xen/Rules.mk Mon Apr 3 14:34:20 2006 +0100 +++ b/xen/Rules.mk Tue Apr 4 16:08:22 2006 -0400 @@ -31,6 +31,9 @@ HDRS += $(wildcard $(BASEDIR)/include HDRS += $(wildcard $(BASEDIR)/include/public/*.h) HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/*.h) HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/$(TARGET_SUBARCH)/*.h) +HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/hvm/*.h) +HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/hvm/svm/*.h) +HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/hvm/vmx/*.h) # Do not depend on auto-generated header files. HDRS := $(subst $(BASEDIR)/include/asm-$(TARGET_ARCH)/asm-offsets.h,,$(HDRS)) HDRS := $(subst $(BASEDIR)/include/xen/banner.h,,$(HDRS)) diff -r d0d3fef37685 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Mon Apr 3 14:34:20 2006 +0100 +++ b/xen/arch/x86/hvm/hvm.c Tue Apr 4 16:08:22 2006 -0400 @@ -201,6 +201,7 @@ void hvm_setup_platform(struct domain* d if ( hvm_apic_support(d) ) { spin_lock_init(&d->arch.hvm_domain.round_robin_lock); + d->arch.hvm_domain.apic_rwlock = RW_LOCK_UNLOCKED; hvm_vioapic_init(d); } } diff -r d0d3fef37685 xen/arch/x86/hvm/intercept.c --- a/xen/arch/x86/hvm/intercept.c Mon Apr 3 14:34:20 2006 +0100 +++ b/xen/arch/x86/hvm/intercept.c Tue Apr 4 16:08:22 2006 -0400 @@ -58,6 +58,12 @@ static inline void hvm_mmio_access(struc } req = &vio->vp_ioreq; + + /* We may need to execute atomic instruction (e.g. XCHG) */ + if (req->dir == IOREQ_WRITE) + write_lock(&v->domain->arch.hvm_domain.apic_rwlock); + else + read_lock(&v->domain->arch.hvm_domain.apic_rwlock); switch (req->type) { case IOREQ_TYPE_COPY: @@ -123,11 +129,22 @@ static inline void hvm_mmio_access(struc req->u.data = tmp1; break; + case IOREQ_TYPE_XCHG: + tmp1 = read_handler(v, req->addr, req->size); + write_handler(v, req->addr, req->size, (unsigned long) req->u.data); + req->u.data = tmp1; + break; + default: printk("error ioreq type for local APIC %x\n", req->type); domain_crash_synchronous(); break; } + + if (req->dir == IOREQ_WRITE) + write_unlock(&v->domain->arch.hvm_domain.apic_rwlock); + else + read_unlock(&v->domain->arch.hvm_domain.apic_rwlock); } int hvm_mmio_intercept(ioreq_t *p) @@ -143,7 +160,7 @@ int hvm_mmio_intercept(ioreq_t *p) if ( hvm_mmio_handlers[i]->check_handler(v, p->addr) ) { hvm_mmio_access(v, p, hvm_mmio_handlers[i]->read_handler, - hvm_mmio_handlers[i]->write_handler); + hvm_mmio_handlers[i]->write_handler); return 1; } } diff -r d0d3fef37685 xen/arch/x86/hvm/platform.c --- a/xen/arch/x86/hvm/platform.c Mon Apr 3 14:34:20 2006 +0100 +++ b/xen/arch/x86/hvm/platform.c Tue Apr 4 16:08:22 2006 -0400 @@ -439,6 +439,14 @@ static int hvm_decode(int realmode, unsi GET_OP_SIZE_FOR_BYTE(size_reg); return mem_reg(size_reg, opcode, instr, rex); + case 0x87: /* xchg {r/m16|r/m32}, {m/r16|m/r32} */ + instr->instr = INSTR_XCHG; + GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); + if (((*(opcode+1)) & 0xc7) == 5) + return reg_mem(instr->op_size, opcode, instr, rex); + else + return mem_reg(instr->op_size, opcode, instr, rex); + case 0x88: /* mov r8, m8 */ instr->instr = INSTR_MOV; instr->op_size = BYTE; @@ -936,6 +944,17 @@ void handle_mmio(unsigned long va, unsig break; } + case INSTR_XCHG: + mmio_opp->flags = mmio_inst.flags; + mmio_opp->instr = mmio_inst.instr; + mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */ + mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */ + + /* send the request and wait for the value */ + send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1, + mmio_inst.op_size, 0, IOREQ_WRITE, 0); + break; + default: printf("Unhandled MMIO instruction\n"); domain_crash_synchronous(); diff -r d0d3fef37685 xen/include/asm-x86/hvm/domain.h --- a/xen/include/asm-x86/hvm/domain.h Mon Apr 3 14:34:20 2006 +0100 +++ b/xen/include/asm-x86/hvm/domain.h Tue Apr 4 16:08:22 2006 -0400 @@ -42,6 +42,8 @@ struct hvm_domain { struct hvm_vioapic vioapic; struct hvm_io_handler io_handler; + rwlock_t apic_rwlock; + unsigned char round_info[256]; spinlock_t round_robin_lock; int interrupt_request; diff -r d0d3fef37685 xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Mon Apr 3 14:34:20 2006 +0100 +++ b/xen/include/asm-x86/hvm/io.h Tue Apr 4 16:08:22 2006 -0400 @@ -66,6 +66,7 @@ #define INSTR_STOS 10 #define INSTR_TEST 11 #define INSTR_BT 12 +#define INSTR_XCHG 13 struct instruction { __s8 instr; /* instruction type */ diff -r d0d3fef37685 xen/include/public/hvm/ioreq.h --- a/xen/include/public/hvm/ioreq.h Mon Apr 3 14:34:20 2006 +0100 +++ b/xen/include/public/hvm/ioreq.h Tue Apr 4 16:08:22 2006 -0400 @@ -34,6 +34,7 @@ #define IOREQ_TYPE_AND 2 #define IOREQ_TYPE_OR 3 #define IOREQ_TYPE_XOR 4 +#define IOREQ_TYPE_XCHG 5 /* * VMExit dispatcher should cooperate with instruction decoder to _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |