From 0034a0f239623388525c884dabf9a125eafb1acb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 14 Jan 2015 17:53:55 +0100 Subject: pc: fix KVM features in pc-1.3 and earlier machine types Due to a typo, instead of disabling KVM_FEATURE_PV_EOI (bit 6) these machine types are disabling bits 1 and 2, which are KVM_FEATURE_NOP_IO_DELAY and KVM_FEATURE_MMU_OP. Not a big deal because they aren't very important and KVM_FEATURE_MMU_OP is disabled anyway. The worst part is actually that KVM_FEATURE_PV_EOI is remaining enabled. Signed-off-by: Paolo Bonzini --- hw/i386/pc_piix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index f0a3201..97a754e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -406,7 +406,7 @@ static void pc_compat_1_3(MachineState *machine) static void pc_compat_1_2(MachineState *machine) { pc_compat_1_3(machine); - x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, KVM_FEATURE_PV_EOI); + x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 << KVM_FEATURE_PV_EOI); } static void pc_init_pci_2_2(MachineState *machine) @@ -483,7 +483,7 @@ static void pc_init_isa(MachineState *machine) if (!machine->cpu_model) { machine->cpu_model = "486"; } - x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, KVM_FEATURE_PV_EOI); + x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 << KVM_FEATURE_PV_EOI); enable_compat_apic_id_mode(); pc_init1(machine, 0, 1); } -- cgit v1.1 From b4168498f613db3d908909106146001a9279e732 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 15 Jan 2015 12:26:43 +0100 Subject: multiboot: Fix offset of bootloader name This fixes a bug introduced in commit 5eba5a66 ('Add bootloader name to multiboot implementation'). The calculation of the bootloader name offset didn't consider space occupied by module command lines, so some unlucky module got its command line partially overwritten with a "qemu" string. Signed-off-by: Kevin Wolf Signed-off-by: Paolo Bonzini --- hw/i386/multiboot.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'hw') diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index f86d351..1adbe9e 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -156,6 +156,7 @@ int load_multiboot(FWCfgState *fw_cfg, MultibootState mbs; uint8_t bootinfo[MBI_SIZE]; uint8_t *mb_bootinfo_data; + uint32_t cmdline_len; /* Ok, let's see if it is a multiboot image. The header is 12x32bit long, so the latest entry may be 8192 - 48. */ @@ -258,27 +259,28 @@ int load_multiboot(FWCfgState *fw_cfg, mbs.offset_mbinfo = mbs.mb_buf_size; /* Calculate space for cmdlines, bootloader name, and mb_mods */ - mbs.mb_buf_size += strlen(kernel_filename) + 1; - mbs.mb_buf_size += strlen(kernel_cmdline) + 1; - mbs.mb_buf_size += strlen(bootloader_name) + 1; + cmdline_len = strlen(kernel_filename) + 1; + cmdline_len += strlen(kernel_cmdline) + 1; if (initrd_filename) { const char *r = initrd_filename; - mbs.mb_buf_size += strlen(r) + 1; + cmdline_len += strlen(r) + 1; mbs.mb_mods_avail = 1; while (*(r = get_opt_value(NULL, 0, r))) { mbs.mb_mods_avail++; r++; } - mbs.mb_buf_size += MB_MOD_SIZE * mbs.mb_mods_avail; } + mbs.mb_buf_size += cmdline_len; + mbs.mb_buf_size += MB_MOD_SIZE * mbs.mb_mods_avail; + mbs.mb_buf_size += strlen(bootloader_name) + 1; + mbs.mb_buf_size = TARGET_PAGE_ALIGN(mbs.mb_buf_size); /* enlarge mb_buf to hold cmdlines, bootloader, mb-info structs */ mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size); mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE; - mbs.offset_bootloader = mbs.offset_cmdlines + strlen(kernel_filename) + 1 - + strlen(kernel_cmdline) + 1; + mbs.offset_bootloader = mbs.offset_cmdlines + cmdline_len; if (initrd_filename) { char *next_initrd, not_last; -- cgit v1.1 From e720677e32e70b1f60637ebbcf2ffb23a4607f3e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 8 Jan 2015 10:18:59 +0100 Subject: vmstate: accept QEMUTimer in VMSTATE_TIMER*, add VMSTATE_TIMER_PTR* Old users of VMSTATE_TIMER* are mechanically changed to VMSTATE_TIMER_PTR variants. Signed-off-by: Paolo Bonzini --- hw/acpi/ich9.c | 2 +- hw/acpi/piix4.c | 2 +- hw/arm/stellaris.c | 2 +- hw/block/fdc.c | 2 +- hw/char/cadence_uart.c | 2 +- hw/char/serial.c | 4 ++-- hw/core/ptimer.c | 2 +- hw/dma/pl330.c | 2 +- hw/input/lm832x.c | 2 +- hw/intc/armv7m_nvic.c | 2 +- hw/isa/vt82c686.c | 2 +- hw/misc/macio/cuda.c | 2 +- hw/net/pcnet.c | 2 +- hw/sd/sdhci.c | 4 ++-- hw/timer/a9gtimer.c | 2 +- hw/timer/arm_mptimer.c | 2 +- hw/timer/hpet.c | 2 +- hw/timer/mc146818rtc.c | 4 ++-- hw/usb/hcd-ehci.c | 2 +- hw/usb/hcd-ohci.c | 2 +- hw/usb/hcd-uhci.c | 2 +- hw/usb/hcd-xhci.c | 2 +- hw/usb/redirect.c | 2 +- hw/watchdog/wdt_i6300esb.c | 2 +- hw/watchdog/wdt_ib700.c | 2 +- 25 files changed, 28 insertions(+), 28 deletions(-) (limited to 'hw') diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index ea991a3..43869d7 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -166,7 +166,7 @@ const VMStateDescription vmstate_ich9_pm = { VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9LPCPMRegs), VMSTATE_UINT16(acpi_regs.pm1.evt.en, ICH9LPCPMRegs), VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, ICH9LPCPMRegs), - VMSTATE_TIMER(acpi_regs.tmr.timer, ICH9LPCPMRegs), + VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, ICH9LPCPMRegs), VMSTATE_INT64(acpi_regs.tmr.overflow_time, ICH9LPCPMRegs), VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, ICH9LPCPMRegs), VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9LPCPMRegs), diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 481a16c..184e7e4 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -285,7 +285,7 @@ static const VMStateDescription vmstate_acpi = { VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState), VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState), VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState), - VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState), + VMSTATE_TIMER_PTR(ar.tmr.timer, PIIX4PMState), VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), VMSTATE_STRUCT_TEST( diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 64bd4b4..ccc3b18 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -306,7 +306,7 @@ static const VMStateDescription vmstate_stellaris_gptm = { VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2), VMSTATE_UINT32(rtc, gptm_state), VMSTATE_INT64_ARRAY(tick, gptm_state, 2), - VMSTATE_TIMER_ARRAY(timer, gptm_state, 2), + VMSTATE_TIMER_PTR_ARRAY(timer, gptm_state, 2), VMSTATE_END_OF_LIST() } }; diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 739a03e..2bf87c9 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -791,7 +791,7 @@ static const VMStateDescription vmstate_fdc_result_timer = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_TIMER(result_timer, FDCtrl), + VMSTATE_TIMER_PTR(result_timer, FDCtrl), VMSTATE_END_OF_LIST() } }; diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index a5736cb..7044b35 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -520,7 +520,7 @@ static const VMStateDescription vmstate_cadence_uart = { VMSTATE_UINT32(rx_count, UartState), VMSTATE_UINT32(tx_count, UartState), VMSTATE_UINT32(rx_wpos, UartState), - VMSTATE_TIMER(fifo_trigger_handle, UartState), + VMSTATE_TIMER_PTR(fifo_trigger_handle, UartState), VMSTATE_END_OF_LIST() } }; diff --git a/hw/char/serial.c b/hw/char/serial.c index 3aca874..bd25c03 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -730,7 +730,7 @@ const VMStateDescription vmstate_serial_fifo_timeout_timer = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_TIMER(fifo_timeout_timer, SerialState), + VMSTATE_TIMER_PTR(fifo_timeout_timer, SerialState), VMSTATE_END_OF_LIST() } }; @@ -763,7 +763,7 @@ const VMStateDescription vmstate_serial_poll = { .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_INT32(poll_msl, SerialState), - VMSTATE_TIMER(modem_status_poll, SerialState), + VMSTATE_TIMER_PTR(modem_status_poll, SerialState), VMSTATE_END_OF_LIST() } }; diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c index 466e543..2abad1f 100644 --- a/hw/core/ptimer.c +++ b/hw/core/ptimer.c @@ -214,7 +214,7 @@ const VMStateDescription vmstate_ptimer = { VMSTATE_INT64(period, ptimer_state), VMSTATE_INT64(last_event, ptimer_state), VMSTATE_INT64(next_event, ptimer_state), - VMSTATE_TIMER(timer, ptimer_state), + VMSTATE_TIMER_PTR(timer, ptimer_state), VMSTATE_END_OF_LIST() } }; diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c index 6b6eaae..16cf77e 100644 --- a/hw/dma/pl330.c +++ b/hw/dma/pl330.c @@ -286,7 +286,7 @@ static const VMStateDescription vmstate_pl330 = { PL330Queue), VMSTATE_STRUCT(write_queue, PL330State, 0, vmstate_pl330_queue, PL330Queue), - VMSTATE_TIMER(timer, PL330State), + VMSTATE_TIMER_PTR(timer, PL330State), VMSTATE_UINT32(inten, PL330State), VMSTATE_UINT32(int_status, PL330State), VMSTATE_UINT32(ev_status, PL330State), diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c index 9eb68e8..530a6e0 100644 --- a/hw/input/lm832x.c +++ b/hw/input/lm832x.c @@ -455,7 +455,7 @@ static const VMStateDescription vmstate_lm_kbd = { VMSTATE_UINT16_ARRAY(pwm.file, LM823KbdState, 256), VMSTATE_UINT8(pwm.faddr, LM823KbdState), VMSTATE_BUFFER(pwm.addr, LM823KbdState), - VMSTATE_TIMER_ARRAY(pwm.tm, LM823KbdState, 3), + VMSTATE_TIMER_PTR_ARRAY(pwm.tm, LM823KbdState, 3), VMSTATE_END_OF_LIST() } }; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index d0543d4..6ff6c7f 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -450,7 +450,7 @@ static const VMStateDescription vmstate_nvic = { VMSTATE_UINT32(systick.control, nvic_state), VMSTATE_UINT32(systick.reload, nvic_state), VMSTATE_INT64(systick.tick, nvic_state), - VMSTATE_TIMER(systick.timer, nvic_state), + VMSTATE_TIMER_PTR(systick.timer, nvic_state), VMSTATE_END_OF_LIST() } }; diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 2f53bf8..17510ce 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -234,7 +234,7 @@ static const VMStateDescription vmstate_acpi = { VMSTATE_UINT16(ar.pm1.evt.en, VT686PMState), VMSTATE_UINT16(ar.pm1.cnt.cnt, VT686PMState), VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState), - VMSTATE_TIMER(ar.tmr.timer, VT686PMState), + VMSTATE_TIMER_PTR(ar.tmr.timer, VT686PMState), VMSTATE_INT64(ar.tmr.overflow_time, VT686PMState), VMSTATE_END_OF_LIST() } diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index b4273aa..47d9771 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -631,7 +631,7 @@ static const VMStateDescription vmstate_cuda_timer = { VMSTATE_UINT16(counter_value, CUDATimer), VMSTATE_INT64(load_time, CUDATimer), VMSTATE_INT64(next_irq_time, CUDATimer), - VMSTATE_TIMER_TEST(timer, CUDATimer, cuda_timer_exist), + VMSTATE_TIMER_PTR_TEST(timer, CUDATimer, cuda_timer_exist), VMSTATE_END_OF_LIST() } }; diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c index 8a1c8f1..8486b80 100644 --- a/hw/net/pcnet.c +++ b/hw/net/pcnet.c @@ -1719,7 +1719,7 @@ const VMStateDescription vmstate_pcnet = { VMSTATE_BUFFER(buffer, PCNetState), VMSTATE_UNUSED_TEST(is_version_2, 4), VMSTATE_INT32(tx_busy, PCNetState), - VMSTATE_TIMER(poll_timer, PCNetState), + VMSTATE_TIMER_PTR(poll_timer, PCNetState), VMSTATE_END_OF_LIST() } }; diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 15064d3..10e5355 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1205,8 +1205,8 @@ const VMStateDescription sdhci_vmstate = { VMSTATE_UINT64(admasysaddr, SDHCIState), VMSTATE_UINT8(stopped_state, SDHCIState), VMSTATE_VBUFFER_UINT32(fifo_buffer, SDHCIState, 1, NULL, 0, buf_maxsz), - VMSTATE_TIMER(insert_timer, SDHCIState), - VMSTATE_TIMER(transfer_timer, SDHCIState), + VMSTATE_TIMER_PTR(insert_timer, SDHCIState), + VMSTATE_TIMER_PTR(transfer_timer, SDHCIState), VMSTATE_END_OF_LIST() } }; diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c index a0656d5..435142a 100644 --- a/hw/timer/a9gtimer.c +++ b/hw/timer/a9gtimer.c @@ -328,7 +328,7 @@ static const VMStateDescription vmstate_a9_gtimer = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_TIMER(timer, A9GTimerState), + VMSTATE_TIMER_PTR(timer, A9GTimerState), VMSTATE_UINT64(counter, A9GTimerState), VMSTATE_UINT64(ref_counter, A9GTimerState), VMSTATE_UINT64(cpu_ref_time, A9GTimerState), diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c index 35a0a23..8b93b3c 100644 --- a/hw/timer/arm_mptimer.c +++ b/hw/timer/arm_mptimer.c @@ -246,7 +246,7 @@ static const VMStateDescription vmstate_timerblock = { VMSTATE_UINT32(control, TimerBlock), VMSTATE_UINT32(status, TimerBlock), VMSTATE_INT64(tick, TimerBlock), - VMSTATE_TIMER(timer, TimerBlock), + VMSTATE_TIMER_PTR(timer, TimerBlock), VMSTATE_END_OF_LIST() } }; diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index d8bc231..78d86be 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -299,7 +299,7 @@ static const VMStateDescription vmstate_hpet_timer = { VMSTATE_UINT64(fsb, HPETTimer), VMSTATE_UINT64(period, HPETTimer), VMSTATE_UINT8(wrap_flag, HPETTimer), - VMSTATE_TIMER(qemu_timer, HPETTimer), + VMSTATE_TIMER_PTR(qemu_timer, HPETTimer), VMSTATE_END_OF_LIST() } }; diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index f18d128..5a107fa 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -758,7 +758,7 @@ static const VMStateDescription vmstate_rtc = { VMSTATE_BUFFER(cmos_data, RTCState), VMSTATE_UINT8(cmos_index, RTCState), VMSTATE_UNUSED(7*4), - VMSTATE_TIMER(periodic_timer, RTCState), + VMSTATE_TIMER_PTR(periodic_timer, RTCState), VMSTATE_INT64(next_periodic_time, RTCState), VMSTATE_UNUSED(3*8), VMSTATE_UINT32_V(irq_coalesced, RTCState, 2), @@ -766,7 +766,7 @@ static const VMStateDescription vmstate_rtc = { VMSTATE_UINT64_V(base_rtc, RTCState, 3), VMSTATE_UINT64_V(last_update, RTCState, 3), VMSTATE_INT64_V(offset, RTCState, 3), - VMSTATE_TIMER_V(update_timer, RTCState, 3), + VMSTATE_TIMER_PTR_V(update_timer, RTCState, 3), VMSTATE_UINT64_V(next_alarm_time, RTCState, 3), VMSTATE_END_OF_LIST() }, diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 1cc0fc1..ccf54b6 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -2437,7 +2437,7 @@ const VMStateDescription vmstate_ehci = { VMSTATE_UINT32(portsc[4], EHCIState), VMSTATE_UINT32(portsc[5], EHCIState), /* frame timer */ - VMSTATE_TIMER(frame_timer, EHCIState), + VMSTATE_TIMER_PTR(frame_timer, EHCIState), VMSTATE_UINT64(last_run_ns, EHCIState), VMSTATE_UINT32(async_stepdown, EHCIState), /* schedule state */ diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 9a84eb6..a0d478e 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -2015,7 +2015,7 @@ static const VMStateDescription vmstate_ohci_eof_timer = { .minimum_version_id = 1, .pre_load = ohci_eof_timer_pre_load, .fields = (VMStateField[]) { - VMSTATE_TIMER(eof_timer, OHCIState), + VMSTATE_TIMER_PTR(eof_timer, OHCIState), VMSTATE_END_OF_LIST() }, }; diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 4a4215d..f903de7 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -419,7 +419,7 @@ static const VMStateDescription vmstate_uhci = { VMSTATE_UINT32(fl_base_addr, UHCIState), VMSTATE_UINT8(sof_timing, UHCIState), VMSTATE_UINT8(status2, UHCIState), - VMSTATE_TIMER(frame_timer, UHCIState), + VMSTATE_TIMER_PTR(frame_timer, UHCIState), VMSTATE_INT64_V(expire_time, UHCIState, 2), VMSTATE_UINT32_V(pending_int_mask, UHCIState, 3), VMSTATE_END_OF_LIST() diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 9a942cf..776699b 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -3855,7 +3855,7 @@ static const VMStateDescription vmstate_xhci = { /* Runtime Registers & state */ VMSTATE_INT64(mfindex_start, XHCIState), - VMSTATE_TIMER(mfwrap_timer, XHCIState), + VMSTATE_TIMER_PTR(mfwrap_timer, XHCIState), VMSTATE_STRUCT(cmd_ring, XHCIState, 1, vmstate_xhci_ring, XHCIRing), VMSTATE_END_OF_LIST() diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 9fbd59e..962d3f5 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -2438,7 +2438,7 @@ static const VMStateDescription usbredir_vmstate = { .post_load = usbredir_post_load, .fields = (VMStateField[]) { VMSTATE_USB_DEVICE(dev, USBRedirDevice), - VMSTATE_TIMER(attach_timer, USBRedirDevice), + VMSTATE_TIMER_PTR(attach_timer, USBRedirDevice), { .name = "parser", .version_id = 0, diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c index 687c8b1..33dd6d4 100644 --- a/hw/watchdog/wdt_i6300esb.c +++ b/hw/watchdog/wdt_i6300esb.c @@ -398,7 +398,7 @@ static const VMStateDescription vmstate_i6300esb = { VMSTATE_INT32(free_run, I6300State), VMSTATE_INT32(locked, I6300State), VMSTATE_INT32(enabled, I6300State), - VMSTATE_TIMER(timer, I6300State), + VMSTATE_TIMER_PTR(timer, I6300State), VMSTATE_UINT32(timer1_preload, I6300State), VMSTATE_UINT32(timer2_preload, I6300State), VMSTATE_INT32(stage, I6300State), diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c index 8cb9827..0917a71 100644 --- a/hw/watchdog/wdt_ib700.c +++ b/hw/watchdog/wdt_ib700.c @@ -93,7 +93,7 @@ static const VMStateDescription vmstate_ib700 = { .version_id = 0, .minimum_version_id = 0, .fields = (VMStateField[]) { - VMSTATE_TIMER(timer, IB700State), + VMSTATE_TIMER_PTR(timer, IB700State), VMSTATE_END_OF_LIST() } }; -- cgit v1.1 From b30934cb52a72a763da21dccc9994c64517d6f25 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 21 Jan 2015 17:48:33 +0100 Subject: hw: misc, add educational driver I am using qemu for teaching the Linux kernel at our university. I wrote a simple PCI device that can answer to writes/reads, generate interrupts and perform DMA. As I am dragging it locally over 2 years, I am sending it to you now. Signed-off-by: Jiri Slaby [Fix 32-bit compilation. - Paolo] Signed-off-by: Paolo Bonzini --- hw/misc/Makefile.objs | 1 + hw/misc/edu.c | 408 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 409 insertions(+) create mode 100644 hw/misc/edu.c (limited to 'hw') diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index e47fea8..029a56f 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -40,3 +40,4 @@ obj-$(CONFIG_SLAVIO) += slavio_misc.o obj-$(CONFIG_ZYNQ) += zynq_slcr.o obj-$(CONFIG_PVPANIC) += pvpanic.o +obj-$(CONFIG_EDU) += edu.o diff --git a/hw/misc/edu.c b/hw/misc/edu.c new file mode 100644 index 0000000..f601069 --- /dev/null +++ b/hw/misc/edu.c @@ -0,0 +1,408 @@ +/* + * QEMU educational PCI device + * + * Copyright (c) 2012-2015 Jiri Slaby + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "hw/pci/pci.h" +#include "qemu/timer.h" +#include "qemu/main-loop.h" /* iothread mutex */ +#include "qapi/visitor.h" + +#define EDU(obj) OBJECT_CHECK(EduState, obj, "edu") + +#define FACT_IRQ 0x00000001 +#define DMA_IRQ 0x00000100 + +#define DMA_START 0x40000 +#define DMA_SIZE 4096 + +typedef struct { + PCIDevice pdev; + MemoryRegion mmio; + + QemuThread thread; + QemuMutex thr_mutex; + QemuCond thr_cond; + bool stopping; + + uint32_t addr4; + uint32_t fact; +#define EDU_STATUS_COMPUTING 0x01 +#define EDU_STATUS_IRQFACT 0x80 + uint32_t status; + + uint32_t irq_status; + +#define EDU_DMA_RUN 0x1 +#define EDU_DMA_DIR(cmd) (((cmd) & 0x2) >> 1) +# define EDU_DMA_FROM_PCI 0 +# define EDU_DMA_TO_PCI 1 +#define EDU_DMA_IRQ 0x4 + struct dma_state { + dma_addr_t src; + dma_addr_t dst; + dma_addr_t cnt; + dma_addr_t cmd; + } dma; + QEMUTimer dma_timer; + char dma_buf[DMA_SIZE]; + uint64_t dma_mask; +} EduState; + +static void edu_raise_irq(EduState *edu, uint32_t val) +{ + edu->irq_status |= val; + if (edu->irq_status) { + pci_set_irq(&edu->pdev, 1); + } +} + +static void edu_lower_irq(EduState *edu, uint32_t val) +{ + edu->irq_status &= ~val; + + if (!edu->irq_status) { + pci_set_irq(&edu->pdev, 0); + } +} + +static bool within(uint32_t addr, uint32_t start, uint32_t end) +{ + return start <= addr && addr < end; +} + +static void edu_check_range(uint32_t addr, uint32_t size1, uint32_t start, + uint32_t size2) +{ + uint32_t end1 = addr + size1; + uint32_t end2 = start + size2; + + if (within(addr, start, end2) && + end1 > addr && within(end1, start, end2)) { + return; + } + + hw_error("EDU: DMA range 0x%.8x-0x%.8x out of bounds (0x%.8x-0x%.8x)!", + addr, end1 - 1, start, end2 - 1); +} + +static dma_addr_t edu_clamp_addr(const EduState *edu, dma_addr_t addr) +{ + dma_addr_t res = addr & edu->dma_mask; + + if (addr != res) { + printf("EDU: clamping DMA %#.16"PRIx64" to %#.16"PRIx64"!\n", addr, res); + } + + return res; +} + +static void edu_dma_timer(void *opaque) +{ + EduState *edu = opaque; + bool raise_irq = false; + + if (!(edu->dma.cmd & EDU_DMA_RUN)) { + return; + } + + if (EDU_DMA_DIR(edu->dma.cmd) == EDU_DMA_FROM_PCI) { + uint32_t dst = edu->dma.dst; + edu_check_range(dst, edu->dma.cnt, DMA_START, DMA_SIZE); + dst -= DMA_START; + pci_dma_read(&edu->pdev, edu_clamp_addr(edu, edu->dma.src), + edu->dma_buf + dst, edu->dma.cnt); + } else { + uint32_t src = edu->dma.src; + edu_check_range(src, edu->dma.cnt, DMA_START, DMA_SIZE); + src -= DMA_START; + pci_dma_write(&edu->pdev, edu_clamp_addr(edu, edu->dma.dst), + edu->dma_buf + src, edu->dma.cnt); + } + + edu->dma.cmd &= ~EDU_DMA_RUN; + if (edu->dma.cmd & EDU_DMA_IRQ) { + raise_irq = true; + } + + if (raise_irq) { + edu_raise_irq(edu, DMA_IRQ); + } +} + +static void dma_rw(EduState *edu, bool write, dma_addr_t *val, dma_addr_t *dma, + bool timer) +{ + if (write && (edu->dma.cmd & EDU_DMA_RUN)) { + return; + } + + if (write) { + *dma = *val; + } else { + *val = *dma; + } + + if (timer) { + timer_mod(&edu->dma_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 100); + } +} + +static uint64_t edu_mmio_read(void *opaque, hwaddr addr, unsigned size) +{ + EduState *edu = opaque; + uint64_t val = ~0ULL; + + if (size != 4) { + return val; + } + + switch (addr) { + case 0x00: + val = 0x010000edu; + break; + case 0x04: + val = edu->addr4; + break; + case 0x08: + qemu_mutex_lock(&edu->thr_mutex); + val = edu->fact; + qemu_mutex_unlock(&edu->thr_mutex); + break; + case 0x20: + val = atomic_read(&edu->status); + break; + case 0x24: + val = edu->irq_status; + break; + case 0x80: + dma_rw(edu, false, &val, &edu->dma.src, false); + break; + case 0x88: + dma_rw(edu, false, &val, &edu->dma.dst, false); + break; + case 0x90: + dma_rw(edu, false, &val, &edu->dma.cnt, false); + break; + case 0x98: + dma_rw(edu, false, &val, &edu->dma.cmd, false); + break; + } + + return val; +} + +static void edu_mmio_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + EduState *edu = opaque; + + if (addr < 0x80 && size != 4) { + return; + } + + if (addr >= 0x80 && size != 4 && size != 8) { + return; + } + + switch (addr) { + case 0x04: + edu->addr4 = ~val; + break; + case 0x08: + if (atomic_read(&edu->status) & EDU_STATUS_COMPUTING) { + break; + } + /* EDU_STATUS_COMPUTING cannot go 0->1 concurrently, because it is only + * set in this function and it is under the iothread mutex. + */ + qemu_mutex_lock(&edu->thr_mutex); + edu->fact = val; + atomic_or(&edu->status, EDU_STATUS_COMPUTING); + qemu_cond_signal(&edu->thr_cond); + qemu_mutex_unlock(&edu->thr_mutex); + break; + case 0x20: + if (val & EDU_STATUS_IRQFACT) { + atomic_or(&edu->status, EDU_STATUS_IRQFACT); + } else { + atomic_and(&edu->status, ~EDU_STATUS_IRQFACT); + } + break; + case 0x60: + edu_raise_irq(edu, val); + break; + case 0x64: + edu_lower_irq(edu, val); + break; + case 0x80: + dma_rw(edu, true, &val, &edu->dma.src, false); + break; + case 0x88: + dma_rw(edu, true, &val, &edu->dma.dst, false); + break; + case 0x90: + dma_rw(edu, true, &val, &edu->dma.cnt, false); + break; + case 0x98: + if (!(val & EDU_DMA_RUN)) { + break; + } + dma_rw(edu, true, &val, &edu->dma.cmd, true); + break; + } +} + +static const MemoryRegionOps edu_mmio_ops = { + .read = edu_mmio_read, + .write = edu_mmio_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +/* + * We purposedly use a thread, so that users are forced to wait for the status + * register. + */ +static void *edu_fact_thread(void *opaque) +{ + EduState *edu = opaque; + + while (1) { + uint32_t val, ret = 1; + + qemu_mutex_lock(&edu->thr_mutex); + while ((atomic_read(&edu->status) & EDU_STATUS_COMPUTING) == 0 && + !edu->stopping) { + qemu_cond_wait(&edu->thr_cond, &edu->thr_mutex); + } + + if (edu->stopping) { + qemu_mutex_unlock(&edu->thr_mutex); + break; + } + + val = edu->fact; + qemu_mutex_unlock(&edu->thr_mutex); + + while (val > 0) { + ret *= val--; + } + + /* + * We should sleep for a random period here, so that students are + * forced to check the status properly. + */ + + qemu_mutex_lock(&edu->thr_mutex); + edu->fact = ret; + qemu_mutex_unlock(&edu->thr_mutex); + atomic_and(&edu->status, ~EDU_STATUS_COMPUTING); + + if (atomic_read(&edu->status) & EDU_STATUS_IRQFACT) { + qemu_mutex_lock_iothread(); + edu_raise_irq(edu, FACT_IRQ); + qemu_mutex_unlock_iothread(); + } + } + + return NULL; +} + +static int pci_edu_init(PCIDevice *pdev) +{ + EduState *edu = DO_UPCAST(EduState, pdev, pdev); + uint8_t *pci_conf = pdev->config; + + timer_init_ms(&edu->dma_timer, QEMU_CLOCK_VIRTUAL, edu_dma_timer, edu); + + qemu_mutex_init(&edu->thr_mutex); + qemu_cond_init(&edu->thr_cond); + qemu_thread_create(&edu->thread, "edu", edu_fact_thread, + edu, QEMU_THREAD_JOINABLE); + + pci_config_set_interrupt_pin(pci_conf, 1); + + memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu, + "edu-mmio", 1 << 20); + pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio); + + return 0; +} + +static void pci_edu_uninit(PCIDevice *pdev) +{ + EduState *edu = DO_UPCAST(EduState, pdev, pdev); + + qemu_mutex_lock(&edu->thr_mutex); + edu->stopping = true; + qemu_mutex_unlock(&edu->thr_mutex); + qemu_cond_signal(&edu->thr_cond); + qemu_thread_join(&edu->thread); + + qemu_cond_destroy(&edu->thr_cond); + qemu_mutex_destroy(&edu->thr_mutex); + + timer_del(&edu->dma_timer); +} + +static void edu_obj_uint64(Object *obj, struct Visitor *v, void *opaque, + const char *name, Error **errp) +{ + uint64_t *val = opaque; + + visit_type_uint64(v, val, name, errp); +} + +static void edu_instance_init(Object *obj) +{ + EduState *edu = EDU(obj); + + edu->dma_mask = (1UL << 28) - 1; + object_property_add(obj, "dma_mask", "uint64", edu_obj_uint64, + edu_obj_uint64, NULL, &edu->dma_mask, NULL); +} + +static void edu_class_init(ObjectClass *class, void *data) +{ + PCIDeviceClass *k = PCI_DEVICE_CLASS(class); + + k->init = pci_edu_init; + k->exit = pci_edu_uninit; + k->vendor_id = PCI_VENDOR_ID_QEMU; + k->device_id = 0x11e8; + k->revision = 0x10; + k->class_id = PCI_CLASS_OTHERS; +} + +static void pci_edu_register_types(void) +{ + static const TypeInfo edu_info = { + .name = "edu", + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(EduState), + .instance_init = edu_instance_init, + .class_init = edu_class_init, + }; + + type_register_static(&edu_info); +} +type_init(pci_edu_register_types) -- cgit v1.1 From 927411fa42c5fcf16ed0fcc0447d5ee8c83b22ca Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 20 Jan 2015 11:07:09 +0100 Subject: apic: do not dereference pointer before it is checked for NULL Right now you only get to apic_init_reset if you have an APIC (do_cpu_init is reached only if CPU_INTERRUPT_INIT is set and that only happens in hw/intc/apic.c). However, this is wrong because for example a port 92 or keyboard controller reset is really an INIT, and that can happen also with no APIC. So keep the check and fix the error that Coverity reported. Reported-by: Markus Armbruster Reviewed-by: Markus Armbruster Signed-off-by: Paolo Bonzini --- hw/intc/apic_common.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'hw') diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index d9bb188..0858b45 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -177,13 +177,14 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time) void apic_init_reset(DeviceState *dev) { - APICCommonState *s = APIC_COMMON(dev); - APICCommonClass *info = APIC_COMMON_GET_CLASS(s); + APICCommonState *s; + APICCommonClass *info; int i; - if (!s) { + if (!dev) { return; } + s = APIC_COMMON(dev); s->tpr = 0; s->spurious_vec = 0xff; s->log_dest = 0; @@ -208,6 +209,7 @@ void apic_init_reset(DeviceState *dev) } s->timer_expiry = -1; + info = APIC_COMMON_GET_CLASS(s); if (info->reset) { info->reset(s); } -- cgit v1.1 From 13704e4c455770d500d6b87b117e32f0d01252c9 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 22 Jan 2015 17:22:54 -0200 Subject: target-i386: Disable HLE and RTM on Haswell & Broadwell All Haswell CPUs and some Broadwell CPUs were updated by Intel to have the HLE and RTM features disabled. This will prevent "-cpu Haswell,enforce" and "-cpu Broadwell,enforce" from running out of the box on those CPUs. Disable those features by default on Broadwell and Haswell CPU models, starting on pc-*-2.3. Users who want to use those features can enable them explicitly on the command-line. Signed-off-by: Eduardo Habkost Signed-off-by: Paolo Bonzini --- hw/i386/pc_piix.c | 4 ++++ hw/i386/pc_q35.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'hw') diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 97a754e..38b42b0 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -328,6 +328,10 @@ static void pc_compat_2_2(MachineState *machine) x86_cpu_compat_set_features("Haswell", FEAT_1_ECX, 0, CPUID_EXT_RDRAND); x86_cpu_compat_set_features("Broadwell", FEAT_1_ECX, 0, CPUID_EXT_F16C); x86_cpu_compat_set_features("Broadwell", FEAT_1_ECX, 0, CPUID_EXT_RDRAND); + x86_cpu_compat_set_features("Haswell", FEAT_7_0_EBX, + CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM, 0); + x86_cpu_compat_set_features("Broadwell", FEAT_7_0_EBX, + CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM, 0); } static void pc_compat_2_1(MachineState *machine) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index a432944..63027ee 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -307,6 +307,10 @@ static void pc_compat_2_2(MachineState *machine) x86_cpu_compat_set_features("Haswell", FEAT_1_ECX, 0, CPUID_EXT_RDRAND); x86_cpu_compat_set_features("Broadwell", FEAT_1_ECX, 0, CPUID_EXT_F16C); x86_cpu_compat_set_features("Broadwell", FEAT_1_ECX, 0, CPUID_EXT_RDRAND); + x86_cpu_compat_set_features("Haswell", FEAT_7_0_EBX, + CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM, 0); + x86_cpu_compat_set_features("Broadwell", FEAT_7_0_EBX, + CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM, 0); } static void pc_compat_2_1(MachineState *machine) -- cgit v1.1