80e28a00ec
- unmodified_drivers: handle IRQF_SAMPLE_RANDOM, it was removed in 3.6-rc1 - bnc#778105 - first XEN-PV VM fails to spawn xend: Increase wait time for disk to appear in host bootloader Modified existing xen-domUloader.diff - Disable the snapshot patches. Snapshot only supported the qcow2 image format which was poorly implemented qemu 0.10.2. Snapshot support may be restored in the future when the newer upstream qemu is used by Xen. - bnc#776995 - attaching scsi control luns with pvscsi - xend/pvscsi: fix passing of SCSI control LUNs xen-bug776995-pvscsi-no-devname.patch - xend/pvscsi: fix usage of persistant device names for SCSI devices xen-bug776995-pvscsi-persistent-names.patch - xend/pvscsi: update sysfs parser for Linux 3.0 xen-bug776995-pvscsi-sysfs-parser.patch - Update to Xen 4.2.0 RC3+ c/s 25779 - Update to Xen 4.2.0 RC2+ c/s 25765 OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=199
246 lines
8.5 KiB
Diff
246 lines
8.5 KiB
Diff
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);
|