[PATCH 1/3] migration/migration: improve error reporting for migrate parameters
use QERR_INVALID_PARAMETER_VALUE instead of "Parameter '%s' expects" for consistency. Signed-off-by: Mao Zhongyi --- migration/migration.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 2b7b5bccfa..e0223f3b15 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1202,16 +1202,17 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp) } if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { -error_setg(errp, "Parameter 'max_bandwidth' expects an integer in the" - " range of 0 to %zu bytes/second", SIZE_MAX); +error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "max_bandwidth", + "an integer in the range of 0 to '2^64 - 1' bytes/second"); return false; } if (params->has_downtime_limit && (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { -error_setg(errp, "Parameter 'downtime_limit' expects an integer in " - "the range of 0 to %d milliseconds", - MAX_MIGRATE_DOWNTIME); +error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "downtime_limit", + "an integer in the range of 0 to 200 milliseconds"); return false; } @@ -2108,9 +2109,9 @@ void qmp_migrate_set_speed(int64_t value, Error **errp) void qmp_migrate_set_downtime(double value, Error **errp) { if (value < 0 || value > MAX_MIGRATE_DOWNTIME_SECONDS) { -error_setg(errp, "Parameter 'downtime_limit' expects an integer in " - "the range of 0 to %d seconds", - MAX_MIGRATE_DOWNTIME_SECONDS); +error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "downtime_limit", + "an integer in the range of 0 to 2000 seconds"); return; } -- 2.17.1
[PATCH 2/3] monitor/hmp-cmds: add hmp_handle_error() for hmp_migrate_set_speed()
Signed-off-by: Mao Zhongyi --- monitor/hmp-cmds.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 790fad3afe..63097ddcc8 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1203,8 +1203,11 @@ void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict) /* Kept for backwards compatibility */ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict) { +Error *err = NULL; + int64_t value = qdict_get_int(qdict, "value"); -qmp_migrate_set_speed(value, NULL); +qmp_migrate_set_speed(value, ); +hmp_handle_error(mon, err); } void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) -- 2.17.1
[PATCH 0/3] Improved reporting for migrate parameters
This series mainly improve the report message of migrate parameters to make it easier to read. Cc: quint...@redhat.com Cc: dgilb...@redhat.com Mao Zhongyi (3): migration/migration: improve error reporting for migrate parameters monitor/hmp-cmds: add hmp_handle_error() for hmp_migrate_set_speed() migration: move the units of migrate parameters from milliseconds to ms. migration/migration.c | 17 + monitor/hmp-cmds.c| 13 - 2 files changed, 17 insertions(+), 13 deletions(-) -- 2.17.1
[PATCH 3/3] migration: move the units of migrate parameters from milliseconds to ms.
Signed-off-by: Mao Zhongyi Suggested-by: Dr. David Alan Gilbert --- migration/migration.c | 2 +- monitor/hmp-cmds.c| 8 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index e0223f3b15..d014da388a 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1212,7 +1212,7 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp) (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "downtime_limit", - "an integer in the range of 0 to 200 milliseconds"); + "an integer in the range of 0 to 200 ms"); return false; } diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 63097ddcc8..c5de8af1ee 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -231,18 +231,18 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) monitor_printf(mon, "\n"); } -monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n", +monitor_printf(mon, "total time: %" PRIu64 " ms\n", info->total_time); if (info->has_expected_downtime) { -monitor_printf(mon, "expected downtime: %" PRIu64 " milliseconds\n", +monitor_printf(mon, "expected downtime: %" PRIu64 " ms\n", info->expected_downtime); } if (info->has_downtime) { -monitor_printf(mon, "downtime: %" PRIu64 " milliseconds\n", +monitor_printf(mon, "downtime: %" PRIu64 " ms\n", info->downtime); } if (info->has_setup_time) { -monitor_printf(mon, "setup: %" PRIu64 " milliseconds\n", +monitor_printf(mon, "setup: %" PRIu64 " ms\n", info->setup_time); } } -- 2.17.1
Re: [PATCH v6 18/61] target/riscv: vector single-width integer multiply instructions
On 2020/3/29 0:13, LIU Zhiwei wrote: On 2020/3/28 23:47, Richard Henderson wrote: On 3/28/20 8:17 AM, LIU Zhiwei wrote: Missed the improvement here. See tcg_gen_mulsu2_i64. Though I have not gotten the principle, the code in tcg_gen_mulsu2_i64 is much tidier. Let A = signed operand, B = unsigned operand P = unsigned product If the sign bit A is set, then P is too large. In that case we subtract 2**64 * B to fix that: HI_P -= (A < 0 ? B : 0) where the conditional is computed as (A >> 63) & B. I think I get it. LET A = 2 ** 64 - X THEN X = 2 ** 64 - A SIGNED_P = -X * B if (A * B == P) then (2 ** 64 - X) * B == P 2 **64 * B - X * B == P -X *B == P - 2**64*B HI_P -= (A < 0 ? B :0) It's confusing here. I paste the clearer code. /* * Let A = signed operand, * B = unsigned operand * P = mulu64(A, B), unsigned product * * LET X = 2 ** 64 - A, 2's complement of A * SP = signed product * THEN * IF A < 0 * SP = -X * B * = -(2 ** 64 - A) * B * = A * B - 2 ** 64 * B * = P - 2 ** 64 * B * ELSE * SP = P * THEN * HI_P -= (A < 0 ? B : 0) */ static int64_t do_mulhsu_d(int64_t s2, uint64_t s1) { uint64_t hi_64, lo_64; mulu64(_64, _64, s2, s1); hi_64 -= s2 < 0 ? s1 : 0; return hi_64; } Zhiwei Zhiwei r~
Re: [PATCH] target/arm: fix incorrect current EL bug in aarch32 exception emulation
On 3/28/20 7:02 AM, Changbin Du wrote: > The arm_current_el() should be invoked after mode switching. Otherwise, we > get a wrong current EL value, since current EL is also determined by > current mode. > > Fixes: 4a2696c0d4 ("target/arm: Set PAN bit as required on exception entry") > Signed-off-by: Changbin Du > --- > target/arm/helper.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) Reviewed-by: Richard Henderson r~
Re: [PATCH v2 0/6] dwc-hsotg (aka dwc2) USB host controller emulation
Patchew URL: https://patchew.org/QEMU/20200329001705.15966-1-pauld...@gmail.com/ Hi, This series seems to have some coding style problems. See output below for more information: Subject: [PATCH v2 0/6] dwc-hsotg (aka dwc2) USB host controller emulation Message-id: 20200329001705.15966-1-pauld...@gmail.com Type: series === TEST SCRIPT BEGIN === #!/bin/bash git rev-parse base > /dev/null || exit 0 git config --local diff.renamelimit 0 git config --local diff.renames True git config --local diff.algorithm histogram ./scripts/checkpatch.pl --mailback base.. === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 Switched to a new branch 'test' 814b833 Wire in the dwc-hsotg USB host controller emulation 6b74a73 Add short-packet handling to usb-storage driver 8f3ea22 dwc-hsotg USB host controller emulation dfe2b0d dwc-hsotg USB host controller state definitions 6c3ebf7 dwc-hsotg USB host controller register definitions 55c66de Add BCM2835 SOC MPHI emulation === OUTPUT BEGIN === 1/6 Checking commit 55c66de0e143 (Add BCM2835 SOC MPHI emulation) WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #62: new file mode 100644 total: 0 errors, 1 warnings, 293 lines checked Patch 1/6 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. 2/6 Checking commit 6c3ebf707965 (dwc-hsotg USB host controller register definitions) WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #16: new file mode 100644 WARNING: architecture specific defines should be avoided #58: FILE: include/hw/usb/dwc2-regs.h:38: +#ifndef __DWC2_HW_H__ ERROR: code indent should never use tabs #61: FILE: include/hw/usb/dwc2-regs.h:41: +#define HSOTG_REG(x)^I(x)$ ERROR: code indent should never use tabs #63: FILE: include/hw/usb/dwc2-regs.h:43: +#define GOTGCTL^I^I^I^IHSOTG_REG(0x000)$ ERROR: code indent should never use tabs #64: FILE: include/hw/usb/dwc2-regs.h:44: +#define GOTGCTL_CHIRPEN^I^I^IBIT(27)$ ERROR: code indent should never use tabs #65: FILE: include/hw/usb/dwc2-regs.h:45: +#define GOTGCTL_MULT_VALID_BC_MASK^I(0x1f << 22)$ ERROR: code indent should never use tabs #66: FILE: include/hw/usb/dwc2-regs.h:46: +#define GOTGCTL_MULT_VALID_BC_SHIFT^I22$ ERROR: code indent should never use tabs #67: FILE: include/hw/usb/dwc2-regs.h:47: +#define GOTGCTL_OTGVER^I^I^IBIT(20)$ ERROR: code indent should never use tabs #68: FILE: include/hw/usb/dwc2-regs.h:48: +#define GOTGCTL_BSESVLD^I^I^IBIT(19)$ ERROR: code indent should never use tabs #69: FILE: include/hw/usb/dwc2-regs.h:49: +#define GOTGCTL_ASESVLD^I^I^IBIT(18)$ ERROR: code indent should never use tabs #70: FILE: include/hw/usb/dwc2-regs.h:50: +#define GOTGCTL_DBNC_SHORT^I^IBIT(17)$ ERROR: code indent should never use tabs #71: FILE: include/hw/usb/dwc2-regs.h:51: +#define GOTGCTL_CONID_B^I^I^IBIT(16)$ ERROR: code indent should never use tabs #72: FILE: include/hw/usb/dwc2-regs.h:52: +#define GOTGCTL_DBNCE_FLTR_BYPASS^IBIT(15)$ ERROR: code indent should never use tabs #73: FILE: include/hw/usb/dwc2-regs.h:53: +#define GOTGCTL_DEVHNPEN^I^IBIT(11)$ ERROR: code indent should never use tabs #74: FILE: include/hw/usb/dwc2-regs.h:54: +#define GOTGCTL_HSTSETHNPEN^I^IBIT(10)$ ERROR: code indent should never use tabs #75: FILE: include/hw/usb/dwc2-regs.h:55: +#define GOTGCTL_HNPREQ^I^I^IBIT(9)$ ERROR: code indent should never use tabs #76: FILE: include/hw/usb/dwc2-regs.h:56: +#define GOTGCTL_HSTNEGSCS^I^IBIT(8)$ ERROR: code indent should never use tabs #77: FILE: include/hw/usb/dwc2-regs.h:57: +#define GOTGCTL_SESREQ^I^I^IBIT(1)$ ERROR: code indent should never use tabs #78: FILE: include/hw/usb/dwc2-regs.h:58: +#define GOTGCTL_SESREQSCS^I^IBIT(0)$ ERROR: code indent should never use tabs #80: FILE: include/hw/usb/dwc2-regs.h:60: +#define GOTGINT^I^I^I^IHSOTG_REG(0x004)$ ERROR: code indent should never use tabs #81: FILE: include/hw/usb/dwc2-regs.h:61: +#define GOTGINT_DBNCE_DONE^I^IBIT(19)$ ERROR: code indent should never use tabs #82: FILE: include/hw/usb/dwc2-regs.h:62: +#define GOTGINT_A_DEV_TOUT_CHG^I^IBIT(18)$ ERROR: code indent should never use tabs #83: FILE: include/hw/usb/dwc2-regs.h:63: +#define GOTGINT_HST_NEG_DET^I^IBIT(17)$ ERROR: code indent should never use tabs #84: FILE: include/hw/usb/dwc2-regs.h:64: +#define GOTGINT_HST_NEG_SUC_STS_CHNG^IBIT(9)$ ERROR: code indent should never use tabs #85: FILE: include/hw/usb/dwc2-regs.h:65: +#define GOTGINT_SES_REQ_SUC_STS_CHNG^IBIT(8)$ ERROR: code indent should never use tabs #86: FILE: include/hw/usb/dwc2-regs.h:66: +#define GOTGINT_SES_END_DET^I^IBIT(2)$ ERROR: code indent should never use tabs #88: FILE: include/hw/usb/dwc2-regs.h:68: +#define GAHBCFG^I^I^I^IHSOTG_REG(0x008)$ ERROR: code indent should never use tabs #89: FILE: include/hw/usb/dwc2-regs.h:69: +#define GAHBCFG_AHB_SINGLE^I^IBIT(23)$ ERROR: code indent should never use tabs #90: FILE:
[PATCH v2 4/6] dwc-hsotg USB host controller emulation
Add the dwc-hsotg (dwc2) USB host controller emulation code. Based on hw/usb/hcd-ehci.c and hw/usb/hcd-ohci.c. Note that to use this with the dwc-otg driver in the Raspbian kernel, you must pass the option "dwc_otg.fiq_fsm_enable=0" on the kernel command line. Emulation of slave mode and of descriptor-DMA mode has not been implemented yet. These modes are seldom used. I have used some on-line sources of information while developing this emulation, including: http://www.capital-micro.com/PDF/CME-M7_Family_User_Guide_EN.pdf has a pretty complete description of the controller starting on page 370. https://sourceforge.net/p/wive-ng/wive-ng-mt/ci/master/tree/docs/DataSheets/RT3050_5x_V2.0_081408_0902.pdf has a description of the controller registers starting on page 130. Signed-off-by: Paul Zimmerman --- hw/usb/hcd-dwc2.c | 1301 +++ hw/usb/trace-events | 47 ++ 2 files changed, 1348 insertions(+) create mode 100644 hw/usb/hcd-dwc2.c diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c new file mode 100644 index 00..fd85543f4d --- /dev/null +++ b/hw/usb/hcd-dwc2.c @@ -0,0 +1,1301 @@ +/* + * dwc-hsotg (dwc2) USB host controller emulation + * + * Based on hw/usb/hcd-ehci.c and hw/usb/hcd-ohci.c + * + * Copyright (c) 2020 Paul Zimmerman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/usb/dwc2-regs.h" +#include "hw/usb/hcd-dwc2.h" +#include "trace.h" +#include "qemu/error-report.h" +#include "qemu/main-loop.h" + +#define USB_HZ_FS 1200 +#define USB_HZ_HS 9600 + +/* nifty macros from Arnon's EHCI version */ +#define get_field(data, field) \ +(((data) & field##_MASK) >> field##_SHIFT) + +#define set_field(data, newval, field) do { \ +uint32_t val = *data; \ +val &= ~field##_MASK; \ +val |= ((newval) << field##_SHIFT) & field##_MASK; \ +*data = val; \ +} while (0) + +#define get_bit(data, bitmask) \ +(!!((data) & bitmask)) + +/* update irq line */ +static inline void dwc2_update_irq(DWC2State *s) +{ +static int oldlevel; +int level = 0; + +if ((s->gintsts & s->gintmsk) && (s->gahbcfg & GAHBCFG_GLBL_INTR_EN)) { +level = 1; +} +if (level != oldlevel) { +oldlevel = level; +trace_usb_dwc2_update_irq(level); +qemu_set_irq(s->irq, level); +} +} + +/* flag interrupt condition */ +static inline void dwc2_raise_global_irq(DWC2State *s, uint32_t intr) +{ +if (!(s->gintsts & intr)) { +s->gintsts |= intr; +trace_usb_dwc2_raise_global_irq(intr); +dwc2_update_irq(s); +} +} + +static inline void dwc2_lower_global_irq(DWC2State *s, uint32_t intr) +{ +if (s->gintsts & intr) { +s->gintsts &= ~intr; +trace_usb_dwc2_lower_global_irq(intr); +dwc2_update_irq(s); +} +} + +static inline void dwc2_raise_host_irq(DWC2State *s, uint32_t host_intr) +{ +if (!(s->haint & host_intr)) { +s->haint |= host_intr; +s->haint &= 0x; +trace_usb_dwc2_raise_host_irq(host_intr); +if (s->haint & s->haintmsk) { +dwc2_raise_global_irq(s, GINTSTS_HCHINT); +} +} +} + +static inline void dwc2_lower_host_irq(DWC2State *s, uint32_t host_intr) +{ +if (s->haint & host_intr) { +s->haint &= ~host_intr; +trace_usb_dwc2_lower_host_irq(host_intr); +if (!(s->haint & s->haintmsk)) { +dwc2_lower_global_irq(s, GINTSTS_HCHINT); +} +} +} + +static inline void dwc2_update_hc_irq(DWC2State *s, int index) +{ +uint32_t host_intr = 1 << (index >> 3); + +if (s->hreg1[index + 2] & s->hreg1[index + 3]) { +dwc2_raise_host_irq(s, host_intr); +} else { +dwc2_lower_host_irq(s, host_intr); +} +} + +/* set a timer for EOF */ +static void dwc2_eof_timer(DWC2State *s) +{ +timer_mod(s->eof_timer, s->sof_time + s->usb_frame_time); +} + +/* Set a timer for EOF and generate a SOF event */ +static void dwc2_sof(DWC2State *s) +{ +s->sof_time += s->usb_frame_time; +trace_usb_dwc2_sof(s->sof_time); +dwc2_eof_timer(s); +dwc2_raise_global_irq(s, GINTSTS_SOF); +} + +/* Do frame processing on frame boundary */ +static void dwc2_frame_boundary(void *opaque) +{ +DWC2State *s = opaque; + +/* Frame boundary, so do EOF stuff here */ + +/* Increment frame number */ +s->frame_number = (s->frame_number + 1) & 0x; +s->hfnum = (s->hfnum & ~HFNUM_FRNUM_MASK) | +
[PATCH v2 6/6] Wire in the dwc-hsotg USB host controller emulation
Wire the dwc-hsotg (dwc2) emulation into Qemu Signed-off-by: Paul Zimmerman --- hw/arm/bcm2835_peripherals.c | 21 - hw/usb/Kconfig | 5 + hw/usb/Makefile.objs | 1 + include/hw/arm/bcm2835_peripherals.h | 3 ++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index dd7e6883cb..932d084a50 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -127,6 +127,13 @@ static void bcm2835_peripherals_init(Object *obj) sysbus_init_child_obj(obj, "mphi", >mphi, sizeof(s->mphi), TYPE_BCM2835_MPHI); +/* DWC2 */ +sysbus_init_child_obj(obj, "dwc2", >dwc2, sizeof(s->dwc2), + TYPE_DWC2_USB); + +object_property_add_const_link(OBJECT(>dwc2), "dma-mr", + OBJECT(>gpu_bus_mr), _abort); + object_property_add_const_link(OBJECT(>gpio), "sdbus-sdhci", OBJECT(>sdhci.sdbus), _abort); object_property_add_const_link(OBJECT(>gpio), "sdbus-sdhost", @@ -384,6 +391,19 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in_named(DEVICE(>ic), BCM2835_IC_GPU_IRQ, INTERRUPT_HOSTPORT)); +/* DWC2 */ +object_property_set_bool(OBJECT(>dwc2), true, "realized", ); +if (err) { +error_propagate(errp, err); +return; +} + +memory_region_add_subregion(>peri_mr, USB_OTG_OFFSET, +sysbus_mmio_get_region(SYS_BUS_DEVICE(>dwc2), 0)); +sysbus_connect_irq(SYS_BUS_DEVICE(>dwc2), 0, +qdev_get_gpio_in_named(DEVICE(>ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_USB)); + create_unimp(s, >armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40); create_unimp(s, >cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000); create_unimp(s, >a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000); @@ -397,7 +417,6 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) create_unimp(s, >otp, "bcm2835-otp", OTP_OFFSET, 0x80); create_unimp(s, >dbus, "bcm2835-dbus", DBUS_OFFSET, 0x8000); create_unimp(s, >ave0, "bcm2835-ave0", AVE0_OFFSET, 0x8000); -create_unimp(s, >dwc2, "dwc-usb2", USB_OTG_OFFSET, 0x1000); create_unimp(s, >sdramc, "bcm2835-sdramc", SDRAMC_OFFSET, 0x100); } diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig index 464348ba14..d4d8c37c28 100644 --- a/hw/usb/Kconfig +++ b/hw/usb/Kconfig @@ -46,6 +46,11 @@ config USB_MUSB bool select USB +config USB_DWC2 +bool +default y +select USB + config TUSB6010 bool select USB_MUSB diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs index 66835e5bf7..fa5c3fa1b8 100644 --- a/hw/usb/Makefile.objs +++ b/hw/usb/Makefile.objs @@ -12,6 +12,7 @@ common-obj-$(CONFIG_USB_EHCI_SYSBUS) += hcd-ehci-sysbus.o common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o +common-obj-$(CONFIG_USB_DWC2) += hcd-dwc2.o common-obj-$(CONFIG_TUSB6010) += tusb6010.o common-obj-$(CONFIG_IMX) += chipidea.o diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h index 77958ca60e..0841d54614 100644 --- a/include/hw/arm/bcm2835_peripherals.h +++ b/include/hw/arm/bcm2835_peripherals.h @@ -26,6 +26,7 @@ #include "hw/sd/bcm2835_sdhost.h" #include "hw/gpio/bcm2835_gpio.h" #include "hw/timer/bcm2835_systmr.h" +#include "hw/usb/hcd-dwc2.h" #include "hw/misc/unimp.h" #define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals" @@ -66,7 +67,7 @@ typedef struct BCM2835PeripheralState { UnimplementedDeviceState ave0; UnimplementedDeviceState bscsl; UnimplementedDeviceState smi; -UnimplementedDeviceState dwc2; +DWC2State dwc2; UnimplementedDeviceState sdramc; } BCM2835PeripheralState; -- 2.17.1
[PATCH v2 2/6] dwc-hsotg USB host controller register definitions
Import the dwc2 register definitions file from the Linux kernel. This is a copy of drivers/usb/dwc2/hw.h from the mainline Linux kernel, the only changes being two instances of 'u32' changed to 'uint32_t' to allow it to compile Signed-off-by: Paul Zimmerman --- include/hw/usb/dwc2-regs.h | 895 + 1 file changed, 895 insertions(+) create mode 100644 include/hw/usb/dwc2-regs.h diff --git a/include/hw/usb/dwc2-regs.h b/include/hw/usb/dwc2-regs.h new file mode 100644 index 00..96dc07fb6f --- /dev/null +++ b/include/hw/usb/dwc2-regs.h @@ -0,0 +1,895 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * hw.h - DesignWare HS OTG Controller hardware definitions + * + * Copyright 2004-2013 Synopsys, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions, and the following disclaimer, + *without modification. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + *to endorse or promote products derived from this software without + *specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DWC2_HW_H__ +#define __DWC2_HW_H__ + +#define HSOTG_REG(x) (x) + +#define GOTGCTLHSOTG_REG(0x000) +#define GOTGCTL_CHIRPENBIT(27) +#define GOTGCTL_MULT_VALID_BC_MASK (0x1f << 22) +#define GOTGCTL_MULT_VALID_BC_SHIFT22 +#define GOTGCTL_OTGVER BIT(20) +#define GOTGCTL_BSESVLDBIT(19) +#define GOTGCTL_ASESVLDBIT(18) +#define GOTGCTL_DBNC_SHORT BIT(17) +#define GOTGCTL_CONID_BBIT(16) +#define GOTGCTL_DBNCE_FLTR_BYPASS BIT(15) +#define GOTGCTL_DEVHNPEN BIT(11) +#define GOTGCTL_HSTSETHNPENBIT(10) +#define GOTGCTL_HNPREQ BIT(9) +#define GOTGCTL_HSTNEGSCS BIT(8) +#define GOTGCTL_SESREQ BIT(1) +#define GOTGCTL_SESREQSCS BIT(0) + +#define GOTGINTHSOTG_REG(0x004) +#define GOTGINT_DBNCE_DONE BIT(19) +#define GOTGINT_A_DEV_TOUT_CHG BIT(18) +#define GOTGINT_HST_NEG_DETBIT(17) +#define GOTGINT_HST_NEG_SUC_STS_CHNG BIT(9) +#define GOTGINT_SES_REQ_SUC_STS_CHNG BIT(8) +#define GOTGINT_SES_END_DETBIT(2) + +#define GAHBCFGHSOTG_REG(0x008) +#define GAHBCFG_AHB_SINGLE BIT(23) +#define GAHBCFG_NOTI_ALL_DMA_WRIT BIT(22) +#define GAHBCFG_REM_MEM_SUPP BIT(21) +#define GAHBCFG_P_TXF_EMP_LVL BIT(8) +#define GAHBCFG_NP_TXF_EMP_LVL BIT(7) +#define GAHBCFG_DMA_EN BIT(5) +#define GAHBCFG_HBSTLEN_MASK (0xf << 1) +#define GAHBCFG_HBSTLEN_SHIFT 1 +#define GAHBCFG_HBSTLEN_SINGLE 0 +#define GAHBCFG_HBSTLEN_INCR 1 +#define GAHBCFG_HBSTLEN_INCR4 3 +#define GAHBCFG_HBSTLEN_INCR8 5 +#define GAHBCFG_HBSTLEN_INCR16 7 +#define GAHBCFG_GLBL_INTR_EN BIT(0) +#define GAHBCFG_CTRL_MASK (GAHBCFG_P_TXF_EMP_LVL | \ +GAHBCFG_NP_TXF_EMP_LVL | \ +GAHBCFG_DMA_EN | \ +GAHBCFG_GLBL_INTR_EN) + +#define GUSBCFGHSOTG_REG(0x00C) +#define GUSBCFG_FORCEDEVMODE BIT(30) +#define GUSBCFG_FORCEHOSTMODE BIT(29) +#define GUSBCFG_TXENDDELAY BIT(28) +#define
[PATCH v2 1/6] Add BCM2835 SOC MPHI emulation
Add BCM2835 SOC MPHI emulation. It is very basic, only providing the FIQ interrupt needed to allow the dwc-otg USB host controller driver in the Raspbian kernel to function. Signed-off-by: Paul Zimmerman --- hw/arm/bcm2835_peripherals.c | 17 +++ hw/misc/Makefile.objs| 1 + hw/misc/bcm2835_mphi.c | 193 +++ include/hw/arm/bcm2835_peripherals.h | 2 + include/hw/misc/bcm2835_mphi.h | 50 +++ 5 files changed, 263 insertions(+) create mode 100644 hw/misc/bcm2835_mphi.c create mode 100644 include/hw/misc/bcm2835_mphi.h diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index 17207ae07e..dd7e6883cb 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -123,6 +123,10 @@ static void bcm2835_peripherals_init(Object *obj) sysbus_init_child_obj(obj, "gpio", >gpio, sizeof(s->gpio), TYPE_BCM2835_GPIO); +/* Mphi */ +sysbus_init_child_obj(obj, "mphi", >mphi, sizeof(s->mphi), + TYPE_BCM2835_MPHI); + object_property_add_const_link(OBJECT(>gpio), "sdbus-sdhci", OBJECT(>sdhci.sdbus), _abort); object_property_add_const_link(OBJECT(>gpio), "sdbus-sdhost", @@ -367,6 +371,19 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) return; } +/* Mphi */ +object_property_set_bool(OBJECT(>mphi), true, "realized", ); +if (err) { +error_propagate(errp, err); +return; +} + +memory_region_add_subregion(>peri_mr, MPHI_OFFSET, +sysbus_mmio_get_region(SYS_BUS_DEVICE(>mphi), 0)); +sysbus_connect_irq(SYS_BUS_DEVICE(>mphi), 0, +qdev_get_gpio_in_named(DEVICE(>ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_HOSTPORT)); + create_unimp(s, >armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40); create_unimp(s, >cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000); create_unimp(s, >a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000); diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 68aae2eabb..91085cc21b 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -57,6 +57,7 @@ common-obj-$(CONFIG_OMAP) += omap_l4.o common-obj-$(CONFIG_OMAP) += omap_sdrc.o common-obj-$(CONFIG_OMAP) += omap_tap.o common-obj-$(CONFIG_RASPI) += bcm2835_mbox.o +common-obj-$(CONFIG_RASPI) += bcm2835_mphi.o common-obj-$(CONFIG_RASPI) += bcm2835_property.o common-obj-$(CONFIG_RASPI) += bcm2835_rng.o common-obj-$(CONFIG_RASPI) += bcm2835_thermal.o diff --git a/hw/misc/bcm2835_mphi.c b/hw/misc/bcm2835_mphi.c new file mode 100644 index 00..2fdd39c138 --- /dev/null +++ b/hw/misc/bcm2835_mphi.c @@ -0,0 +1,193 @@ +/* + * BCM2835 SOC MPHI emulation + * + * Very basic emulation, only providing the FIQ interrupt needed to + * allow the dwc-otg USB host controller driver in the Raspbian kernel + * to function. + * + * Copyright (c) 2020 Paul Zimmerman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/misc/bcm2835_mphi.h" +#include "qemu/error-report.h" +#include "qemu/main-loop.h" + +static inline void mphi_raise_irq(BCM2835MphiState *s) +{ +qemu_set_irq(s->irq, 1); +} + +static inline void mphi_lower_irq(BCM2835MphiState *s) +{ +qemu_set_irq(s->irq, 0); +} + +static uint64_t mphi_reg_read(void *ptr, hwaddr addr, unsigned size) +{ +BCM2835MphiState *s = ptr; +uint32_t reg = s->regbase + addr; +uint32_t val = 0; + +switch (reg) { +case 0x28: /* outdda */ +val = s->outdda; +break; +case 0x2c: /* outddb */ +val = s->outddb; +break; +case 0x4c: /* ctrl */ +val = s->ctrl; +val |= 1 << 17; +break; +case 0x50: /* intstat */ +val = s->intstat; +break; +case 0x1f0: /* swirq_set */ +val = s->swirq_set; +break; +case 0x1f4: /* swirq_clr */ +val = s->swirq_clr; +break; +default: +break; +} + +return val; +} + +static void mphi_reg_write(void *ptr, hwaddr addr, uint64_t val, unsigned size) +{ +BCM2835MphiState *s = ptr; +uint32_t reg = s->regbase + addr; +uint32_t old; +int do_irq = 0; + +val &= 0x; + +switch (reg) { +case 0x28: /* outdda */ +old = s->outdda; +s->outdda = val; +break; +case 0x2c: /* outddb */ +old = s->outddb; +
[PATCH v2 0/6] dwc-hsotg (aka dwc2) USB host controller emulation
This patch series adds emulation for the dwc-hsotg USB controller, which is used on the Raspberry Pi 3 and earlier, as well as a number of other development boards. The main benefit for Raspberry Pi is that this enables networking on these boards, since the network adapter is attached via USB. The emulation is working quite well, I have tested with USB network, mass storage, mouse, keyboard, and tablet. I have tested with the dwc2 driver in the upstream Linux kernel, and with the dwc-otg driver in the Raspbian kernel. One remaining issue is that USB redirection does not work, I tried connecting to a USB stick on the host, but the device generates babble errors and does not work. I will continue to work on this issue. The patch series also includes a very basic emulation of the MPHI device on the Raspberry Pi SOC, which provides the FIQ interrupt that is used by the dwc-otg driver in the Raspbian kernel. But that driver still does not work in full FIQ mode, so it is necessary to add a parameter to the kernel command line ("dwc_otg.fiq_fsm_enable=0") to make it work. I have used some on-line sources of information while developing this emulation, including: http://www.capital-micro.com/PDF/CME-M7_Family_User_Guide_EN.pdf has a pretty complete description of the controller starting on page 370. https://sourceforge.net/p/wive-ng/wive-ng-mt/ci/master/tree/docs/DataSheets/RT3050_5x_V2.0_081408_0902.pdf has a description of the controller registers starting on page 130. Changes from v1: - Fixed checkpatch errors/warnings, except for dwc2-regs.h since that is a direct import from the Linux kernel. - Switched from debug printfs to tracepoints in hcd-dwc2.c, on the advice of Gerd. I just dropped the debug prints in bcm2835_mphi.c, since I didn't consider them very useful. - Updated a couple of the commit messages with more info. Thanks for your time, Paul --- Paul Zimmerman (6): Add BCM2835 SOC MPHI emulation dwc-hsotg USB host controller register definitions dwc-hsotg USB host controller state definitions dwc-hsotg USB host controller emulation Add short-packet handling to usb-storage driver Wire in the dwc-hsotg USB host controller emulation hw/arm/bcm2835_peripherals.c | 38 +- hw/misc/Makefile.objs|1 + hw/misc/bcm2835_mphi.c | 193 hw/usb/Kconfig |5 + hw/usb/Makefile.objs |1 + hw/usb/dev-storage.c | 15 +- hw/usb/hcd-dwc2.c| 1301 ++ hw/usb/hcd-dwc2.h| 180 hw/usb/trace-events | 47 + include/hw/arm/bcm2835_peripherals.h |5 +- include/hw/misc/bcm2835_mphi.h | 50 + include/hw/usb/dwc2-regs.h | 895 ++ 12 files changed, 2728 insertions(+), 3 deletions(-) create mode 100644 hw/misc/bcm2835_mphi.c create mode 100644 hw/usb/hcd-dwc2.c create mode 100644 hw/usb/hcd-dwc2.h create mode 100644 include/hw/misc/bcm2835_mphi.h create mode 100644 include/hw/usb/dwc2-regs.h -- 2.17.1
[PATCH v2 5/6] Add short-packet handling to usb-storage driver
The dwc-hsotg (dwc2) USB host depends on a short packet to indicate the end of an IN transfer. The usb-storage driver currently doesn't provide this, so fix it. I have tested this change rather extensively using a PC emulation with xhci, ehci, and uhci controllers, and have not observed any regressions. Signed-off-by: Paul Zimmerman --- hw/usb/dev-storage.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 5c4b57b06b..ae3c550042 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -229,6 +229,9 @@ static void usb_msd_copy_data(MSDState *s, USBPacket *p) usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len); s->scsi_len -= len; s->scsi_off += len; +if (len > s->data_len) { +len = s->data_len; +} s->data_len -= len; if (s->scsi_len == 0 || s->data_len == 0) { scsi_req_continue(s->req); @@ -303,6 +306,9 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t r if (s->data_len) { int len = (p->iov.size - p->actual_length); usb_packet_skip(p, len); +if (len > s->data_len) { +len = s->data_len; +} s->data_len -= len; } if (s->data_len == 0) { @@ -469,6 +475,9 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p) int len = p->iov.size - p->actual_length; if (len) { usb_packet_skip(p, len); +if (len > s->data_len) { +len = s->data_len; +} s->data_len -= len; if (s->data_len == 0) { s->mode = USB_MSDM_CSW; @@ -528,13 +537,17 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p) int len = p->iov.size - p->actual_length; if (len) { usb_packet_skip(p, len); +if (len > s->data_len) { +len = s->data_len; +} s->data_len -= len; if (s->data_len == 0) { s->mode = USB_MSDM_CSW; } } } -if (p->actual_length < p->iov.size) { +if (p->actual_length < p->iov.size && (p->short_not_ok || +s->scsi_len >= p->ep->max_packet_size)) { DPRINTF("Deferring packet %p [wait data-in]\n", p); s->packet = p; p->status = USB_RET_ASYNC; -- 2.17.1
[PATCH v2 3/6] dwc-hsotg USB host controller state definitions
Add the dwc-hsotg (dwc2) USB host controller state definitions. Mostly based on hw/usb/hcd-ehci.h. Signed-off-by: Paul Zimmerman --- hw/usb/hcd-dwc2.h | 180 ++ 1 file changed, 180 insertions(+) create mode 100644 hw/usb/hcd-dwc2.h diff --git a/hw/usb/hcd-dwc2.h b/hw/usb/hcd-dwc2.h new file mode 100644 index 00..80956fa318 --- /dev/null +++ b/hw/usb/hcd-dwc2.h @@ -0,0 +1,180 @@ +/* + * dwc-hsotg (dwc2) USB host controller state definitions + * + * Based on hw/usb/hcd-ehci.h + * + * Copyright (c) 2020 Paul Zimmerman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 HW_USB_DWC2_H +#define HW_USB_DWC2_H + +#include "qemu/timer.h" +#include "hw/irq.h" +#include "hw/sysbus.h" +#include "hw/usb.h" +#include "sysemu/dma.h" + +#define DWC2_MMIO_SIZE 0x11000 + +#define NB_PORTS1 /* Number of downstream ports */ +#define NB_CHAN 8 /* Number of host channels */ +#define MAX_XFER_SIZE 65536 /* Max transfer size expected in HCTSIZ */ + +typedef struct DWC2Packet DWC2Packet; +typedef struct DWC2State DWC2State; + +enum async_state { +DWC2_ASYNC_NONE = 0, +DWC2_ASYNC_INITIALIZED, +DWC2_ASYNC_INFLIGHT, +DWC2_ASYNC_FINISHED, +}; + +struct DWC2Packet { +USBPacket packet; +USBDevice *dev; +USBEndpoint *ep; +uint32_t index; +uint32_t epnum; +uint32_t mps; +uint32_t pid; +uint32_t pcnt; +uint32_t len; +bool small; +bool needs_service; +enum async_state async; +}; + +struct DWC2State { +SysBusDevice parent_obj; +USBBus bus; +DeviceState *device; +qemu_irq irq; +MemoryRegion *dma_mr; +AddressSpace *as; +AddressSpace dma_as; +MemoryRegion mem; +MemoryRegion mem_glbreg; +MemoryRegion mem_fszreg; +MemoryRegion mem_hreg0; +MemoryRegion mem_hreg1; +MemoryRegion mem_pcgreg; +MemoryRegion mem_hreg2; +uint16_t glbregbase; +uint16_t fszregbase; +uint16_t hreg0base; +uint16_t hreg1base; +uint16_t pcgregbase; +uint16_t hreg2base; +uint16_t portnr; + +union { +uint32_t glbreg[0x70 / sizeof(uint32_t)]; +struct { +uint32_t gotgctl; /* 00 */ +uint32_t gotgint; /* 04 */ +uint32_t gahbcfg; /* 08 */ +uint32_t gusbcfg; /* 0c */ +uint32_t grstctl; /* 10 */ +uint32_t gintsts; /* 14 */ +uint32_t gintmsk; /* 18 */ +uint32_t grxstsr; /* 1c */ +uint32_t grxstsp; /* 20 */ +uint32_t grxfsiz; /* 24 */ +uint32_t gnptxfsiz; /* 28 */ +uint32_t gnptxsts; /* 2c */ +uint32_t gi2cctl; /* 30 */ +uint32_t gpvndctl; /* 34 */ +uint32_t ggpio; /* 38 */ +uint32_t guid; /* 3c */ +uint32_t gsnpsid; /* 40 */ +uint32_t ghwcfg1; /* 44 */ +uint32_t ghwcfg2; /* 48 */ +uint32_t ghwcfg3; /* 4c */ +uint32_t ghwcfg4; /* 50 */ +uint32_t glpmcfg; /* 54 */ +uint32_t gpwrdn;/* 58 */ +uint32_t gdfifocfg; /* 5c */ +uint32_t gadpctl; /* 60 */ +uint32_t grefclk; /* 64 */ +uint32_t gintmsk2; /* 68 */ +uint32_t gintsts2; /* 6c */ +}; +}; + +union { +uint32_t fszreg[0x4 / sizeof(uint32_t)]; +struct { +uint32_t hptxfsiz; /* 100 */ +}; +}; + +union { +uint32_t hreg0[0x44 / sizeof(uint32_t)]; +struct { +uint32_t hcfg; /* 400 */ +uint32_t hfir; /* 404 */ +uint32_t hfnum; /* 408 */ +uint32_t rsvd0; /* 40c */ +uint32_t hptxsts; /* 410 */ +uint32_t haint; /* 414 */ +uint32_t haintmsk; /* 418 */ +uint32_t hflbaddr; /* 41c */ +uint32_t rsvd1[8]; /* 420-43c */ +uint32_t hprt0; /* 440 */ +}; +}; + +uint32_t hreg1[0x20 * NB_CHAN / sizeof(uint32_t)]; +#define hcchar(_ch) hreg1[((_ch) << 3) + 0] /* 500, 520, ... */ +#define hcsplt(_ch) hreg1[((_ch) << 3) + 1] /* 504, 524, ... */ +#define hcint(_ch) hreg1[((_ch) << 3) + 2] /* 508, 528, ... */ +#define hcintmsk(_ch) hreg1[((_ch) << 3) + 3]
Re: [PATCH] target/mips: Add MAC2008 support
于 2020年3月29日 GMT+08:00 上午3:09:16, Richard Henderson 写到: >On 3/28/20 2:08 AM, Jiaxun Yang wrote: >> -gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); >> +if (ctx->mac2008) { >> +gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, >fp2); >> +} else { >> +gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, >fp2); >> +} >> > >Surely this test is backward, that mac2008 invokes maddf. Sorry for my stupid fault. Will fix in v2. > > >r~ -- Jiaxun Yang
Re: [PATCH] target/mips: Add MAC2008 support
On 3/28/20 2:08 AM, Jiaxun Yang wrote: > -gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); > +if (ctx->mac2008) { > +gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); > +} else { > +gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); > +} > Surely this test is backward, that mac2008 invokes maddf. r~
[PATCH] i386: hvf: Reset IRQ inhibition after moving RIP
The sequence of instructions exposes an issue: sti hlt Interrupts cannot be delivered to hvf after hlt instruction cpu because HF_INHIBIT_IRQ_MASK is set just before hlt is handled and never reset after moving instruction pointer beyond hlt. So, after hvf_vcpu_exec() returns, CPU thread gets locked up forever in qemu_wait_io_event() (cpu_thread_is_idle() evaluates inhibition flag and considers the CPU idle if the flag is set). Cc: Cameron Esfahani Signed-off-by: Roman Bolshakov --- target/i386/hvf/vmx.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h index 03d2c79b9c..ce2a1532d5 100644 --- a/target/i386/hvf/vmx.h +++ b/target/i386/hvf/vmx.h @@ -167,6 +167,8 @@ static inline void macvm_set_cr4(hv_vcpuid_t vcpu, uint64_t cr4) static inline void macvm_set_rip(CPUState *cpu, uint64_t rip) { +X86CPU *x86_cpu = X86_CPU(cpu); +CPUX86State *env = _cpu->env; uint64_t val; /* BUG, should take considering overlap.. */ @@ -176,6 +178,7 @@ static inline void macvm_set_rip(CPUState *cpu, uint64_t rip) val = rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY); if (val & (VMCS_INTERRUPTIBILITY_STI_BLOCKING | VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) { +env->hflags &= ~HF_INHIBIT_IRQ_MASK; wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, val & ~(VMCS_INTERRUPTIBILITY_STI_BLOCKING | VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)); -- 2.24.1
Re: [PATCH v6 57/61] target/riscv: floating-point scalar move instructions
On 2020/3/28 11:44, Richard Henderson wrote: On 3/17/20 8:06 AM, LIU Zhiwei wrote: +/* Floating-Point Scalar Move Instructions */ +static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a) +{ +if (!s->vill && has_ext(s, RVF) && +(s->mstatus_fs != 0) && (s->sew != 0)) { +#ifdef HOST_WORDS_BIGENDIAN +int ofs = vreg_ofs(s, a->rs2) + ((7 >> s->sew) << s->sew); +#else +int ofs = vreg_ofs(s, a->rs2); +#endif Use endian_ofs from patch 55. Yes, I forgot it. +switch (s->sew) { +case MO_8: +tcg_gen_ld8u_i64(cpu_fpr[a->rd], cpu_env, ofs); +tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], +0xff00ULL); +break; MO_8 should be illegal. Yes, it has been checked in s->sew != 0. +case MO_16: +tcg_gen_ld16u_i64(cpu_fpr[a->rd], cpu_env, ofs); +tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], +0xULL); +break; +case MO_32: +tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs); +tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], +0xULL); +break; +default: +if (has_ext(s, RVD)) { +tcg_gen_ld_i64(cpu_fpr[a->rd], cpu_env, ofs); +} else { +tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs); +tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], +0xULL); +} +break; Maybe better with MO_64 and default: g_assert_not_reached(). +static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) +{ +if (!s->vill && has_ext(s, RVF) && (s->sew != 0)) { +TCGv_ptr dest; +TCGv_i64 src1; +static gen_helper_vfmv_s_f * const fns[3] = { +gen_helper_vfmv_s_f_h, +gen_helper_vfmv_s_f_w, +gen_helper_vfmv_s_f_d You shouldn't need to duplicate the vmv_s_x_* helpers. All these helpers will be away in v7. Zhiwei r~
Re: [PATCH v6 55/61] target/riscv: integer extract instruction
On 2020/3/28 11:36, Richard Henderson wrote: On 3/17/20 8:06 AM, LIU Zhiwei wrote: +/* Integer Extract Instruction */ +static void extract_element(TCGv dest, TCGv_ptr base, +int ofs, int sew) +{ +switch (sew) { +case MO_8: +tcg_gen_ld8u_tl(dest, base, ofs); +break; +case MO_16: +tcg_gen_ld16u_tl(dest, base, ofs); +break; +default: +tcg_gen_ld32u_tl(dest, base, ofs); +break; +#if TARGET_LONG_BITS == 64 +case MO_64: +tcg_gen_ld_i64(dest, base, ofs); +break; +#endif +} +} I just remembered that this doesn't handle HOST_WORDS_BIGENDIAN properly -- the MO_64 case for TARGET_LONG_BITS == 32. Because we computed the offset for MO_64, not MO_32, we need case MO_64: if (TARGET_LONG_BITS == 64) { tcg_gen_ld_i64(dest, base, ofs); break; } #ifdef HOST_WORDS_BIGENDIAN ofs += 4; #endif /* fall through */ case MO_32: tcg_gen_ld32u_tl(dest, base, ofs); break; default: g_assert_not_reached(); Yes, it should be. As extract_element and gather_element are very similar . I will merge them to load_element in v7. Zhiwei r~
Re: [PATCH v6 18/61] target/riscv: vector single-width integer multiply instructions
On 2020/3/28 23:47, Richard Henderson wrote: On 3/28/20 8:17 AM, LIU Zhiwei wrote: Missed the improvement here. See tcg_gen_mulsu2_i64. Though I have not gotten the principle, the code in tcg_gen_mulsu2_i64 is much tidier. Let A = signed operand, B = unsigned operand P = unsigned product If the sign bit A is set, then P is too large. In that case we subtract 2**64 * B to fix that: HI_P -= (A < 0 ? B : 0) where the conditional is computed as (A >> 63) & B. I think I get it. LET A = 2 ** 64 - X THEN X = 2 ** 64 - A SIGNED_P = -X * B if (A * B == P) then (2 ** 64 - X) * B == P 2 **64 * B - X * B == P -X *B == P - 2**64*B HI_P -= (A < 0 ? B :0) Zhiwei r~
Re: [PATCH v4 0/2] Replaced locks with lock guard macros
On 3/27/20 11:38 PM, Daniel Brodsky wrote: > On Thu, Mar 26, 2020 at 11:01 AM Richard Henderson > wrote: >> >> My preference is to add -Wno-tautological-type-limit-compare in >> configure, so we don't have to work around this same issue elsewhere >> in the code base. >> >> r~ > > What do you think would be the best way to add this? I could change > all additions of the `-m32` flag to instead use `-m32 > -Wno-tautological-type-limit-compare` or add the flag if qemu is being > compiled with clang and `-m32` already enabled. I was going to add it unconditionally, with all of the other warning flags. Except that it doesn't work -- clang-9 *still* warns. Clearly a clang bug, but there doesn't seem to be any workaround at all except --disable-werror. r~
[Bug 1868116] Re: QEMU monitor no longer works
** Bug watch added: Debian Bug tracker #954266 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=954266 ** Also affects: qemu (Debian) via https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=954266 Importance: Unknown Status: Unknown -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1868116 Title: QEMU monitor no longer works Status in QEMU: New Status in qemu package in Ubuntu: Triaged Status in vte2.91 package in Ubuntu: Fix Released Status in qemu package in Debian: Unknown Bug description: Repro: VTE $ meson _build && ninja -C _build && ninja -C _build install qemu: $ ../configure --python=/usr/bin/python3 --disable-werror --disable-user --disable-linux-user --disable-docs --disable-guest-agent --disable-sdl --enable-gtk --disable-vnc --disable-xen --disable-brlapi --disable-fdt --disable-hax --disable-vde --disable-netmap --disable-rbd --disable-libiscsi --disable-libnfs --disable-smartcard --disable-libusb --disable-usb-redir --disable-seccomp --disable-glusterfs --disable-tpm --disable-numa --disable-opengl --disable-virglrenderer --disable-xfsctl --disable-vxhs --disable-slirp --disable-blobs --target-list=x86_64-softmmu --disable-rdma --disable-pvrdma --disable-attr --disable-vhost-net --disable-vhost-vsock --disable-vhost-scsi --disable-vhost-crypto --disable-vhost-user --disable-spice --disable-qom-cast-debug --disable-vxhs --disable-bochs --disable-cloop --disable-dmg --disable-qcow1 --disable-vdi --disable-vvfat --disable-qed --disable-parallels --disable-sheepdog --disable-avx2 --disable-nettle --disable-gnutls --disable-capstone --disable-tools --disable-libpmem --disable-iconv --disable-cap-ng $ make Test: $ LD_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH ./build/x86_64-softmmu/qemu-system-x86_64 -enable-kvm --drive media=cdrom,file=http://archive.ubuntu.com/ubuntu/dists/bionic/main/installer-amd64/current/images/netboot/mini.iso - switch to monitor with CTRL+ALT+2 - try to enter something Affects head of both usptream git repos. --- original bug --- It was observed that the QEMU console (normally accessible using Ctrl+Alt+2) accepts no input, so it can't be used. This is being problematic because there are cases where it's required to send commands to the guest, or key combinations that the host would grab (as Ctrl-Alt-F1 or Alt-F4). ProblemType: Bug DistroRelease: Ubuntu 20.04 Package: qemu 1:4.2-3ubuntu2 Uname: Linux 5.6.0-rc6+ x86_64 ApportVersion: 2.20.11-0ubuntu20 Architecture: amd64 CurrentDesktop: XFCE Date: Thu Mar 19 12:16:31 2020 Dependencies: InstallationDate: Installed on 2017-06-13 (1009 days ago) InstallationMedia: Xubuntu 17.04 "Zesty Zapus" - Release amd64 (20170412) KvmCmdLine: COMMAND STAT EUID RUID PIDPPID %CPU COMMAND qemu-system-x86 Sl+ 1000 1000 34275 25235 29.2 qemu-system-x86_64 -m 4G -cpu Skylake-Client -device virtio-vga,virgl=true,xres=1280,yres=720 -accel kvm -device nec-usb-xhci -serial vc -serial stdio -hda /home/usuario/Sistemas/androidx86.img -display gtk,gl=on -device usb-audio kvm-nx-lpage-re S0 0 34284 2 0.0 [kvm-nx-lpage-re] kvm-pit/34275 S0 0 34286 2 0.0 [kvm-pit/34275] MachineType: LENOVO 80UG ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-5.6.0-rc6+ root=UUID=6b4ae5c0-c78c-49a6-a1ba-029192618a7a ro quiet ro kvm.ignore_msrs=1 kvm.report_ignored_msrs=0 kvm.halt_poll_ns=0 kvm.halt_poll_ns_grow=0 i915.enable_gvt=1 i915.fastboot=1 cgroup_enable=memory swapaccount=1 zswap.enabled=1 zswap.zpool=z3fold resume=UUID=a82e38a0-8d20-49dd-9cbd-de7216b589fc log_buf_len=16M usbhid.quirks=0x0079:0x0006:0x10 config_scsi_mq_default=y scsi_mod.use_blk_mq=1 mtrr_gran_size=64M mtrr_chunk_size=64M nbd.nbds_max=2 nbd.max_part=63 SourcePackage: qemu UpgradeStatus: Upgraded to focal on 2019-12-22 (87 days ago) dmi.bios.date: 08/09/2018 dmi.bios.vendor: LENOVO dmi.bios.version: 0XCN45WW dmi.board.asset.tag: NO Asset Tag dmi.board.name: Toronto 4A2 dmi.board.vendor: LENOVO dmi.board.version: SDK0J40679 WIN dmi.chassis.asset.tag: NO Asset Tag dmi.chassis.type: 10 dmi.chassis.vendor: LENOVO dmi.chassis.version: Lenovo ideapad 310-14ISK dmi.modalias: dmi:bvnLENOVO:bvr0XCN45WW:bd08/09/2018:svnLENOVO:pn80UG:pvrLenovoideapad310-14ISK:rvnLENOVO:rnToronto4A2:rvrSDK0J40679WIN:cvnLENOVO:ct10:cvrLenovoideapad310-14ISK: dmi.product.family: IDEAPAD dmi.product.name: 80UG dmi.product.sku: LENOVO_MT_80UG_BU_idea_FM_Lenovo ideapad 310-14ISK dmi.product.version: Lenovo ideapad 310-14ISK dmi.sys.vendor: LENOVO mtime.conffile..etc.apport.crashdb.conf: 2019-08-29T08:39:36.787240 To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1868116/+subscriptions
Re: [PATCH v6 41/61] target/riscv: vector floating-point merge instructions
On 2020/3/28 11:23, Richard Henderson wrote: On 3/17/20 8:06 AM, LIU Zhiwei wrote: +for (i = 0; i < vl; i++) {\ +if (!vm && !vext_elem_mask(v0, mlen, i)) {\ +ETYPE s2 = *((ETYPE *)vs2 + H(i));\ +*((ETYPE *)vd + H1(i)) = s2; \ H1 should be H. Yes. +} else { \ +*((ETYPE *)vd + H(i)) = (ETYPE)s1;\ +} \ You can also hoist the s2 dereference out of the IF, and let the assignment be unconditional. *((ETYPE *)vd + H(i)) = (!vm && !vext_elem_mask(v0, mlen, i) ? s2 : s1); Yes, it's much better. Zhiwei r~
Re: [PATCH v6 18/61] target/riscv: vector single-width integer multiply instructions
On 3/28/20 8:17 AM, LIU Zhiwei wrote: >> Missed the improvement here. See tcg_gen_mulsu2_i64. > Though I have not gotten the principle, the code in tcg_gen_mulsu2_i64 is much > tidier. Let A = signed operand, B = unsigned operand P = unsigned product If the sign bit A is set, then P is too large. In that case we subtract 2**64 * B to fix that: HI_P -= (A < 0 ? B : 0) where the conditional is computed as (A >> 63) & B. r~
[Bug 1869497] [NEW] x86_cpu_gdb_read_register segfaults when gdb requests registers
Public bug reported: When attempting to attach to the gdbstub, a segfault occurs. I traced this down to a problem in a call to gdb_get_reg16 where the mem_buf was being treated like a uint8_t* instead of a GByteArray. The buffer passed to gdb_get_reg16 ends up passing an invalid GByteArray pointer, which subsequentlycauses a segfault in memcpy. I have a fix for this - just need to educate myself on how to submit a patch. ** Affects: qemu Importance: Undecided Status: New ** Description changed: When attempting to attach to the gdbstub, a segfault occurs. - I traced this down to a problem in a call to gdb_get_reg16 where the mem_buf - was being treated like a uint8_t* instead of a GByteArray. The buffer passed - to gdb_get_reg16 ends up passing an invalid GByteArray pointer, which subsequently - causes a segfault in memcpy. + I traced this down to a problem in a call to gdb_get_reg16 where the + mem_buf was being treated like a uint8_t* instead of a GByteArray. The + buffer passed to gdb_get_reg16 ends up passing an invalid GByteArray + pointer, which subsequentlycauses a segfault in memcpy. I have a fix for this - just need to educate myself on how to submit a patch. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1869497 Title: x86_cpu_gdb_read_register segfaults when gdb requests registers Status in QEMU: New Bug description: When attempting to attach to the gdbstub, a segfault occurs. I traced this down to a problem in a call to gdb_get_reg16 where the mem_buf was being treated like a uint8_t* instead of a GByteArray. The buffer passed to gdb_get_reg16 ends up passing an invalid GByteArray pointer, which subsequentlycauses a segfault in memcpy. I have a fix for this - just need to educate myself on how to submit a patch. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1869497/+subscriptions
Re: [PATCH v6 39/61] target/riscv: vector floating-point compare instructions
On 2020/3/28 10:01, Richard Henderson wrote: On 3/17/20 8:06 AM, LIU Zhiwei wrote: +static uint8_t vmfne16(uint16_t a, uint16_t b, float_status *s) +{ +int compare = float16_compare_quiet(a, b, s); +return compare != float_relation_equal && + compare != float_relation_unordered; +} + +static uint8_t vmfne32(uint32_t a, uint32_t b, float_status *s) +{ +int compare = float32_compare_quiet(a, b, s); +return compare != float_relation_equal && + compare != float_relation_unordered; +} + +static uint8_t vmfne64(uint64_t a, uint64_t b, float_status *s) +{ +int compare = float64_compare_quiet(a, b, s); +return compare != float_relation_equal && + compare != float_relation_unordered; +} This is incorrect -- the result should be true for unordered. The text for 0.7.1 does not specify, but this is the normal interpretation of NE. The text for 0.8 explicitly says that the result is 1 for NaN. Agree! Thanks for pointing that. IEEE-754 has not defined the NE. An opposite setting with EQ is reasonable. Zhiwei r~
Re: [PATCH v6 26/61] target/riscv: vector single-width fractional multiply with rounding and saturation
On 2020/3/28 9:08, Richard Henderson wrote: On 3/17/20 8:06 AM, LIU Zhiwei wrote: +static int64_t vsmul64(CPURISCVState *env, int vxrm, int64_t a, int64_t b) +{ +uint8_t round; +uint64_t hi_64, lo_64, Hi62; +uint8_t hi62, hi63, lo63; + +muls64(_64, _64, a, b); +hi62 = extract64(hi_64, 62, 1); +lo63 = extract64(lo_64, 63, 1); +hi63 = extract64(hi_64, 63, 1); +Hi62 = extract64(hi_64, 0, 62); This seems like way more work than necessary. +if (hi62 != hi63) { +env->vxsat = 0x1; +return INT64_MAX; +} This can only happen for a == b == INT64_MIN. Perhaps just test exactly that and move it above the multiply? +round = get_round(vxrm, lo_64, 63); +if (round && (Hi62 == 0x3fff) && lo63) { +env->vxsat = 0x1; +return hi62 ? INT64_MIN : INT64_MAX; +} else { +if (lo63 && round) { +return (hi_64 + 1) << 1; +} else { +return (hi_64 << 1) | lo63 | round; +} +} Yes, it's an error here. As INT64_MIN will never be a right result. /* Cannot overflow, as there are always 2 sign bits after multiply. */ ret = (hi_64 << 1) | (lo_64 >> 63); if (round) { if (ret == INT64_MAX) { env->vxsat = 1; } else { ret += 1; } } return ret; Thanks. I think it's right and much clearer. Zhiwei. r~
Re: [RFC PATCH] crypto/secret: support fetching secrets from Linux keyring
Patchew URL: https://patchew.org/QEMU/20200328114014.6362-1-alex-krasi...@yandex-team.ru/ Hi, This series failed the docker-mingw@fedora build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #! /bin/bash export ARCH=x86_64 make docker-image-fedora V=1 NETWORK=1 time make docker-test-mingw@fedora J=14 NETWORK=1 === TEST SCRIPT END === CC chardev/char-ringbuf.o CC chardev/char-serial.o CC chardev/char-socket.o /tmp/qemu-test/src/crypto/secret.c:22:10: fatal error: asm/unistd.h: No such file or directory #include ^~ compilation terminated. make: *** [/tmp/qemu-test/src/rules.mak:69: crypto/secret.o] Error 1 make: *** Waiting for unfinished jobs Traceback (most recent call last): File "./tests/docker/docker.py", line 664, in --- raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=4961116ada114c5d93e518eb1e9d8685', '-u', '1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-rgq6jw7h/src/docker-src.2020-03-28-11.34.05.19902:/var/tmp/qemu:z,ro', 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit status 2. filter=--filter=label=com.qemu.instance.uuid=4961116ada114c5d93e518eb1e9d8685 make[1]: *** [docker-run] Error 1 make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-rgq6jw7h/src' make: *** [docker-run-test-mingw@fedora] Error 2 real1m49.176s user0m7.677s The full log is available at http://patchew.org/logs/20200328114014.6362-1-alex-krasi...@yandex-team.ru/testing.docker-mingw@fedora/?type=message. --- Email generated automatically by Patchew [https://patchew.org/]. Please send your feedback to patchew-de...@redhat.com
Re: [PATCH v6 25/61] target/riscv: vector single-width averaging add and subtract
On 2020/3/28 9:22, Richard Henderson wrote: On 3/27/20 6:07 PM, LIU Zhiwei wrote: On 2020/3/28 8:32, Richard Henderson wrote: On 3/18/20 8:46 PM, LIU Zhiwei wrote: +static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a, int32_t b) +{ +int64_t res = (int64_t)a - b; +uint8_t round = get_round(vxrm, res, 1); + +return (res >> 1) + round; +} + I find a corner case here. As the spec said in Section 13.2 "There can be no overflow in the result". If the a is 0x7fff, b is 0x8000, and the round mode is round to up(rnu), then the result is (0x7fff - 0x8000 + 1) >> 1, equals 0x8000, according the v0.7.1 That's why we used int64_t as the intermediate type: 0x7fff - 0x8000 + 1 = 0x7fff + 0x8000 + 1 = 0x + 1 = 0x0001 Shift that right by 1 and you do indeed get 0x8000. There's no saturation involved. The minuend 0x7fff is INT32_MAX, and the subtrahend 0x8000 is INT32_MIN. The difference between the minuend and the subtrahend should be a positive number. But the result here is 0x8000. So it is overflow. However, according to the spec, it should not overflow. Unless I'm missing something, the spec is wrong about "there can be no overflow", the above being a counter-example. Do you have hardware to compare against? Perhaps it is in fact "overflow is ignored", as the 0.8 spec says for vasubu? Agree! the overflow is just ignored. The code in the patch is OK now. I discussed it with hardware coworker and software coworker. The hardware coworker points that it is an error in spec. The software coworker think overflow will make this instruction some awkward, as the shift and round should protect the result from overflow. Like vasubu, overflow ignore is much better for vasub in this case. Zhiwei I wouldn't add saturation, because the spec says nothing about saturation, and does mention truncation, at least for vasubu. r~
Re: [PATCH v6 18/61] target/riscv: vector single-width integer multiply instructions
On 2020/3/28 8:06, Richard Henderson wrote: On 3/17/20 8:06 AM, LIU Zhiwei wrote: +static int64_t do_mulhsu_d(int64_t s2, uint64_t s1) +{ +uint64_t hi_64, lo_64, abs_s2 = s2; + +if (s2 < 0) { +abs_s2 = -s2; +} +mulu64(_64, _64, abs_s2, s1); +if (s2 < 0) { +lo_64 = ~lo_64; +hi_64 = ~hi_64; +if (lo_64 == UINT64_MAX) { +lo_64 = 0; +hi_64 += 1; +} else { +lo_64 += 1; +} +} + +return hi_64; +} Missed the improvement here. See tcg_gen_mulsu2_i64. Though I have not gotten the principle, the code in tcg_gen_mulsu2_i64 is much tidier. Thanks for pointing that. Zhiwei Otherwise, Reviewed-by: Richard Henderson r~
[RFC PATCH] crypto/secret: support fetching secrets from Linux keyring
Add the ability for the secret object to obtain secret data from the Linux in-kernel key managment and retention facility, as an extra option to the existing ones: reading from a file or passing directly as a string. The secret is identified by the key serial number. The upper layers need to instantiate the key and make sure the QEMU process has access rights to read it. Signed-off-by: Alexey Krasikov --- crypto/secret.c | 88 +++-- include/crypto/secret.h | 3 ++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/crypto/secret.c b/crypto/secret.c index 1cf0ad0ce8..2e8be6241c 100644 --- a/crypto/secret.c +++ b/crypto/secret.c @@ -19,6 +19,8 @@ */ #include "qemu/osdep.h" +#include +#include #include "crypto/secret.h" #include "crypto/cipher.h" #include "qapi/error.h" @@ -28,6 +30,40 @@ #include "trace.h" +static inline +long keyctl_read(key_serial_t key, uint8_t *buffer, size_t buflen) +{ +#ifdef __NR_keyctl +return syscall(__NR_keyctl, KEYCTL_READ, key, buffer, buflen, 0); +#else +errno = ENOSYS; +return -1; +#endif +} + +static +long keyctl_read_alloc(key_serial_t key, uint8_t **buffer) +{ +uint8_t *loc_buf; +long retcode = keyctl_read(key, NULL, 0); +if (retcode < 0) { +return retcode; +} +loc_buf = g_malloc(retcode + 1); +retcode = keyctl_read(key, loc_buf, retcode + 1); + /* +* We don't have key operations locks between syscalls. +* For example, the key could have been removed or expired. +*/ +if (retcode >= 0) { +loc_buf[retcode] = '\0'; +*buffer = loc_buf; +} else { +g_free(loc_buf); +} +return retcode; +} + static void qcrypto_secret_load_data(QCryptoSecret *secret, uint8_t **output, @@ -41,10 +77,28 @@ qcrypto_secret_load_data(QCryptoSecret *secret, *output = NULL; *outputlen = 0; -if (secret->file) { +if (secret->syskey) { +uint8_t *buffer = NULL; +long retcode; +if (secret->data || secret->file) { +error_setg(errp, + "'syskey', 'file' and 'data' are mutually exclusive"); +return; +} +retcode = keyctl_read_alloc(secret->syskey, ); +if (retcode < 0) { +error_setg_errno(errp, errno, + "Unable to read serial key %08x", + secret->syskey); +return; +} else { +*outputlen = retcode; +*output = buffer; +} +} else if (secret->file) { if (secret->data) { error_setg(errp, - "'file' and 'data' are mutually exclusive"); + "'syskey', 'file' and 'data' are mutually exclusive"); return; } if (!g_file_get_contents(secret->file, , , )) { @@ -60,7 +114,8 @@ qcrypto_secret_load_data(QCryptoSecret *secret, *outputlen = strlen(secret->data); *output = (uint8_t *)g_strdup(secret->data); } else { -error_setg(errp, "Either 'file' or 'data' must be provided"); +error_setg(errp, + "Either 'syskey' or 'file' or 'data' must be provided"); } } @@ -298,6 +353,29 @@ qcrypto_secret_prop_get_file(Object *obj, } +static void +qcrypto_secret_prop_set_syskey(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ +QCryptoSecret *secret = QCRYPTO_SECRET(obj); +int32_t value; +visit_type_int32(v, name, , errp); +secret->syskey = value; +} + + +static void +qcrypto_secret_prop_get_syskey(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ +QCryptoSecret *secret = QCRYPTO_SECRET(obj); +int32_t value = secret->syskey; +visit_type_int32(v, name, , errp); +} + + static void qcrypto_secret_prop_set_iv(Object *obj, const char *value, @@ -384,6 +462,10 @@ qcrypto_secret_class_init(ObjectClass *oc, void *data) qcrypto_secret_prop_get_file, qcrypto_secret_prop_set_file, NULL); +object_class_property_add(oc, "syskey", "key_serial_t", + qcrypto_secret_prop_get_syskey, + qcrypto_secret_prop_set_syskey, + NULL, NULL, NULL); object_class_property_add_str(oc, "keyid", qcrypto_secret_prop_get_keyid, qcrypto_secret_prop_set_keyid, diff --git a/include/crypto/secret.h b/include/crypto/secret.h index 5e07e29bae..9d350e35ed 100644 --- a/include/crypto/secret.h +++ b/include/crypto/secret.h @@ -31,6 +31,8 @@ typedef struct QCryptoSecret QCryptoSecret; typedef struct
Re: [PATCH v6 10/61] target/riscv: vector single-width integer add and subtract
On 2020/3/28 7:54, Richard Henderson wrote: On 3/17/20 8:06 AM, LIU Zhiwei wrote: +if (a->vm && s->vl_eq_vlmax) { +gvec_fn(s->sew, vreg_ofs(s, a->rd), +vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1), +MAXSZ(s), MAXSZ(s)); Indentation is off here. Do you mean I should adjust the indentation for parameters in gvec_fn like +if (a->vm && s->vl_eq_vlmax) { +gvec_fn(s->sew, vreg_ofs(s, a->rd), +vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1), +MAXSZ(s), MAXSZ(s)); +static inline bool +do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn, + gen_helper_opivx *fn) +{ +if (!opivx_check(s, a)) { +return false; +} + +if (a->vm && s->vl_eq_vlmax) { +TCGv_i64 src1 = tcg_temp_new_i64(); +TCGv tmp = tcg_temp_new(); + +gen_get_gpr(tmp, a->rs1); +tcg_gen_ext_tl_i64(src1, tmp); +gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), +src1, MAXSZ(s), MAXSZ(s)); + +tcg_temp_free_i64(src1); +tcg_temp_free(tmp); +return true; +} else { +return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s); +} +return true; +} This final return is unreachable, and I'm sure some static analyzer (e.g. Coverity) will complain. Since the if-then has a return, we can drop the else like so: if (a->vm && s->vl_eq_vlmax) { ... return true; } return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s); Yes, it's tidier. Thanks. Zhiwei Otherwise, Reviewed-by: Richard Henderson r~
[PATCH] target/arm: fix incorrect current EL bug in aarch32 exception emulation
The arm_current_el() should be invoked after mode switching. Otherwise, we get a wrong current EL value, since current EL is also determined by current mode. Fixes: 4a2696c0d4 ("target/arm: Set PAN bit as required on exception entry") Signed-off-by: Changbin Du --- target/arm/helper.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index b7b6887241..163c91a1cc 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -9172,7 +9172,6 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, /* Change the CPU state so as to actually take the exception. */ switch_mode(env, new_mode); -new_el = arm_current_el(env); /* * For exceptions taken to AArch32 we must clear the SS bit in both @@ -9184,6 +9183,10 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, env->condexec_bits = 0; /* Switch to the new mode, and to the correct instruction set. */ env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode; + +/* This must be after mode switching. */ +new_el = arm_current_el(env); + /* Set new mode endianness */ env->uncached_cpsr &= ~CPSR_E; if (env->cp15.sctlr_el[new_el] & SCTLR_EE) { -- 2.25.1
Re: [PATCH v6 58/61] target/riscv: vector slide instructions
On 2020/3/17 23:06, LIU Zhiwei wrote: Signed-off-by: LIU Zhiwei --- target/riscv/helper.h | 17 target/riscv/insn32.decode | 7 ++ target/riscv/insn_trans/trans_rvv.inc.c | 17 target/riscv/vector_helper.c| 128 4 files changed, 169 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 044538aef9..3b1612012c 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1118,3 +1118,20 @@ DEF_HELPER_3(vmv_s_x_d, void, ptr, tl, env) DEF_HELPER_3(vfmv_s_f_h, void, ptr, i64, env) DEF_HELPER_3(vfmv_s_f_w, void, ptr, i64, env) DEF_HELPER_3(vfmv_s_f_d, void, ptr, i64, env) + +DEF_HELPER_6(vslideup_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslideup_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslideup_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslideup_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslidedown_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslidedown_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslidedown_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslidedown_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslide1up_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslide1up_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslide1up_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslide1up_vx_d, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslide1down_vx_b, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32) +DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 79f9b37b29..34ccad53a9 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -72,6 +72,7 @@ @r2_vm .. vm:1 . . ... . ... %rs2 %rd @r1_vm .. vm:1 . . ... . ... %rd @r_nfvm ... ... vm:1 . . ... . ... %nf %rs2 %rs1 %rd +@r2rd... . . ... . ... %rs2 %rd @r_vm.. vm:1 . . ... . ... %rs2 %rs1 %rd @r_vm_1 .. . . . ... . ... vm=1 %rs2 %rs1 %rd @r_vm_0 .. . . . ... . ... vm=0 %rs2 %rs1 %rd @@ -565,6 +566,12 @@ vext_x_v001100 1 . . 010 . 1010111 @r vmv_s_x 001101 1 0 . 110 . 1010111 @r2 vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd vfmv_s_f001101 1 0 . 101 . 1010111 @r2 +vslideup_vx 001110 . . . 100 . 1010111 @r_vm +vslideup_vi 001110 . . . 011 . 1010111 @r_vm +vslide1up_vx001110 . . . 110 . 1010111 @r_vm +vslidedown_vx 00 . . . 100 . 1010111 @r_vm +vslidedown_vi 00 . . . 011 . 1010111 @r_vm +vslide1down_vx 00 . . . 110 . 1010111 @r_vm vsetvli 0 ... . 111 . 1010111 @r2_zimm vsetvl 100 . . 111 . 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 07033662c3..10482fd1d4 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -2536,3 +2536,20 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) } return false; } + +/* Vector Slide Instructions */ +static bool slideup_check(DisasContext *s, arg_rmrr *a) +{ +return (vext_check_isa_ill(s) && +vext_check_overlap_mask(s, a->rd, a->vm, true) && +vext_check_reg(s, a->rd, false) && +vext_check_reg(s, a->rs2, false) && +(a->rd != a->rs2)); +} +GEN_OPIVX_TRANS(vslideup_vx, slideup_check) +GEN_OPIVX_TRANS(vslide1up_vx, slideup_check) +GEN_OPIVI_TRANS(vslideup_vi, 1, vslideup_vx, slideup_check) + +GEN_OPIVX_TRANS(vslidedown_vx, opivx_check) +GEN_OPIVX_TRANS(vslide1down_vx, opivx_check) +GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, opivx_check) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 723e15a670..b0439ac3d1 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -4706,3 +4706,131 @@ void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env)\ GEN_VEXT_VFMV_S_F(vfmv_s_f_h, uint16_t, H2, clearh) GEN_VEXT_VFMV_S_F(vfmv_s_f_w, uint32_t, H4, clearl) GEN_VEXT_VFMV_S_F(vfmv_s_f_d, uint64_t, H8, clearq) + +/* Vector Slide Instructions */ +#define GEN_VEXT_VSLIDEUP_VX(NAME, ETYPE, H, CLEAR_FN)\ +void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ +CPURISCVState *env, uint32_t desc)\ +{ \ +uint32_t mlen = vext_mlen(desc);
[PATCH v4 2/2] net/colo-compare.c: handling of the full primary or secondary queue
The pervious handling of the full primary or queue is only dropping the packet. If there are lots of clients to the guest VM, the "drop" will lead to the lost of the networking connection until next checkpoint. To address the issue, this patch drops the packet firstly. Then, do checkpoint and flush packets. Signed-off-by: Derek Su --- net/colo-compare.c | 39 --- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/net/colo-compare.c b/net/colo-compare.c index cdd87b2aa8..fe8779cf2d 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -125,6 +125,12 @@ static const char *colo_mode[] = { [SECONDARY_IN] = "secondary", }; +enum { +QUEUE_INSERT_ERR = -1, +QUEUE_INSERT_OK = 0, +QUEUE_INSERT_FULL = 1, +}; + static int compare_chr_send(CompareState *s, const uint8_t *buf, uint32_t size, @@ -211,8 +217,10 @@ static int colo_insert_packet(GQueue *queue, Packet *pkt, uint32_t *max_ack) } /* - * Return 0 on success, if return -1 means the pkt - * is unsupported(arp and ipv6) and will be sent later + * Return QUEUE_INSERT_OK on success. + * If return QUEUE_INSERT_FULL means list is full, and + * QUEUE_INSERT_ERR means the pkt is unsupported(arp and ipv6) and + * will be sent later */ static int packet_enqueue(CompareState *s, int mode, Connection **con) { @@ -234,7 +242,7 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con) if (parse_packet_early(pkt)) { packet_destroy(pkt, NULL); pkt = NULL; -return -1; +return QUEUE_INSERT_ERR; } fill_connection_key(pkt, ); @@ -258,11 +266,12 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con) "drop packet", colo_mode[mode]); packet_destroy(pkt, NULL); pkt = NULL; +return QUEUE_INSERT_FULL; } *con = conn; -return 0; +return QUEUE_INSERT_OK; } static inline bool after(uint32_t seq1, uint32_t seq2) @@ -995,17 +1004,21 @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs) { CompareState *s = container_of(pri_rs, CompareState, pri_rs); Connection *conn = NULL; +int ret; -if (packet_enqueue(s, PRIMARY_IN, )) { +ret = packet_enqueue(s, PRIMARY_IN, ); +if (ret == QUEUE_INSERT_OK) { +/* compare packet in the specified connection */ +colo_compare_connection(conn, s); +} else if (ret == QUEUE_INSERT_FULL) { +colo_compare_inconsistency_notify(s); +} else { trace_colo_compare_main("primary: unsupported packet in"); compare_chr_send(s, pri_rs->buf, pri_rs->packet_len, pri_rs->vnet_hdr_len, false); -} else { -/* compare packet in the specified connection */ -colo_compare_connection(conn, s); } } @@ -1013,12 +1026,16 @@ static void compare_sec_rs_finalize(SocketReadState *sec_rs) { CompareState *s = container_of(sec_rs, CompareState, sec_rs); Connection *conn = NULL; +int ret; -if (packet_enqueue(s, SECONDARY_IN, )) { -trace_colo_compare_main("secondary: unsupported packet in"); -} else { +ret = packet_enqueue(s, SECONDARY_IN, ); +if (ret == QUEUE_INSERT_OK) { /* compare packet in the specified connection */ colo_compare_connection(conn, s); +} else if (ret == QUEUE_INSERT_FULL) { +colo_compare_inconsistency_notify(s); +} else { +trace_colo_compare_main("secondary: unsupported packet in"); } } -- 2.17.1
[PATCH v4 0/2] COLO: handling of the full primary or secondary queue
The series is to handle the full primary or secondary queue in colo-compare. (1) fix the "pkt" memory leak in packet_enqueue(). Reproduce steps: 1. Setup PVM and SVM both with NIC e1000 by the steps descripted in the wiki qemu/COLO 2. Run "iperf3 -s" in PVM 3. Run "iperf3 -c -t 7200" in client The memory usage of qemu-system-x86_64 increases as the PVM's QMP shows "qemu-system-x86_64: colo compare secondary queue size too big, drop packet". (2) The pervious handling of the full primary or queue is only dropping the packet. If there are lots of clients to the guest VM, the "drop" will lead to the lost of the networking connection until next checkpoint, and therefore decrease the response of service. This patch drops the packet firstly. Then, send all queued primary packets, remove all queued secondary packets (flush packets) and do checkpoint. Please help to review, thanks. V4: - Remove redundant flush of packets V3: - handling of the full primary or secondary queue according to the suggestion from Zhang Chen V2: - Fix incorrect patch format Derek Su (2): net/colo-compare.c: Fix memory leak in packet_enqueue() net/colo-compare.c: handling of the full primary or secondary queue net/colo-compare.c | 62 -- 1 file changed, 43 insertions(+), 19 deletions(-) -- 2.17.1
[PATCH v4 1/2] net/colo-compare.c: Fix memory leak in packet_enqueue()
The patch is to fix the "pkt" memory leak in packet_enqueue(). The allocated "pkt" needs to be freed if the colo compare primary or secondary queue is too big. Signed-off-by: Derek Su --- net/colo-compare.c | 23 +++ 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/net/colo-compare.c b/net/colo-compare.c index 7ee17f2cf8..cdd87b2aa8 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -120,6 +120,10 @@ enum { SECONDARY_IN, }; +static const char *colo_mode[] = { +[PRIMARY_IN] = "primary", +[SECONDARY_IN] = "secondary", +}; static int compare_chr_send(CompareState *s, const uint8_t *buf, @@ -215,6 +219,7 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con) ConnectionKey key; Packet *pkt = NULL; Connection *conn; +int ret; if (mode == PRIMARY_IN) { pkt = packet_new(s->pri_rs.buf, @@ -243,16 +248,18 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con) } if (mode == PRIMARY_IN) { -if (!colo_insert_packet(>primary_list, pkt, >pack)) { -error_report("colo compare primary queue size too big," - "drop packet"); -} +ret = colo_insert_packet(>primary_list, pkt, >pack); } else { -if (!colo_insert_packet(>secondary_list, pkt, >sack)) { -error_report("colo compare secondary queue size too big," - "drop packet"); -} +ret = colo_insert_packet(>secondary_list, pkt, >sack); } + +if (!ret) { +error_report("colo compare %s queue size too big," + "drop packet", colo_mode[mode]); +packet_destroy(pkt, NULL); +pkt = NULL; +} + *con = conn; return 0; -- 2.17.1
Re: [RFC for-5.1 4/4] spapr: Don't allow unplug of NVLink2 devices
On 26/03/2020 16:40, David Gibson wrote: > Currently, we can't properly handle unplug of NVLink2 devices, because we > don't have code to tear down their special memory resources. There's not > a lot of impetus to implement that. Since hardware NVLink2 devices can't > be hot unplugged, the guest side drivers don't usually support unplug > anyway. > > Therefore, simply prevent unplug of NVLink2 devices. > > Signed-off-by: David Gibson > --- > hw/ppc/spapr_pci.c | 5 + > 1 file changed, 5 insertions(+) > > diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c > index 55ca9dee1e..5c8262413a 100644 > --- a/hw/ppc/spapr_pci.c > +++ b/hw/ppc/spapr_pci.c > @@ -1666,6 +1666,11 @@ static void spapr_pci_unplug_request(HotplugHandler > *plug_handler, > return; > } > > +if (spapr_phb_is_nvlink_dev(pdev, phb)) { > +error_setg(errp, "PCI: Cannot unplug NVLink2 devices"); > +return; > +} Just this would do as well: Object *po = OBJECT(pdev); uint64_t tgt = object_property_get_uint(po, "nvlink2-tgt", NULL); if (tgt) { error_setg(errp, "PCI: Cannot unplug NVLink2 devices"); return; } honestly, I admin what 1/4 fixes is cryptic but since there is not going to be any more new nvlinkX, this does not deserve this many patches imho. > + > /* ensure any other present functions are pending unplug */ > if (PCI_FUNC(pdev->devfn) == 0) { > for (i = 1; i < 8; i++) { > -- Alexey
[Bug 1821515] Re: qemu-ppc (user) incorrectly converts float(nan)->double(non-nan)
*** This bug is a duplicate of bug 1821444 *** https://bugs.launchpad.net/bugs/1821444 ** This bug has been marked a duplicate of bug 1821444 qemu-ppc (user) incorrectly translates float32 arithmetics -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1821515 Title: qemu-ppc (user) incorrectly converts float(nan)->double(non-nan) Status in QEMU: New Bug description: Noticed on qemu-3.1.0 on GHC test suite where float32 comparisons didn't work on NaNs. Here is the minimal reproducer: ```c // cat a.c #include #include #include int main() { volatile float f1 = NAN; volatile float f2 = NAN; printf ("f1 (%e, %#x) >= f2 (%e, %#x): %s\n", f1, *(volatile uint32_t*), f2, *(volatile uint32_t*), (f1 >= f2) ? "True" : "False"); volatile double d = f1; printf ("d (%e, %#llx)\n", d, *(volatile uint64_t*)); } ``` ``` # incorrect execution: $ powerpc-unknown-linux-gnu-gcc -O2 a.c -o a -static && qemu-ppc ./a f1 (5.104236e+38, 0x7fc0) >= f2 (5.104236e+38, 0x7fc0): True d (5.104236e+38, 0x47f8) # correct execution $ scp a timberdoodle.ppc64.dev.gentoo.org:~/; ssh timberdoodle.ppc64.dev.gentoo.org ./a f1 (nan, 0x7fc0) >= f2 (nan, 0x7fc0): False d (nan, 0x7ff8) ``` Note: qemu-ppc handled float32 extension as it was not a NaN (exp=111..) but a normalized number. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1821515/+subscriptions
Re: [PULL 0/5] Ide patches
On Fri, 27 Mar 2020 at 20:15, John Snow wrote: > > The following changes since commit cfe68ae025f704f336d7dd3d1903ce37b445831d: > > Merge remote-tracking branch > 'remotes/vivier2/tags/linux-user-for-5.0-pull-request' into staging > (2020-03-26 20:55:54 +) > > are available in the Git repository at: > > https://github.com/jnsnow/qemu.git tags/ide-pull-request > > for you to fetch changes up to cbf4c9ac9c000f7caf1bfee031041b62d2b000c8: > > cmd646-ide: use qdev gpio rather than qemu_allocate_irqs() (2020-03-27 > 14:30:08 -0400) > > > Pull request > > --- Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/5.0 for any user-visible changes. -- PMM
[PATCH] target/mips: Add MAC2008 support
MAC2008 was introduced in MIPS Release 3 but removed in MIPS Release 5. However, there are some processors implemented this feature. some Ingenic MCU can config MAC2008 status runtime while whole Loongson-64 family are MAC2008 only. FCSR.MAC2008 bit indicates FMA family of instructions on these processors have fused behavior, similiar to FMA in Release 6, so we can reuse helpers with them. Signed-off-by: Jiaxun Yang --- target/mips/cpu.h| 1 + target/mips/fpu_helper.c | 61 + target/mips/helper.h | 12 +++ target/mips/translate.c | 74 +--- 4 files changed, 107 insertions(+), 41 deletions(-) diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 94d01ea798..b20e6e3387 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -63,6 +63,7 @@ struct CPUMIPSFPUContext { uint32_t fcr31_rw_bitmask; uint32_t fcr31; #define FCR31_FS 24 +#define FCR31_MAC2008 20 #define FCR31_ABS2008 19 #define FCR31_NAN2008 18 #define SET_FP_COND(num, env) do { ((env).fcr31) |= \ diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c index 5287c86c61..2e50d50f36 100644 --- a/target/mips/fpu_helper.c +++ b/target/mips/fpu_helper.c @@ -1357,7 +1357,7 @@ FLOAT_MINMAX(mina_d, 64, minnummag) }\ } -/* FMA based operations */ +/* FMA based operations (both unfused and fused) */ #define FLOAT_FMA(name, type)\ uint64_t helper_float_ ## name ## _d(CPUMIPSState *env, \ uint64_t fdt0, uint64_t fdt1, \ @@ -1392,33 +1392,52 @@ uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env, \ UNFUSED_FMA(float32, fsth0, fsth1, fsth2, type); \ update_fcr31(env, GETPC()); \ return ((uint64_t)fsth0 << 32) | fst0; \ +}\ +uint64_t helper_float_ ## name ## f_d(CPUMIPSState *env, \ + uint64_t fdt0, uint64_t fdt1, \ + uint64_t fdt2) \ +{\ +fdt0 = float64_muladd(fdt0, fdt1, fdt2, type,\ +>active_fpu.fp_status); \ +update_fcr31(env, GETPC()); \ +return fdt0; \ +}\ + \ +uint32_t helper_float_ ## name ## f_s(CPUMIPSState *env, \ + uint32_t fst0, uint32_t fst1, \ + uint32_t fst2) \ +{\ +fst0 = float32_muladd(fst0, fst1, fst2, type,\ +>active_fpu.fp_status); \ +update_fcr31(env, GETPC()); \ +return fst0; \ +}\ + \ +uint64_t helper_float_ ## name ## f_ps(CPUMIPSState *env,\ + uint64_t fdt0, uint64_t fdt1, \ + uint64_t fdt2) \ +{\ +uint32_t fst0 = fdt0 & 0X; \ +uint32_t fsth0 = fdt0 >> 32; \ +uint32_t fst1 = fdt1 & 0X; \ +uint32_t fsth1 = fdt1 >> 32; \ +uint32_t fst2 = fdt2 & 0X; \ +uint32_t fsth2 = fdt2 >> 32; \ + \ +fst0 = float32_muladd(fst0, fst1, fst2, type,\ +>active_fpu.fp_status); \ +fsth0 = float32_muladd(fsth0, fsth1, fsth2, type,\ +>active_fpu.fp_status); \ +update_fcr31(env, GETPC()); \ +return ((uint64_t)fsth0 << 32) | fst0; \ } + FLOAT_FMA(madd, 0) FLOAT_FMA(msub, float_muladd_negate_c) FLOAT_FMA(nmadd, float_muladd_negate_result) FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c) #undef FLOAT_FMA -#define FLOAT_FMADDSUB(name, bits, muladd_arg) \
Re: [PATCH v4] piix: fix xenfv regression, add compat machine xenfv-qemu4
Nope, that's fine. If you are okay I can apply them myself. Paolo Il sab 28 mar 2020, 08:09 Olaf Hering ha scritto: > On Fri, Mar 27, Paolo Bonzini wrote: > > > Looks good, I would just do the following adjustments to have more > > consistency between pc and xenfv machine types > > Do you want me to resend with this change? > > Olaf > >
Re: [PATCH v4] piix: fix xenfv regression, add compat machine xenfv-qemu4
On Fri, Mar 27, Paolo Bonzini wrote: > Looks good, I would just do the following adjustments to have more > consistency between pc and xenfv machine types Do you want me to resend with this change? Olaf
Re: [PATCH v4 0/2] Replaced locks with lock guard macros
On Thu, Mar 26, 2020 at 11:01 AM Richard Henderson wrote: > > My preference is to add -Wno-tautological-type-limit-compare in > configure, so we don't have to work around this same issue elsewhere > in the code base. > > r~ What do you think would be the best way to add this? I could change all additions of the `-m32` flag to instead use `-m32 -Wno-tautological-type-limit-compare` or add the flag if qemu is being compiled with clang and `-m32` already enabled. Daniel