# HG changeset patch
# User Alastair Tse <atse@xxxxxxxxxxxxx>
# Node ID aab2b3f739d28d3f1b2417e95c32e35fab6f18f5
# Parent f7cff5d296bff920355f0cbd56f0c5777d116062
# Parent 2dd4569e064041bb222eaa3da6b3d63319511d34
Merge
---
tools/firmware/vmxassist/head.S | 2
tools/firmware/vmxassist/setup.c | 4
tools/firmware/vmxassist/vm86.c | 213 +++++++++++++++-------------------
tools/ioemu/hw/tpm_tis.c | 12 +
tools/ioemu/target-i386-dm/cpu.h | 3
tools/ioemu/target-i386-dm/exec-dm.c | 17 ++
tools/ioemu/vl.c | 154 ++++++++++++++++++------
tools/ioemu/vl.h | 20 +++
tools/libxc/xc_hvm_build.c | 16 +-
tools/libxc/xc_linux_build.c | 12 +
tools/libxc/xc_load_elf.c | 103 ++++++++++++----
tools/libxc/xc_private.c | 76 ++++++++++++
tools/libxc/xc_private.h | 19 ---
tools/libxc/xenctrl.h | 42 ++++++
tools/python/xen/lowlevel/xc/xc.c | 104 +++++++++-------
tools/python/xen/xend/server/blkif.py | 2
xen/arch/x86/boot/x86_32.S | 9 -
xen/arch/x86/boot/x86_64.S | 9 -
xen/include/xen/multiboot.h | 35 +++++
19 files changed, 584 insertions(+), 268 deletions(-)
diff -r f7cff5d296bf -r aab2b3f739d2 tools/firmware/vmxassist/head.S
--- a/tools/firmware/vmxassist/head.S Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/firmware/vmxassist/head.S Thu Dec 07 11:44:05 2006 +0000
@@ -130,7 +130,7 @@ _start:
clts
/* setup my own stack */
- movl $stack_top - 4*4, %esp
+ movl $stack_top, %esp
movl %esp, %ebp
/* go ... */
diff -r f7cff5d296bf -r aab2b3f739d2 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/firmware/vmxassist/setup.c Thu Dec 07 11:44:05 2006 +0000
@@ -125,7 +125,7 @@ setup_gdt(void)
/* setup task state segment */
memset(&tss, 0, sizeof(tss));
tss.ss0 = DATA_SELECTOR;
- tss.esp0 = (unsigned) stack_top - 4*4;
+ tss.esp0 = (unsigned) stack_top;
tss.iomap_base = offsetof(struct tss, iomap);
/* initialize gdt's tss selector */
@@ -258,7 +258,7 @@ setup_ctx(void)
memset(c, 0, sizeof(*c));
c->eip = (unsigned long) switch_to_real_mode;
- c->esp = (unsigned) stack_top - 4*4;
+ c->esp = (unsigned) stack_top;
c->eflags = 0x2; /* no interrupts, please */
/*
diff -r f7cff5d296bf -r aab2b3f739d2 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/firmware/vmxassist/vm86.c Thu Dec 07 11:44:05 2006 +0000
@@ -1,6 +1,6 @@
/*
* vm86.c: A vm86 emulator. The main purpose of this emulator is to do as
- * little work as possible.
+ * little work as possible.
*
* Leendert van Doorn, leendert@xxxxxxxxxxxxxx
* Copyright (c) 2005-2006, International Business Machines Corporation.
@@ -52,8 +52,8 @@ static char *rnames[] = { "ax", "cx", "d
static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
#endif /* DEBUG */
-#define PDE_PS (1 << 7)
-#define PT_ENTRY_PRESENT 0x1
+#define PDE_PS (1 << 7)
+#define PT_ENTRY_PRESENT 0x1
/* We only support access to <=4G physical memory due to 1:1 mapping */
static uint64_t
@@ -136,7 +136,7 @@ address(struct regs *regs, unsigned seg,
}
if (mode == VM86_REAL || seg > oldctx.gdtr_limit ||
- (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
+ (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
return ((seg & 0xFFFF) << 4) + off;
gdt_phys_base = guest_linear_to_phys(oldctx.gdtr_base);
@@ -153,13 +153,13 @@ address(struct regs *regs, unsigned seg,
seg_limit = (entry_high & 0xF0000) | (entry_low & 0xFFFF);
if (entry_high & 0x8000 &&
- ((entry_high & 0x800000 && off >> 12 <= seg_limit) ||
- (!(entry_high & 0x800000) && off <= seg_limit)))
+ ((entry_high & 0x800000 && off >> 12 <= seg_limit) ||
+ (!(entry_high & 0x800000) && off <= seg_limit)))
return seg_base + off;
panic("should never reach here in function address():\n\t"
- "entry=0x%08x%08x, mode=%d, seg=0x%08x, offset=0x%08x\n",
- entry_high, entry_low, mode, seg, off);
+ "entry=0x%08x%08x, mode=%d, seg=0x%08x, offset=0x%08x\n",
+ entry_high, entry_low, mode, seg, off);
return 0;
}
@@ -172,7 +172,7 @@ trace(struct regs *regs, int adjust, cha
va_list ap;
if ((traceset & (1 << mode)) &&
- (mode == VM86_REAL_TO_PROTECTED || mode == VM86_REAL)) {
+ (mode == VM86_REAL_TO_PROTECTED || mode == VM86_REAL)) {
/* 16-bit, seg:off addressing */
unsigned addr = address(regs, regs->cs, off);
printf("0x%08x: 0x%x:0x%04x ", addr, regs->cs, off);
@@ -183,7 +183,7 @@ trace(struct regs *regs, int adjust, cha
printf("\n");
}
if ((traceset & (1 << mode)) &&
- (mode == VM86_PROTECTED_TO_REAL || mode == VM86_PROTECTED)) {
+ (mode == VM86_PROTECTED_TO_REAL || mode == VM86_PROTECTED)) {
/* 16-bit, gdt addressing */
unsigned addr = address(regs, regs->cs, off);
printf("0x%08x: 0x%x:0x%08x ", addr, regs->cs, off);
@@ -430,7 +430,7 @@ operand(unsigned prefix, struct regs *re
case 2: return address(regs, seg, regs->edx);
case 3: return address(regs, seg, regs->ebx);
case 4: return address(regs, seg,
- sib(regs, mod, fetch8(regs)));
+ sib(regs, mod,
fetch8(regs)));
case 5: return address(regs, seg, fetch32(regs));
case 6: return address(regs, seg, regs->esi);
case 7: return address(regs, seg, regs->edi);
@@ -450,7 +450,7 @@ operand(unsigned prefix, struct regs *re
case 2: return address(regs, seg, regs->edx + disp);
case 3: return address(regs, seg, regs->ebx + disp);
case 4: return address(regs, seg,
- sib(regs, mod, fetch8(regs)));
+ sib(regs, mod,
fetch8(regs)));
case 5: return address(regs, seg, regs->ebp + disp);
case 6: return address(regs, seg, regs->esi + disp);
case 7: return address(regs, seg, regs->edi + disp);
@@ -507,7 +507,7 @@ operand(unsigned prefix, struct regs *re
}
}
- return 0;
+ return 0;
}
/*
@@ -859,7 +859,7 @@ mov_to_seg(struct regs *regs, unsigned p
fail:
printf("%s:%d: missed opcode %02x %02x\n",
- __FUNCTION__, __LINE__, opc, modrm);
+ __FUNCTION__, __LINE__, opc, modrm);
return 0;
}
@@ -896,11 +896,11 @@ load_seg(unsigned long sel, uint32_t *ba
((entry >> (32-16)) & 0x00FF0000) |
((entry >> ( 16)) & 0x0000FFFF));
*limit = (((entry >> (48-16)) & 0x000F0000) |
- ((entry ) & 0x0000FFFF));
+ (entry & 0x0000FFFF));
arbytes->bytes = 0;
arbytes->fields.seg_type = (entry >> (8+32)) & 0xF; /* TYPE */
- arbytes->fields.s = (entry >> (12+32)) & 0x1; /* S */
+ arbytes->fields.s = (entry >> (12+32)) & 0x1; /* S */
if (arbytes->fields.s)
arbytes->fields.seg_type |= 1; /* accessed */
arbytes->fields.dpl = (entry >> (13+32)) & 0x3; /* DPL */
@@ -924,7 +924,7 @@ load_or_clear_seg(unsigned long sel, uin
load_or_clear_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union
vmcs_arbytes *arbytes)
{
if (!load_seg(sel, base, limit, arbytes))
- load_seg(0, base, limit, arbytes);
+ load_seg(0, base, limit, arbytes);
}
@@ -988,21 +988,21 @@ real_mode(struct regs *regs)
panic("%%ss 0x%lx higher than 1MB", regs->uss);
regs->uss = address(regs, regs->uss, 0) >> 4;
} else {
- regs->uss = saved_rm_regs.uss;
+ regs->uss = saved_rm_regs.uss;
}
if (regs->vds != 0) {
if (regs->vds >= HIGHMEM)
panic("%%ds 0x%lx higher than 1MB", regs->vds);
regs->vds = address(regs, regs->vds, 0) >> 4;
} else {
- regs->vds = saved_rm_regs.vds;
+ regs->vds = saved_rm_regs.vds;
}
if (regs->ves != 0) {
if (regs->ves >= HIGHMEM)
panic("%%es 0x%lx higher than 1MB", regs->ves);
regs->ves = address(regs, regs->ves, 0) >> 4;
} else {
- regs->ves = saved_rm_regs.ves;
+ regs->ves = saved_rm_regs.ves;
}
/* this should get us into 16-bit mode */
@@ -1029,10 +1029,7 @@ set_mode(struct regs *regs, enum vm86_mo
(mode == VM86_REAL_TO_PROTECTED)) {
regs->eflags &= ~EFLAGS_TF;
real_mode(regs);
- break;
- } else if (mode == VM86_REAL) {
- break;
- } else
+ } else if (mode != VM86_REAL)
panic("unexpected real mode transition");
break;
@@ -1049,25 +1046,19 @@ set_mode(struct regs *regs, enum vm86_mo
oldctx.fs_sel = 0;
oldctx.gs_sel = 0;
oldctx.ss_sel = 0;
- break;
- } else if (mode == VM86_REAL_TO_PROTECTED) {
- break;
- } else
+ } else if (mode != VM86_REAL_TO_PROTECTED)
panic("unexpected real-to-protected mode transition");
break;
case VM86_PROTECTED_TO_REAL:
- if (mode == VM86_PROTECTED) {
- break;
- } else
+ if (mode != VM86_PROTECTED)
panic("unexpected protected-to-real mode transition");
break;
case VM86_PROTECTED:
- if (mode == VM86_REAL_TO_PROTECTED) {
- protected_mode(regs);
- } else
+ if (mode != VM86_REAL_TO_PROTECTED)
panic("unexpected protected mode transition");
+ protected_mode(regs);
break;
}
@@ -1081,25 +1072,19 @@ jmpl(struct regs *regs, int prefix)
unsigned n = regs->eip;
unsigned cs, eip;
- if (mode == VM86_REAL_TO_PROTECTED) { /* jump to protected mode */
- eip = (prefix & DATA32) ? fetch32(regs) : fetch16(regs);
- cs = fetch16(regs);
-
- TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
-
- regs->cs = cs;
- regs->eip = eip;
+ eip = (prefix & DATA32) ? fetch32(regs) : fetch16(regs);
+ cs = fetch16(regs);
+
+ TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
+
+ regs->cs = cs;
+ regs->eip = eip;
+
+ if (mode == VM86_REAL_TO_PROTECTED) /* jump to protected
mode */
set_mode(regs, VM86_PROTECTED);
- } else if (mode == VM86_PROTECTED_TO_REAL) { /* jump to real mode */
- eip = (prefix & DATA32) ? fetch32(regs) : fetch16(regs);
- cs = fetch16(regs);
-
- TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
-
- regs->cs = cs;
- regs->eip = eip;
+ else if (mode == VM86_PROTECTED_TO_REAL)/* jump to real mode */
set_mode(regs, VM86_REAL);
- } else
+ else
panic("jmpl");
}
@@ -1110,29 +1095,22 @@ jmpl_indirect(struct regs *regs, int pre
unsigned cs, eip;
unsigned addr;
- addr = operand(prefix, regs, modrm);
-
- if (mode == VM86_REAL_TO_PROTECTED) { /* jump to protected mode */
- eip = (prefix & DATA32) ? read32(addr) : read16(addr);
- addr += (prefix & DATA32) ? 4 : 2;
- cs = read16(addr);
-
- TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
-
- regs->cs = cs;
- regs->eip = eip;
+ addr = operand(prefix, regs, modrm);
+
+ eip = (prefix & DATA32) ? read32(addr) : read16(addr);
+ addr += (prefix & DATA32) ? 4 : 2;
+ cs = read16(addr);
+
+ TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
+
+ regs->cs = cs;
+ regs->eip = eip;
+
+ if (mode == VM86_REAL_TO_PROTECTED) /* jump to protected
mode */
set_mode(regs, VM86_PROTECTED);
- } else if (mode == VM86_PROTECTED_TO_REAL) { /* jump to real mode */
- eip = (prefix & DATA32) ? read32(addr) : read16(addr);
- addr += (prefix & DATA32) ? 4 : 2;
- cs = read16(addr);
-
- TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
-
- regs->cs = cs;
- regs->eip = eip;
+ else if (mode == VM86_PROTECTED_TO_REAL)/* jump to real mode */
set_mode(regs, VM86_REAL);
- } else
+ else
panic("jmpl");
}
@@ -1151,15 +1129,14 @@ retl(struct regs *regs, int prefix)
TRACE((regs, 1, "retl (to 0x%x:0x%x)", cs, eip));
- if (mode == VM86_REAL_TO_PROTECTED) { /* jump to protected mode */
- regs->cs = cs;
- regs->eip = eip;
+ regs->cs = cs;
+ regs->eip = eip;
+
+ if (mode == VM86_REAL_TO_PROTECTED) /* jump to protected
mode */
set_mode(regs, VM86_PROTECTED);
- } else if (mode == VM86_PROTECTED_TO_REAL) { /* jump to real mode */
- regs->cs = cs;
- regs->eip = eip;
+ else if (mode == VM86_PROTECTED_TO_REAL)/* jump to real mode */
set_mode(regs, VM86_REAL);
- } else
+ else
panic("retl");
}
@@ -1259,8 +1236,8 @@ pushrm(struct regs *regs, int prefix, un
unsigned addr;
unsigned data;
- addr = operand(prefix, regs, modrm);
-
+ addr = operand(prefix, regs, modrm);
+
if (prefix & DATA32) {
data = read32(addr);
push32(regs, data);
@@ -1386,11 +1363,11 @@ opcode(struct regs *regs)
case 0x3B: /* addr32 cmp r/m16, r16 */
if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
goto invalid;
- if ((prefix & ADDR32) == 0)
- goto invalid;
- if (!cmp(regs, prefix, opc))
- goto invalid;
- return OPC_EMULATED;
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!cmp(regs, prefix, opc))
+ goto invalid;
+ return OPC_EMULATED;
case 0x3E:
TRACE((regs, regs->eip - eip, "%%ds:"));
@@ -1412,7 +1389,7 @@ opcode(struct regs *regs)
prefix |= DATA32;
continue;
- case 0x67:
+ case 0x67:
TRACE((regs, regs->eip - eip, "addr32"));
prefix |= ADDR32;
continue;
@@ -1421,18 +1398,18 @@ opcode(struct regs *regs)
case 0x8A: /* addr32 mov r/m8, r8 */
if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
goto invalid;
- if ((prefix & ADDR32) == 0)
- goto invalid;
- if (!movr(regs, prefix, opc))
- goto invalid;
- return OPC_EMULATED;
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!movr(regs, prefix, opc))
+ goto invalid;
+ return OPC_EMULATED;
case 0x89: /* addr32 mov r16, r/m16 */
if (mode == VM86_PROTECTED_TO_REAL) {
unsigned modrm = fetch8(regs);
unsigned addr = operand(prefix, regs, modrm);
unsigned val, r = (modrm >> 3) & 7;
-
+
if (prefix & DATA32) {
val = getreg16(regs, r);
write32(addr, val);
@@ -1447,11 +1424,11 @@ opcode(struct regs *regs)
case 0x8B: /* addr32 mov r/m16, r16 */
if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
goto invalid;
- if ((prefix & ADDR32) == 0)
- goto invalid;
- if (!movr(regs, prefix, opc))
- goto invalid;
- return OPC_EMULATED;
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!movr(regs, prefix, opc))
+ goto invalid;
+ return OPC_EMULATED;
case 0x8E: /* mov r16, sreg */
if (!mov_to_seg(regs, prefix, opc))
@@ -1459,11 +1436,11 @@ opcode(struct regs *regs)
return OPC_EMULATED;
case 0x8F: /* addr32 pop r/m16 */
- if ((prefix & ADDR32) == 0)
- goto invalid;
- if (!pop(regs, prefix, opc))
- goto invalid;
- return OPC_EMULATED;
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!pop(regs, prefix, opc))
+ goto invalid;
+ return OPC_EMULATED;
case 0x90: /* nop */
TRACE((regs, regs->eip - eip, "nop"));
@@ -1487,7 +1464,7 @@ opcode(struct regs *regs)
regs->eflags |= EFLAGS_VM;
return OPC_EMULATED;
- case 0xA1: /* mov ax, r/m16 */
+ case 0xA1: /* mov ax, r/m16 */
{
int addr, data;
int seg = segment(prefix, regs, regs->vds);
@@ -1521,15 +1498,15 @@ opcode(struct regs *regs)
return OPC_EMULATED;
case 0xC6: /* addr32 movb $imm, r/m8 */
- if ((prefix & ADDR32) == 0)
- goto invalid;
- if (!movr(regs, prefix, opc))
- goto invalid;
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!movr(regs, prefix, opc))
+ goto invalid;
return OPC_EMULATED;
case 0xCB: /* retl */
if ((mode == VM86_REAL_TO_PROTECTED) ||
- (mode == VM86_PROTECTED_TO_REAL)) {
+ (mode == VM86_PROTECTED_TO_REAL)) {
retl(regs, prefix);
return OPC_INVALID;
}
@@ -1567,7 +1544,7 @@ opcode(struct regs *regs)
case 0xEA: /* jmpl */
if ((mode == VM86_REAL_TO_PROTECTED) ||
- (mode == VM86_PROTECTED_TO_REAL)) {
+ (mode == VM86_PROTECTED_TO_REAL)) {
jmpl(regs, prefix);
return OPC_INVALID;
}
@@ -1579,7 +1556,7 @@ opcode(struct regs *regs)
switch((modrm >> 3) & 7) {
case 5: /* jmpl (indirect) */
if ((mode == VM86_REAL_TO_PROTECTED) ||
- (mode == VM86_PROTECTED_TO_REAL)) {
+ (mode ==
VM86_PROTECTED_TO_REAL)) {
jmpl_indirect(regs, prefix,
modrm);
return OPC_INVALID;
}
@@ -1596,7 +1573,7 @@ opcode(struct regs *regs)
case 0xEB: /* short jump */
if ((mode == VM86_REAL_TO_PROTECTED) ||
- (mode == VM86_PROTECTED_TO_REAL)) {
+ (mode == VM86_PROTECTED_TO_REAL)) {
disp = (char) fetch8(regs);
TRACE((regs, 2, "jmp 0x%x", regs->eip + disp));
regs->eip += disp;
@@ -1619,10 +1596,10 @@ opcode(struct regs *regs)
continue;
case 0xF6: /* addr32 testb $imm, r/m8 */
- if ((prefix & ADDR32) == 0)
- goto invalid;
- if (!test(regs, prefix, opc))
- goto invalid;
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!test(regs, prefix, opc))
+ goto invalid;
return OPC_EMULATED;
case 0xFA: /* cli */
@@ -1682,6 +1659,8 @@ trap(int trapno, int errno, struct regs
case 1: /* Debug */
if (regs->eflags & EFLAGS_VM) {
/* emulate any 8086 instructions */
+ if (mode == VM86_REAL)
+ return;
if (mode != VM86_REAL_TO_PROTECTED)
panic("not in real-to-protected mode");
emulate(regs);
@@ -1702,7 +1681,7 @@ trap(int trapno, int errno, struct regs
default:
invalid:
printf("Trap (0x%x) while in %s mode\n",
- trapno, regs->eflags & EFLAGS_VM ? "real" : "protected");
+ trapno, regs->eflags & EFLAGS_VM ? "real" :
"protected");
if (trapno == 14)
printf("Page fault address 0x%x\n", get_cr2());
dump_regs(regs);
diff -r f7cff5d296bf -r aab2b3f739d2 tools/ioemu/hw/tpm_tis.c
--- a/tools/ioemu/hw/tpm_tis.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/ioemu/hw/tpm_tis.c Thu Dec 07 11:44:05 2006 +0000
@@ -132,7 +132,7 @@ typedef struct TPMState {
/* local prototypes */
-static int TPM_Send(tpmState *s, tpmBuffer *buffer, char *msg);
+static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg);
static int TPM_Receive(tpmState *s, tpmBuffer *buffer);
static uint32_t vtpm_instance_from_xenstore(void);
static void tis_poll_timer(void *opaque);
@@ -271,6 +271,8 @@ static int create_local_socket(tpmState
/*
* the 'write' method for sending requests to the vTPM
* four bytes with the vTPM instance number are prepended to each request
+ * the locality in which the command was sent is transmitted in the
+ * highest 3 bits
*/
static int write_local_socket(tpmState *s, const tpmBuffer *buffer)
{
@@ -608,7 +610,7 @@ static void tis_mem_writel(void *opaque,
}
}
if (val & STS_TPM_GO) {
- n = TPM_Send(s, &s->buffer,"tpm_data_write");
+ n = TPM_Send(s, &s->buffer, locty, "tpm_data_write");
if (n > 0) {
/* sending of data was successful */
s->offset = 0;
@@ -915,7 +917,7 @@ const static unsigned char tpm_failure[]
/*
* Send a TPM request.
*/
-static int TPM_Send(tpmState *s, tpmBuffer *buffer, char *msg)
+static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg)
{
int len;
uint32_t size = tpm_get_size_from_buffer(buffer->buf);
@@ -944,6 +946,10 @@ static int TPM_Send(tpmState *s, tpmBuff
#ifdef DEBUG_TPM
showBuff(buffer->buf, "To TPM");
#endif
+
+ /* transmit the locality in the highest 3 bits */
+ buffer->instance[0] &= 0x1f;
+ buffer->instance[0] |= (locty << 5);
len = vTPMTransmit[s->Transmitlayer].write(s, buffer);
if (len < 0) {
diff -r f7cff5d296bf -r aab2b3f739d2 tools/ioemu/target-i386-dm/cpu.h
--- a/tools/ioemu/target-i386-dm/cpu.h Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/ioemu/target-i386-dm/cpu.h Thu Dec 07 11:44:05 2006 +0000
@@ -25,7 +25,8 @@
#ifdef TARGET_X86_64
#define TARGET_LONG_BITS 64
#else
-#define TARGET_LONG_BITS 32
+/* #define TARGET_LONG_BITS 32 */
+#define TARGET_LONG_BITS 64 /* for Qemu map cache */
#endif
/* target supports implicit self modifying code */
diff -r f7cff5d296bf -r aab2b3f739d2 tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/ioemu/target-i386-dm/exec-dm.c Thu Dec 07 11:44:05 2006 +0000
@@ -36,6 +36,7 @@
#include "cpu.h"
#include "exec-all.h"
+#include "vl.h"
//#define DEBUG_TB_INVALIDATE
//#define DEBUG_FLUSH
@@ -426,6 +427,12 @@ static inline int paddr_is_ram(target_ph
#endif
}
+#if defined(__i386__) || defined(__x86_64__)
+#define phys_ram_addr(x) (qemu_map_cache(x))
+#elif defined(__ia64__)
+#define phys_ram_addr(x) (phys_ram_base + (x))
+#endif
+
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write)
{
@@ -438,7 +445,7 @@ void cpu_physical_memory_rw(target_phys_
l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
if (l > len)
l = len;
-
+
io_index = iomem_index(addr);
if (is_write) {
if (io_index) {
@@ -460,9 +467,10 @@ void cpu_physical_memory_rw(target_phys_
}
} else if (paddr_is_ram(addr)) {
/* Reading from RAM */
- memcpy(phys_ram_base + addr, buf, l);
+ ptr = phys_ram_addr(addr);
+ memcpy(ptr, buf, l);
#ifdef __ia64__
- sync_icache((unsigned long)(phys_ram_base + addr), l);
+ sync_icache(ptr, l);
#endif
}
} else {
@@ -485,7 +493,8 @@ void cpu_physical_memory_rw(target_phys_
}
} else if (paddr_is_ram(addr)) {
/* Reading from RAM */
- memcpy(buf, phys_ram_base + addr, l);
+ ptr = phys_ram_addr(addr);
+ memcpy(buf, ptr, l);
} else {
/* Neither RAM nor known MMIO space */
memset(buf, 0xff, len);
diff -r f7cff5d296bf -r aab2b3f739d2 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/ioemu/vl.c Thu Dec 07 11:44:05 2006 +0000
@@ -5807,6 +5807,92 @@ int set_mm_mapping(int xc_handle, uint32
return 0;
}
+
+#if defined(__i386__) || defined(__x86_64__)
+static struct map_cache *mapcache_entry;
+static unsigned long nr_buckets;
+
+static int qemu_map_cache_init(unsigned long nr_pages)
+{
+ unsigned long max_pages = MAX_MCACHE_SIZE >> PAGE_SHIFT;
+ int i;
+
+ if (nr_pages < max_pages)
+ max_pages = nr_pages;
+
+ nr_buckets = (max_pages << PAGE_SHIFT) >> MCACHE_BUCKET_SHIFT;
+
+ fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
+
+ mapcache_entry = malloc(nr_buckets * sizeof(struct map_cache));
+ if (mapcache_entry == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ memset(mapcache_entry, 0, nr_buckets * sizeof(struct map_cache));
+
+ /*
+ * To avoid ENOMEM from xc_map_foreign_batch() at runtime, we
+ * pre-fill all the map caches in advance.
+ */
+ for (i = 0; i < nr_buckets; i++)
+ (void)qemu_map_cache(((target_phys_addr_t)i) << MCACHE_BUCKET_SHIFT);
+
+ return 0;
+}
+
+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
+{
+ struct map_cache *entry;
+ unsigned long address_index = phys_addr >> MCACHE_BUCKET_SHIFT;
+ unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1);
+
+ /* For most cases (>99.9%), the page address is the same. */
+ static unsigned long last_address_index = ~0UL;
+ static uint8_t *last_address_vaddr;
+
+ if (address_index == last_address_index)
+ return last_address_vaddr + address_offset;
+
+ entry = &mapcache_entry[address_index % nr_buckets];
+
+ if (entry->vaddr_base == NULL || entry->paddr_index != address_index)
+ {
+ /* We need to remap a bucket. */
+ uint8_t *vaddr_base;
+ unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
+ unsigned int i;
+
+ if (entry->vaddr_base != NULL) {
+ errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
+ if (errno) {
+ fprintf(logfile, "unmap fails %d\n", errno);
+ exit(-1);
+ }
+ }
+
+ for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i++)
+ pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-PAGE_SHIFT)) + i;
+
+ vaddr_base = xc_map_foreign_batch(
+ xc_handle, domid, PROT_READ|PROT_WRITE,
+ pfns, MCACHE_BUCKET_SIZE >> PAGE_SHIFT);
+ if (vaddr_base == NULL) {
+ fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
+ exit(-1);
+ }
+
+ entry->vaddr_base = vaddr_base;
+ entry->paddr_index = address_index;;
+ }
+
+ last_address_index = address_index;
+ last_address_vaddr = entry->vaddr_base;
+
+ return last_address_vaddr + address_offset;
+}
+#endif
int main(int argc, char **argv)
{
@@ -6130,6 +6216,7 @@ int main(int argc, char **argv)
break;
case QEMU_OPTION_m:
ram_size = atol(optarg) * 1024 * 1024;
+ ram_size = (uint64_t)atol(optarg) * 1024 * 1024;
if (ram_size <= 0)
help();
#ifndef CONFIG_DM
@@ -6400,50 +6487,41 @@ int main(int argc, char **argv)
shared_page_nr = nr_pages - 1;
#endif
+#if defined(__i386__) || defined(__x86_64__)
+
+ if ( qemu_map_cache_init(tmp_nr_pages) )
+ {
+ fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
+ exit(-1);
+ }
+
+ shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+ PROT_READ|PROT_WRITE, shared_page_nr);
+ if (shared_page == NULL) {
+ fprintf(logfile, "map shared IO page returned error %d\n", errno);
+ exit(-1);
+ }
+
+ fprintf(logfile, "shared page at pfn:%lx\n", shared_page_nr);
+
+ buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ shared_page_nr - 2);
+ if (buffered_io_page == NULL) {
+ fprintf(logfile, "map buffered IO page returned error %d\n", errno);
+ exit(-1);
+ }
+
+ fprintf(logfile, "buffered io page at pfn:%lx\n", shared_page_nr - 2);
+
+#elif defined(__ia64__)
+
page_array = (xen_pfn_t *)malloc(tmp_nr_pages * sizeof(xen_pfn_t));
if (page_array == NULL) {
fprintf(logfile, "malloc returned error %d\n", errno);
exit(-1);
}
-#if defined(__i386__) || defined(__x86_64__)
- for ( i = 0; i < tmp_nr_pages; i++)
- page_array[i] = i;
-
- phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
- PROT_READ|PROT_WRITE, page_array,
- tmp_nr_pages);
- if (phys_ram_base == NULL) {
- fprintf(logfile, "batch map guest memory returned error %d\n", errno);
- exit(-1);
- }
-
- shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
- PROT_READ|PROT_WRITE,
- page_array[shared_page_nr]);
- if (shared_page == NULL) {
- fprintf(logfile, "map shared IO page returned error %d\n", errno);
- exit(-1);
- }
-
- fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n",
- shared_page_nr, (uint64_t)(page_array[shared_page_nr]));
-
- buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
- PROT_READ|PROT_WRITE,
- page_array[shared_page_nr - 2]);
- if (buffered_io_page == NULL) {
- fprintf(logfile, "map buffered IO page returned error %d\n", errno);
- exit(-1);
- }
-
- fprintf(logfile, "buffered io page at pfn:%lx, mfn: %"PRIx64"\n",
- shared_page_nr - 2, (uint64_t)(page_array[shared_page_nr - 2]));
-
- free(page_array);
-
-#elif defined(__ia64__)
-
if (xc_ia64_get_pfn_list(xc_handle, domid, page_array,
IO_PAGE_START >> PAGE_SHIFT, 3) != 3) {
fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
diff -r f7cff5d296bf -r aab2b3f739d2 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/ioemu/vl.h Thu Dec 07 11:44:05 2006 +0000
@@ -156,6 +156,26 @@ extern void *shared_vram;
extern FILE *logfile;
+
+#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__)
+#define MAX_MCACHE_SIZE 0x40000000 /* 1GB max for x86 */
+#define MCACHE_BUCKET_SHIFT 16
+#elif defined(__x86_64__)
+#define MAX_MCACHE_SIZE 0x1000000000 /* 64GB max for x86_64 */
+#define MCACHE_BUCKET_SHIFT 20
+#endif
+
+#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
+
+struct map_cache {
+ unsigned long paddr_index;
+ uint8_t *vaddr_base;
+};
+
+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr);
+#endif
+
extern int xc_handle;
extern int domid;
diff -r f7cff5d296bf -r aab2b3f739d2 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/libxc/xc_hvm_build.c Thu Dec 07 11:44:05 2006 +0000
@@ -285,7 +285,6 @@ static int xc_hvm_build_internal(int xc_
if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt) < 0 )
{
- ERROR("Error constructing guest OS");
goto error_out;
}
@@ -329,26 +328,30 @@ static int parseelfimage(char *elfbase,
if ( !IS_ELF(*ehdr) )
{
- ERROR("Kernel image does not have an ELF header.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel image does not have an ELF header.");
return -EINVAL;
}
if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
{
- ERROR("ELF program headers extend beyond end of image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF program headers extend beyond end of image.");
return -EINVAL;
}
if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
{
- ERROR("ELF section headers extend beyond end of image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF section headers extend beyond end of image.");
return -EINVAL;
}
/* Find the section-header strings table. */
if ( ehdr->e_shstrndx == SHN_UNDEF )
{
- ERROR("ELF image has no section-header strings table (shstrtab).");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF image has no section-header strings table
(shstrtab).");
return -EINVAL;
}
shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
@@ -370,7 +373,8 @@ static int parseelfimage(char *elfbase,
(ehdr->e_entry < kernstart) ||
(ehdr->e_entry > kernend) )
{
- ERROR("Malformed ELF image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Malformed ELF image.");
return -EINVAL;
}
diff -r f7cff5d296bf -r aab2b3f739d2 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/libxc/xc_linux_build.c Thu Dec 07 11:44:05 2006 +0000
@@ -120,7 +120,7 @@ static int probeimageformat(const char *
if ( probe_elf(image, image_size, load_funcs) &&
probe_bin(image, image_size, load_funcs) )
{
- ERROR( "Unrecognized image format" );
+ xc_set_error(XC_INVALID_KERNEL, "Not a valid ELF or raw kernel image");
return -EINVAL;
}
@@ -618,17 +618,20 @@ static int compat_check(int xc_handle, s
xen_capabilities_info_t xen_caps = "";
if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
- ERROR("Cannot determine host capabilities.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Cannot determine host capabilities.");
return 0;
}
if (strstr(xen_caps, "xen-3.0-x86_32p")) {
if (dsi->pae_kernel == PAEKERN_no) {
- ERROR("Non PAE-kernel on PAE host.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Non PAE-kernel on PAE host.");
return 0;
}
} else if (dsi->pae_kernel != PAEKERN_no) {
- ERROR("PAE-kernel on non-PAE host.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "PAE-kernel on non-PAE host.");
return 0;
}
@@ -1141,7 +1144,6 @@ static int xc_linux_build_internal(int x
console_evtchn, console_mfn,
features_bitmap) < 0 )
{
- ERROR("Error constructing guest OS");
goto error_out;
}
diff -r f7cff5d296bf -r aab2b3f739d2 tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/libxc/xc_load_elf.c Thu Dec 07 11:44:05 2006 +0000
@@ -29,20 +29,46 @@ loadelfsymtab(
*/
#if defined(__ia64__)
#define ELFCLASS ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
#define ELFDATA ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
#define ELFMACHINE EM_IA_64
+#define ELFMACHINE_DESC "ia64"
+
+
#elif defined(__i386__)
#define ELFCLASS ELFCLASS32
+#define ELFCLASS_DESC "32-bit"
+
#define ELFDATA ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
#define ELFMACHINE EM_386
+#define ELFMACHINE_DESC "i386"
+
+
#elif defined(__x86_64__)
#define ELFCLASS ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
#define ELFDATA ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
#define ELFMACHINE EM_X86_64
+#define ELFMACHINE_DESC "x86_64"
+
+
#elif defined(__powerpc__)
#define ELFCLASS ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
#define ELFDATA ELFDATA2MSB
+#define ELFDATA_DESC "Big-Endian"
+
#define ELFMACHINE EM_PPC64
+#define ELFMACHINE_DESC "ppc64"
#endif
int probe_elf(const char *image,
@@ -231,7 +257,8 @@ unsigned long long xen_elfnote_numeric(s
*defined = 1;
return *(uint64_t*)ELFNOTE_DESC(note);
default:
- ERROR("elfnotes: unknown data size %#x for numeric type note %#x\n",
+ xc_set_error(XC_INVALID_KERNEL,
+ "elfnotes: unknown data size %#x for numeric type note
%#x\n",
note->descsz, type);
return 0;
}
@@ -250,35 +277,59 @@ static int parseelfimage(const char *ima
if ( !IS_ELF(*ehdr) )
{
- ERROR("Kernel image does not have an ELF header.");
- return -EINVAL;
- }
-
- if ( (ehdr->e_ident[EI_CLASS] != ELFCLASS) ||
- (ehdr->e_machine != ELFMACHINE) ||
- (ehdr->e_ident[EI_DATA] != ELFDATA) ||
- (ehdr->e_type != ET_EXEC) )
- {
- ERROR("Kernel not a Xen-compatible Elf image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel image does not have an ELF header.");
+ return -EINVAL;
+ }
+
+ if (ehdr->e_machine != ELFMACHINE)
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel ELF architecture '%d' does not match Xen
architecture '%d' (%s)",
+ ehdr->e_machine, ELFMACHINE, ELFMACHINE_DESC);
+ return -EINVAL;
+ }
+ if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel ELF wordsize '%d' does not match Xen wordsize
'%d' (%s)",
+ ehdr->e_ident[EI_CLASS], ELFCLASS, ELFCLASS_DESC);
+ return -EINVAL;
+ }
+ if (ehdr->e_ident[EI_DATA] != ELFDATA)
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel ELF endianness '%d' does not match Xen endianness
'%d' (%s)",
+ ehdr->e_ident[EI_DATA], ELFDATA, ELFDATA_DESC);
+ return -EINVAL;
+ }
+ if (ehdr->e_type != ET_EXEC)
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel ELF type '%d' does not match Xen type '%d'",
+ ehdr->e_type, ET_EXEC);
return -EINVAL;
}
if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
{
- ERROR("ELF program headers extend beyond end of image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF program headers extend beyond end of image.");
return -EINVAL;
}
if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
{
- ERROR("ELF section headers extend beyond end of image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF section headers extend beyond end of image.");
return -EINVAL;
}
/* Find the section-header strings table. */
if ( ehdr->e_shstrndx == SHN_UNDEF )
{
- ERROR("ELF image has no section-header strings table (shstrtab).");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF image has no section-header strings table
(shstrtab).");
return -EINVAL;
}
shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
@@ -325,22 +376,25 @@ static int parseelfimage(const char *ima
if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
{
- ERROR("Will only load images built for the generic loader "
- "or Linux images");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Will only load images built for the generic loader "
+ "or Linux images");
return -EINVAL;
}
if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
{
- ERROR("Will only load images built for Xen v3.0");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Will only load images built for Xen v3.0");
return -EINVAL;
}
}
else
{
#if defined(__x86_64__) || defined(__i386__)
- ERROR("Not a Xen-ELF image: "
- "No ELF notes or '__xen_guest' section found.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Not a Xen-ELF image: "
+ "No ELF notes or '__xen_guest' section found.");
return -EINVAL;
#endif
}
@@ -396,8 +450,9 @@ static int parseelfimage(const char *ima
if ( elf_pa_off_defined && !virt_base_defined )
{
- ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
- " notes or __xen_guest section.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
+ " notes or __xen_guest section.");
return -EINVAL;
}
@@ -409,7 +464,8 @@ static int parseelfimage(const char *ima
vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
if ( (vaddr + phdr->p_memsz) < vaddr )
{
- ERROR("ELF program header %d is too large.", h);
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF program header %d is too large.", h);
return -EINVAL;
}
@@ -431,7 +487,8 @@ static int parseelfimage(const char *ima
(dsi->v_kernentry > kernend) ||
(dsi->v_start > kernstart) )
{
- ERROR("ELF start or entries are out of bounds.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF start or entries are out of bounds.");
return -EINVAL;
}
diff -r f7cff5d296bf -r aab2b3f739d2 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/libxc/xc_private.c Thu Dec 07 11:44:05 2006 +0000
@@ -7,6 +7,82 @@
#include <inttypes.h>
#include "xc_private.h"
#include "xg_private.h"
+
+#include <stdarg.h>
+
+static __thread xc_error last_error = { XC_ERROR_NONE, ""};
+#if DEBUG
+static xc_error_handler error_handler = xc_default_error_handler;
+#else
+static xc_error_handler error_handler = NULL;
+#endif
+
+void xc_default_error_handler(const xc_error const *err)
+{
+ const char *desc = xc_error_code_to_desc(err->code);
+ fprintf(stderr, "ERROR %s: %s\n", desc, err->message);
+}
+
+const xc_error const *xc_get_last_error(void)
+{
+ return &last_error;
+}
+
+void xc_clear_last_error(void)
+{
+ last_error.code = XC_ERROR_NONE;
+ last_error.message[0] = '\0';
+}
+
+const char *xc_error_code_to_desc(int code)
+{
+ /* Sync to members of xc_error_code enumeration in xenctrl.h */
+ switch ( code )
+ {
+ case XC_ERROR_NONE:
+ return "No error details";
+ case XC_INTERNAL_ERROR:
+ return "Internal error";
+ case XC_INVALID_KERNEL:
+ return "Invalid kernel";
+ }
+
+ return "Unknown error code";
+}
+
+xc_error_handler xc_set_error_handler(xc_error_handler handler)
+{
+ xc_error_handler old = error_handler;
+ error_handler = handler;
+ return old;
+}
+
+
+static void _xc_set_error(int code, const char *msg)
+{
+ last_error.code = code;
+ strncpy(last_error.message, msg, XC_MAX_ERROR_MSG_LEN - 1);
+ last_error.message[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+}
+
+void xc_set_error(int code, const char *fmt, ...)
+{
+ int saved_errno = errno;
+ char msg[XC_MAX_ERROR_MSG_LEN];
+ va_list args;
+
+ va_start(args, fmt);
+ vsnprintf(msg, XC_MAX_ERROR_MSG_LEN-1, fmt, args);
+ msg[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+ va_end(args);
+
+ _xc_set_error(code, msg);
+
+ errno = saved_errno;
+
+ if ( error_handler != NULL )
+ error_handler(&last_error);
+}
int lock_pages(void *addr, size_t len)
{
diff -r f7cff5d296bf -r aab2b3f739d2 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/libxc/xc_private.h Thu Dec 07 11:44:05 2006 +0000
@@ -59,23 +59,14 @@
#define PPRINTF(_f, _a...)
#endif
-#define ERROR(_m, _a...) \
-do { \
- int __saved_errno = errno; \
- DPRINTF("ERROR: " _m "\n" , ## _a ); \
- errno = __saved_errno; \
-} while (0)
+void xc_set_error(int code, const char *fmt, ...);
+
+#define ERROR(_m, _a...) xc_set_error(XC_INTERNAL_ERROR, _m , ## _a )
+#define PERROR(_m, _a...) xc_set_error(XC_INTERNAL_ERROR, _m " (%d = %s)", \
+ _m , ## _a , errno, strerror(errno))
int lock_pages(void *addr, size_t len);
void unlock_pages(void *addr, size_t len);
-
-#define PERROR(_m, _a...) \
-do { \
- int __saved_errno = errno; \
- DPRINTF("ERROR: " _m " (%d = %s)\n" , ## _a , \
- __saved_errno, strerror(__saved_errno)); \
- errno = __saved_errno; \
-} while (0)
static inline void safe_munlock(const void *addr, size_t len)
{
diff -r f7cff5d296bf -r aab2b3f739d2 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/libxc/xenctrl.h Thu Dec 07 11:44:05 2006 +0000
@@ -682,4 +682,46 @@ int xc_hvm_set_pci_link_route(
int xc_hvm_set_pci_link_route(
int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
+
+typedef enum {
+ XC_ERROR_NONE = 0,
+ XC_INTERNAL_ERROR = 1,
+ XC_INVALID_KERNEL = 2,
+} xc_error_code;
+
+#define XC_MAX_ERROR_MSG_LEN 1024
+typedef struct {
+ int code;
+ char message[XC_MAX_ERROR_MSG_LEN];
+} xc_error;
+
+/*
+ * Return a pointer to the last error. This pointer and the
+ * data pointed to are only valid until the next call to
+ * libxc.
+ */
+const xc_error const *xc_get_last_error(void);
+
+/*
+ * Clear the last error
+ */
+void xc_clear_last_error(void);
+
+typedef void (*xc_error_handler)(const xc_error const* err);
+
+/*
+ * The default error handler which prints to stderr
+ */
+void xc_default_error_handler(const xc_error const* err);
+
+/*
+ * Convert an error code into a text description
+ */
+const char *xc_error_code_to_desc(int code);
+
+/*
+ * Registers a callback to handle errors
+ */
+xc_error_handler xc_set_error_handler(xc_error_handler handler);
+
#endif
diff -r f7cff5d296bf -r aab2b3f739d2 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/python/xen/lowlevel/xc/xc.c Thu Dec 07 11:44:05 2006 +0000
@@ -29,7 +29,7 @@
#define PKG "xen.lowlevel.xc"
#define CLS "xc"
-static PyObject *xc_error, *zero;
+static PyObject *xc_error_obj, *zero;
typedef struct {
PyObject_HEAD;
@@ -40,6 +40,23 @@ static PyObject *dom_op(XcObject *self,
static PyObject *dom_op(XcObject *self, PyObject *args,
int (*fn)(int, uint32_t));
+static PyObject *pyxc_error_to_exception(void)
+{
+ PyObject *pyerr;
+ const xc_error const *err = xc_get_last_error();
+ const char *desc = xc_error_code_to_desc(err->code);
+
+ if (err->message[1])
+ pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
+ else
+ pyerr = Py_BuildValue("(is)", err->code, desc);
+
+ xc_clear_last_error();
+
+ PyErr_SetObject(xc_error_obj, pyerr);
+
+ return NULL;
+}
static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
{
@@ -53,7 +70,7 @@ static PyObject *pyxc_domain_dumpcore(Xc
return NULL;
if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -101,13 +118,13 @@ static PyObject *pyxc_domain_create(XcOb
if ( (ret = xc_domain_create(self->xc_handle, ssidref,
handle, flags, &dom)) < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return PyInt_FromLong(dom);
out_exception:
errno = EINVAL;
- PyErr_SetFromErrno(xc_error);
+ PyErr_SetFromErrno(xc_error_obj);
return NULL;
}
@@ -119,7 +136,7 @@ static PyObject *pyxc_domain_max_vcpus(X
return NULL;
if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -164,7 +181,7 @@ static PyObject *pyxc_vcpu_setaffinity(X
}
if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -184,7 +201,7 @@ static PyObject *pyxc_domain_setcpuweigh
return NULL;
if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -215,14 +232,13 @@ static PyObject *pyxc_domain_sethandle(X
}
if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
out_exception:
- errno = EINVAL;
- PyErr_SetFromErrno(xc_error);
+ PyErr_SetFromErrno(xc_error_obj);
return NULL;
}
@@ -251,7 +267,7 @@ static PyObject *pyxc_domain_getinfo(XcO
if (nr_doms < 0)
{
free(info);
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
}
list = PyList_New(nr_doms);
@@ -306,10 +322,10 @@ static PyObject *pyxc_vcpu_getinfo(XcObj
rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
if ( rc < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
if ( rc < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
"online", info.online,
@@ -360,9 +376,7 @@ static PyObject *pyxc_linux_build(XcObje
ramdisk, cmdline, features, flags,
store_evtchn, &store_mfn,
console_evtchn, &console_mfn) != 0 ) {
- if (!errno)
- errno = EINVAL;
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
}
return Py_BuildValue("{s:i,s:i}",
"store_mfn", store_mfn,
@@ -389,14 +403,14 @@ static PyObject *pyxc_hvm_build(XcObject
return NULL;
if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
/* Set up the HVM info table. */
va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
PROT_READ | PROT_WRITE,
HVM_INFO_PFN);
if ( va_map == NULL )
- return PyErr_SetFromErrno(xc_error);
+ return PyErr_SetFromErrno(xc_error_obj);
va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
memset(va_hvm, 0, sizeof(*va_hvm));
strncpy(va_hvm->signature, "HVM INFO", 8);
@@ -431,7 +445,7 @@ static PyObject *pyxc_evtchn_alloc_unbou
return NULL;
if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) <
0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return PyInt_FromLong(port);
}
@@ -452,7 +466,7 @@ static PyObject *pyxc_physdev_pci_access
ret = xc_physdev_pci_access_modify(
self->xc_handle, dom, bus, dev, func, enable);
if ( ret != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -474,7 +488,7 @@ static PyObject *pyxc_readconsolering(Xc
ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
if ( ret < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return PyString_FromStringAndSize(str, count);
}
@@ -504,7 +518,7 @@ static PyObject *pyxc_physinfo(XcObject
int i;
if ( xc_physinfo(self->xc_handle, &info) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
*q=0;
for(i=0;i<sizeof(info.hw_cap)/4;i++)
@@ -542,25 +556,25 @@ static PyObject *pyxc_xeninfo(XcObject *
xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) !=
0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
if (xen_pagesize < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
"xen_major", xen_version >> 16,
@@ -593,7 +607,7 @@ static PyObject *pyxc_sedf_domain_set(Xc
return NULL;
if ( xc_sedf_domain_set(self->xc_handle, domid, period,
slice, latency, extratime,weight) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -610,7 +624,7 @@ static PyObject *pyxc_sedf_domain_get(Xc
if (xc_sedf_domain_get(self->xc_handle, domid, &period,
&slice,&latency,&extratime,&weight))
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
"domid", domid,
@@ -638,7 +652,7 @@ static PyObject *pyxc_shadow_control(PyO
if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
< 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -668,7 +682,7 @@ static PyObject *pyxc_shadow_mem_control
op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
}
if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
mbarg = mb;
return Py_BuildValue("i", mbarg);
@@ -678,7 +692,7 @@ static PyObject *pyxc_sched_id_get(XcObj
int sched_id;
if (xc_sched_id(self->xc_handle, &sched_id) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return PyErr_SetFromErrno(xc_error_obj);
return Py_BuildValue("i", sched_id);
}
@@ -704,7 +718,7 @@ static PyObject *pyxc_sched_credit_domai
sdom.cap = cap;
if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -719,7 +733,7 @@ static PyObject *pyxc_sched_credit_domai
return NULL;
if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return Py_BuildValue("{s:H,s:H}",
"weight", sdom.weight,
@@ -735,7 +749,7 @@ static PyObject *pyxc_domain_setmaxmem(X
return NULL;
if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -762,7 +776,7 @@ static PyObject *pyxc_domain_memory_incr
if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
nr_extents, extent_order,
address_bits, NULL) )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -784,7 +798,7 @@ static PyObject *pyxc_domain_ioport_perm
ret = xc_domain_ioport_permission(
self->xc_handle, dom, first_port, nr_ports, allow_access);
if ( ret != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -807,7 +821,7 @@ static PyObject *pyxc_domain_irq_permiss
ret = xc_domain_irq_permission(
xc->xc_handle, dom, pirq, allow_access);
if ( ret != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -830,7 +844,7 @@ static PyObject *pyxc_domain_iomem_permi
ret = xc_domain_iomem_permission(
xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
if ( ret != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -870,7 +884,7 @@ static PyObject *dom_op(XcObject *self,
return NULL;
if (fn(self->xc_handle, dom) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
@@ -1199,7 +1213,7 @@ PyXc_init(XcObject *self, PyObject *args
PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
{
if ((self->xc_handle = xc_interface_open()) == -1) {
- PyErr_SetFromErrno(xc_error);
+ pyxc_error_to_exception();
return -1;
}
@@ -1272,7 +1286,7 @@ PyMODINIT_FUNC initxc(void)
if (m == NULL)
return;
- xc_error = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
+ xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
zero = PyInt_FromLong(0);
/* KAF: This ensures that we get debug output in a timely manner. */
@@ -1282,8 +1296,8 @@ PyMODINIT_FUNC initxc(void)
Py_INCREF(&PyXcType);
PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
- Py_INCREF(xc_error);
- PyModule_AddObject(m, "Error", xc_error);
+ Py_INCREF(xc_error_obj);
+ PyModule_AddObject(m, "Error", xc_error_obj);
/* Expose some libxc constants to Python */
PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
diff -r f7cff5d296bf -r aab2b3f739d2 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py Thu Dec 07 11:41:38 2006 +0000
+++ b/tools/python/xen/xend/server/blkif.py Thu Dec 07 11:44:05 2006 +0000
@@ -124,6 +124,8 @@ class BlkifController(DevController):
config['dev'] = dev
if typ and params:
config['uname'] = typ +':' + params
+ else:
+ config['uname'] = None
if mode:
config['mode'] = mode
if uuid:
diff -r f7cff5d296bf -r aab2b3f739d2 xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S Thu Dec 07 11:41:38 2006 +0000
+++ b/xen/arch/x86/boot/x86_32.S Thu Dec 07 11:44:05 2006 +0000
@@ -1,4 +1,5 @@
#include <xen/config.h>
+#include <xen/multiboot.h>
#include <public/xen.h>
#include <asm/asm_defns.h>
#include <asm/desc.h>
@@ -17,12 +18,14 @@ ENTRY(_stext)
.align 4
/*** MULTIBOOT HEADER ****/
+#define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_HEADER_MODS_ALIGNED | \
+ MULTIBOOT_HEADER_WANT_MEMORY)
/* Magic number indicating a Multiboot header. */
- .long 0x1BADB002
+ .long MULTIBOOT_HEADER_MAGIC
/* Flags to bootloader (see Multiboot spec). */
- .long 0x00000003
+ .long MULTIBOOT_HEADER_FLAGS
/* Checksum: must be the negated sum of the first two fields. */
- .long -0x1BADB005
+ .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
not_multiboot_msg:
.asciz "ERR: Not a Multiboot bootloader!"
diff -r f7cff5d296bf -r aab2b3f739d2 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S Thu Dec 07 11:41:38 2006 +0000
+++ b/xen/arch/x86/boot/x86_64.S Thu Dec 07 11:44:05 2006 +0000
@@ -1,4 +1,5 @@
#include <xen/config.h>
+#include <xen/multiboot.h>
#include <public/xen.h>
#include <asm/asm_defns.h>
#include <asm/desc.h>
@@ -19,12 +20,14 @@ ENTRY(_stext)
.org 0x004
/*** MULTIBOOT HEADER ****/
+#define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_HEADER_MODS_ALIGNED | \
+ MULTIBOOT_HEADER_WANT_MEMORY)
/* Magic number indicating a Multiboot header. */
- .long 0x1BADB002
+ .long MULTIBOOT_HEADER_MAGIC
/* Flags to bootloader (see Multiboot spec). */
- .long 0x00000003
+ .long MULTIBOOT_HEADER_FLAGS
/* Checksum: must be the negated sum of the first two fields. */
- .long -0x1BADB005
+ .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
.Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
.Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
diff -r f7cff5d296bf -r aab2b3f739d2 xen/include/xen/multiboot.h
--- a/xen/include/xen/multiboot.h Thu Dec 07 11:41:38 2006 +0000
+++ b/xen/include/xen/multiboot.h Thu Dec 07 11:44:05 2006 +0000
@@ -18,15 +18,29 @@
#ifndef __MULTIBOOT_H__
#define __MULTIBOOT_H__
+
+/*
+ * Multiboot header structure.
+ */
+#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
+#define MULTIBOOT_HEADER_MODS_ALIGNED 0x00000001
+#define MULTIBOOT_HEADER_WANT_MEMORY 0x00000002
+#define MULTIBOOT_HEADER_HAS_VBE 0x00000004
+#define MULTIBOOT_HEADER_HAS_ADDR 0x00010000
+
/* The magic number passed by a Multiboot-compliant boot loader. */
-#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
#define MBI_MEMLIMITS (1<<0)
#define MBI_DRIVES (1<<1)
#define MBI_CMDLINE (1<<2)
#define MBI_MODULES (1<<3)
+#define MBI_AOUT_SYMS (1<<4)
+#define MBI_ELF_SYMS (1<<5)
#define MBI_MEMMAP (1<<6)
#define MBI_LOADERNAME (1<<9)
+
+#ifndef __ASSEMBLY__
/* The symbol table for a.out. */
typedef struct {
@@ -47,16 +61,28 @@ typedef struct {
/* The Multiboot information. */
typedef struct {
u32 flags;
+
+ /* Valid if flags sets MBI_MEMLIMITS */
u32 mem_lower;
u32 mem_upper;
+
+ /* Valid if flags sets MBI_DRIVES */
u32 boot_device;
+
+ /* Valid if flags sets MBI_CMDLINE */
u32 cmdline;
+
+ /* Valid if flags sets MBI_MODULES */
u32 mods_count;
u32 mods_addr;
+
+ /* Valid if flags sets ... */
union {
- aout_symbol_table_t aout_sym;
- elf_section_header_table_t elf_sec;
+ aout_symbol_table_t aout_sym; /* ... MBI_AOUT_SYMS */
+ elf_section_header_table_t elf_sec; /* ... MBI_ELF_SYMS */
} u;
+
+ /* Valid if flags sets MBI_MEMMAP */
u32 mmap_length;
u32 mmap_addr;
} multiboot_info_t;
@@ -80,4 +106,7 @@ typedef struct {
u32 type;
} memory_map_t;
+
+#endif /* __ASSEMBLY__ */
+
#endif /* __MULTIBOOT_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|