From f64134cdb81cfd4da7ab674a863eb976f5bf5669 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 09:22:06 +0100 Subject: [PATCH 1/9] x86: Fix time_resume() to notify all domains of wallclock change. Signed-off-by: Keir Fraser --- xen/arch/x86/time.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 81e5598eae..78fe1d4bf2 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -957,14 +957,12 @@ int time_suspend(void) int time_resume(void) { - u64 now_sec, tmp = init_pit_and_calibrate_tsc(); + u64 tmp = init_pit_and_calibrate_tsc(); set_time_scale(&this_cpu(cpu_time).tsc_scale, tmp); resume_platform_timer(); - now_sec = read_platform_stime(); - do_div(now_sec, SECONDS(1)); - wc_sec = get_cmos_time() - now_sec; + do_settime(get_cmos_time(), 0, read_platform_stime()); init_percpu_time(); From b2023adb2e06555b6ab32541fb1d87824d2c216f Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 11:04:27 +0100 Subject: [PATCH 2/9] x86: Fix VBE EDID interrogation. Add a new boot option 'edid={no,force}'. Signed-off-by: Keir Fraser --- docs/src/user.tex | 7 ++++ xen/arch/x86/boot/cmdline.S | 69 ++++++++++++++++++++++++++++--------- xen/arch/x86/boot/video.S | 44 ++++++++++++----------- xen/arch/x86/setup.c | 36 +++++++++++++++++-- 4 files changed, 115 insertions(+), 41 deletions(-) diff --git a/docs/src/user.tex b/docs/src/user.tex index f93fcab4fa..64b0fa4c1a 100644 --- a/docs/src/user.tex +++ b/docs/src/user.tex @@ -3188,6 +3188,13 @@ editing \path{grub.conf}. \end{description} The mode may optionally be followed by `{\bf,keep}' to cause Xen to keep writing to the VGA console after domain 0 starts booting (e.g., `vga=text-80x50,keep'). +\item [ no-real-mode ] (x86 only) Do not execute real-mode bootstrap + code when booting Xen. This option should not be used except for + debugging. It will effectively disable the {\bf vga} option, which + relies on real mode to set the video mode. +\item [ edid=no,force ] (x86 only) Either force retrieval of monitor + EDID information via VESA DDC, or disable it (edid=no). This option + should not normally be required except for debugging purposes. \item [ console\_to\_ring ] Place guest console output into the hypervisor console ring buffer. This is disabled by default. When enabled, both hypervisor output and guest console output diff --git a/xen/arch/x86/boot/cmdline.S b/xen/arch/x86/boot/cmdline.S index bbbaed83b2..45798dda65 100644 --- a/xen/arch/x86/boot/cmdline.S +++ b/xen/arch/x86/boot/cmdline.S @@ -157,10 +157,10 @@ cmdline_parse_early: mov sym_phys(multiboot_ptr),%ebx mov MB_flags(%ebx),%eax test $4,%al - jz 1f + jz .Lcmdline_exit mov MB_cmdline(%ebx),%eax test %eax,%eax - jz 1f + jz .Lcmdline_exit /* Check for 'no-real-mode' command-line option. */ pushl $sym_phys(.Lno_rm_opt) @@ -169,14 +169,40 @@ cmdline_parse_early: test %eax,%eax setnz bootsym_phys(skip_realmode) + /* Check for 'edid=' command-line option. */ + movl $sym_phys(.Ledid_opt),4(%esp) + call .Lfind_option + test %eax,%eax + jz .Lparse_vga + cmpb $'=',4(%eax) + jne .Lparse_vga + add $5,%eax + mov %eax,%ebx + push %ebx + pushl $sym_phys(.Ledid_force) + call .Lstr_prefix + add $8,%esp + movb $2,bootsym_phys(opt_edid) /* opt_edid=2: edid=force */ + test %eax,%eax + jz .Lparse_vga + push %ebx + pushl $sym_phys(.Ledid_no) + call .Lstr_prefix + add $8,%esp + decb bootsym_phys(opt_edid) /* opt_edid=1: edid=no */ + test %eax,%eax + jz .Lparse_vga + decb bootsym_phys(opt_edid) /* opt_edid=0: default */ + +.Lparse_vga: /* Check for 'vga=' command-line option. */ movl $sym_phys(.Lvga_opt),4(%esp) call .Lfind_option add $8,%esp test %eax,%eax - jz 1f + jz .Lcmdline_exit cmpb $'=',3(%eax) - jne 1f + jne .Lcmdline_exit add $4,%eax /* Found the 'vga=' option. Default option is to display vga menu. */ @@ -189,7 +215,7 @@ cmdline_parse_early: call .Lstr_prefix add $8,%esp test %eax,%eax - jnz 3f + jnz .Lparse_vga_gfx /* We have 'vga=text-80x'. */ add $8,%ebx @@ -198,22 +224,23 @@ cmdline_parse_early: add $4,%esp mov %ax,%bx lea sym_phys(.Lvga_text_modes),%esi -2: lodsw +1: lodsw test %ax,%ax - jz 1f + jz .Lcmdline_exit cmp %ax,%bx lodsw - jne 2b + jne 1b mov %ax,bootsym_phys(boot_vid_mode) - jmp 1f + jmp .Lcmdline_exit +.Lparse_vga_gfx: /* Check for 'vga=gfx-xx'. */ -3: push %ebx + push %ebx pushl $sym_phys(.Lvga_gfx) call .Lstr_prefix add $8,%esp test %eax,%eax - jnz 3f + jnz .Lparse_vga_mode /* We have 'vga=gfx-xx'. */ /* skip 'gfx-' */ @@ -226,7 +253,7 @@ cmdline_parse_early: /* skip 'x' */ lodsb cmpb $'x',%al - jne 1f + jne .Lcmdline_exit /* parse */ push %esi call .Latoi @@ -235,7 +262,7 @@ cmdline_parse_early: /* skip 'x' */ lodsb cmpb $'x',%al - jne 1f + jne .Lcmdline_exit /* parse */ push %esi call .Latoi @@ -243,15 +270,16 @@ cmdline_parse_early: mov %ax,bootsym_phys(vesa_size)+4 /* commit to vesa mode */ movw $VIDEO_VESA_BY_SIZE,bootsym_phys(boot_vid_mode) - jmp 1f + jmp .Lcmdline_exit +.Lparse_vga_mode: /* Check for 'vga=mode-'. */ -3: push %ebx + push %ebx pushl $sym_phys(.Lvga_mode) call .Lstr_prefix add $8,%esp test %eax,%eax - jnz 1f + jnz .Lcmdline_exit /* We have 'vga=mode-'. */ add $5,%ebx @@ -260,7 +288,8 @@ cmdline_parse_early: add $4,%esp mov %ax,bootsym_phys(boot_vid_mode) -1: popa +.Lcmdline_exit: + popa ret .Lvga_text_modes: /* rows, mode_number */ @@ -283,3 +312,9 @@ cmdline_parse_early: .asciz "mode-" .Lno_rm_opt: .asciz "no-real-mode" +.Ledid_opt: + .asciz "edid" +.Ledid_force: + .asciz "force" +.Ledid_no: + .asciz "no" diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S index 03ce6ab578..e4c45298a8 100644 --- a/xen/arch/x86/boot/video.S +++ b/xen/arch/x86/boot/video.S @@ -882,27 +882,18 @@ gettime: store_edid: #ifdef CONFIG_FIRMWARE_EDID - pushw %es # just save all registers pushw %ax pushw %bx pushw %cx pushw %dx pushw %di - pushw %fs - popw %es - - movl $0x13131313, %eax # memset block with 0x13 - movw $32, %cx - movw $0x140, %di - cld - rep - stosl + cmpb $1, bootsym(opt_edid) # EDID disabled on cmdline (edid=no)? + je .Lno_edid cmpw $0x0200, bootsym(vbe_version) # only do EDID on >= VBE2.0 - jl no_edid + jl .Lno_edid - pushw %es # save ES xorw %di, %di # Report Capability pushw %di popw %es # ES:DI must be 0:0 @@ -910,31 +901,40 @@ store_edid: xorw %bx, %bx xorw %cx, %cx int $0x10 - popw %es # restore ES + cmpw $0x004f, %ax # Call failed? + jne .Lno_edid - cmpb $0x00, %ah # call successful - jne no_edid + movw %bx, bootsym(boot_edid_caps) - cmpb $0x4f, %al # function supported - jne no_edid + cmpb $2, bootsym(opt_edid) # EDID forced on cmdline (edid=force)? + je .Lforce_edid + /* EDID not forced on cmdline, so perform further sanity checks. */ + testb $3,%bl # No DDC capabilities? + jz .Lno_edid + cmpb $5,%bh # Longer than 5s to read EDID? + ja .Lno_edid + +.Lforce_edid: movw $0x4f15, %ax # do VBE/DDC movw $0x01, %bx movw $0x00, %cx movw $0x00, %dx - movw $0x140, %di + pushw %ds + popw %es + movw $bootsym(boot_edid_info), %di int $0x10 -no_edid: +.Lno_edid: popw %di # restore all registers popw %dx popw %cx popw %bx popw %ax - popw %es #endif ret +opt_edid: .byte 0 # EDID parsing option (force/no/default) mt_end: .word 0 # End of video mode table if built edit_buf: .space 6 # Line editor buffer card_name: .word 0 # Pointer to adapter name @@ -983,7 +983,7 @@ force_size: .word 0 # Use this size instead of the one in BIOS vars vesa_size: .word 0,0,0 # width x depth x height - .globl boot_vid_info + .globl boot_vid_info, boot_edid_info, boot_edid_caps /* If we don't run at all, assume basic video mode 3 at 80x25. */ boot_vid_mode: .word VIDEO_80x25 boot_vid_info: .byte 0, 0 /* orig_x, orig_y */ @@ -992,3 +992,5 @@ boot_vid_info: .byte 0, 0 /* orig_x, orig_y */ .byte 1 /* isVGA */ .word 16 /* 8x16 font */ .fill 0x28,1,0 +boot_edid_info: .fill 128,1,0x13 +boot_edid_caps: .word 0x1313 diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index a942ab5c75..fbc9f4db52 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -47,6 +47,10 @@ extern void dmi_scan_machine(void); extern void generic_apic_probe(void); extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); +extern u16 boot_edid_caps; +extern u8 boot_edid_info[128]; +extern struct boot_video_info boot_vid_info; + /* * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the * page_info table and allocation bitmap. @@ -348,7 +352,6 @@ struct boot_video_info { static void __init parse_video_info(void) { - extern struct boot_video_info boot_vid_info; struct boot_video_info *bvi = &bootsym(boot_vid_info); if ( (bvi->orig_video_isVGA == 1) && (bvi->orig_video_mode == 3) ) @@ -444,20 +447,47 @@ void __init __start_xen(multiboot_info_t *mbi) printk("Command line: %s\n", cmdline); + printk("Video information:\n"); + + /* Print VGA display mode information. */ switch ( vga_console_info.video_type ) { case XEN_VGATYPE_TEXT_MODE_3: - printk("VGA is text mode %dx%d, font 8x%d\n", + printk(" VGA is text mode %dx%d, font 8x%d\n", vga_console_info.u.text_mode_3.columns, vga_console_info.u.text_mode_3.rows, vga_console_info.u.text_mode_3.font_height); break; case XEN_VGATYPE_VESA_LFB: - printk("VGA is graphics mode %dx%d, %d bpp\n", + printk(" VGA is graphics mode %dx%d, %d bpp\n", vga_console_info.u.vesa_lfb.width, vga_console_info.u.vesa_lfb.height, vga_console_info.u.vesa_lfb.bits_per_pixel); break; + default: + printk(" No VGA detected\n"); + break; + } + + /* Print VBE/DDC EDID information. */ + if ( bootsym(boot_edid_caps) != 0x1313 ) + { + u16 caps = bootsym(boot_edid_caps); + printk(" VBE/DDC methods:%s%s%s; ", + (caps & 1) ? " V1" : "", + (caps & 2) ? " V2" : "", + !(caps & 3) ? " none" : ""); + printk("EDID transfer time: %d seconds\n", caps >> 8); + if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 ) + { + printk(" EDID info not retrieved because "); + if ( !(caps & 3) ) + printk("no DDC retrieval method detected\n"); + else if ( (caps >> 8) > 5 ) + printk("takes longer than 5 seconds\n"); + else + printk("of reasons unknown\n"); + } } /* Check that we have at least one Multiboot module. */ From ea511d357e85dfe5dbcd71fe31428c06991f0754 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 11:26:51 +0100 Subject: [PATCH 3/9] tools: Clean up usage of const type qualifier. Signed-off-by: Keir Fraser --- tools/firmware/hvmloader/util.c | 2 +- tools/firmware/rombios/32bit/util.c | 2 +- tools/firmware/vmxassist/util.c | 4 ++-- tools/libxc/xc_private.c | 2 +- tools/libxc/xenctrl.h | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index dd69f80035..790cffa38f 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -405,7 +405,7 @@ static char *printnum(char *p, unsigned long num, int base) return p; } -static void _doprint(void (*put)(char), char const *fmt, va_list ap) +static void _doprint(void (*put)(char), const char *fmt, va_list ap) { register char *str, c; int lflag, zflag, nflag; diff --git a/tools/firmware/rombios/32bit/util.c b/tools/firmware/rombios/32bit/util.c index e177522795..25a450f8c9 100644 --- a/tools/firmware/rombios/32bit/util.c +++ b/tools/firmware/rombios/32bit/util.c @@ -290,7 +290,7 @@ static char *printnum(char *p, unsigned long num, int base) return p; } -static void _doprint(void (*put)(char), char const *fmt, va_list ap) +static void _doprint(void (*put)(char), const char *fmt, va_list ap) { register char *str, c; int lflag, zflag, nflag; diff --git a/tools/firmware/vmxassist/util.c b/tools/firmware/vmxassist/util.c index 2c4c016989..c7d71703ed 100644 --- a/tools/firmware/vmxassist/util.c +++ b/tools/firmware/vmxassist/util.c @@ -27,7 +27,7 @@ static void putchar(int); static char *printnum(char *, unsigned long, int); -static void _doprint(void (*)(int), char const *, va_list); +static void _doprint(void (*)(int), const char *, va_list); void cpuid_addr_value(uint64_t addr, uint64_t *value) @@ -321,7 +321,7 @@ putchar(int ch) * but still powerful enough for most tasks. */ static void -_doprint(void (*put)(int), char const *fmt, va_list ap) +_doprint(void (*put)(int), const char *fmt, va_list ap) { register char *str, c; int lflag, zflag, nflag; diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 9ac035f8af..cfb129ef9e 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -17,7 +17,7 @@ static xc_error_handler error_handler = xc_default_error_handler; static xc_error_handler error_handler = NULL; #endif -void xc_default_error_handler(const xc_error const *err) +void xc_default_error_handler(const xc_error *err) { const char *desc = xc_error_code_to_desc(err->code); fprintf(stderr, "ERROR %s: %s\n", desc, err->message); diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index db8b63b82f..df71417c7e 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -823,12 +823,12 @@ const xc_error *xc_get_last_error(void); */ void xc_clear_last_error(void); -typedef void (*xc_error_handler)(const xc_error * const err); +typedef void (*xc_error_handler)(const xc_error *err); /* * The default error handler which prints to stderr */ -void xc_default_error_handler(const xc_error * const err); +void xc_default_error_handler(const xc_error *err); /* * Convert an error code into a text description From e8299fcc5b663248d428ea405aa34ec9d35ebd60 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 11:29:27 +0100 Subject: [PATCH 4/9] Fix xm vcpu-pin command for keyword 'all'. The keyword 'all' was supported as the 2nd argument of xm vcpu-pin command since changeset 11619. However, we cannot use the keyword 'all' since changeset 14481. Signed-off-by: Masaki Kanno --- tools/python/xen/xm/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index bc27b6f9cd..d19a131972 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -140,7 +140,7 @@ SUBCOMMAND_HELP = { 'Send a trigger to a domain.'), 'vcpu-list' : ('[]', 'List the VCPUs for a domain or all domains.'), - 'vcpu-pin' : (' ', + 'vcpu-pin' : (' ', 'Set which CPUs a VCPU can use.'), 'vcpu-set' : (' ', 'Set the number of active VCPUs for allowed for the' @@ -1330,7 +1330,7 @@ def xm_vcpu_pin(args): return cpus dom = args[0] - vcpu = int(args[1]) + vcpu = args[1] if args[2] == 'all': cpumap = cpu_make_map('0-63') else: From ab053a8b3369584cb18c4aa2473cf88f56b0294f Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 11:32:03 +0100 Subject: [PATCH 5/9] [IA64] When a domU is destroyed, it will fall into NVRAM saving path. But if there is no NVRAM file for the domU, the save operation would fail. Then domU blocked by Xend's exception. This patch fixs that issue. Signed-off-by: Zhang Xin --- tools/libxc/ia64/xc_ia64_hvm_build.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tools/libxc/ia64/xc_ia64_hvm_build.c b/tools/libxc/ia64/xc_ia64_hvm_build.c index 0f41772fa1..522ec2d03c 100644 --- a/tools/libxc/ia64/xc_ia64_hvm_build.c +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c @@ -712,11 +712,15 @@ int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom) xc_get_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, &nvram_fd); if ( !IS_VALID_NVRAM_FD(nvram_fd) ) - { PERROR("Nvram not be initialized. Nvram save fail!\n"); - return -1; - } - return copy_from_GFW_to_nvram(xc_handle, dom, (int)nvram_fd); + else + copy_from_GFW_to_nvram(xc_handle, dom, (int)nvram_fd); + + // although save to nvram maybe fail, we don't return any error number + // to Xend. This is quite logical because damage of NVRAM on native would + // not block OS's executive path. Return error number will cause an exception + // of Xend and block XenU when it destroy. + return 0; } #define NVRAM_FILE_PATH "/usr/lib/xen/boot/nvram_" @@ -862,7 +866,10 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize, nvram_start = 0; else if ( copy_from_nvram_to_GFW(xc_handle, dom, (int)nvram_fd ) == -1 ) + { nvram_start = 0; + close(nvram_fd); + } vcpus = domctl.u.getdomaininfo.max_vcpu_id + 1; From ff2fc71eda783205e4eca61af1b60138251439cd Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 11:38:31 +0100 Subject: [PATCH 6/9] tools: warn_unused_result build fixes. Note that some of the existing error checking for asprintf was wrong for Linux. asprintf in glibc returns -1 on error, but leaves the pointer uninitialized. Only the BSDs zero out the pointer on error. Also, while fixing these warnings I saw several error paths that were incorrect. This patch minimally fixes the warn_unused_result; more complete error path cleanup will be a later patch. Signed-off-by: Charles Coffing --- tools/blktap/drivers/blktapctrl.c | 27 ++++++++++++------- tools/blktap/drivers/block-qcow.c | 7 +++-- tools/blktap/drivers/tapdisk.c | 3 ++- tools/blktap/lib/xenbus.c | 6 ++--- tools/blktap/lib/xs_api.c | 45 +++++++++++++++---------------- tools/console/daemon/io.c | 5 +++- 6 files changed, 53 insertions(+), 40 deletions(-) diff --git a/tools/blktap/drivers/blktapctrl.c b/tools/blktap/drivers/blktapctrl.c index aeec870af2..6613768654 100644 --- a/tools/blktap/drivers/blktapctrl.c +++ b/tools/blktap/drivers/blktapctrl.c @@ -143,7 +143,8 @@ static int get_new_dev(int *major, int *minor, blkif_t *blkif) return -1; } - asprintf(&devname,"%s/%s%d",BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, *minor); + if (asprintf(&devname,"%s/%s%d",BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, *minor) == -1) + return -1; make_blktap_dev(devname,*major,*minor); DPRINTF("Received device id %d and major %d, " "sent domid %d and be_id %d\n", @@ -495,20 +496,27 @@ int blktapctrl_new_blkif(blkif_t *blkif) if (!exist) { DPRINTF("Process does not exist:\n"); - asprintf(&rdctldev, - "%s/tapctrlread%d", BLKTAP_CTRL_DIR, minor); + if (asprintf(&rdctldev, + "%s/tapctrlread%d", BLKTAP_CTRL_DIR, minor) == -1) + return -1; + if (asprintf(&wrctldev, + "%s/tapctrlwrite%d", BLKTAP_CTRL_DIR, minor) == -1) { + free(rdctldev); + return -1; + } + if (asprintf(&cmd, "tapdisk %s %s", wrctldev, rdctldev) == -1) { + free(rdctldev); + free(wrctldev); + return -1; + } + blkif->fds[READ] = open_ctrl_socket(rdctldev); - - - asprintf(&wrctldev, - "%s/tapctrlwrite%d", BLKTAP_CTRL_DIR, minor); blkif->fds[WRITE] = open_ctrl_socket(wrctldev); if (blkif->fds[READ] == -1 || blkif->fds[WRITE] == -1) goto fail; /*launch the new process*/ - asprintf(&cmd, "tapdisk %s %s", wrctldev, rdctldev); DPRINTF("Launching process, CMDLINE [%s]\n",cmd); if (system(cmd) == -1) { DPRINTF("Unable to fork, cmdline: [%s]\n",cmd); @@ -692,7 +700,8 @@ int main(int argc, char *argv[]) register_new_unmap_hook(unmap_blktapctrl); /* Attach to blktap0 */ - asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME); + if (asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME) == -1) + goto open_failed; if ((ret = xc_find_device_number("blktap0")) < 0) { DPRINTF("couldn't find device number for 'blktap0'\n"); goto open_failed; diff --git a/tools/blktap/drivers/block-qcow.c b/tools/blktap/drivers/block-qcow.c index a1fab17c55..928e517ef5 100644 --- a/tools/blktap/drivers/block-qcow.c +++ b/tools/blktap/drivers/block-qcow.c @@ -871,7 +871,10 @@ int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags) } s->fd = fd; - asprintf(&s->name,"%s", name); + if (asprintf(&s->name,"%s", name) == -1) { + close(fd); + return -1; + } ASSERT(sizeof(QCowHeader) + sizeof(QCowHeader_ext) < 512); @@ -1165,7 +1168,7 @@ int tdqcow_close(struct disk_driver *dd) offset = sizeof(QCowHeader) + sizeof(uint32_t); lseek(fd, offset, SEEK_SET); out = cpu_to_be32(cksum); - write(fd, &out, sizeof(uint32_t)); + if (write(fd, &out, sizeof(uint32_t))) ; close(fd); } diff --git a/tools/blktap/drivers/tapdisk.c b/tools/blktap/drivers/tapdisk.c index 954901b2a8..94a4e48c30 100644 --- a/tools/blktap/drivers/tapdisk.c +++ b/tools/blktap/drivers/tapdisk.c @@ -220,7 +220,8 @@ static int map_new_dev(struct td_state *s, int minor) fd_list_entry_t *ptr; int page_size; - asprintf(&devname,"%s/%s%d", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, minor); + if (asprintf(&devname,"%s/%s%d", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, minor) == -1) + return -1; tap_fd = open(devname, O_RDWR); if (tap_fd == -1) { diff --git a/tools/blktap/lib/xenbus.c b/tools/blktap/lib/xenbus.c index fb36e748fe..53a3338f1e 100644 --- a/tools/blktap/lib/xenbus.c +++ b/tools/blktap/lib/xenbus.c @@ -360,8 +360,7 @@ int add_blockdevice_probe_watch(struct xs_handle *h, const char *domid) char *path; struct xenbus_watch *vbd_watch; - asprintf(&path, "/local/domain/%s/backend/tap", domid); - if (path == NULL) + if (asprintf(&path, "/local/domain/%s/backend/tap", domid) == -1) return -ENOMEM; vbd_watch = (struct xenbus_watch *)malloc(sizeof(struct xenbus_watch)); @@ -399,8 +398,7 @@ int watch_for_domid(struct xs_handle *h) struct xenbus_watch *domid_watch; char *path = NULL; - asprintf(&path, "/local/domain"); - if (path == NULL) + if (asprintf(&path, "/local/domain") == -1) return -ENOMEM; domid_watch = malloc(sizeof(struct xenbus_watch)); diff --git a/tools/blktap/lib/xs_api.c b/tools/blktap/lib/xs_api.c index 539d0e3c51..783b4ce3b3 100644 --- a/tools/blktap/lib/xs_api.c +++ b/tools/blktap/lib/xs_api.c @@ -126,10 +126,12 @@ int xs_printf(struct xs_handle *h, const char *dir, const char *node, ret = vasprintf(&buf, fmt, ap); va_end(ap); - asprintf(&path, "%s/%s", dir, node); - - if ((path == NULL) || (buf == NULL)) - return 0; + if (ret == -1) + return ENOMEM; + if (asprintf(&path, "%s/%s", dir, node) == -1) { + free(buf); + return ENOMEM; + } ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1); @@ -180,10 +182,11 @@ char *get_dom_domid(struct xs_handle *h) e = xs_directory(h, xth, "/local/domain", &num); if (e == NULL) - return NULL; + goto done; for (i = 0; (i < num) && (domid == NULL); i++) { - asprintf(&path, "/local/domain/%s/name", e[i]); + if (asprintf(&path, "/local/domain/%s/name", e[i]) == -1) + break; val = xs_read(h, xth, path, &len); free(path); if (val == NULL) @@ -191,29 +194,31 @@ char *get_dom_domid(struct xs_handle *h) if (strcmp(val, DOMNAME) == 0) { /* match! */ - asprintf(&path, "/local/domain/%s/domid", e[i]); + if (asprintf(&path, "/local/domain/%s/domid", e[i]) == -1) { + free(val); + break; + } domid = xs_read(h, xth, path, &len); free(path); } free(val); } +done: xs_transaction_end(h, xth, 0); - - free(e); + if (e) + free(e); return domid; } int convert_dev_name_to_num(char *name) { - char *p_sd, *p_hd, *p_xvd, *p_plx, *p, *alpha,*ptr; + char *p, *ptr; int majors[10] = {3,22,33,34,56,57,88,89,90,91}; int maj,i,ret = 0; - - asprintf(&p_sd,"/dev/sd"); - asprintf(&p_hd,"/dev/hd"); - asprintf(&p_xvd,"/dev/xvd"); - asprintf(&p_plx,"plx"); - asprintf(&alpha,"abcdefghijklmnop"); - + char *p_sd = "/dev/sd"; + char *p_hd = "/dev/hd"; + char *p_xvd = "/dev/xvd"; + char *p_plx = "plx"; + char *alpha = "abcdefghijklmnop"; if (strstr(name, p_sd) != NULL) { p = name + strlen(p_sd); @@ -251,12 +256,6 @@ int convert_dev_name_to_num(char *name) { ret = BASE_DEV_VAL; } - free(p_sd); - free(p_hd); - free(p_xvd); - free(p_plx); - free(alpha); - return ret; } diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index 92c57ec605..d67f4c3abd 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -303,7 +303,10 @@ int xs_gather(struct xs_handle *xs, const char *dir, ...) void *result = va_arg(ap, void *); char *p; - asprintf(&path, "%s/%s", dir, name); + if (asprintf(&path, "%s/%s", dir, name) == -1) { + ret = ENOMEM; + break; + } p = xs_read(xs, XBT_NULL, path, NULL); free(path); if (p == NULL) { From 1b0d4ab994bfcb2dda4cf4a0f0f385d1d6c90954 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 11:39:51 +0100 Subject: [PATCH 7/9] Fix fully-virtualized core dumps for 32-bit guests. Signed-off-by: Chris Lalancette --- tools/libxc/xc_core_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/libxc/xc_core_x86.c b/tools/libxc/xc_core_x86.c index b3d5d26fbf..3932f8e96b 100644 --- a/tools/libxc/xc_core_x86.c +++ b/tools/libxc/xc_core_x86.c @@ -49,7 +49,7 @@ xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info, } map->addr = 0; - map->size = p2m_size << PAGE_SHIFT; + map->size = ((uint64_t)p2m_size) << PAGE_SHIFT; *mapp = map; *nr_entries = 1; From 79e96982cade240531d7d84fa5b966b2b64c04af Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 14:03:09 +0100 Subject: [PATCH 8/9] x86: Gather BIOS EDD info during boot. Still needs plumbing to dom0. Signed-off-by: Keir Fraser --- xen/arch/x86/boot/Makefile | 2 +- xen/arch/x86/boot/cmdline.S | 20 ++++ xen/arch/x86/boot/edd.S | 161 +++++++++++++++++++++++++++++++++ xen/arch/x86/boot/trampoline.S | 9 +- xen/arch/x86/boot/video.S | 2 +- xen/arch/x86/setup.c | 7 ++ xen/include/asm-x86/edd.h | 44 +++++++++ 7 files changed, 240 insertions(+), 5 deletions(-) create mode 100644 xen/arch/x86/boot/edd.S create mode 100644 xen/include/asm-x86/edd.h diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index da74c8e89e..2083f253dd 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -1,3 +1,3 @@ obj-y += head.o -head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S cmdline.S +head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S cmdline.S edd.S diff --git a/xen/arch/x86/boot/cmdline.S b/xen/arch/x86/boot/cmdline.S index 45798dda65..34c183a268 100644 --- a/xen/arch/x86/boot/cmdline.S +++ b/xen/arch/x86/boot/cmdline.S @@ -169,6 +169,24 @@ cmdline_parse_early: test %eax,%eax setnz bootsym_phys(skip_realmode) +.Lparse_edd: + /* Check for 'edd=' command-line option. */ + movl $sym_phys(.Ledd_opt),4(%esp) + call .Lfind_option + test %eax,%eax + jz .Lparse_edid + cmpb $'=',3(%eax) + jne .Lparse_edid + add $4,%eax + movb $2,bootsym_phys(opt_edd) /* opt_edd=2: edd=off */ + cmpw $0x666f,(%eax) /* 0x666f == "of" */ + je .Lparse_edid + decb bootsym_phys(opt_edd) /* opt_edd=1: edd=skipmbr */ + cmpw $0x6b73,(%eax) /* 0x6b73 == "sk" */ + je .Lparse_edid + decb bootsym_phys(opt_edid) /* opt_edd=0: edd=on (default) */ + +.Lparse_edid: /* Check for 'edid=' command-line option. */ movl $sym_phys(.Ledid_opt),4(%esp) call .Lfind_option @@ -318,3 +336,5 @@ cmdline_parse_early: .asciz "force" .Ledid_no: .asciz "no" +.Ledd_opt: + .asciz "edd" diff --git a/xen/arch/x86/boot/edd.S b/xen/arch/x86/boot/edd.S new file mode 100644 index 0000000000..fcc8132e5e --- /dev/null +++ b/xen/arch/x86/boot/edd.S @@ -0,0 +1,161 @@ +/****************************************************************************** + * edd.S + * + * BIOS Enhanced Disk Drive support + * + * Copyright (C) 2002, 2003, 2004 Dell, Inc. + * by Matt Domsch October 2002 + * conformant to T13 Committee www.t13.org + * projects 1572D, 1484D, 1386D, 1226DT + * disk signature read by Matt Domsch + * and Andrew Wilks September 2003, June 2004 + * legacy CHS retrieval by Patrick J. LoPresti + * March 2004 + * Command line option parsing, Matt Domsch, November 2004 + * + * Updated and ported for Xen by Keir Fraser June 2007 + */ + + .code16 + +/* Offset of disc signature in the MBR. */ +#define EDD_MBR_SIG_OFFSET 0x1B8 + +/* Maximum number of EDD information structures at boot_edd_info. */ +#define EDD_INFO_MAX 6 + +/* Maximum number of MBR signatures at boot_edd_signature. */ +#define EDD_MBR_SIG_MAX 16 + +/* Size of components of EDD information structure. */ +#define EDDEXTSIZE 8 +#define EDDPARMSIZE 74 + +get_edd: + cmpb $2, bootsym(opt_edd) # edd=off ? + je edd_done + cmpb $1, bootsym(opt_edd) # edd=skipmbr ? + je edd_start + +# Read the first sector of each BIOS disk device and store the 4-byte signature +edd_mbr_sig_start: + movb $0x80, %dl # from device 80 + movw $bootsym(boot_edd_signature),%bx # store buffer ptr in bx +edd_mbr_sig_read: + movl $0xFFFFFFFF, %eax + movl %eax, (%bx) # assume failure + pushw %bx + movb $0x02, %ah # 0x02 Read Sectors + movb $1, %al # read 1 sector + movb $0, %dh # at head 0 + movw $1, %cx # cylinder 0, sector 0 + pushw %es + pushw %ds + popw %es + movw $bootsym(boot_edd_info), %bx # disk's data goes into info + pushw %dx # work around buggy BIOSes + stc # work around buggy BIOSes + int $0x13 + sti # work around buggy BIOSes + popw %dx + popw %es + popw %bx + jc edd_mbr_sig_done # on failure, we're done. + cmpb $0, %ah # some BIOSes do not set CF + jne edd_mbr_sig_done # on failure, we're done. + movl bootsym(boot_edd_info)+EDD_MBR_SIG_OFFSET,%eax + movl %eax, (%bx) # store signature from MBR + incb bootsym(boot_edd_signature_nr) # note that we stored something + incb %dl # increment to next device + addw $4, %bx # increment sig buffer ptr + cmpb $EDD_MBR_SIG_MAX,bootsym(boot_edd_signature_nr) + jb edd_mbr_sig_read +edd_mbr_sig_done: + +# Do the BIOS Enhanced Disk Drive calls +# This consists of two calls: +# int 13h ah=41h "Check Extensions Present" +# int 13h ah=48h "Get Device Parameters" +# int 13h ah=08h "Legacy Get Device Parameters" +# +# A buffer of size EDD_INFO_MAX*(EDDEXTSIZE+EDDPARMSIZE) is reserved at +# boot_edd_info, the first four bytes of which are used to store the device +# number, interface support map and version results from fn41. The next four +# bytes are used to store the legacy cylinders, heads, and sectors from fn08. +# The following 74 bytes are used to store the results from fn48. +# This code is sensitive to the size of the structs in edd.h +edd_start: + /* ds:si points at fn48 results. Fn41 results go immediately before. */ + movw $bootsym(boot_edd_info)+EDDEXTSIZE, %si + movb $0x80, %dl # BIOS device 0x80 + +edd_check_ext: + movb $0x41, %ah # 0x41 Check Extensions Present + movw $0x55AA, %bx # magic + int $0x13 # make the call + jc edd_done # no more BIOS devices + + cmpw $0xAA55, %bx # is magic right? + jne edd_next # nope, next... + + movb %dl, %ds:-8(%si) # store device number + movb %ah, %ds:-7(%si) # store version + movw %cx, %ds:-6(%si) # store extensions + incb bootsym(boot_edd_info_nr) # note that we stored something + +edd_get_device_params: + movw $EDDPARMSIZE, %ds:(%si) # put size + movw $0x0, %ds:2(%si) # work around buggy BIOSes + movb $0x48, %ah # 0x48 Get Device Parameters + int $0x13 # make the call + # Don't check for fail return + # it doesn't matter. +edd_get_legacy_chs: + xorw %ax, %ax + movw %ax, %ds:-4(%si) + movw %ax, %ds:-2(%si) + # Ralf Brown's Interrupt List says to set ES:DI to + # 0000h:0000h "to guard against BIOS bugs" + pushw %es + movw %ax, %es + movw %ax, %di + pushw %dx # legacy call clobbers %dl + movb $0x08, %ah # 0x08 Legacy Get Device Params + int $0x13 # make the call + jc edd_legacy_done # failed + movb %cl, %al # Low 6 bits are max + andb $0x3F, %al # sector number + movb %al, %ds:-1(%si) # Record max sect + movb %dh, %ds:-2(%si) # Record max head number + movb %ch, %al # Low 8 bits of max cyl + shr $6, %cl + movb %cl, %ah # High 2 bits of max cyl + movw %ax, %ds:-4(%si) + +edd_legacy_done: + popw %dx + popw %es + movw %si, %ax # increment si + addw $EDDPARMSIZE+EDDEXTSIZE, %ax + movw %ax, %si + +edd_next: + incb %dl # increment to next device + cmpb $EDD_INFO_MAX,bootsym(boot_edd_info_nr) + jb edd_check_ext + +edd_done: + ret + +opt_edd: + .byte 0 # edd=on/off/skipmbr + +.globl boot_edd_info_nr, boot_edd_signature_nr +boot_edd_info_nr: + .byte 0 +boot_edd_signature_nr: + .byte 0 +boot_edd_signature: + .fill EDD_MBR_SIG_MAX*4,1,0 +boot_edd_info: + .fill 512,1,0 # big enough for a disc sector diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S index ed63518b40..492d42aaab 100644 --- a/xen/arch/x86/boot/trampoline.S +++ b/xen/arch/x86/boot/trampoline.S @@ -142,17 +142,19 @@ trampoline_boot_cpu_entry: mov %ax,%es mov %ax,%ss - /* Stack grows down from 0x9200. Initialise IDT and enable irqs. */ - mov $0x2000,%sp + /* Stack grows down from 0x93000. Initialise IDT and enable irqs. */ + mov $0x3000,%sp lidt bootsym(rm_idt) sti /* * Do real-mode work: * 1. Get memory map. - * 2. Set video mode. + * 2. Get Enhanced Disk Drive (EDD) information. + * 3. Set video mode. */ call get_memory_map + call get_edd call video /* Disable irqs before returning to protected mode. */ @@ -187,4 +189,5 @@ skip_realmode: rm_idt: .word 256*4-1, 0, 0 #include "mem.S" +#include "edd.S" #include "video.S" diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S index e4c45298a8..d8b3fab537 100644 --- a/xen/arch/x86/boot/video.S +++ b/xen/arch/x86/boot/video.S @@ -15,7 +15,7 @@ #include "video.h" -#define modelist (0x2000) +#define modelist (0x3000) /* Retrieve Extended Display Identification Data. */ #define CONFIG_FIRMWARE_EDID diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index fbc9f4db52..779b7fb37d 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -34,6 +34,7 @@ #include #include #include +#include #if defined(CONFIG_X86_64) #define BOOTSTRAP_DIRECTMAP_END (1UL << 32) @@ -490,6 +491,12 @@ void __init __start_xen(multiboot_info_t *mbi) } } + printk("Disc information:\n"); + printk(" Found %d MBR signatures\n", + bootsym(boot_edd_signature_nr)); + printk(" Found %d EDD information structures\n", + bootsym(boot_edd_info_nr)); + /* Check that we have at least one Multiboot module. */ if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) ) EARLY_FAIL("dom0 kernel not specified. " diff --git a/xen/include/asm-x86/edd.h b/xen/include/asm-x86/edd.h new file mode 100644 index 0000000000..4079dafe09 --- /dev/null +++ b/xen/include/asm-x86/edd.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * edd.h + * + * Copyright (C) 2002, 2003, 2004 Dell Inc. + * by Matt Domsch + * + * structures and definitions for the int 13h, ax={41,48}h + * BIOS Enhanced Disk Drive Services + * This is based on the T13 group document D1572 Revision 0 (August 14 2002) + * available at http://www.t13.org/docs2002/d1572r0.pdf. It is + * very similar to D1484 Revision 3 http://www.t13.org/docs2002/d1484r3.pdf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2.0 as published by + * the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __XEN_EDD_H__ +#define __XEN_EDD_H__ + +struct edd_info { + /* Int13, Fn48: Check Extensions Present. */ + u8 device; /* %dl: device */ + u8 version; /* %ah: major version */ + u16 interface_support; /* %cx: interface support bitmap */ + /* Int13, Fn08: Legacy Get Device Parameters. */ + u16 legacy_max_cylinder; /* %cl[7:6]:%ch: maximum cylinder number */ + u8 legacy_max_head; /* %dh: maximum head number */ + u8 legacy_sectors_per_track; /* %cl[5:0]: maximum sector number */ + /* Int13, Fn41: Get Device Parameters */ + u8 edd_device_params[74]; /* as filled into %ds:%si */ +} __attribute__ ((packed)); + +extern u32 boot_edd_signature[]; +extern u8 boot_edd_signature_nr; +extern struct edd_info boot_edd_info[]; +extern u8 boot_edd_info_nr; + +#endif /* __XEN_EDD_H__ */ From d46dd79904bf6ac05570d24bd11166d6b1043889 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 12 Jun 2007 14:06:37 +0100 Subject: [PATCH 9/9] x86: Initialise %ds when booting APs, otherwise data accesses go to the wrong place. Signed-off-by: Kevin Tian Signed-off-by: Keir Fraser --- xen/arch/x86/boot/trampoline.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S index 492d42aaab..b76a25a3e7 100644 --- a/xen/arch/x86/boot/trampoline.S +++ b/xen/arch/x86/boot/trampoline.S @@ -6,11 +6,13 @@ .globl trampoline_realmode_entry trampoline_realmode_entry: + mov %cs,%ax + mov %ax,%ds movb $0xA5,bootsym(trampoline_cpu_started) cld cli - lidt %cs:bootsym(idt_48) - lgdt %cs:bootsym(gdt_48) + lidt bootsym(idt_48) + lgdt bootsym(gdt_48) xor %ax, %ax inc %ax lmsw %ax # CR0.PE = 1 (enter protected mode)