Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
xen.3265
kernel-boot-hvm.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File kernel-boot-hvm.patch of Package xen.3265
Direct kernel boot to HVM guests has regression from xen-3.3 to xen-4.0. Foreport this feature to latest qemu-xen. Make a fake boot sector with given kernel and initrd, which could be accessed by hvmloader. Signed-off-by: Chunyan Liu <cyliu@novell.com> Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.c =================================================================== --- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block.c +++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.c @@ -596,6 +596,16 @@ int bdrv_read(BlockDriverState *bs, int6 if (bdrv_check_request(bs, sector_num, nb_sectors)) return -EIO; + + if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { + memcpy(buf, bs->boot_sector_data, 512); + sector_num++; + nb_sectors--; + buf += 512; + if (nb_sectors == 0) + return 0; + } + if (drv->bdrv_pread) { int ret, len; len = nb_sectors * 512; @@ -631,6 +641,10 @@ int bdrv_write(BlockDriverState *bs, int if (bdrv_check_request(bs, sector_num, nb_sectors)) return -EIO; + if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { + memcpy(bs->boot_sector_data, buf, 512); + } + if (drv->bdrv_pwrite) { int ret, len, count = 0; len = nb_sectors * 512; @@ -934,6 +948,16 @@ void bdrv_guess_geometry(BlockDriverStat } } +/* force a given boot sector. */ +void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size) +{ + bs->boot_sector_enabled = 1; + if (size > 512) + size = 512; + memcpy(bs->boot_sector_data, data, size); + memset(bs->boot_sector_data + size, 0, 512 - size); +} + void bdrv_set_geometry_hint(BlockDriverState *bs, int cyls, int heads, int secs) { @@ -1464,6 +1488,14 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDri if (bdrv_check_request(bs, sector_num, nb_sectors)) return NULL; + /* XXX: we assume that nb_sectors == 0 is suppored by the async read */ + if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { + memcpy(buf, bs->boot_sector_data, 512); + sector_num++; + nb_sectors--; + buf += 512; + } + ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque); if (ret) { @@ -1489,6 +1521,10 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDr if (bdrv_check_request(bs, sector_num, nb_sectors)) return NULL; + if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { + memcpy(bs->boot_sector_data, buf, 512); + } + ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque); if (ret) { Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block_int.h =================================================================== --- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block_int.h +++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block_int.h @@ -122,6 +122,9 @@ struct BlockDriverState { BlockDriver *drv; /* NULL means no media */ void *opaque; + int boot_sector_enabled; + uint8_t boot_sector_data[512]; + char filename[1024]; char backing_file[1024]; /* if non zero, the image is a diff of this file image */ Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pc.c =================================================================== --- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pc.c +++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pc.c @@ -474,45 +474,28 @@ static void bochs_bios_init(void) /* Generate an initial boot sector which sets state and jump to a specified vector */ -static void generate_bootsect(uint8_t *option_rom, - uint32_t gpr[8], uint16_t segs[6], uint16_t ip) +static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip) { - uint8_t rom[512], *p, *reloc; - uint8_t sum; + uint8_t bootsect[512], *p; int i; + int hda; + + hda = drive_get_index(IF_IDE, 0, 0); + if (hda == -1) { + fprintf(stderr, "A disk image must be given for 'hda' when booting " + "a Linux kernel\n(if you really don't want it, use /dev/zero)\n"); + exit(1); + } + memset(bootsect, 0, sizeof(bootsect)); - memset(rom, 0, sizeof(rom)); - - p = rom; - /* Make sure we have an option rom signature */ - *p++ = 0x55; - *p++ = 0xaa; - - /* ROM size in sectors*/ - *p++ = 1; - - /* Hook int19 */ - - *p++ = 0x50; /* push ax */ - *p++ = 0x1e; /* push ds */ - *p++ = 0x31; *p++ = 0xc0; /* xor ax, ax */ - *p++ = 0x8e; *p++ = 0xd8; /* mov ax, ds */ - - *p++ = 0xc7; *p++ = 0x06; /* movvw _start,0x64 */ - *p++ = 0x64; *p++ = 0x00; - reloc = p; - *p++ = 0x00; *p++ = 0x00; - - *p++ = 0x8c; *p++ = 0x0e; /* mov cs,0x66 */ - *p++ = 0x66; *p++ = 0x00; - - *p++ = 0x1f; /* pop ds */ - *p++ = 0x58; /* pop ax */ - *p++ = 0xcb; /* lret */ - - /* Actual code */ - *reloc = (p - rom); + /* Copy the MSDOS partition table if possible */ + bdrv_read(drives_table[hda].bdrv, 0, bootsect, 1); + /* Make sure we have a partition signature */ + bootsect[510] = 0x55; + bootsect[511] = 0xaa; + /* Actual code */ + p = bootsect; *p++ = 0xfa; /* CLI */ *p++ = 0xfc; /* CLD */ @@ -542,13 +525,7 @@ static void generate_bootsect(uint8_t *o *p++ = segs[1]; /* CS */ *p++ = segs[1] >> 8; - /* sign rom */ - sum = 0; - for (i = 0; i < (sizeof(rom) - 1); i++) - sum += rom[i]; - rom[sizeof(rom) - 1] = -sum; - - memcpy(option_rom, rom, sizeof(rom)); + bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect)); } static long get_file_size(FILE *f) @@ -565,8 +542,7 @@ static long get_file_size(FILE *f) return size; } -static void load_linux(uint8_t *option_rom, - const char *kernel_filename, +static void load_linux(const char *kernel_filename, const char *initrd_filename, const char *kernel_cmdline) { @@ -632,7 +608,9 @@ static void load_linux(uint8_t *option_r /* Special pages are placed at end of low RAM: pick an arbitrary one and * subtract a suitably large amount of padding (64kB) to skip BIOS data. */ - xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &end_low_ram); + //xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &end_low_ram); + /* BUFIO Page beyond last_pfn, use 0x7ffc instead. Fix ME. */ + end_low_ram = 0x7ffc; end_low_ram = (end_low_ram << 12) - (64*1024); /* highest address for loading the initrd */ @@ -721,7 +699,7 @@ static void load_linux(uint8_t *option_r memset(gpr, 0, sizeof gpr); gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */ - generate_bootsect(option_rom, gpr, seg, 0); + generate_bootsect(gpr, seg, 0); #endif } @@ -932,14 +910,6 @@ vga_bios_error: int size, offset; offset = 0; - if (linux_boot) { - option_rom_offset = qemu_ram_alloc(TARGET_PAGE_SIZE); - load_linux(phys_ram_base + option_rom_offset, - kernel_filename, initrd_filename, kernel_cmdline); - cpu_register_physical_memory(0xd0000, TARGET_PAGE_SIZE, - option_rom_offset | IO_MEM_ROM); - offset = TARGET_PAGE_SIZE; - } for (i = 0; i < nb_option_roms; i++) { size = get_image_size(option_rom[i]); @@ -973,6 +943,9 @@ vga_bios_error: bochs_bios_init(); + if (linux_boot) + load_linux(kernel_filename, initrd_filename, kernel_cmdline); + cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1); i8259 = i8259_init(cpu_irq[0]); ferr_irq = i8259[13]; Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.h =================================================================== --- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block.h +++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.h @@ -82,6 +82,7 @@ int64_t bdrv_getlength(BlockDriverState void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs); int bdrv_commit(BlockDriverState *bs); +void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size); /* async block I/O */ typedef struct BlockDriverAIOCB BlockDriverAIOCB; typedef void BlockDriverCompletionFunc(void *opaque, int ret);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor