From f24f1e2a857db4b5bccced87a1e29f11d478b862 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 8 May 2009 10:13:01 -0500 Subject: Enable power button even generation. Signed-off-by: Gleb Natapov Signed-off-by: Anthony Liguori --- .../0015_enable-power-button-even-generation.patch | 20 ++++++++++++++++++++ pc-bios/bios-pq/series | 1 + pc-bios/bios.bin | Bin 131072 -> 131072 bytes 3 files changed, 21 insertions(+) create mode 100644 pc-bios/bios-pq/0015_enable-power-button-even-generation.patch diff --git a/pc-bios/bios-pq/0015_enable-power-button-even-generation.patch b/pc-bios/bios-pq/0015_enable-power-button-even-generation.patch new file mode 100644 index 000000000..fb5880280 --- /dev/null +++ b/pc-bios/bios-pq/0015_enable-power-button-even-generation.patch @@ -0,0 +1,20 @@ +Enable power button event generation. + +Signed-off-by: Gleb Natapov +Signed-off-by: Anthony Liguori + +diff --git a/bios/rombios32.c b/bios/rombios32.c +index 81e3bad..9986531 100644 +--- a/bios/rombios32.c ++++ b/bios/rombios32.c +@@ -1767,8 +1767,8 @@ void acpi_bios_init(void) + fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported + fadt->gpe0_blk = cpu_to_le32(0xafe0); + fadt->gpe0_blk_len = 4; +- /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */ +- fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6)); ++ /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */ ++ fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6)); + acpi_build_table_header((struct acpi_table_header *)fadt, "FACP", + sizeof(*fadt), 1); + diff --git a/pc-bios/bios-pq/series b/pc-bios/bios-pq/series index fade61858..5132c301f 100644 --- a/pc-bios/bios-pq/series +++ b/pc-bios/bios-pq/series @@ -10,3 +10,4 @@ 0010_bios-mark-the-acpi-sci-interrupt-as-connected-to-irq-9.patch 0011_read-additional-acpi-tables-from-a-vm.patch 0013_fix-non-acpi-timer-interrupt-routing.patch +0015_enable-power-button-even-generation.patch diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin index ab94bae9a..59cc28500 100644 Binary files a/pc-bios/bios.bin and b/pc-bios/bios.bin differ -- cgit v1.2.3 From 8bc2ad6a6aec73844fb0091f9daf73dc8ee4d61c Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 7 May 2009 11:31:44 +0300 Subject: Fix cluster freeing in qcow2 Need to drop QCOW_OFLAG_COPIED from a cluster pointer before freeing it. Add an explanation how thing meant to work. Signed-off-by: Gleb Natapov Signed-off-by: Anthony Liguori --- block-qcow2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/block-qcow2.c b/block-qcow2.c index 74a0dfa15..a984611a9 100644 --- a/block-qcow2.c +++ b/block-qcow2.c @@ -903,6 +903,12 @@ static int alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset, goto err; for (i = 0; i < m->nb_clusters; i++) { + /* if two concurrent writes happen to the same unallocated cluster + * each write allocates separate cluster and writes data concurrently. + * The first one to complete updates l2 table with pointer to its + * cluster the second one has to do RMW (which is done above by + * copy_sectors()), update l2 table with its cluster pointer and free + * old cluster. This is what this loop does */ if(l2_table[l2_index + i] != 0) old_cluster[j++] = l2_table[l2_index + i]; @@ -916,7 +922,8 @@ static int alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset, goto err; for (i = 0; i < j; i++) - free_any_clusters(bs, be64_to_cpu(old_cluster[i]), 1); + free_any_clusters(bs, be64_to_cpu(old_cluster[i]) & ~QCOW_OFLAG_COPIED, + 1); ret = 0; err: -- cgit v1.2.3 From b468f27acd45de96026f69397e2a38fcd831a718 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Fri, 8 May 2009 02:22:12 -0300 Subject: register reset handler for option_roms Currently, boot options are not preserved across a system reset. option roms can modify themselves, or can for instance restore the real int 0x19 vector after they tried to boot from it. To properly do that, we need a reset handler registered to deal with option roms. This patch is based on current version on qemu-kvm.git Signed-off-by: Glauber Costa Signed-off-by: Anthony Liguori --- hw/pc.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hw/pc.c b/hw/pc.c index 6e3d03f6c..c33cd7556 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -63,6 +63,30 @@ static PITState *pit; static IOAPICState *ioapic; static PCIDevice *i440fx_state; +typedef struct rom_reset_data { + uint8_t *data; + target_phys_addr_t addr; + unsigned size; +} RomResetData; + +static void option_rom_reset(void *_rrd) +{ + RomResetData *rrd = _rrd; + + cpu_physical_memory_write_rom(rrd->addr, rrd->data, rrd->size); +} + +static void option_rom_setup_reset(target_phys_addr_t addr, unsigned size) +{ + RomResetData *rrd = qemu_malloc(sizeof *rrd); + + rrd->data = qemu_malloc(size); + cpu_physical_memory_read(addr, rrd->data, size); + rrd->addr = addr; + rrd->size = size; + qemu_register_reset(option_rom_reset, rrd); +} + static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { } -- cgit v1.2.3 From 2da1e398641d9fccf683645c808dee0d088f84cf Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Fri, 8 May 2009 02:22:13 -0300 Subject: reset state for load_linux The linux loader is just an option rom like any other, just with some special requirements. Right now, our option rom resetting mechanism is not being applied to it. As a result, users using -kernel will not be able to successfully reboot their machines This patch fixes it by saving all the data we generated in the load_linux() function, to be used later by the option rom resetting mechanism. Signed-off-by: Glauber Costa Signed-off-by: Anthony Liguori --- hw/pc.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index c33cd7556..1b1637337 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -471,7 +471,7 @@ 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, +static void generate_bootsect(target_phys_addr_t option_rom, uint32_t gpr[8], uint16_t segs[6], uint16_t ip) { uint8_t rom[512], *p, *reloc; @@ -545,7 +545,8 @@ static void generate_bootsect(uint8_t *option_rom, sum += rom[i]; rom[sizeof(rom) - 1] = -sum; - memcpy(option_rom, rom, sizeof(rom)); + cpu_physical_memory_write_rom(option_rom, rom, sizeof(rom)); + option_rom_setup_reset(option_rom, sizeof (rom)); } static long get_file_size(FILE *f) @@ -562,7 +563,7 @@ static long get_file_size(FILE *f) return size; } -static void load_linux(uint8_t *option_rom, +static void load_linux(target_phys_addr_t option_rom, const char *kernel_filename, const char *initrd_filename, const char *kernel_cmdline) @@ -713,6 +714,12 @@ static void load_linux(uint8_t *option_rom, memset(gpr, 0, sizeof gpr); gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */ + option_rom_setup_reset(real_addr, setup_size); + option_rom_setup_reset(prot_addr, kernel_size); + option_rom_setup_reset(cmdline_addr, cmdline_size); + if (initrd_filename) + option_rom_setup_reset(initrd_addr, initrd_size); + generate_bootsect(option_rom, gpr, seg, 0); } @@ -920,7 +927,7 @@ vga_bios_error: offset = 0; if (linux_boot) { option_rom_offset = qemu_ram_alloc(TARGET_PAGE_SIZE); - load_linux(phys_ram_base + option_rom_offset, + load_linux(option_rom_offset, kernel_filename, initrd_filename, kernel_cmdline); cpu_register_physical_memory(0xd0000, TARGET_PAGE_SIZE, option_rom_offset); -- cgit v1.2.3 From 8bd8199f708c41fd779e2b84a7bcc1b8cdb5b753 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 6 May 2009 02:58:48 +0200 Subject: AIO deletion race fix When deleting an fd event there is a chance the object doesn't get deleted, but only ->deleted set positive and deleted somewhere later. Now, if we create a handler for the fd again before the actual deletion occurs, we end up writing data into an object that has ->deleted set, which is obviously wrong. I see two ways to fix this: 1. Don't return ->deleted objects in the search 2. Unset ->deleted in the search This patch implements 1. which feels safer to do. It fixes AIO issues I've seen with curl, as libcurl unsets fd event listeners pretty frequently. Signed-off-by: Alexander Graf Signed-off-by: Anthony Liguori --- aio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aio.c b/aio.c index 200320c97..11fbb6c0c 100644 --- a/aio.c +++ b/aio.c @@ -44,7 +44,8 @@ static AioHandler *find_aio_handler(int fd) LIST_FOREACH(node, &aio_handlers, node) { if (node->fd == fd) - return node; + if (!node->deleted) + return node; } return NULL; -- cgit v1.2.3 From 2fd0f9328634d0b156add2b4d7c10f7c193d2e20 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 4 May 2009 18:02:04 +0530 Subject: e1000: Do not reinit pci config space to 0 pci_register_device already mallocs the pci config space buffer filled with zeroes. Doing this again breaks some default config space writes like setting the subsystem vendor id and subsystem device id. Signed-off-by: Amit Shah Signed-off-by: Anthony Liguori --- hw/e1000.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/e1000.c b/hw/e1000.c index b0fe91734..940e893ba 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -1067,7 +1067,6 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn) return NULL; pci_conf = d->dev.config; - memset(pci_conf, 0, 256); pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(pci_conf, E1000_DEVID); -- cgit v1.2.3 From 9fd0e57dc9d5601d5d62366639e593b9bd1d0b24 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 8 May 2009 14:47:24 +0200 Subject: Improve block range checks This patch makes the range checks for block requests more strict: It fixes a potential integer overflow and checks for negative offsets. Also, it adds the check for compressed writes. Signed-off-by: Kevin Wolf Signed-off-by: Anthony Liguori --- block.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index 465a09f9b..b12318fe2 100644 --- a/block.c +++ b/block.c @@ -533,7 +533,10 @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, len = bdrv_getlength(bs); - if ((offset + size) > len) + if (offset < 0) + return -EIO; + + if ((offset > len) || (len - offset < size)) return -EIO; return 0; @@ -1170,6 +1173,8 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, return -ENOMEDIUM; if (!drv->bdrv_write_compressed) return -ENOTSUP; + if (bdrv_check_request(bs, sector_num, nb_sectors)) + return -EIO; return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); } -- cgit v1.2.3