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
|