# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 5be9e927533d94ed1389f8926d51c65849133556
# Parent 1dd2062668b2ef87f6dd9df254dc1063944694ac
[HVM] Fix a bug in the emulation of the xchg instruction.
This bug has prevented us from booting fully virtualized SMP guests
that write to the APIC using the xchg instruction (when
CONFIG_X86_GOOD_APIC is not set). On 32 bit platforms, sles 10 kernels
are built without CONFIG_x86_GOOD_APIC not set and hence we have had
problems booting fully virtualized SMP sles 10 guests.
Signed-off-by: K. Y. Srinivasan <ksrinivasan@xxxxxxxxxx>
---
xen/arch/x86/hvm/io.c | 10 ++++++++++
xen/arch/x86/hvm/platform.c | 24 ++++++++++++++++++++----
2 files changed, 30 insertions(+), 4 deletions(-)
diff -r 1dd2062668b2 -r 5be9e927533d xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Tue May 30 12:28:46 2006 +0100
+++ b/xen/arch/x86/hvm/io.c Tue May 30 12:30:47 2006 +0100
@@ -648,6 +648,16 @@ static void hvm_mmio_assist(struct vcpu
regs->eflags &= ~X86_EFLAGS_CF;
break;
+
+ case INSTR_XCHG:
+ if (src & REGISTER) {
+ index = operand_index(src);
+ set_reg_value(size, index, 0, regs, p->u.data);
+ } else {
+ index = operand_index(dst);
+ set_reg_value(size, index, 0, regs, p->u.data);
+ }
+ break;
}
hvm_load_cpu_guest_regs(v, regs);
diff -r 1dd2062668b2 -r 5be9e927533d xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Tue May 30 12:28:46 2006 +0100
+++ b/xen/arch/x86/hvm/platform.c Tue May 30 12:30:47 2006 +0100
@@ -954,10 +954,26 @@ void handle_mmio(unsigned long va, unsig
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);
+ if (mmio_inst.operand[0] & REGISTER) {
+ long value;
+ unsigned long operand = mmio_inst.operand[0];
+ value = get_reg_value(operand_size(operand),
+ operand_index(operand), 0,
+ mmio_opp->inst_decoder_regs);
+ /* send the request and wait for the value */
+ send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+ mmio_inst.op_size, value, IOREQ_WRITE, 0);
+ } else {
+ /* the destination is a register */
+ long value;
+ unsigned long operand = mmio_inst.operand[1];
+ value = get_reg_value(operand_size(operand),
+ operand_index(operand), 0,
+ mmio_opp->inst_decoder_regs);
+ /* send the request and wait for the value */
+ send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+ mmio_inst.op_size, value, IOREQ_WRITE, 0);
+ }
break;
default:
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|