RE: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Anup Patel
Hi,

From: Aleksandar Markovic  
Sent: Saturday, October 19, 2019 2:45 AM
To: Anup Patel 
Cc: Peter Maydell ; Palmer Dabbelt 
; Alistair Francis ; Sagar 
Karandikar ; Bastian Koppelmann 
; Atish Patra ; 
qemu-ri...@nongnu.org; qemu-devel@nongnu.org; Anup Patel 
Subject: Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

ū

On Tuesday, October 15, 2019, Anup Patel  wrote:
This patch adds model for Google Goldfish virtual platform RTC device.

We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
for providing real date-time to Guest Linux. The corresponding Linux
driver for Goldfish RTC device is already available in upstream Linux.

For now, VM migration support is available but untested for Goldfish RTC
device. It will be hardened in-future when we implement VM migration for
KVM RISC-V.

Signed-off-by: Anup Patel 
---
 hw/rtc/Kconfig                  |   3 +
 hw/rtc/Makefile.objs            |   1 +
 hw/rtc/goldfish_rtc.c           | 278 
 include/hw/timer/goldfish_rtc.h |  46 ++
 4 files changed, 328 insertions(+)
 create mode 100644 hw/rtc/goldfish_rtc.c
 create mode 100644 include/hw/timer/goldfish_rtc.h

Do you plan to add some other devices from Goldfish platform?

[Anup] Nopes, we just needed a simple RTC device for RISC-V
[Anup] virt machine hence this patch. 

[Anup] Most of the required devices are already there in
[Anup] the VirtIO spec. The RTC device was missing in
[Anup] VirtIO spec so instead of creating new virtual RTC
[Anup] device we just re-use Goldfish RTC. This help us
[Anup] re-use the Linux Goldfish RTC driver.

Did you base your code on Android emulator code?

[Anup] Nopes, the android emulator code seemed too simple
[Anup] and lacking. In fact, the Linux Goldfish RTC driver does
[Anup] much more.

[Anup] Based on the documentation and Linux Goldfish RTC
[Anup] driver, I wrote it from scratch.

[Anup] I first added Goldfish RTC emulator to Xvisor RISC-V
[Anup] virt machine. Got it working over there and then
[Anup] ported it to QEMU. For qemu emulation, I looked
[Anup] at existing RTC emulators (such as PL031) for QEMU
[Anup] API usage.

Related to the previous question, are you sure the copyright line should go to 
Western Digital only?

[Anup] I thought copyright will be of implementer hence I
[Anup] put Western Digital only. The spec and Linux driver
[Anup] can be written by totally different folks.

Regards,
Anup
 
diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
index 45daa8d655..bafe6ac2c9 100644
--- a/hw/rtc/Kconfig
+++ b/hw/rtc/Kconfig
@@ -21,3 +21,6 @@ config MC146818RTC

 config SUN4V_RTC
     bool
+
+config GOLDFISH_RTC
+    bool
diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
index 8dc9fcd3a9..aa208d0d10 100644
--- a/hw/rtc/Makefile.objs
+++ b/hw/rtc/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
+common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
new file mode 100644
index 00..223616ed75
--- /dev/null
+++ b/hw/rtc/goldfish_rtc.c
@@ -0,0 +1,278 @@
+/*
+ * Goldfish virtual platform RTC
+ *
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ *
+ * For more details on Google Goldfish virtual platform refer:
+ * 
https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/timer/goldfish_rtc.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+
+#define RTC_TIME_LOW            0x00
+#define RTC_TIME_HIGH           0x04
+#define RTC_ALARM_LOW           0x08
+#define RTC_ALARM_HIGH          0x0c
+#define RTC_IRQ_ENABLED         0x10
+#define RTC_CLEAR_ALARM         0x14
+#define RTC_ALARM_STATUS        0x18
+#define RTC_CLEAR_INTERRUPT     0x1c
+
+static void goldfish_rtc_update(GoldfishRTCState *s)
+{
+    qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
+}
+
+static void goldfish_rtc_interrupt(void *opaque)
+{
+    

[Bug 1834113] Re: QEMU touchpad input erratic after wakeup from sleep

2019-10-18 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1834113

Title:
  QEMU touchpad input erratic after wakeup from sleep

Status in QEMU:
  Expired
Status in libvirt package in Ubuntu:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  Using Ubuntu host and guest. Normally the touchpad works great. Within
  the last few days, suddenly, apparently after a wake from sleep, the
  touchpad will behave erratically. For example, it will take two clicks
  to select something, and when moving the cursor it will act as though
  it is dragging even with the button not clicked.

  A reboot fixes the issue temporarily.

  ProblemType: Bug
  DistroRelease: Ubuntu 19.04
  Package: qemu 1:3.1+dfsg-2ubuntu3.1
  Uname: Linux 5.1.14-050114-generic x86_64
  ApportVersion: 2.20.10-0ubuntu27
  Architecture: amd64
  CurrentDesktop: ubuntu:GNOME
  Date: Mon Jun 24 20:55:44 2019
  Dependencies:
   
  EcryptfsInUse: Yes
  InstallationDate: Installed on 2019-02-20 (124 days ago)
  InstallationMedia: Ubuntu 18.04 "Bionic" - Build amd64 LIVE Binary 
20180608-09:38
  Lsusb:
   Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
   Bus 001 Device 002: ID 8087:0025 Intel Corp. 
   Bus 001 Device 003: ID 0c45:671d Microdia 
   Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  MachineType: Dell Inc. Precision 5530
  ProcEnviron:
   TERM=xterm-256color
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=
   LANG=en_US.UTF-8
   SHELL=/bin/bash
  ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-5.1.14-050114-generic 
root=UUID=18e8777c-1764-41e4-a19f-62476055de23 ro mem_sleep_default=deep 
mem_sleep_default=deep acpi_rev_override=1 scsi_mod.use_blk_mq=1 
nouveau.modeset=0 nouveau.runpm=0 nouveau.blacklist=1 acpi_backlight=none 
acpi_osi=Linux acpi_osi=!
  SourcePackage: qemu
  UpgradeStatus: No upgrade log present (probably fresh install)
  dmi.bios.date: 04/26/2019
  dmi.bios.vendor: Dell Inc.
  dmi.bios.version: 1.10.1
  dmi.board.name: 0FP2W2
  dmi.board.vendor: Dell Inc.
  dmi.board.version: A00
  dmi.chassis.type: 10
  dmi.chassis.vendor: Dell Inc.
  dmi.modalias: 
dmi:bvnDellInc.:bvr1.10.1:bd04/26/2019:svnDellInc.:pnPrecision5530:pvr:rvnDellInc.:rn0FP2W2:rvrA00:cvnDellInc.:ct10:cvr:
  dmi.product.family: Precision
  dmi.product.name: Precision 5530
  dmi.product.sku: 087D
  dmi.sys.vendor: Dell Inc.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1834113/+subscriptions



[Bug 1834113] Re: QEMU touchpad input erratic after wakeup from sleep

2019-10-18 Thread Launchpad Bug Tracker
[Expired for libvirt (Ubuntu) because there has been no activity for 60
days.]

** Changed in: libvirt (Ubuntu)
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1834113

Title:
  QEMU touchpad input erratic after wakeup from sleep

Status in QEMU:
  Expired
Status in libvirt package in Ubuntu:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  Using Ubuntu host and guest. Normally the touchpad works great. Within
  the last few days, suddenly, apparently after a wake from sleep, the
  touchpad will behave erratically. For example, it will take two clicks
  to select something, and when moving the cursor it will act as though
  it is dragging even with the button not clicked.

  A reboot fixes the issue temporarily.

  ProblemType: Bug
  DistroRelease: Ubuntu 19.04
  Package: qemu 1:3.1+dfsg-2ubuntu3.1
  Uname: Linux 5.1.14-050114-generic x86_64
  ApportVersion: 2.20.10-0ubuntu27
  Architecture: amd64
  CurrentDesktop: ubuntu:GNOME
  Date: Mon Jun 24 20:55:44 2019
  Dependencies:
   
  EcryptfsInUse: Yes
  InstallationDate: Installed on 2019-02-20 (124 days ago)
  InstallationMedia: Ubuntu 18.04 "Bionic" - Build amd64 LIVE Binary 
20180608-09:38
  Lsusb:
   Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
   Bus 001 Device 002: ID 8087:0025 Intel Corp. 
   Bus 001 Device 003: ID 0c45:671d Microdia 
   Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  MachineType: Dell Inc. Precision 5530
  ProcEnviron:
   TERM=xterm-256color
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=
   LANG=en_US.UTF-8
   SHELL=/bin/bash
  ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-5.1.14-050114-generic 
root=UUID=18e8777c-1764-41e4-a19f-62476055de23 ro mem_sleep_default=deep 
mem_sleep_default=deep acpi_rev_override=1 scsi_mod.use_blk_mq=1 
nouveau.modeset=0 nouveau.runpm=0 nouveau.blacklist=1 acpi_backlight=none 
acpi_osi=Linux acpi_osi=!
  SourcePackage: qemu
  UpgradeStatus: No upgrade log present (probably fresh install)
  dmi.bios.date: 04/26/2019
  dmi.bios.vendor: Dell Inc.
  dmi.bios.version: 1.10.1
  dmi.board.name: 0FP2W2
  dmi.board.vendor: Dell Inc.
  dmi.board.version: A00
  dmi.chassis.type: 10
  dmi.chassis.vendor: Dell Inc.
  dmi.modalias: 
dmi:bvnDellInc.:bvr1.10.1:bd04/26/2019:svnDellInc.:pnPrecision5530:pvr:rvnDellInc.:rn0FP2W2:rvrA00:cvnDellInc.:ct10:cvr:
  dmi.product.family: Precision
  dmi.product.name: Precision 5530
  dmi.product.sku: 087D
  dmi.sys.vendor: Dell Inc.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1834113/+subscriptions



[Bug 1834113] Re: QEMU touchpad input erratic after wakeup from sleep

2019-10-18 Thread Launchpad Bug Tracker
[Expired for qemu (Ubuntu) because there has been no activity for 60
days.]

** Changed in: qemu (Ubuntu)
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1834113

Title:
  QEMU touchpad input erratic after wakeup from sleep

Status in QEMU:
  Expired
Status in libvirt package in Ubuntu:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  Using Ubuntu host and guest. Normally the touchpad works great. Within
  the last few days, suddenly, apparently after a wake from sleep, the
  touchpad will behave erratically. For example, it will take two clicks
  to select something, and when moving the cursor it will act as though
  it is dragging even with the button not clicked.

  A reboot fixes the issue temporarily.

  ProblemType: Bug
  DistroRelease: Ubuntu 19.04
  Package: qemu 1:3.1+dfsg-2ubuntu3.1
  Uname: Linux 5.1.14-050114-generic x86_64
  ApportVersion: 2.20.10-0ubuntu27
  Architecture: amd64
  CurrentDesktop: ubuntu:GNOME
  Date: Mon Jun 24 20:55:44 2019
  Dependencies:
   
  EcryptfsInUse: Yes
  InstallationDate: Installed on 2019-02-20 (124 days ago)
  InstallationMedia: Ubuntu 18.04 "Bionic" - Build amd64 LIVE Binary 
20180608-09:38
  Lsusb:
   Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
   Bus 001 Device 002: ID 8087:0025 Intel Corp. 
   Bus 001 Device 003: ID 0c45:671d Microdia 
   Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  MachineType: Dell Inc. Precision 5530
  ProcEnviron:
   TERM=xterm-256color
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=
   LANG=en_US.UTF-8
   SHELL=/bin/bash
  ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-5.1.14-050114-generic 
root=UUID=18e8777c-1764-41e4-a19f-62476055de23 ro mem_sleep_default=deep 
mem_sleep_default=deep acpi_rev_override=1 scsi_mod.use_blk_mq=1 
nouveau.modeset=0 nouveau.runpm=0 nouveau.blacklist=1 acpi_backlight=none 
acpi_osi=Linux acpi_osi=!
  SourcePackage: qemu
  UpgradeStatus: No upgrade log present (probably fresh install)
  dmi.bios.date: 04/26/2019
  dmi.bios.vendor: Dell Inc.
  dmi.bios.version: 1.10.1
  dmi.board.name: 0FP2W2
  dmi.board.vendor: Dell Inc.
  dmi.board.version: A00
  dmi.chassis.type: 10
  dmi.chassis.vendor: Dell Inc.
  dmi.modalias: 
dmi:bvnDellInc.:bvr1.10.1:bd04/26/2019:svnDellInc.:pnPrecision5530:pvr:rvnDellInc.:rn0FP2W2:rvrA00:cvnDellInc.:ct10:cvr:
  dmi.product.family: Precision
  dmi.product.name: Precision 5530
  dmi.product.sku: 087D
  dmi.sys.vendor: Dell Inc.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1834113/+subscriptions



RE: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Anup Patel


> -Original Message-
> From: Alistair Francis 
> Sent: Saturday, October 19, 2019 2:29 AM
> To: Anup Patel 
> Cc: Peter Maydell ; Palmer Dabbelt
> ; Alistair Francis ; Sagar
> Karandikar ; Bastian Koppelmann
> ; Atish Patra ;
> qemu-ri...@nongnu.org; qemu-devel@nongnu.org; Anup Patel
> 
> Subject: Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device
> 
> On Tue, Oct 15, 2019 at 1:36 AM Anup Patel  wrote:
> >
> > This patch adds model for Google Goldfish virtual platform RTC device.
> >
> > We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
> > for providing real date-time to Guest Linux. The corresponding Linux
> > driver for Goldfish RTC device is already available in upstream Linux.
> >
> > For now, VM migration support is available but untested for Goldfish
> > RTC device. It will be hardened in-future when we implement VM
> > migration for KVM RISC-V.
> >
> > Signed-off-by: Anup Patel 
> > ---
> >  hw/rtc/Kconfig  |   3 +
> >  hw/rtc/Makefile.objs|   1 +
> >  hw/rtc/goldfish_rtc.c   | 278 
> >  include/hw/timer/goldfish_rtc.h |  46 ++
> >  4 files changed, 328 insertions(+)
> >  create mode 100644 hw/rtc/goldfish_rtc.c  create mode 100644
> > include/hw/timer/goldfish_rtc.h
> >
> > diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig index
> > 45daa8d655..bafe6ac2c9 100644
> > --- a/hw/rtc/Kconfig
> > +++ b/hw/rtc/Kconfig
> > @@ -21,3 +21,6 @@ config MC146818RTC
> >
> >  config SUN4V_RTC
> >  bool
> > +
> > +config GOLDFISH_RTC
> > +bool
> > diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs index
> > 8dc9fcd3a9..aa208d0d10 100644
> > --- a/hw/rtc/Makefile.objs
> > +++ b/hw/rtc/Makefile.objs
> > @@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) +=
> exynos4210_rtc.o
> >  obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
> >  common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
> >  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
> > +common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
> > diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c new file
> > mode 100644 index 00..223616ed75
> > --- /dev/null
> > +++ b/hw/rtc/goldfish_rtc.c
> > @@ -0,0 +1,278 @@
> > +/*
> > + * Goldfish virtual platform RTC
> > + *
> > + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> > + *
> > + * For more details on Google Goldfish virtual platform refer:
> > + *
> >
> +https://android.googlesource.com/platform/external/qemu/+/master/doc
> s
> > +/GOLDFISH-VIRTUAL-HARDWARE.TXT
> > + *
> > + * This program is free software; you can redistribute it and/or
> > +modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2 or later, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope 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.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > +along with
> > + * this program.  If not, see .
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu-common.h"
> > +#include "hw/timer/goldfish_rtc.h"
> > +#include "migration/vmstate.h"
> > +#include "hw/irq.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/sysbus.h"
> > +#include "qemu/timer.h"
> > +#include "sysemu/sysemu.h"
> > +#include "qemu/cutils.h"
> > +#include "qemu/log.h"
> > +
> > +#define RTC_TIME_LOW0x00
> > +#define RTC_TIME_HIGH   0x04
> > +#define RTC_ALARM_LOW   0x08
> > +#define RTC_ALARM_HIGH  0x0c
> > +#define RTC_IRQ_ENABLED 0x10
> > +#define RTC_CLEAR_ALARM 0x14
> > +#define RTC_ALARM_STATUS0x18
> > +#define RTC_CLEAR_INTERRUPT 0x1c
> > +
> > +static void goldfish_rtc_update(GoldfishRTCState *s) {
> > +qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
> > +}
> > +
> > +static void goldfish_rtc_interrupt(void *opaque) {
> > +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> > +
> > +s->alarm_running = 0;
> > +s->irq_pending = 1;
> > +goldfish_rtc_update(s);
> > +}
> > +
> > +static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s) {
> > +return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
> > +}
> > +
> > +static void goldfish_rtc_clear_alarm(GoldfishRTCState *s) {
> > +timer_del(s->timer);
> > +s->alarm_running = 0;
> > +}
> > +
> > +static void goldfish_rtc_set_alarm(GoldfishRTCState *s) {
> > +uint64_t ticks = goldfish_rtc_get_count(s);
> > +uint64_t event = s->alarm_next;
> > +
> > +if (event <= ticks) {
> > +goldfish_rtc_clear_alarm(s);
> > +goldfish_rtc_interrupt(s);
> > +} else {
> > +int64_t now = qemu_clock_get_ns(rtc_clock);
> > +timer_mod(s->timer, now + (event - 

Re: [PATCH v2 0/4] apic: Fix migration breakage of >255 vcpus

2019-10-18 Thread Peter Xu
On Wed, Oct 16, 2019 at 11:40:01AM -0300, Eduardo Habkost wrote:
> On Wed, Oct 16, 2019 at 10:29:29AM +0800, Peter Xu wrote:
> > v2:
> > - use uint32_t rather than int64_t [Juan]
> > - one more patch (patch 4) to check dup SaveStateEntry [Dave]
> > - one more patch to define a macro (patch 1) to simplify patch 2
> > 
> > Please review, thanks.
> 
> I wonder how hard it is to write a simple test case to reproduce
> the original bug.  We can extend tests/migration-test.c or
> tests/acceptance/migration.py.  If using -device with explicit
> apic-id, we probably don't even need to create >255 VCPUs.

I can give it a shot next week. :)

-- 
Peter Xu



[PATCH] hw/xtensa: add virt machine

2019-10-18 Thread Max Filippov
virt machine is a sim machine with generic PCI host controller.
Make common parts of sim machine initialization reusable.
Add PCI controller at 0xf000 with PIO space at its base address,
ECAM space at base address + 1M and MMIO space at base address + 64M.
Connect IRQ lines to consecutive CPU external IRQ pins starting from 0.
Instantiate network interfaces on virt machine.

Xtensa linux kernel configuration virt_defconfig can successfully boot
on this machine.

Signed-off-by: Max Filippov 
---
 MAINTAINERS|   5 ++
 default-configs/xtensa-softmmu.mak |   1 +
 hw/xtensa/Kconfig  |   6 ++
 hw/xtensa/Makefile.objs|   1 +
 hw/xtensa/sim.c|  41 +
 hw/xtensa/virt.c   | 135 +
 hw/xtensa/xtensa_sim.h |  34 
 7 files changed, 208 insertions(+), 15 deletions(-)
 create mode 100644 hw/xtensa/virt.c
 create mode 100644 hw/xtensa/xtensa_sim.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 50eaf005f40e..7c2f35a2320f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1302,6 +1302,11 @@ M: Max Filippov 
 S: Maintained
 F: hw/xtensa/sim.c
 
+virt
+M: Max Filippov 
+S: Maintained
+F: hw/xtensa/virt.c
+
 XTFPGA (LX60, LX200, ML605, KC705)
 M: Max Filippov 
 S: Maintained
diff --git a/default-configs/xtensa-softmmu.mak 
b/default-configs/xtensa-softmmu.mak
index 3aa20a47a7fb..4fe1bf00c94b 100644
--- a/default-configs/xtensa-softmmu.mak
+++ b/default-configs/xtensa-softmmu.mak
@@ -5,4 +5,5 @@ CONFIG_SEMIHOSTING=y
 # Boards:
 #
 CONFIG_XTENSA_SIM=y
+CONFIG_XTENSA_VIRT=y
 CONFIG_XTENSA_XTFPGA=y
diff --git a/hw/xtensa/Kconfig b/hw/xtensa/Kconfig
index d72817d012e3..0740657ea58f 100644
--- a/hw/xtensa/Kconfig
+++ b/hw/xtensa/Kconfig
@@ -1,6 +1,12 @@
 config XTENSA_SIM
 bool
 
+config XTENSA_VIRT
+bool
+select XTENSA_SIM
+select PCI_EXPRESS_GENERIC_BRIDGE
+select PCI_DEVICES
+
 config XTENSA_XTFPGA
 bool
 select OPENCORES_ETH
diff --git a/hw/xtensa/Makefile.objs b/hw/xtensa/Makefile.objs
index 0bbfccd6deae..2b40e1b60a0e 100644
--- a/hw/xtensa/Makefile.objs
+++ b/hw/xtensa/Makefile.objs
@@ -2,4 +2,5 @@ obj-y += mx_pic.o
 obj-y += pic_cpu.o
 obj-y += xtensa_memory.o
 obj-$(CONFIG_XTENSA_SIM) += sim.o
+obj-$(CONFIG_XTENSA_VIRT) += virt.o
 obj-$(CONFIG_XTENSA_XTFPGA) += xtfpga.o
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index 981dbb7bbebb..a22743a3d61c 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -37,6 +37,7 @@
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
 #include "xtensa_memory.h"
+#include "xtensa_sim.h"
 
 static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
 {
@@ -52,12 +53,11 @@ static void sim_reset(void *opaque)
 cpu_reset(CPU(cpu));
 }
 
-static void xtensa_sim_init(MachineState *machine)
+XtensaCPU *xtensa_sim_common_init(MachineState *machine)
 {
 XtensaCPU *cpu = NULL;
 CPUXtensaState *env = NULL;
 ram_addr_t ram_size = machine->ram_size;
-const char *kernel_filename = machine->kernel_filename;
 int n;
 
 for (n = 0; n < machine->smp.cpus; n++) {
@@ -89,30 +89,41 @@ static void xtensa_sim_init(MachineState *machine)
 xtensa_create_memory_regions(, "xtensa.sysram",
  get_system_memory());
 }
-
 if (serial_hd(0)) {
 xtensa_sim_open_console(serial_hd(0));
 }
-if (kernel_filename) {
-uint64_t elf_entry;
-uint64_t elf_lowaddr;
+return cpu;
+}
+
+void xtensa_sim_load_kernel(XtensaCPU *cpu, MachineState *machine)
+{
+const char *kernel_filename = machine->kernel_filename;
 #ifdef TARGET_WORDS_BIGENDIAN
-int success = load_elf(kernel_filename, NULL,
-   translate_phys_addr, cpu,
-   _entry, _lowaddr,
-   NULL, 1, EM_XTENSA, 0, 0);
+int big_endian = true;
 #else
-int success = load_elf(kernel_filename, NULL,
-   translate_phys_addr, cpu,
-   _entry, _lowaddr,
-   NULL, 0, EM_XTENSA, 0, 0);
+int big_endian = false;
 #endif
+
+if (kernel_filename) {
+uint64_t elf_entry;
+uint64_t elf_lowaddr;
+int success = load_elf(kernel_filename, NULL, translate_phys_addr, cpu,
+   _entry, _lowaddr, NULL, big_endian,
+   EM_XTENSA, 0, 0);
+
 if (success > 0) {
-env->pc = elf_entry;
+cpu->env.pc = elf_entry;
 }
 }
 }
 
+static void xtensa_sim_init(MachineState *machine)
+{
+XtensaCPU *cpu = xtensa_sim_common_init(machine);
+
+xtensa_sim_load_kernel(cpu, machine);
+}
+
 static void xtensa_sim_machine_init(MachineClass *mc)
 {
 mc->desc = "sim machine (" XTENSA_DEFAULT_CPU_MODEL ")";
diff --git a/hw/xtensa/virt.c b/hw/xtensa/virt.c
new file mode 100644
index ..b22dcf938a16
--- 

Re: Using virtual IOMMU in guest hypervisors other than KVM and Xen?

2019-10-18 Thread Peter Xu
On Wed, Oct 16, 2019 at 03:01:22PM -0700, Jintack Lim wrote:
> On Mon, Oct 14, 2019 at 7:50 PM Peter Xu  wrote:
> >
> > On Mon, Oct 14, 2019 at 01:28:49PM -0700, Jintack Lim wrote:
> > > Hi,
> >
> > Hello, Jintack,
> >
> Hi Peter,
> 
> > >
> > > I'm trying to pass through a physical network device to a nested VM
> > > using virtual IOMMU. While I was able to do it successfully using KVM
> > > and Xen guest hypervisors running in a VM respectively, I couldn't do
> > > it with Hyper-V as I described below. I wonder if anyone have
> > > successfully used virtual IOMMU in other hypervisors other than KVM
> > > and Xen? (like Hyper-V or VMware)
> > >
> > > The issue I have with Hyper-V is that Hyper-V gives an error that the
> > > underlying hardware is not capable of doing passthrough. The exact
> > > error message is as follows.
> > >
> > > Windows Power-shell > (Get-VMHost).IovSupportReasons
> > > The chipset on the system does not do DMA remapping, without which
> > > SR-IOV cannot be supported.
> > >
> > > I'm pretty sure that Hyper-V recognizes virtual IOMMU, though; I have
> > > enabled iommu in windows boot loader[1], and I see differences when
> > > booing a Windows VM with and without virtual IOMMU. I also checked
> > > that virtual IOMMU traces are printed.
> >
> > What traces have you checked?  More explicitly, have you seen DMAR
> > enabled and page table setup for that specific device to be
> > pass-throughed?
> 
> Thanks for the pointers. I checked that DMAR is NOT enabled. The only
> registers that Windows guest accessed were Version Register,
> Capability Register, and Extended Capability Register. On the other
> hand, a Linux guest accessed other registers and enabled DMAR.
> Here's a link to the trace I got using QEMU 4.1.0. Do you see anything
> interesting there?
> http://paste.ubuntu.com/p/YcSyxG9Z3x/

Then I feel like Windows is reluctant to enable DMAR due to lacking of
some caps.

> 
> >
> > >
> > > I have tried multiple KVM/QEMU versions including the latest ones
> > > (kernel v5.3, QEMU 4.1.0) as well as two different Windows servers
> > > (2016 and 2019), but I see the same result. [4]
> > >
> > > I'd love to hear if somebody is using virtual IOMMU in Hyper-V or
> > > VMware successfully, especially for passthrough. I also appreciate if
> > > somebody can point out any configuration errors I have.
> > >
> > > Here's the qemu command line I use, basically from the QEMU vt-d
> > > page[2] and Hyper-v on KVM from kvmforum [3].
> > >
> > > ./qemu/x86_64-softmmu/qemu-system-x86_64 -device
> > > intel-iommu,intremap=on,caching-mode=on -smp 6 -m 24G -M
> >
> > Have you tried to use 4-level IOMMU page table (aw-bits=48 on latest
> > QEMU, or x-aw-bits=48 on some old ones)?  IIRC we've encountered
> > issues when trying to pass the SVVP Windows test with this, in which
> > 4-level is required.  I'm not sure whether whether that is required in
> > general usages of vIOMMU in Windows.
> 
> I just tried the option you mentioned, but it didn't change anything.
> BTW, what version of Windows was it?

Sorry I don't remember that. I didn't do the test but I was just
acknowledged that with it the test passed.  I assume you're using the
latest QEMU here because I know Windows could require another
capability (DMA draining) and it should be on by default in latest
qemu master.

At that time the complete cmdline to pass the test should be:

  -device intel-iommu,intremap=on,aw-bits=48,caching-mode=off,eim=on

I also don't remember on why caching-mode needs to be off at that
time (otherwise SVVP fails too).

-- 
Peter Xu




Re: [PATCH 0/6] migration/postcopy: enable compress during postcopy

2019-10-18 Thread Wei Yang
On Fri, Oct 18, 2019 at 09:50:05AM -0700, no-re...@patchew.org wrote:
>Patchew URL: 
>https://patchew.org/QEMU/20191018004850.9888-1-richardw.y...@linux.intel.com/
>
>
>
>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  aarch64-softmmu/hw/timer/allwinner-a10-pit.o
>In file included from /tmp/qemu-test/src/migration/ram.c:29:
>/tmp/qemu-test/src/migration/ram.c: In function 'ram_load_postcopy':
>/tmp/qemu-test/src/migration/ram.c:4177:56: error: cast from pointer to 
>integer of different size [-Werror=pointer-to-int-cast]
> void *place_dest = (void *)QEMU_ALIGN_DOWN((unsigned long)host,
>^

Sounds should use uintptr_t.

Would change it in next version.

>/tmp/qemu-test/src/include/qemu/osdep.h:268:33: note: in definition of macro 
>'QEMU_ALIGN_DOWN'
> #define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
> ^
>cc1: all warnings being treated as errors
>make[1]: *** [/tmp/qemu-test/src/rules.mak:69: migration/ram.o] Error 1
>make[1]: *** Waiting for unfinished jobs
>  CC  x86_64-softmmu/target/i386/arch_dump.o
>  CC  aarch64-softmmu/hw/usb/tusb6010.o
>---
>  CC  aarch64-softmmu/hw/arm/xlnx-zynqmp.o
>In file included from /tmp/qemu-test/src/migration/ram.c:29:
>/tmp/qemu-test/src/migration/ram.c: In function 'ram_load_postcopy':
>/tmp/qemu-test/src/migration/ram.c:4177:56: error: cast from pointer to 
>integer of different size [-Werror=pointer-to-int-cast]
> void *place_dest = (void *)QEMU_ALIGN_DOWN((unsigned long)host,
>^
>/tmp/qemu-test/src/include/qemu/osdep.h:268:33: note: in definition of macro 
>'QEMU_ALIGN_DOWN'
> #define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
> ^
>cc1: all warnings being treated as errors
>make[1]: *** [/tmp/qemu-test/src/rules.mak:69: migration/ram.o] Error 1
>make[1]: *** Waiting for unfinished jobs
>make: *** [Makefile:482: aarch64-softmmu/all] Error 2
>make: *** Waiting for unfinished jobs
>make: *** [Makefile:482: x86_64-softmmu/all] Error 2
>Traceback (most recent call last):
>  File "./tests/docker/docker.py", line 662, in 
>sys.exit(main())
>---
>raise CalledProcessError(retcode, cmd)
>subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
>'--label', 'com.qemu.instance.uuid=90570434880344249cff701baa188163', '-u', 
>'1001', '--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/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
>'/var/tmp/patchew-tester-tmp-dh8p6f27/src/docker-src.2019-10-18-12.47.19.4164:/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=90570434880344249cff701baa188163
>make[1]: *** [docker-run] Error 1
>make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-dh8p6f27/src'
>make: *** [docker-run-test-mingw@fedora] Error 2
>
>real2m45.691s
>user0m8.390s
>
>
>The full log is available at
>http://patchew.org/logs/20191018004850.9888-1-richardw.y...@linux.intel.com/testing.docker-mingw@fedora/?type=message.
>---
>Email generated automatically by Patchew [https://patchew.org/].
>Please send your feedback to patchew-de...@redhat.com

-- 
Wei Yang
Help you, Help me



Re: [PATCH] Do not use %m in common code to print error messages

2019-10-18 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20191018104438.6158-1-th...@redhat.com/



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  hw/ssi/pl022.o
In file included from /tmp/qemu-test/src/hw/misc/tmp421.c:30:
/tmp/qemu-test/src/hw/misc/tmp421.c: In function 'tmp421_set_temperature':
/tmp/qemu-test/src/include/qapi/error.h:166:25: error: format '%s' expects a 
matching 'char *' argument [-Werror=format=]
 (fmt), ## __VA_ARGS__)
 ^
/tmp/qemu-test/src/hw/misc/tmp421.c:166:9: note: in expansion of macro 
'error_setg'
 error_setg(errp, "error reading %s: %s", errmsg);
 ^~
cc1: all warnings being treated as errors
make: *** [/tmp/qemu-test/src/rules.mak:69: hw/misc/tmp421.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 662, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=aeeffa7799634227ba70e98b4d08d799', '-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-4zudpx4q/src/docker-src.2019-10-18-19.29.53.18800:/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=aeeffa7799634227ba70e98b4d08d799
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-4zudpx4q/src'
make: *** [docker-run-test-mingw@fedora] Error 2

real2m1.697s
user0m7.284s


The full log is available at
http://patchew.org/logs/20191018104438.6158-1-th...@redhat.com/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] Do not use %m in common code to print error messages

2019-10-18 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20191018104438.6158-1-th...@redhat.com/



Hi,

This series failed the docker-quick@centos7 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
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  hw/misc/imx6_ccm.o
  CC  hw/misc/imx6ul_ccm.o
/tmp/qemu-test/src/hw/misc/tmp421.c: In function 'tmp421_set_temperature':
/tmp/qemu-test/src/hw/misc/tmp421.c:166:9: error: format '%s' expects a 
matching 'char *' argument [-Werror=format=]
 error_setg(errp, "error reading %s: %s", errmsg);
 ^
cc1: all warnings being treated as errors
  CC  hw/misc/imx7_ccm.o
  CC  hw/misc/imx2_wdt.o
make: *** [hw/misc/tmp421.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 662, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=eae0544322904584b30d3ce7bcb77a82', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-786nsriq/src/docker-src.2019-10-18-19.26.59.10681:/var/tmp/qemu:z,ro',
 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=eae0544322904584b30d3ce7bcb77a82
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-786nsriq/src'
make: *** [docker-run-test-quick@centos7] Error 2

real2m5.578s
user0m7.522s


The full log is available at
http://patchew.org/logs/20191018104438.6158-1-th...@redhat.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH] migration: savevm_state_insert_handler: constant-time element insertion

2019-10-18 Thread Juan Quintela
Scott Cheloha  wrote:
> On Thu, Oct 17, 2019 at 10:43:08AM +0200, Juan Quintela wrote:
>> Scott Cheloha  wrote:
>> 
>> > Registering a SaveStateEntry object via savevm_state_insert_handler()
>> > is an O(n) operation because the list is a priority queue maintained by
>> > walking the list from head to tail to find a suitable insertion point.
>> >
>> > This adds considerable overhead for VMs with many such objects.  For
>> > instance, ppc64 machines with large maxmem (8T+) spend ~10% or more of
>> > their CPU time in savevm_state_insert_handler() before attempting to
>> > boot a kernel.

> I was trying to avoid churning the file more than absolutely
> necessary.  There are 18 QTAILQ_FOREACH() loops in savevm.c right now.
> Making ~15 of them double-loops doesn't make the code easier to read.

Change thecode to be something different, I agree that is more churn,
but ...

>
> I think incurring slight complexity on insertion/removal to make
> insertion fast is well worth the conceptual simplicity of addressing
> one big list of elements for every other operation.
>
>> savevm_state_handler_insert() for instance becomes even easier, just a
>> QTALIQ_INSERT_TAIL() in the proper queue, right?
>
> Yes, insertion becomes extremely obvious: you just append the element
> to the tail of its priority queue, which must already exist.
>
> But see above for the cost.
>
>> I agree with the idea of the patch.  Especially when you told us how bad
>> the performance of the current code is.
>> 
>> Out of curiosity, how many objects are we talking about?
>
> At maxmem=8T I'm seeing about 4 elements in that list.  At
> maxmem=64T I'm seeing around 262000.  The vast majority of these
> elements are "spapr_drc" objects, each of which (IIRC) corresponds to
> a 256MB chunk of address space.

We are having trouble because we have too many objects.  So, the right
approach IMHO is just to add the list of queueue.  Looking into the
functions:

static int calculate_new_instance_id(const char *idstr)
static int calculate_compat_instance_id(const char *idstr)
   * We can call QTAILQ_FOREACH in the propper subqueue

static void savevm_state_handler_insert(SaveStateEntry *nse)
   * We don't need the call if we do propper subqueues array

void unregister_savevm(DeviceState *dev, const char *idstr, void
   *opaque)
   * We can use the propper subqueue

vmstate_unregister
   * We can use the propper subqueue

bool qemu_savevm_state_blocked(Error **errp)
  * We need to loop over all queues

void qemu_savevm_state_setup(QEMUFile *f)
int qemu_savevm_state_resume_prepare(MigrationState *s)
int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy)
void qemu_savevm_state_complete_postcopy(QEMUFile *f)
int qemu_savevm_state_complete_precopy_iterable(QEMUFile *f, bool
  in_postcopy)
int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
void qemu_savevm_state_pending(QEMUFile *f, uint64_t threshold_size,
void qemu_savevm_state_cleanup(void)
int qemu_save_device_state(QEMUFile *f)
static int qemu_loadvm_state_setup(QEMUFile *f)
void qemu_loadvm_state_cleanup(void)
 * Loop over all queues

static SaveStateEntry *find_se(const char *idstr, int instance_id)
qemu_loadvm_section_part_end(QEMUFile *f, MigrationIncomingState *mis)
* we know the propper queue


But basically all the ones that we need to loop over all queues don't
have local state, so we can create a

loop_over_all_handlers() function that takes a callback and does all the
work.  They don't share states between iterations.

What do you think?
My problem with your appreach is that it makes insertion/removal more
expensive, that is where you are showing performance problems.  In the
places where we need to loop over all queues, we need to do it over all
elements anyways, so the performance difference is going to be
negigible.

Once told that, having 4 elements on that queue, it will make
"downtime" for migration "interesting", to say the least, no?  How much
size are we talking about?  Should we consider moving it to a live
section?


Later, Juan.



qemu crashing when attaching an ISO file to a virtio-scsi CD-ROM device through libvirt

2019-10-18 Thread Fernando Casas Schössow
Hi,

Today while working with two different Windows Server 2012 R2 guests I 
found that when I try to attach an ISO file to a SCSI CD-ROM device 
through libvirt (virsh or virt-manager) while the guest is running, 
qemu crashes and the following message is logged:

Assertion failed: blk_get_aio_context(d->conf.blk) == s->ctx 
(/home/buildozer/aports/main/qemu/src/qemu-4.0.0/hw/scsi/virtio-scsi.c: 
virtio_scsi_ctx_check: 246)

I can repro this at will. All I have to do is to try to attach an ISO 
file to the SCSI CDROM while the guest is running.
The SCSI controller model is virtio-scsi with iothread enabled.
Please find below all the details about my setup that I considered 
relevant but I missed something please don't hesitate to let me know:

Host arch: x86_64
Distro: Alpine Linux 3.10.2
qemu version: 4.0
Linux kernel version: 4.19.67
libvirt: 5.5.0
Emulated SCSI controller: virtio-scsi (with iothread enabled)
Guest firmware: OVMF-EFI
Guest OS: Window Server 2012 R2
Guest virtio drivers version: 171 (current stable)

qemu command line:

/usr/bin/qemu-system-x86_64 -name guest=DCHOMENET01,debug-threads=on -S 
-object 
secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-78-DCHOMENET01/master-key.aes
 
-machine pc-i440fx-4.0,accel=kvm,usb=off,dump-guest-core=on -cpu 
IvyBridge,ss=on,vmx=off,pcid=on,hypervisor=on,arat=on,tsc_adjust=on,umip=on,xsaveopt=on,hv_time,hv_relaxed,hv_vapic,hv_spinlocks=0x1fff
 
-drive 
file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd,if=pflash,format=raw,unit=0,readonly=on
 
-drive 
file=/var/lib/libvirt/qemu/nvram/DCHOMENET01_VARS.fd,if=pflash,format=raw,unit=1
 
-m 1536 -overcommit mem-lock=off -smp 1,sockets=1,cores=1,threads=1 
-object iothread,id=iothread1 -uuid 
f06978ad-2734-44ab-a518-5dfcf71d625e -no-user-config -nodefaults 
-chardev socket,id=charmonitor,fd=33,server,nowait -mon 
chardev=charmonitor,id=monitor,mode=control -rtc 
base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay 
-no-hpet -no-shutdown -global PIIX4_PM.disable_s3=1 -global 
PIIX4_PM.disable_s4=1 -boot strict=on -device 
qemu-xhci,id=usb,bus=pci.0,addr=0x4 -device 
virtio-scsi-pci,iothread=iothread1,id=scsi0,num_queues=1,bus=pci.0,addr=0x5 
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 -drive 
file=/storage/storage-hdd-vms/virtual_machines_hdd/dchomenet01.qcow2,format=qcow2,if=none,id=drive-scsi0-0-0-0,cache=none,discard=unmap,aio=threads
 
-device 
scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi0-0-0-0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=1,write-cache=on
 
-drive if=none,id=drive-scsi0-0-0-1,readonly=on -device 
scsi-cd,bus=scsi0.0,channel=0,scsi-id=0,lun=1,device_id=drive-scsi0-0-0-1,drive=drive-scsi0-0-0-1,id=scsi0-0-0-1
 
-netdev tap,fd=41,id=hostnet0,vhost=on,vhostfd=43 -device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:99:b5:62,bus=pci.0,addr=0x3 
-chardev 
socket,id=charserial0,host=127.0.0.1,port=4900,telnet,server,nowait 
-device isa-serial,chardev=charserial0,id=serial0 -chardev 
spicevmc,id=charchannel0,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
 
-chardev socket,id=charchannel1,fd=45,server,nowait -device 
virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=org.qemu.guest_agent.0
 
-chardev spiceport,id=charchannel2,name=org.spice-space.webdav.0 
-device 
virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,name=org.spice-space.webdav.0
 
-device virtio-tablet-pci,id=input2,bus=pci.0,addr=0x7 -spice 
port=5900,addr=127.0.0.1,disable-ticketing,seamless-migration=on 
-device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pci.0,addr=0x2
 
-chardev spicevmc,id=charredir0,name=usbredir -device 
usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev 
spicevmc,id=charredir1,name=usbredir -device 
usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 -sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny 
-msg timestamp=on

I can provide a core dump of the process if needed for debugging and 
the guest XML as well.

Thanks.

Fernando




qemu crashing when attaching an ISO file to a virtio-scsi CD-ROM device through libvirt

2019-10-18 Thread Fernando Casas Schössow
Hi,

Today while working with two different Windows Server 2012 R2 guests I found 
that when I try to attach an ISO file to a SCSI CD-ROM device through libvirt 
(virsh or virt-manager) while the guest is running, qemu crashes and the 
following message is logged:

Assertion failed: blk_get_aio_context(d->conf.blk) == s->ctx 
(/home/buildozer/aports/main/qemu/src/qemu-4.0.0/hw/scsi/virtio-scsi.c: 
virtio_scsi_ctx_check: 246)

I can repro this at will. All I have to do is to try to attach an ISO file to 
the SCSI CDROM while the guest is running.
The SCSI controller model is virtio-scsi with iothread enabled.
Please find below all the details about my setup that I considered relevant but 
I missed something please don't hesitate to let me know:

Host arch: x86_64
Distro: Alpine Linux 3.10.2
qemu version: 4.0
Linux kernel version: 4.19.67
libvirt: 5.5.0
Emulated SCSI controller: virtio-scsi (with iothread enabled)
Guest firmware: OVMF-EFI
Guest OS: Window Server 2012 R2
Guest virtio drivers version: 171 (current stable)

qemu command line:

/usr/bin/qemu-system-x86_64 -name guest=DCHOMENET01,debug-threads=on -S -object 
secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-78-DCHOMENET01/master-key.aes
 -machine pc-i440fx-4.0,accel=kvm,usb=off,dump-guest-core=on -cpu 
IvyBridge,ss=on,vmx=off,pcid=on,hypervisor=on,arat=on,tsc_adjust=on,umip=on,xsaveopt=on,hv_time,hv_relaxed,hv_vapic,hv_spinlocks=0x1fff
 -drive 
file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd,if=pflash,format=raw,unit=0,readonly=on
 -drive 
file=/var/lib/libvirt/qemu/nvram/DCHOMENET01_VARS.fd,if=pflash,format=raw,unit=1
 -m 1536 -overcommit mem-lock=off -smp 1,sockets=1,cores=1,threads=1 -object 
iothread,id=iothread1 -uuid f06978ad-2734-44ab-a518-5dfcf71d625e 
-no-user-config -nodefaults -chardev socket,id=charmonitor,fd=33,server,nowait 
-mon chardev=charmonitor,id=monitor,mode=control -rtc 
base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet 
-no-shutdown -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot 
strict=on -device qemu-xhci,id=usb,bus=pci.0,addr=0x4 -device 
virtio-scsi-pci,iothread=iothread1,id=scsi0,num_queues=1,bus=pci.0,addr=0x5 
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 -drive 
file=/storage/storage-hdd-vms/virtual_machines_hdd/dchomenet01.qcow2,format=qcow2,if=none,id=drive-scsi0-0-0-0,cache=none,discard=unmap,aio=threads
 -device 
scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi0-0-0-0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=1,write-cache=on
 -drive if=none,id=drive-scsi0-0-0-1,readonly=on -device 
scsi-cd,bus=scsi0.0,channel=0,scsi-id=0,lun=1,device_id=drive-scsi0-0-0-1,drive=drive-scsi0-0-0-1,id=scsi0-0-0-1
 -netdev tap,fd=41,id=hostnet0,vhost=on,vhostfd=43 -device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:99:b5:62,bus=pci.0,addr=0x3 
-chardev socket,id=charserial0,host=127.0.0.1,port=4900,telnet,server,nowait 
-device isa-serial,chardev=charserial0,id=serial0 -chardev 
spicevmc,id=charchannel0,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
 -chardev socket,id=charchannel1,fd=45,server,nowait -device 
virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=org.qemu.guest_agent.0
 -chardev spiceport,id=charchannel2,name=org.spice-space.webdav.0 -device 
virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,name=org.spice-space.webdav.0
 -device virtio-tablet-pci,id=input2,bus=pci.0,addr=0x7 -spice 
port=5900,addr=127.0.0.1,disable-ticketing,seamless-migration=on -device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pci.0,addr=0x2
 -chardev spicevmc,id=charredir0,name=usbredir -device 
usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev 
spicevmc,id=charredir1,name=usbredir -device 
usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 -sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg 
timestamp=on

I can provide a core dump of the process if needed for debugging and the guest 
XML as well.

Thanks.

Fernando




Re: [PATCH] configure: Require Python >= 3.5

2019-10-18 Thread John Snow



On 10/18/19 5:14 PM, Eduardo Habkost wrote:
> On Fri, Oct 18, 2019 at 05:07:36PM -0400, John Snow wrote:
>>
>>
>> On 10/16/19 6:42 PM, Eduardo Habkost wrote:
>>> Python 3.5 is the oldest Python version available on our
>>> supported build platforms, and Python 2 end of life will be 3
>>> weeks after the planned release date of QEMU 4.2.0.  Drop Python
>>> 2 support from configure completely, and require Python 3.5 or
>>> newer.
>>>
>>
>> Which distributions constrain us to 3.5 right now? I know Debian9 is one
>> of them, but I'm not sure what others exist.
>>
>> I know I went through and checked a month ago, but I'm very smart and
>> didn't write it down.
>>
>> It might be nice to document (somewhere) so we know when we can require
>> something newer than 3.5 at the next major deprecation event.
> 
> I've summarized the release dates and Python version information I
> could find here: https://wiki.qemu.org/Supported_Build_Platforms
> 

You are an ABSOLUTE CHAMPION. Thank you so much!



Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Aleksandar Markovic
ū

On Tuesday, October 15, 2019, Anup Patel  wrote:

> This patch adds model for Google Goldfish virtual platform RTC device.
>
> We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
> for providing real date-time to Guest Linux. The corresponding Linux
> driver for Goldfish RTC device is already available in upstream Linux.
>
> For now, VM migration support is available but untested for Goldfish RTC
> device. It will be hardened in-future when we implement VM migration for
> KVM RISC-V.
>
> Signed-off-by: Anup Patel 
> ---
>  hw/rtc/Kconfig  |   3 +
>  hw/rtc/Makefile.objs|   1 +
>  hw/rtc/goldfish_rtc.c   | 278 
>  include/hw/timer/goldfish_rtc.h |  46 ++
>  4 files changed, 328 insertions(+)
>  create mode 100644 hw/rtc/goldfish_rtc.c
>  create mode 100644 include/hw/timer/goldfish_rtc.h
>
>
Do you plan to add some other devices from Goldfish platform?

Did you base your code on Android emulator code?

Related to the previous question, are you sure the copyright line should go
to Western Digital only?

Thanks, A.




> diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
> index 45daa8d655..bafe6ac2c9 100644
> --- a/hw/rtc/Kconfig
> +++ b/hw/rtc/Kconfig
> @@ -21,3 +21,6 @@ config MC146818RTC
>
>  config SUN4V_RTC
>  bool
> +
> +config GOLDFISH_RTC
> +bool
> diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
> index 8dc9fcd3a9..aa208d0d10 100644
> --- a/hw/rtc/Makefile.objs
> +++ b/hw/rtc/Makefile.objs
> @@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
>  obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
>  common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
>  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
> +common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
> diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> new file mode 100644
> index 00..223616ed75
> --- /dev/null
> +++ b/hw/rtc/goldfish_rtc.c
> @@ -0,0 +1,278 @@
> +/*
> + * Goldfish virtual platform RTC
> + *
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * For more details on Google Goldfish virtual platform refer:
> + * https://android.googlesource.com/platform/external/qemu/+/
> master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License
> along with
> + * this program.  If not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "hw/timer/goldfish_rtc.h"
> +#include "migration/vmstate.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "qemu/timer.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/cutils.h"
> +#include "qemu/log.h"
> +
> +#define RTC_TIME_LOW0x00
> +#define RTC_TIME_HIGH   0x04
> +#define RTC_ALARM_LOW   0x08
> +#define RTC_ALARM_HIGH  0x0c
> +#define RTC_IRQ_ENABLED 0x10
> +#define RTC_CLEAR_ALARM 0x14
> +#define RTC_ALARM_STATUS0x18
> +#define RTC_CLEAR_INTERRUPT 0x1c
> +
> +static void goldfish_rtc_update(GoldfishRTCState *s)
> +{
> +qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
> +}
> +
> +static void goldfish_rtc_interrupt(void *opaque)
> +{
> +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> +
> +s->alarm_running = 0;
> +s->irq_pending = 1;
> +goldfish_rtc_update(s);
> +}
> +
> +static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s)
> +{
> +return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
> +}
> +
> +static void goldfish_rtc_clear_alarm(GoldfishRTCState *s)
> +{
> +timer_del(s->timer);
> +s->alarm_running = 0;
> +}
> +
> +static void goldfish_rtc_set_alarm(GoldfishRTCState *s)
> +{
> +uint64_t ticks = goldfish_rtc_get_count(s);
> +uint64_t event = s->alarm_next;
> +
> +if (event <= ticks) {
> +goldfish_rtc_clear_alarm(s);
> +goldfish_rtc_interrupt(s);
> +} else {
> +int64_t now = qemu_clock_get_ns(rtc_clock);
> +timer_mod(s->timer, now + (event - ticks));
> +s->alarm_running = 1;
> +}
> +}
> +
> +static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
> +  unsigned size)
> +{
> +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> +uint64_t r;
> +
> +switch (offset) {
> +case RTC_TIME_LOW:
> +r = goldfish_rtc_get_count(s) & 0x;
> +break;
> +case 

Re: [PATCH] configure: Require Python >= 3.5

2019-10-18 Thread Eduardo Habkost
On Fri, Oct 18, 2019 at 05:07:36PM -0400, John Snow wrote:
> 
> 
> On 10/16/19 6:42 PM, Eduardo Habkost wrote:
> > Python 3.5 is the oldest Python version available on our
> > supported build platforms, and Python 2 end of life will be 3
> > weeks after the planned release date of QEMU 4.2.0.  Drop Python
> > 2 support from configure completely, and require Python 3.5 or
> > newer.
> > 
> 
> Which distributions constrain us to 3.5 right now? I know Debian9 is one
> of them, but I'm not sure what others exist.
> 
> I know I went through and checked a month ago, but I'm very smart and
> didn't write it down.
> 
> It might be nice to document (somewhere) so we know when we can require
> something newer than 3.5 at the next major deprecation event.

I've summarized the release dates and Python version information I
could find here: https://wiki.qemu.org/Supported_Build_Platforms

> 
> > Signed-off-by: Eduardo Habkost 
> 
> 
> Reviewed-by: John Snow 

Thanks!

-- 
Eduardo



Re: [PATCH] iotests: Remove 130 from the "auto" group

2019-10-18 Thread John Snow



On 10/18/19 12:10 PM, Thomas Huth wrote:
> Peter hit a "Could not open 'TEST_DIR/t.IMGFMT': Failed to get shared
> 'write' lock - Is another process using the image [TEST_DIR/t.IMGFMT]?"
> error with 130 already twice. Looks like this test is a little bit
> shaky, and currently nobody has a real clue what could be causing this
> issue, so for the time being, let's disable it from the "auto" group so
> that it does not gate the pull requests.
> 
> Signed-off-by: Thomas Huth 

Reviewed-by: John Snow 

> ---
>  tests/qemu-iotests/group | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
> index 7dac79a783..6aa4b8d098 100644
> --- a/tests/qemu-iotests/group
> +++ b/tests/qemu-iotests/group
> @@ -151,7 +151,7 @@
>  127 rw backing quick
>  128 rw quick
>  129 rw quick
> -130 rw auto quick
> +130 rw quick
>  131 rw quick
>  132 rw quick
>  133 auto quick
> 

-- 
—js



Re: [PATCH] configure: Require Python >= 3.5

2019-10-18 Thread John Snow



On 10/16/19 6:42 PM, Eduardo Habkost wrote:
> Python 3.5 is the oldest Python version available on our
> supported build platforms, and Python 2 end of life will be 3
> weeks after the planned release date of QEMU 4.2.0.  Drop Python
> 2 support from configure completely, and require Python 3.5 or
> newer.
> 

Which distributions constrain us to 3.5 right now? I know Debian9 is one
of them, but I'm not sure what others exist.

I know I went through and checked a month ago, but I'm very smart and
didn't write it down.

It might be nice to document (somewhere) so we know when we can require
something newer than 3.5 at the next major deprecation event.

> Signed-off-by: Eduardo Habkost 


Reviewed-by: John Snow 

Thanks!

> ---
>  configure  | 18 --
>  tests/Makefile.include |  5 -
>  2 files changed, 4 insertions(+), 19 deletions(-)
> 
> diff --git a/configure b/configure
> index 08ca4bcb46..870657ec7b 100755
> --- a/configure
> +++ b/configure
> @@ -895,9 +895,9 @@ fi
>  : ${install=${INSTALL-install}}
>  # We prefer python 3.x. A bare 'python' is traditionally
>  # python 2.x, but some distros have it as python 3.x, so
> -# we check that before python2
> +# we check that too
>  python=
> -for binary in "${PYTHON-python3}" python python2
> +for binary in "${PYTHON-python3}" python
>  do
>  if has "$binary"
>  then
> @@ -1824,8 +1824,8 @@ fi
>  
>  # Note that if the Python conditional here evaluates True we will exit
>  # with status 1 which is a shell 'false' value.
> -if ! $python -c 'import sys; sys.exit(sys.version_info < (2,7))'; then
> -  error_exit "Cannot use '$python', Python 2 >= 2.7 or Python 3 is 
> required." \
> +if ! $python -c 'import sys; sys.exit(sys.version_info < (3,5))'; then
> +  error_exit "Cannot use '$python', Python >= 3.5 is required." \
>"Use --python=/path/to/python to specify a supported Python."
>  fi
>  
> @@ -6456,15 +6456,6 @@ if test "$supported_os" = "no"; then
>  echo "us upstream at qemu-devel@nongnu.org."
>  fi
>  
> -# Note that if the Python conditional here evaluates True we will exit
> -# with status 1 which is a shell 'false' value.
> -if ! $python -c 'import sys; sys.exit(sys.version_info < (3,0))'; then
> -  echo
> -  echo "warning: Python 2 support is deprecated" >&2
> -  echo "warning: Python 3 will be required for building future versions of 
> QEMU" >&2
> -  python2="y"
> -fi
> -
>  config_host_mak="config-host.mak"
>  
>  echo "# Automatically generated by configure - do not modify" 
> >config-all-disas.mak
> @@ -7282,7 +7273,6 @@ echo "INSTALL_DATA=$install -c -m 0644" >> 
> $config_host_mak
>  echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
>  echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak
>  echo "PYTHON=$python" >> $config_host_mak
> -echo "PYTHON2=$python2" >> $config_host_mak
>  echo "CC=$cc" >> $config_host_mak
>  if $iasl -h > /dev/null 2>&1; then
>echo "IASL=$iasl" >> $config_host_mak
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 3543451ed3..54ee1f0a2f 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -1137,7 +1137,6 @@ TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
>  AVOCADO_SHOW=app
>  AVOCADO_TAGS=$(patsubst %-softmmu,-t arch:%, $(filter 
> %-softmmu,$(TARGET_DIRS)))
>  
> -ifneq ($(PYTHON2),y)
>  $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
>   $(call quiet-command, \
>  $(PYTHON) -m venv --system-site-packages $@, \
> @@ -1146,10 +1145,6 @@ $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
>  $(TESTS_VENV_DIR)/bin/python -m pip -q install -r 
> $(TESTS_VENV_REQ), \
>  PIP, $(TESTS_VENV_REQ))
>   $(call quiet-command, touch $@)
> -else
> -$(TESTS_VENV_DIR):
> - $(error "venv directory for tests requires Python 3")
> -endif
>  
>  $(TESTS_RESULTS_DIR):
>   $(call quiet-command, mkdir -p $@, \
> 



Re: [PATCH v3 2/2] riscv: virt: Use Goldfish RTC device

2019-10-18 Thread Alistair Francis
On Tue, Oct 15, 2019 at 1:37 AM Anup Patel  wrote:
>
> We extend QEMU RISC-V virt machine by adding Goldfish RTC device
> to it. This will allow Guest Linux to sync it's local date/time
> with Host date/time via RTC device.
>
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/Kconfig|  1 +
>  hw/riscv/virt.c | 15 +++
>  include/hw/riscv/virt.h |  2 ++
>  3 files changed, 18 insertions(+)
>
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index fb19b2df3a..b33753c780 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -34,6 +34,7 @@ config RISCV_VIRT
>  select PCI
>  select HART
>  select SERIAL
> +select GOLDFISH_RTC
>  select VIRTIO_MMIO
>  select PCI_EXPRESS_GENERIC_BRIDGE
>  select SIFIVE
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index d36f5625ec..95c42ab993 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -57,6 +57,7 @@ static const struct MemmapEntry {
>  [VIRT_DEBUG] =   {0x0, 0x100 },
>  [VIRT_MROM] ={ 0x1000,   0x11000 },
>  [VIRT_TEST] ={   0x10,0x1000 },
> +[VIRT_RTC] = {   0x101000,0x1000 },
>  [VIRT_CLINT] =   {  0x200,   0x1 },
>  [VIRT_PLIC] ={  0xc00, 0x400 },
>  [VIRT_UART0] =   { 0x1000, 0x100 },
> @@ -310,6 +311,17 @@ static void create_fdt(RISCVVirtState *s, const struct 
> MemmapEntry *memmap,
>  qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
>  qemu_fdt_setprop_cell(fdt, nodename, "interrupts", UART0_IRQ);
>
> +nodename = g_strdup_printf("/rtc@%lx",
> +(long)memmap[VIRT_RTC].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible",
> +"google,goldfish-rtc");
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +0x0, memmap[VIRT_RTC].base,
> +0x0, memmap[VIRT_RTC].size);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupts", RTC_IRQ);
> +
>  qemu_fdt_add_subnode(fdt, "/chosen");
>  qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
>  if (cmdline) {
> @@ -496,6 +508,9 @@ static void riscv_virt_board_init(MachineState *machine)
>  0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
>  serial_hd(0), DEVICE_LITTLE_ENDIAN);
>
> +sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,
> +qdev_get_gpio_in(DEVICE(s->plic), RTC_IRQ));
> +
>  g_free(plic_hart_config);
>  }
>
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 6e5fbe5d3b..e6423258d3 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -37,6 +37,7 @@ enum {
>  VIRT_DEBUG,
>  VIRT_MROM,
>  VIRT_TEST,
> +VIRT_RTC,
>  VIRT_CLINT,
>  VIRT_PLIC,
>  VIRT_UART0,
> @@ -49,6 +50,7 @@ enum {
>
>  enum {
>  UART0_IRQ = 10,
> +RTC_IRQ = 11,
>  VIRTIO_IRQ = 1, /* 1 to 8 */
>  VIRTIO_COUNT = 8,
>  PCIE_IRQ = 0x20, /* 32 to 35 */
> --
> 2.17.1
>
>



Re: [PATCH] configure: Require Python >= 3.5

2019-10-18 Thread John Snow



On 10/18/19 4:15 AM, Kevin Wolf wrote:
> Am 17.10.2019 um 21:39 hat John Snow geschrieben:
>> On 10/17/19 7:21 AM, Kevin Wolf wrote:
>>> Am 17.10.2019 um 00:48 hat John Snow geschrieben:
 On 10/16/19 6:42 PM, Eduardo Habkost wrote:
> Python 3.5 is the oldest Python version available on our
> supported build platforms, and Python 2 end of life will be 3
> weeks after the planned release date of QEMU 4.2.0.  Drop Python
> 2 support from configure completely, and require Python 3.5 or
> newer.
>
> Signed-off-by: Eduardo Habkost 

 Seems like a good time and place to mention this. Kevin, you require
 3.6+ for iotests, which are -- at present -- invoked as part of "make
 check".

 Do we care? Basically, this just means that iotests won't run for
 systems that don't have 3.6+, which would be platforms like Debian 9 --
 which is why ehabkost is choosing 3.5 here.
>>>
>>> I think we were aware of this when we made the change to iotests. That
>>> all tests of the current upstream QEMU version are run on Debian
>>> oldstable (with the distro Python version) is, to say the least, not a
>>> priority for me. They must not fail, but I'd say skipping is fine.
>>>
>>> And actually, we should still have a reasonable coverage there with the
>>> shell-based test cases.
>>
>> This seems like a weirdly arbitrary decision for a benefit that's not
>> clear to me. Is it because you want variable annotations?
> 
> Yes, the discussion about type annotations is what made me check whether
> we could do 3.6, because if we want to make use of type checking, we'll
> need it for both functions and variables to get reasonable results.
> 
> And actually, we currently don't have any Python tests in the auto
> group, so the only effect is for people manually running ./check on
> Debian oldstable. I'm not sure, but I suspect this might be the empty
> set.
> 
> Kevin
> 

It would have an effect on `make docker-test-block@debian-amd64" I
think, but I guess nobody runs that right now.

Well, alright.

--js



Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Alistair Francis
On Tue, Oct 15, 2019 at 1:36 AM Anup Patel  wrote:
>
> This patch adds model for Google Goldfish virtual platform RTC device.
>
> We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
> for providing real date-time to Guest Linux. The corresponding Linux
> driver for Goldfish RTC device is already available in upstream Linux.
>
> For now, VM migration support is available but untested for Goldfish RTC
> device. It will be hardened in-future when we implement VM migration for
> KVM RISC-V.
>
> Signed-off-by: Anup Patel 
> ---
>  hw/rtc/Kconfig  |   3 +
>  hw/rtc/Makefile.objs|   1 +
>  hw/rtc/goldfish_rtc.c   | 278 
>  include/hw/timer/goldfish_rtc.h |  46 ++
>  4 files changed, 328 insertions(+)
>  create mode 100644 hw/rtc/goldfish_rtc.c
>  create mode 100644 include/hw/timer/goldfish_rtc.h
>
> diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
> index 45daa8d655..bafe6ac2c9 100644
> --- a/hw/rtc/Kconfig
> +++ b/hw/rtc/Kconfig
> @@ -21,3 +21,6 @@ config MC146818RTC
>
>  config SUN4V_RTC
>  bool
> +
> +config GOLDFISH_RTC
> +bool
> diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
> index 8dc9fcd3a9..aa208d0d10 100644
> --- a/hw/rtc/Makefile.objs
> +++ b/hw/rtc/Makefile.objs
> @@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
>  obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
>  common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
>  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
> +common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
> diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> new file mode 100644
> index 00..223616ed75
> --- /dev/null
> +++ b/hw/rtc/goldfish_rtc.c
> @@ -0,0 +1,278 @@
> +/*
> + * Goldfish virtual platform RTC
> + *
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * For more details on Google Goldfish virtual platform refer:
> + * 
> https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program.  If not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "hw/timer/goldfish_rtc.h"
> +#include "migration/vmstate.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "qemu/timer.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/cutils.h"
> +#include "qemu/log.h"
> +
> +#define RTC_TIME_LOW0x00
> +#define RTC_TIME_HIGH   0x04
> +#define RTC_ALARM_LOW   0x08
> +#define RTC_ALARM_HIGH  0x0c
> +#define RTC_IRQ_ENABLED 0x10
> +#define RTC_CLEAR_ALARM 0x14
> +#define RTC_ALARM_STATUS0x18
> +#define RTC_CLEAR_INTERRUPT 0x1c
> +
> +static void goldfish_rtc_update(GoldfishRTCState *s)
> +{
> +qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
> +}
> +
> +static void goldfish_rtc_interrupt(void *opaque)
> +{
> +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> +
> +s->alarm_running = 0;
> +s->irq_pending = 1;
> +goldfish_rtc_update(s);
> +}
> +
> +static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s)
> +{
> +return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
> +}
> +
> +static void goldfish_rtc_clear_alarm(GoldfishRTCState *s)
> +{
> +timer_del(s->timer);
> +s->alarm_running = 0;
> +}
> +
> +static void goldfish_rtc_set_alarm(GoldfishRTCState *s)
> +{
> +uint64_t ticks = goldfish_rtc_get_count(s);
> +uint64_t event = s->alarm_next;
> +
> +if (event <= ticks) {
> +goldfish_rtc_clear_alarm(s);
> +goldfish_rtc_interrupt(s);
> +} else {
> +int64_t now = qemu_clock_get_ns(rtc_clock);
> +timer_mod(s->timer, now + (event - ticks));

Isn't this just: event - s->tick_offset?

> +s->alarm_running = 1;
> +}
> +}
> +
> +static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
> +  unsigned size)
> +{
> +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> +uint64_t r;

There should be a trace or debug print showing read/write operations.

> +
> +switch (offset) {
> +case RTC_TIME_LOW:
> +r = goldfish_rtc_get_count(s) & 0x;
> +break;
> +case RTC_TIME_HIGH:
> +r = goldfish_rtc_get_count(s) >> 32;
> +break;
> +case RTC_ALARM_LOW:
> +

Re: [PATCH] qemu-img.texi: Describe data_file and data_file_raw

2019-10-18 Thread John Snow
CC qemu-block

On 10/18/19 5:59 AM, Han Han wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1763105
> 
> Signed-off-by: Han Han 
> ---
>  qemu-img.texi | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/qemu-img.texi b/qemu-img.texi
> index b5156d6316..44596c2d93 100644
> --- a/qemu-img.texi
> +++ b/qemu-img.texi
> @@ -763,6 +763,16 @@ file which is COW and has data blocks already, it 
> couldn't be changed to NOCOW
>  by setting @code{nocow=on}. One can issue @code{lsattr filename} to check if
>  the NOCOW flag is set or not (Capital 'C' is NOCOW flag).
>  
> +@item data_file
> +File name of data file that is stored in the image and used as a default for
> +opening the image. If the option is used, qcow2 file only stores the metadata
> +of the image.
> +

This is a little unclear, and seems to imply the data file is stored
*IN* the image.

"Optional filename to be used as a data store for this qcow2 file. If
this option is used, the qcow2 file only stores metadata for this image."

> +@item data_file_raw
> +This option requires @option{data_file}. If this option is set to @code{on},
> +qemu will always keep the external data file consistent as a standalone
> +read-only raw image. Default value is @code{off}.
> +
>  @end table
>  
>  @item Other
> 




Re: [PATCH v2 1/1] riscv/boot: Fix possible memory leak

2019-10-18 Thread Palmer Dabbelt

On Thu, 17 Oct 2019 05:08:39 PDT (-0700), Peter Maydell wrote:

Ping? It would be nice to see this patch get into master
to silence the coverity errors.


Sorry, it looks like I dropped this.  It's in my queue, I hope to submit a PR 
soon.




thanks
-- PMM

On Thu, 3 Oct 2019 at 18:05, Alistair Francis  wrote:


Coverity (CID 1405786) thinks that there is a possible memory leak as
we don't guarantee that the memory allocated from riscv_find_firmware()
is freed. This is a false positive, but let's tidy up the code to fix
the warning.

Signed-off-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
v2:
 - Fix commit typos

 hw/riscv/boot.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 2e92fb0680..7fee98d2f8 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -38,7 +38,7 @@ void riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
   hwaddr firmware_load_addr)
 {
-char *firmware_filename;
+char *firmware_filename = NULL;

 if (!machine->firmware) {
 /*
@@ -70,14 +70,11 @@ void riscv_find_and_load_firmware(MachineState *machine,
  * if no -bios option is set without breaking anything.
  */
 firmware_filename = riscv_find_firmware(default_machine_firmware);
-} else {
-firmware_filename = machine->firmware;
-if (strcmp(firmware_filename, "none")) {
-firmware_filename = riscv_find_firmware(firmware_filename);
-}
+} else if (strcmp(machine->firmware, "none")) {
+firmware_filename = riscv_find_firmware(machine->firmware);
 }

-if (strcmp(firmware_filename, "none")) {
+if (firmware_filename) {
 /* If not "none" load the firmware */
 riscv_load_firmware(firmware_filename, firmware_load_addr);
 g_free(firmware_filename);
--
2.23.0




Re: [PATCH 05/11] qapi: add unplug primary event

2019-10-18 Thread Eric Blake

On 10/18/19 3:20 PM, Jens Freimann wrote:

This event is emitted when we sent a request to unplug a
failover primary device from the Guest OS and it includes the
device id of the primary device.

Signed-off-by: Jens Freimann 
---
  qapi/migration.json | 19 +++
  1 file changed, 19 insertions(+)

diff --git a/qapi/migration.json b/qapi/migration.json
index 82feb5bd39..52e69e2868 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1448,3 +1448,22 @@
  # Since: 3.0
  ##
  { 'command': 'migrate-pause', 'allow-oob': true }
+
+##
+# @UNPLUG_PRIMARY:
+#
+# Emitted from source side of a migration when migration state is
+# WAIT_UNPLUG. Device was unplugged by guest operating system.
+# Device resources in QEMU are kept on standby to be able to re-plug it in case
+# of migration failure.
+#
+# @device_id: QEMU device id of the unplugged device
+#
+# Since: 4.2
+#
+# Example:
+#   {"event": "UNPLUG_PRIMARY", "data": {"device_id": "hostdev0"} }


Unless there is a strong reason in favor of 'device_id' (such as 
consistency with a similar event), our naming convention prefers this to 
be 'device-id'.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org



[PATCH 07/11] migration: allow unplug during migration for failover devices

2019-10-18 Thread Jens Freimann
In "b06424de62 migration: Disable hotplug/unplug during migration" we
added a check to disable unplug for all devices until we have figured
out what works. For failover primary devices qdev_unplug() is called
from the migration handler, i.e. during migration.

This patch adds a flag to DeviceState which is set to false for all
devices and makes an exception for vfio-pci devices that are also
primary devices in a failover pair.

Signed-off-by: Jens Freimann 
---
 hw/core/qdev.c | 1 +
 include/hw/qdev-core.h | 1 +
 qdev-monitor.c | 2 +-
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 89c134ec53..b1be568af3 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -995,6 +995,7 @@ static void device_initfn(Object *obj)
 
 dev->instance_id_alias = -1;
 dev->realized = false;
+dev->allow_unplug_during_migration = false;
 
 object_property_add_bool(obj, "realized",
  device_get_realized, device_set_realized, NULL);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 28f594a47d..6b690e85b1 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -143,6 +143,7 @@ struct DeviceState {
 bool pending_deleted_event;
 QemuOpts *opts;
 int hotplugged;
+bool allow_unplug_during_migration;
 BusState *parent_bus;
 QLIST_HEAD(, NamedGPIOList) gpios;
 QLIST_HEAD(, BusState) child_bus;
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 508d85df87..265ab4f0d5 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -848,7 +848,7 @@ void qdev_unplug(DeviceState *dev, Error **errp)
 return;
 }
 
-if (!migration_is_idle()) {
+if (!migration_is_idle() && !dev->allow_unplug_during_migration) {
 error_setg(errp, "device_del not allowed while migrating");
 return;
 }
-- 
2.21.0




[PATCH 10/11] net/virtio: add failover support

2019-10-18 Thread Jens Freimann
This patch adds support to handle failover device pairs of a virtio-net
device and a vfio-pci device, where the virtio-net acts as the standby
device and the vfio-pci device as the primary.

The general idea is that we have a pair of devices, a vfio-pci and a
emulated (virtio-net) device. Before migration the vfio device is
unplugged and data flows to the emulated device, on the target side
another vfio-pci device is plugged in to take over the data-path. In the
guest the net_failover module will pair net devices with the same MAC
address.

To achieve this we need:

1. Provide a callback function for the should_be_hidden DeviceListener.
   It is called when the primary device is plugged in. Evaluate the QOpt
   passed in to check if it is the matching primary device. It returns
   two values:
 - one to signal if the device to be added is the matching
   primary device
 - another one to signal to qdev if it should actually
   continue with adding the device or skip it.

   In the latter case it stores the device options in the VirtioNet
   struct and the device is added once the VIRTIO_NET_F_STANDBY feature is
   negotiated during virtio feature negotiation.

   If the virtio-net devices are not realized at the time the vfio-pci
   devices are realized, we need to connect the devices later. This way
   we make sure primary and standby devices can be specified in any
   order.

2. Register a callback for migration status notifier. When called it
   will unplug its primary device before the migration happens.

3. Register a callback for the migration code that checks if a device
   needs to be unplugged from the guest.

Signed-off-by: Jens Freimann 
---
 hw/net/virtio-net.c| 282 +
 include/hw/virtio/virtio-net.h |  12 ++
 include/hw/virtio/virtio.h |   1 +
 3 files changed, 295 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9f11422337..afe113f083 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/atomic.h"
 #include "qemu/iov.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
@@ -21,6 +22,10 @@
 #include "net/tap.h"
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
+#include "qemu/option.h"
+#include "qemu/option_int.h"
+#include "qemu/config-file.h"
+#include "qapi/qmp/qdict.h"
 #include "hw/virtio/virtio-net.h"
 #include "net/vhost_net.h"
 #include "net/announce.h"
@@ -28,11 +33,15 @@
 #include "qapi/error.h"
 #include "qapi/qapi-events-net.h"
 #include "hw/qdev-properties.h"
+#include "qapi/qapi-types-migration.h"
+#include "qapi/qapi-events-migration.h"
 #include "hw/virtio/virtio-access.h"
 #include "migration/misc.h"
 #include "standard-headers/linux/ethtool.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
+#include "monitor/qdev.h"
+#include "hw/pci/pci.h"
 
 #define VIRTIO_NET_VM_VERSION11
 
@@ -746,9 +755,85 @@ static inline uint64_t 
virtio_net_supported_guest_offloads(VirtIONet *n)
 return virtio_net_guest_offloads_by_features(vdev->guest_features);
 }
 
+static void failover_add_primary(VirtIONet *n)
+{
+Error *err = NULL;
+
+n->primary_device_opts = qemu_opts_find(qemu_find_opts("device"),
+n->primary_device_id);
+if (n->primary_device_opts) {
+n->primary_dev = qdev_device_add(n->primary_device_opts, );
+if (err) {
+qemu_opts_del(n->primary_device_opts);
+}
+if (n->primary_dev) {
+n->primary_bus = n->primary_dev->parent_bus;
+if (err) {
+qdev_unplug(n->primary_dev, );
+qdev_set_id(n->primary_dev, "");
+
+}
+}
+}
+if (err) {
+error_report_err(err);
+}
+}
+
+static int is_my_primary(void *opaque, QemuOpts *opts, Error **errp)
+{
+VirtIONet *n = opaque;
+int ret = 0;
+
+const char *standby_id = qemu_opt_get(opts, "net_failover_pair_id");
+
+if (standby_id != NULL && (g_strcmp0(standby_id, n->netclient_name) == 0)) 
{
+n->primary_device_id = g_strdup(opts->id);
+ret = 1;
+}
+
+return ret;
+}
+
+static DeviceState *virtio_net_find_primary(VirtIONet *n, Error *err)
+{
+DeviceState *dev = NULL;
+
+if (qemu_opts_foreach(qemu_find_opts("device"),
+ is_my_primary, n, )) {
+if (n->primary_device_id) {
+dev = qdev_find_recursive(sysbus_get_default(),
+n->primary_device_id);
+} else {
+return NULL;
+}
+}
+return dev;
+}
+
+
+
+static DeviceState *virtio_connect_failover_devices(VirtIONet *n,
+DeviceState *dev,
+Error **errp)
+{
+DeviceState *prim_dev = NULL;
+
+prim_dev = virtio_net_find_primary(n, *errp);
+if (prim_dev) {
+n->primary_device_id = g_strdup(prim_dev->id);
+

[PATCH 11/11] vfio: unplug failover primary device before migration

2019-10-18 Thread Jens Freimann
As usual block all vfio-pci devices from being migrated, but make an
exception for failover primary devices. This is achieved by setting
unmigratable to 0 but also add a migration blocker for all vfio-pci
devices except failover primary devices. These will be unplugged before
migration happens by the migration handler of the corresponding
virtio-net standby device.

Signed-off-by: Jens Freimann 
---
 hw/vfio/pci.c | 31 +--
 hw/vfio/pci.h |  1 +
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 12fac39804..a15b83c6b6 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -40,6 +40,9 @@
 #include "pci.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "migration/blocker.h"
+#include "qemu/option.h"
+#include "qemu/option_int.h"
 
 #define TYPE_VFIO_PCI "vfio-pci"
 #define PCI_VFIO(obj)OBJECT_CHECK(VFIOPCIDevice, obj, TYPE_VFIO_PCI)
@@ -2712,12 +2715,26 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 int i, ret;
 bool is_mdev;
 
+if (!pdev->net_failover_pair_id) {
+error_setg(>migration_blocker,
+"VFIO device doesn't support migration");
+ret = migrate_add_blocker(vdev->migration_blocker, );
+if (err) {
+error_propagate(errp, err);
+goto error;
+}
+} else {
+pdev->qdev.allow_unplug_during_migration = true;
+}
+
 if (!vdev->vbasedev.sysfsdev) {
 if (!(~vdev->host.domain || ~vdev->host.bus ||
   ~vdev->host.slot || ~vdev->host.function)) {
 error_setg(errp, "No provided host device");
 error_append_hint(errp, "Use -device vfio-pci,host=:BB:DD.F "
   "or -device vfio-pci,sysfsdev=PATH_TO_DEVICE\n");
+migrate_del_blocker(vdev->migration_blocker);
+error_free(vdev->migration_blocker);
 return;
 }
 vdev->vbasedev.sysfsdev =
@@ -2729,6 +2746,8 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 if (stat(vdev->vbasedev.sysfsdev, ) < 0) {
 error_setg_errno(errp, errno, "no such host device");
 error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.sysfsdev);
+migrate_del_blocker(vdev->migration_blocker);
+error_free(vdev->migration_blocker);
 return;
 }
 
@@ -3008,6 +3027,8 @@ out_teardown:
 vfio_bars_exit(vdev);
 error:
 error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
+migrate_del_blocker(vdev->migration_blocker);
+error_free(vdev->migration_blocker);
 }
 
 static void vfio_instance_finalize(Object *obj)
@@ -3019,6 +3040,10 @@ static void vfio_instance_finalize(Object *obj)
 vfio_bars_finalize(vdev);
 g_free(vdev->emulated_config_bits);
 g_free(vdev->rom);
+if (vdev->migration_blocker) {
+migrate_del_blocker(vdev->migration_blocker);
+error_free(vdev->migration_blocker);
+}
 /*
  * XXX Leaking igd_opregion is not an oversight, we can't remove the
  * fw_cfg entry therefore leaking this allocation seems like the safest
@@ -3151,11 +3176,6 @@ static Property vfio_pci_dev_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
-static const VMStateDescription vfio_pci_vmstate = {
-.name = "vfio-pci",
-.unmigratable = 1,
-};
-
 static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -3163,7 +3183,6 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, 
void *data)
 
 dc->reset = vfio_pci_reset;
 dc->props = vfio_pci_dev_properties;
-dc->vmsd = _pci_vmstate;
 dc->desc = "VFIO-based PCI device assignment";
 set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 pdc->realize = vfio_realize;
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 834a90d646..b329d50338 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -168,6 +168,7 @@ typedef struct VFIOPCIDevice {
 bool no_vfio_ioeventfd;
 bool enable_ramfb;
 VFIODisplay *dpy;
+Error *migration_blocker;
 } VFIOPCIDevice;
 
 uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);
-- 
2.21.0




[PATCH 04/11] pci: mark device having guest unplug request pending

2019-10-18 Thread Jens Freimann
Set pending_deleted_event in DeviceState for failover
primary devices that were successfully unplugged by the Guest OS.

Signed-off-by: Jens Freimann 
---
 hw/pci/pcie.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 19363ff8ce..08718188bb 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -457,6 +457,7 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, 
void *opaque)
 HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(dev));
 
 if (dev->partially_hotplugged) {
+dev->qdev.pending_deleted_event = false;
 return;
 }
 hotplug_handler_unplug(hotplug_ctrl, DEVICE(dev), _abort);
@@ -476,6 +477,8 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 return;
 }
 
+dev->pending_deleted_event = true;
+
 /* In case user cancel the operation of multi-function hot-add,
  * remove the function that is unexposed to guest individually,
  * without interaction with guest.
-- 
2.21.0




[PATCH 09/11] libqos: tolerate wait-unplug migration state

2019-10-18 Thread Jens Freimann
Signed-off-by: Jens Freimann 
---
 tests/libqos/libqos.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index d71557c5cb..f229eb2cb8 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -125,7 +125,8 @@ void migrate(QOSState *from, QOSState *to, const char *uri)
 break;
 }
 
-if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0)) {
+if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0)
+|| (strcmp(st, "wait-unplug") == 0)) {
 qobject_unref(rsp);
 g_usleep(5000);
 continue;
-- 
2.21.0




[PATCH 06/11] qapi: add failover negotiated event

2019-10-18 Thread Jens Freimann
This event is sent to let libvirt know that VIRTIO_NET_F_STANDBY
feature was not negotiated during virtio feature negotiation. If this
event is received it means any primary devices hotplugged before
this were were never really added to QEMU devices.

Signed-off-by: Jens Freimann 
---
 qapi/net.json | 16 
 1 file changed, 16 insertions(+)

diff --git a/qapi/net.json b/qapi/net.json
index 728990f4fb..8c5f3f1fb2 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -737,3 +737,19 @@
 ##
 { 'command': 'announce-self', 'boxed': true,
   'data' : 'AnnounceParameters'}
+
+##
+# @FAILOVER_NEGOTIATED:
+#
+# Emitted when VIRTIO_NET_F_STANDBY was negotiated during feature negotiation
+#
+# Since: 4.2
+#
+# Example:
+#
+# <- { "event": "FAILOVER_NEGOTIATED",
+#  "data": {} }
+#
+##
+{ 'event': 'FAILOVER_NEGOTIATED',
+  'data': {} }
-- 
2.21.0




[PATCH 08/11] migration: add new migration state wait-unplug

2019-10-18 Thread Jens Freimann
This patch adds a new migration state called wait-unplug.  It is entered
after the SETUP state if failover devices are present. It will transition
into ACTIVE once all devices were succesfully unplugged from the guest.

So if a guest doesn't respond or takes long to honor the unplug request
the user will see the migration state 'wait-unplug'.

In the migration thread we query failover devices if they're are still
pending the guest unplug. When all are unplugged the migration
continues. If one device won't unplug migration will stay in wait_unplug
state.

Signed-off-by: Jens Freimann 
---
 include/migration/vmstate.h |  2 ++
 migration/migration.c   | 21 +
 migration/migration.h   |  3 +++
 migration/savevm.c  | 36 
 migration/savevm.h  |  2 ++
 qapi/migration.json |  5 -
 6 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index b9ee563aa4..ac4f46a67d 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -186,6 +186,8 @@ struct VMStateDescription {
 int (*pre_save)(void *opaque);
 int (*post_save)(void *opaque);
 bool (*needed)(void *opaque);
+bool (*dev_unplug_pending)(void *opaque);
+
 const VMStateField *fields;
 const VMStateDescription **subsections;
 };
diff --git a/migration/migration.c b/migration/migration.c
index 3febd0f8f3..51764f2565 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -52,6 +52,7 @@
 #include "hw/qdev-properties.h"
 #include "monitor/monitor.h"
 #include "net/announce.h"
+#include "qemu/queue.h"
 
 #define MAX_THROTTLE  (32 << 20)  /* Migration transfer speed throttling */
 
@@ -819,6 +820,7 @@ bool migration_is_setup_or_active(int state)
 case MIGRATION_STATUS_SETUP:
 case MIGRATION_STATUS_PRE_SWITCHOVER:
 case MIGRATION_STATUS_DEVICE:
+case MIGRATION_STATUS_WAIT_UNPLUG:
 return true;
 
 default:
@@ -954,6 +956,9 @@ static void fill_source_migration_info(MigrationInfo *info)
 case MIGRATION_STATUS_CANCELLED:
 info->has_status = true;
 break;
+case MIGRATION_STATUS_WAIT_UNPLUG:
+info->has_status = true;
+break;
 }
 info->status = s->state;
 }
@@ -1694,6 +1699,7 @@ bool migration_is_idle(void)
 case MIGRATION_STATUS_COLO:
 case MIGRATION_STATUS_PRE_SWITCHOVER:
 case MIGRATION_STATUS_DEVICE:
+case MIGRATION_STATUS_WAIT_UNPLUG:
 return false;
 case MIGRATION_STATUS__MAX:
 g_assert_not_reached();
@@ -3264,6 +3270,19 @@ static void *migration_thread(void *opaque)
 
 qemu_savevm_state_setup(s->to_dst_file);
 
+if (qemu_savevm_nr_failover_devices()) {
+migrate_set_state(>state, MIGRATION_STATUS_SETUP,
+  MIGRATION_STATUS_WAIT_UNPLUG);
+
+while (s->state == MIGRATION_STATUS_WAIT_UNPLUG &&
+!qemu_savevm_state_guest_unplug_pending()) {
+qemu_sem_timedwait(>wait_unplug_sem, 250);
+}
+
+migrate_set_state(>state, MIGRATION_STATUS_WAIT_UNPLUG,
+MIGRATION_STATUS_ACTIVE);
+}
+
 s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
 migrate_set_state(>state, MIGRATION_STATUS_SETUP,
   MIGRATION_STATUS_ACTIVE);
@@ -3511,6 +3530,7 @@ static void migration_instance_finalize(Object *obj)
 qemu_mutex_destroy(>qemu_file_lock);
 g_free(params->tls_hostname);
 g_free(params->tls_creds);
+qemu_sem_destroy(>wait_unplug_sem);
 qemu_sem_destroy(>rate_limit_sem);
 qemu_sem_destroy(>pause_sem);
 qemu_sem_destroy(>postcopy_pause_sem);
@@ -3556,6 +3576,7 @@ static void migration_instance_init(Object *obj)
 qemu_sem_init(>postcopy_pause_rp_sem, 0);
 qemu_sem_init(>rp_state.rp_sem, 0);
 qemu_sem_init(>rate_limit_sem, 0);
+qemu_sem_init(>wait_unplug_sem, 0);
 qemu_mutex_init(>qemu_file_lock);
 }
 
diff --git a/migration/migration.h b/migration/migration.h
index 4f2fe193dc..79b3dda146 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -206,6 +206,9 @@ struct MigrationState
 /* Flag set once the migration thread called bdrv_inactivate_all */
 bool block_inactive;
 
+/* Migration is waiting for guest to unplug device */
+QemuSemaphore wait_unplug_sem;
+
 /* Migration is paused due to pause-before-switchover */
 QemuSemaphore pause_sem;
 
diff --git a/migration/savevm.c b/migration/savevm.c
index 8d95e261f6..0f18dea49e 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1113,6 +1113,42 @@ void qemu_savevm_state_header(QEMUFile *f)
 }
 }
 
+int qemu_savevm_nr_failover_devices(void)
+{
+SaveStateEntry *se;
+int n = 0;
+
+QTAILQ_FOREACH(se, _state.handlers, entry) {
+if (se->vmsd && se->vmsd->dev_unplug_pending) {
+n++;
+}
+}
+
+return n;
+}
+
+bool 

[PATCH 05/11] qapi: add unplug primary event

2019-10-18 Thread Jens Freimann
This event is emitted when we sent a request to unplug a
failover primary device from the Guest OS and it includes the
device id of the primary device.

Signed-off-by: Jens Freimann 
---
 qapi/migration.json | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/qapi/migration.json b/qapi/migration.json
index 82feb5bd39..52e69e2868 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1448,3 +1448,22 @@
 # Since: 3.0
 ##
 { 'command': 'migrate-pause', 'allow-oob': true }
+
+##
+# @UNPLUG_PRIMARY:
+#
+# Emitted from source side of a migration when migration state is
+# WAIT_UNPLUG. Device was unplugged by guest operating system.
+# Device resources in QEMU are kept on standby to be able to re-plug it in case
+# of migration failure.
+#
+# @device_id: QEMU device id of the unplugged device
+#
+# Since: 4.2
+#
+# Example:
+#   {"event": "UNPLUG_PRIMARY", "data": {"device_id": "hostdev0"} }
+#
+##
+{ 'event': 'UNPLUG_PRIMARY',
+  'data': { 'device_id': 'str' } }
-- 
2.21.0




[PATCH 03/11] pci: mark devices partially unplugged

2019-10-18 Thread Jens Freimann
Only the guest unplug request was triggered. This is needed for
the failover feature. In case of a failed migration we need to
plug the device back to the guest.

Signed-off-by: Jens Freimann 
---
 hw/pci/pcie.c| 3 +++
 include/hw/pci/pci.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index a6beb567bd..19363ff8ce 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -456,6 +456,9 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, 
void *opaque)
 {
 HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(dev));
 
+if (dev->partially_hotplugged) {
+return;
+}
 hotplug_handler_unplug(hotplug_ctrl, DEVICE(dev), _abort);
 object_unparent(OBJECT(dev));
 }
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index def5435685..7b7eac845c 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -265,6 +265,7 @@ typedef struct PCIReqIDCache PCIReqIDCache;
 
 struct PCIDevice {
 DeviceState qdev;
+bool partially_hotplugged;
 
 /* PCI config space */
 uint8_t *config;
-- 
2.21.0




[PATCH v4 0/11] add failover feature for assigned network devices

2019-10-18 Thread Jens Freimann
This is implementing the host side of the net_failover concept
(https://www.kernel.org/doc/html/latest/networking/net_failover.html)

Changes since v3:
* Patch 1,  make return values of qdev_should_hide_device() more clear
* Patch 1,  clarify comment about new should_be_hidden DeviceListener
* Patch 2   new patch, add net_failover_option_id to PCIDevice, only
allow PCIExpress devices for now 
* Patch 8,  only go into wait_unplug state when failover devices are present
* Patch 8,  add new state to migration_is_setup_or_active, tested cancelling
while migration is in this state
* Patch 8,  simplify handling of wait_unplug state, don't cancel migration after
timeout, let upper layer do this, get rid of retry counter 
(dgilbert)
* Patch 11, move net_failover_pair_id to PCIDev, move check for pci class
to PCI code, only allow PCIe devices for now as we only support
hotplugging these devices (aw)
* verified qemu make check tests ran, checked that docker-test-quick@centos7 
runs
  successful, tested migration with/without failover, without vfio-pci 
* this now allows only PCIe devices because that's the only hotplug
  controller that supports the partial unplug as of now. I'll work on 
  making it discoverable for libvirt or on support for the
  other hotplug controllers in a follow-on patch set
 
The general idea is that we have a pair of devices, a vfio-pci and a
virtio-net device. Before migration the vfio device is unplugged and data
flows to the virtio-net device, on the target side another vfio-pci device
is plugged in to take over the data-path. In the guest the net_failover
module will pair net devices with the same MAC address.

* Patch 1 adds the infrastructure to hide the device for the qbus and qdev APIs

* Patch 2 adds checks to PCIDevice for only allowing ethernet devices as
  failover primary and only PCIExpress capable devices

* Patch 3 sets a new flag for PCIDevice 'partially_hotplugged' which we
  use to skip the unrealize code path when doing a unplug of the primary
  device

* Patch 4 sets the pending_deleted_event before triggering the guest
  unplug request

* Patch 5 and 6 add new qmp events, one sends the device id of a device
  that was just requested to be unplugged from the guest and another one
  to let libvirt know if VIRTIO_NET_F_STANDBY was negotiated

* Patch 7 make sure that we can unplug the vfio-device before
  migration starts

* Patch 8 adds a new migration state that is entered while we wait for
  devices to be unplugged by guest OS

* Patch 9 just adds the new migration state to a check in libqos code

* Patch 10 In the second patch the virtio-net uses the API to defer adding the 
vfio
  device until the VIRTIO_NET_F_STANDBY feature is acked. It also
  implements the migration handler to unplug the device from the guest and
  re-plug in case of migration failure

* Patch 11 allows migration for failover vfio-pci devices

Previous discussion:
  RFC v1 https://patchwork.ozlabs.org/cover/989098/
  RFC v2 https://www.mail-archive.com/qemu-devel@nongnu.org/msg606906.html
  v1: https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg03968.html
  v2: https://www.mail-archive.com/qemu-devel@nongnu.org/msg635214.html
  v3: https://patchew.org/QEMU/2019102015.11785-1-jfreim...@redhat.com/

To summarize concerns/feedback from previous discussion:
1.- guest OS can reject or worse _delay_ unplug by any amount of time.
  Migration might get stuck for unpredictable time with unclear reason.
  This approach combines two tricky things, hot/unplug and migration.
  -> We need to let libvirt know what's happening. Add new qmp events
 and a new migration state. When a primary device is (partially)
 unplugged (only from guest) we send a qmp event with the device id. When
 it is unplugged from the guest the DEVICE_DELETED event is sent.
 Migration will enter the wait-unplug state while waiting for the guest
 os to unplug all primary devices and then move on with migration.
2. PCI devices are a precious ressource. The primary device should never
  be added to QEMU if it won't be used by guest instead of hiding it in
  QEMU.
  -> We only hotplug the device when the standby feature bit was
 negotiated. We save the device cmdline options until we need it for
 qdev_device_add()
 Hiding a device can be a useful concept to model. For example a
 pci device in a powered-off slot could be marked as hidden until the slot 
is
 powered on (mst).
3. Management layer software should handle this. Open Stack already has
  components/code to handle unplug/replug VFIO devices and metadata to
  provide to the guest for detecting which devices should be paired.
  -> An approach that includes all software from firmware to
 higher-level management software wasn't tried in the last years. This is
 an attempt to keep it simple and contained in QEMU as much as possible.
 One of the problems that stopped 

[PATCH 01/11] qdev/qbus: add hidden device support

2019-10-18 Thread Jens Freimann
This adds support for hiding a device to the qbus and qdev APIs.  The
first user of this will be the virtio-net failover feature but the API
introduced with this patch could be used to implement other features as
well, for example hiding pci devices when a pci bus is powered off.

qdev_device_add() is modified to check for a net_failover_pair_id
argument in the option string. A DeviceListener callback
should_be_hidden() is added. It can be used by a standby device to
inform qdev that this device should not be added now. The standby device
handler can store the device options to plug the device in at a later
point in time.

One reason for hiding the device is that we don't want to expose both
devices to the guest kernel until the respective virtio feature bit
VIRTIO_NET_F_STANDBY was negotiated and we know that the devices will be
handled correctly by the guest.

More information on the kernel feature this is using:
 https://www.kernel.org/doc/html/latest/networking/net_failover.html

An example where the primary device is a vfio-pci device and the standby
device is a virtio-net device:

A device is hidden when it has an "net_failover_pair_id" option, e.g.

 -device virtio-net-pci,...,failover=on,...
 -device vfio-pci,...,net_failover_pair_id=net1,...

Signed-off-by: Jens Freimann 
---
 hw/core/qdev.c | 23 +++
 include/hw/qdev-core.h |  8 
 qdev-monitor.c | 36 +---
 vl.c   |  6 --
 4 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index cbad6c1d55..89c134ec53 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -212,6 +212,29 @@ void device_listener_unregister(DeviceListener *listener)
 QTAILQ_REMOVE(_listeners, listener, link);
 }
 
+bool qdev_should_hide_device(QemuOpts *opts)
+{
+int rc;
+DeviceListener *listener;
+
+QTAILQ_FOREACH(listener, _listeners, link) {
+   if (listener->should_be_hidden) {
+/* should_be_hidden_will return
+ *  1 if device matches opts and it should be hidden
+ *  0 if device matches opts and should not be hidden
+ *  -1 if device doesn't match ops
+ */
+rc = listener->should_be_hidden(listener, opts);
+}
+
+if (rc > 0) {
+break;
+}
+}
+
+return rc > 0;
+}
+
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
  int required_for_version)
 {
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index aa123f88cb..28f594a47d 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -154,6 +154,12 @@ struct DeviceState {
 struct DeviceListener {
 void (*realize)(DeviceListener *listener, DeviceState *dev);
 void (*unrealize)(DeviceListener *listener, DeviceState *dev);
+/*
+ * This callback is called upon init of the DeviceState and allows to
+ * inform qdev that a device should be hidden, depending on the device
+ * opts, for example, to hide a standby device.
+ */
+int (*should_be_hidden)(DeviceListener *listener, QemuOpts *device_opts);
 QTAILQ_ENTRY(DeviceListener) link;
 };
 
@@ -451,4 +457,6 @@ static inline bool qbus_is_hotpluggable(BusState *bus)
 void device_listener_register(DeviceListener *listener);
 void device_listener_unregister(DeviceListener *listener);
 
+bool qdev_should_hide_device(QemuOpts *opts);
+
 #endif
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 148df9cacf..508d85df87 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -32,9 +32,11 @@
 #include "qemu/help_option.h"
 #include "qemu/option.h"
 #include "qemu/qemu-print.h"
+#include "qemu/option_int.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "migration/misc.h"
+#include "migration/migration.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
@@ -562,14 +564,40 @@ void qdev_set_id(DeviceState *dev, const char *id)
 }
 }
 
+static int is_failover_device(void *opaque, const char *name, const char 
*value,
+Error **errp)
+{
+if (strcmp(name, "net_failover_pair_id") == 0) {
+QemuOpts *opts = (QemuOpts *)opaque;
+
+if (qdev_should_hide_device(opts)) {
+return 1;
+}
+}
+
+return 0;
+}
+
+static bool should_hide_device(QemuOpts *opts)
+{
+if (qemu_opt_foreach(opts, is_failover_device, opts, NULL) == 0) {
+return false;
+}
+return true;
+}
+
 DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
 {
 DeviceClass *dc;
 const char *driver, *path;
-DeviceState *dev;
+DeviceState *dev = NULL;
 BusState *bus = NULL;
 Error *err = NULL;
 
+if (opts && should_hide_device(opts)) {
+return NULL;
+}
+
 driver = qemu_opt_get(opts, "driver");
 if (!driver) {
 error_setg(errp, QERR_MISSING_PARAMETER, "driver");
@@ -648,8 +676,10 @@ DeviceState 

[PATCH 02/11] pci: add option for net failover

2019-10-18 Thread Jens Freimann
This patch adds a net_failover_pair_id property to PCIDev which is
used to link the primary device in a failover pair (the PCI dev) to
a standby (a virtio-net-pci) device.

It only supports ethernet devices. Also currently it only supports
PCIe devices. QEMU will exit with an error message otherwise.

Signed-off-by: Jens Freimann 
---
 hw/pci/pci.c | 17 +
 include/hw/pci/pci.h |  3 +++
 2 files changed, 20 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index aa05c2b9b2..fa9b5219f8 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -75,6 +75,8 @@ static Property pci_props[] = {
 QEMU_PCIE_LNKSTA_DLLLA_BITNR, true),
 DEFINE_PROP_BIT("x-pcie-extcap-init", PCIDevice, cap_present,
 QEMU_PCIE_EXTCAP_INIT_BITNR, true),
+DEFINE_PROP_STRING("net_failover_pair_id", PCIDevice,
+net_failover_pair_id),
 DEFINE_PROP_END_OF_LIST()
 };
 
@@ -2077,6 +2079,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error 
**errp)
 ObjectClass *klass = OBJECT_CLASS(pc);
 Error *local_err = NULL;
 bool is_default_rom;
+uint16_t class_id;
 
 /* initialize cap_present for pci_is_express() and pci_config_size(),
  * Note that hybrid PCIs are not set automatically and need to manage
@@ -2101,6 +2104,20 @@ static void pci_qdev_realize(DeviceState *qdev, Error 
**errp)
 }
 }
 
+if (pci_dev->net_failover_pair_id) {
+if (!pci_is_express(pci_dev)) {
+error_setg(errp, "failover device is not a PCIExpress device");
+error_propagate(errp, local_err);
+return;
+}
+class_id = pci_get_word(pci_dev->config + PCI_CLASS_DEVICE);
+if (class_id != PCI_CLASS_NETWORK_ETHERNET) {
+error_setg(errp, "failover device is not an Ethernet device");
+error_propagate(errp, local_err);
+return;
+}
+}
+
 /* rom loading */
 is_default_rom = false;
 if (pci_dev->romfile == NULL && pc->romfile != NULL) {
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index f3f0ffd5fb..def5435685 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -352,6 +352,9 @@ struct PCIDevice {
 MSIVectorUseNotifier msix_vector_use_notifier;
 MSIVectorReleaseNotifier msix_vector_release_notifier;
 MSIVectorPollNotifier msix_vector_poll_notifier;
+
+/* ID of standby device in net_failover pair */
+char *net_failover_pair_id;
 };
 
 void pci_register_bar(PCIDevice *pci_dev, int region_num,
-- 
2.21.0




Re: [PATCH] target/riscv: PMP violation due to wrong size parameter

2019-10-18 Thread Dayeol Lee
I'll move the entire check into pmp_hart_has_privs as it makes more sense.

Thanks!

On Fri, Oct 18, 2019, 3:01 PM Palmer Dabbelt  wrote:

> On Tue, 15 Oct 2019 10:04:32 PDT (-0700), day...@berkeley.edu wrote:
> > Hi,
> >
> > Could this patch go through?
> > If not please let me know so that I can fix.
> > Thank you!
>
> Sorry, I dropped this one.  It's in the patch queue now.  We should also
> check
> for size==0 in pmp_hart_has_privs(), as that won't work.  LMK if you want
> to
> send a patch for that.
>
> >
> > Dayeol
> >
> >
> > On Sat, Oct 12, 2019, 11:30 AM Dayeol Lee  wrote:
> >
> >> No it doesn't mean that.
> >> But the following code will make the size TARGET_PAGE_SIZE - (page
> offset)
> >> if the address is not aligned.
> >>
> >> pmp_size = -(address | TARGET_PAGE_MASK)
> >>
> >>
> >> On Fri, Oct 11, 2019, 7:37 PM Jonathan Behrens 
> wrote:
> >>
> >>> How do you know that the access won't straddle a page boundary? Is
> there
> >>> a guarantee somewhere that size=0 means that the access is naturally
> >>> aligned?
> >>>
> >>> Jonathan
> >>>
> >>>
> >>> On Fri, Oct 11, 2019 at 7:14 PM Dayeol Lee 
> wrote:
> >>>
>  riscv_cpu_tlb_fill() uses the `size` parameter to check PMP violation
>  using pmp_hart_has_privs().
>  However, if the size is unknown (=0), the ending address will be
>  `addr - 1` as it is `addr + size - 1` in `pmp_hart_has_privs()`.
>  This always causes a false PMP violation on the starting address of
> the
>  range, as `addr - 1` is not in the range.
> 
>  In order to fix, we just assume that all bytes from addr to the end of
>  the page will be accessed if the size is unknown.
> 
>  Signed-off-by: Dayeol Lee 
>  Reviewed-by: Richard Henderson 
>  ---
>   target/riscv/cpu_helper.c | 13 -
>   1 file changed, 12 insertions(+), 1 deletion(-)
> 
>  diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
>  index e32b6126af..7d9a22b601 100644
>  --- a/target/riscv/cpu_helper.c
>  +++ b/target/riscv/cpu_helper.c
>  @@ -441,6 +441,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address,
>  int size,
>   CPURISCVState *env = >env;
>   hwaddr pa = 0;
>   int prot;
>  +int pmp_size = 0;
>   bool pmp_violation = false;
>   int ret = TRANSLATE_FAIL;
>   int mode = mmu_idx;
>  @@ -460,9 +461,19 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
>  address, int size,
> "%s address=%" VADDR_PRIx " ret %d physical "
>  TARGET_FMT_plx
> " prot %d\n", __func__, address, ret, pa, prot);
> 
>  +/*
>  + * if size is unknown (0), assume that all bytes
>  + * from addr to the end of the page will be accessed.
>  + */
>  +if (size == 0) {
>  +pmp_size = -(address | TARGET_PAGE_MASK);
>  +} else {
>  +pmp_size = size;
>  +}
>  +
>   if (riscv_feature(env, RISCV_FEATURE_PMP) &&
>   (ret == TRANSLATE_SUCCESS) &&
>  -!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
>  +!pmp_hart_has_privs(env, pa, pmp_size, 1 << access_type,
> mode))
>  {
>   ret = TRANSLATE_PMP_FAIL;
>   }
>   if (ret == TRANSLATE_PMP_FAIL) {
>  --
>  2.20.1
> 
> 
> 
>


Re: [PATCH v1 5/6] s390x/tcg: Fix VECTOR SUBTRACT WITH BORROW INDICATION

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> Testing this, there seems to be something messed up. We are dealing with
> unsigned numbers. "Each operand is treated as an unsigned binary integer."
> Let's just implement as written in the PoP:
> 
> "A subtraction is performed by adding the contents of
>  the second operand with the bitwise complement of
>  the third operand along with a borrow indication from
>  the rightmost bit position of the fourth operand and
>  the result is placed in the first operand."
> 
> Fixes: 48390a7c2716 ("s390x/tcg: Implement VECTOR SUBTRACT WITH BORROW 
> INDICATION")
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/translate_vx.inc.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson 


r~




Re: [PATCH v5 2/3] tests/vm: Let subclasses disable IPv6

2019-10-18 Thread Philippe Mathieu-Daudé

On 10/18/19 8:17 PM, Eduardo Habkost wrote:

The mechanism will be used to work around issues related to IPv6
on the netbsd image builder.

Signed-off-by: Eduardo Habkost 
---
  tests/vm/basevm.py | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index b5d1479bee..2929de23aa 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -57,6 +57,8 @@ class BaseVM(object):
  arch = "#arch"
  # command to halt the guest, can be overridden by subclasses
  poweroff = "poweroff"
+# enable IPv6 networking
+ipv6 = True
  def __init__(self, debug=False, vcpus=None):
  self._guest = None
  self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
@@ -81,7 +83,8 @@ class BaseVM(object):
  self._args = [ \
  "-nodefaults", "-m", "4G",
  "-cpu", "max",
-"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22",
+"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22" +
+   (",ipv6=no" if not self.ipv6 else ""),
  "-device", "virtio-net-pci,netdev=vnet",
  "-vnc", "127.0.0.1:0,to=20"]
  if vcpus and vcpus > 1:



Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v1 3/6] s390x/tcg: Fix VECTOR SHIFT RIGHT ARITHMETIC BY BYTE

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> We forgot to propagate the highest bit accross the high doubleword in
> two cases (shift >=64).
> 
> Fixes: 5f724887e3dd ("s390x/tcg: Implement VECTOR SHIFT RIGHT ARITHMETIC")
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/vec_int_helper.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson 


r~




Re: [PATCH v1 2/6] s390x/tcg: Fix VECTOR MULTIPLY AND ADD *

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> We missed that we always read a "double-wide even-odd element
> pair of the fourth operand". Fix it in all four variants.
> 
> Fixes: 1b430aec4157 ("s390x/tcg: Implement VECTOR MULTIPLY AND ADD *")
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/vec_int_helper.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson 


r~




Re: [PATCH v1 1/6] s390x/tcg: Fix VECTOR MULTIPLY LOGICAL ODD

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> We have to read from odd offsets.
> 
> Fixes: 2bf3ee38f1f8 ("s390x/tcg: Implement VECTOR MULTIPLY *")
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/vec_int_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH] target/riscv: PMP violation due to wrong size parameter

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 10:04:32 PDT (-0700), day...@berkeley.edu wrote:

Hi,

Could this patch go through?
If not please let me know so that I can fix.
Thank you!


Sorry, I dropped this one.  It's in the patch queue now.  We should also check 
for size==0 in pmp_hart_has_privs(), as that won't work.  LMK if you want to 
send a patch for that.




Dayeol


On Sat, Oct 12, 2019, 11:30 AM Dayeol Lee  wrote:


No it doesn't mean that.
But the following code will make the size TARGET_PAGE_SIZE - (page offset)
if the address is not aligned.

pmp_size = -(address | TARGET_PAGE_MASK)


On Fri, Oct 11, 2019, 7:37 PM Jonathan Behrens  wrote:


How do you know that the access won't straddle a page boundary? Is there
a guarantee somewhere that size=0 means that the access is naturally
aligned?

Jonathan


On Fri, Oct 11, 2019 at 7:14 PM Dayeol Lee  wrote:


riscv_cpu_tlb_fill() uses the `size` parameter to check PMP violation
using pmp_hart_has_privs().
However, if the size is unknown (=0), the ending address will be
`addr - 1` as it is `addr + size - 1` in `pmp_hart_has_privs()`.
This always causes a false PMP violation on the starting address of the
range, as `addr - 1` is not in the range.

In order to fix, we just assume that all bytes from addr to the end of
the page will be accessed if the size is unknown.

Signed-off-by: Dayeol Lee 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu_helper.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e32b6126af..7d9a22b601 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -441,6 +441,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address,
int size,
 CPURISCVState *env = >env;
 hwaddr pa = 0;
 int prot;
+int pmp_size = 0;
 bool pmp_violation = false;
 int ret = TRANSLATE_FAIL;
 int mode = mmu_idx;
@@ -460,9 +461,19 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
address, int size,
   "%s address=%" VADDR_PRIx " ret %d physical "
TARGET_FMT_plx
   " prot %d\n", __func__, address, ret, pa, prot);

+/*
+ * if size is unknown (0), assume that all bytes
+ * from addr to the end of the page will be accessed.
+ */
+if (size == 0) {
+pmp_size = -(address | TARGET_PAGE_MASK);
+} else {
+pmp_size = size;
+}
+
 if (riscv_feature(env, RISCV_FEATURE_PMP) &&
 (ret == TRANSLATE_SUCCESS) &&
-!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
+!pmp_hart_has_privs(env, pa, pmp_size, 1 << access_type, mode))
{
 ret = TRANSLATE_PMP_FAIL;
 }
 if (ret == TRANSLATE_PMP_FAIL) {
--
2.20.1







Re: [PATCH v1 6/6] s390x/tcg: Fix VECTOR SUBTRACT WITH BORROW COMPUTE BORROW INDICATION

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> +/* Isolate the carry to the next doubleword */
>  tcg_gen_andi_i64(dl, th, 1);

You can remove this now, since the only possible results are 0/1; it was only
our subtract implementation that produced -1/0.


r~



Re: [PATCH v1 4/6] s390x/tcg: Fix VECTOR SUBTRACT COMPUTE BORROW INDICATION

2019-10-18 Thread Richard Henderson
On 10/18/19 11:18 AM, David Hildenbrand wrote:
> On 18.10.19 19:41, David Hildenbrand wrote:
>> On 18.10.19 18:10, David Hildenbrand wrote:
>>> Looks like my idea of what a "borrow" is was wrong. We are dealing with
>>> unsigned numbers. A subtraction is simply an addition with the bitwise
>>> complement. If we get a carry during the addition, that's the borrow.
>>> "The operands are treated as unsigned binary integers."
>>>
>>> This is nice, as we can reuse the VECTOR ADD COMPUTE CARRY functions
>>> and avoid helpers, all we have to do is compute the bitwise complement.
>>>
>>> Fixes: 1ee2d7ba72f6 ("s390x/tcg: Implement VECTOR SUBTRACT COMPUTE BORROW
>>> INDICATION")
>>> Signed-off-by: David Hildenbrand 
>>> ---
>>>    target/s390x/helper.h   |  2 --
>>>    target/s390x/translate_vx.inc.c | 45 -
>>>    target/s390x/vec_int_helper.c   | 16 
>>>    3 files changed, 33 insertions(+), 30 deletions(-)
>>>
>>> diff --git a/target/s390x/helper.h b/target/s390x/helper.h
>>> index 56e8149866..ca1e08100a 100644
>>> --- a/target/s390x/helper.h
>>> +++ b/target/s390x/helper.h
>>> @@ -207,8 +207,6 @@ DEF_HELPER_FLAGS_4(gvec_verim16, TCG_CALL_NO_RWG, void,
>>> ptr, cptr, cptr, i32)
>>>    DEF_HELPER_FLAGS_4(gvec_vsl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
>>>    DEF_HELPER_FLAGS_4(gvec_vsra, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
>>>    DEF_HELPER_FLAGS_4(gvec_vsrl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
>>> -DEF_HELPER_FLAGS_4(gvec_vscbi8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, 
>>> i32)
>>> -DEF_HELPER_FLAGS_4(gvec_vscbi16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, 
>>> i32)
>>>    DEF_HELPER_4(gvec_vtm, void, ptr, cptr, env, i32)
>>>       /* === Vector String Instructions === */
>>> diff --git a/target/s390x/translate_vx.inc.c 
>>> b/target/s390x/translate_vx.inc.c
>>> index 5ce7bfb0af..40bcc1604e 100644
>>> --- a/target/s390x/translate_vx.inc.c
>>> +++ b/target/s390x/translate_vx.inc.c
>>> @@ -2130,14 +2130,40 @@ static DisasJumpType op_vs(DisasContext *s, DisasOps
>>> *o)
>>>    return DISAS_NEXT;
>>>    }
>>>    +static void gen_scbi8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
>>> +{
>>> +    TCGv_i64 t = tcg_temp_new_i64();
>>> +
>>> +    tcg_gen_not_i64(t, b);
>>> +    gen_acc(d, a, t, ES_8);
>>> +    tcg_temp_free_i64(t);
>>> +}
>>
>> BTW, I would have thought that we need the 2nd complement in all these
>> cases. However, the description of the other functions confused me
>> (VECTOR SUBTRACT WITH BORROW INDICATION) - add bitwise complement and
>> add the borrow.
>>
>> This passes my test cases (that are verified against real HW), but I am
>> not sure if I check all the corner cases.
>>
>> @Richard, do you have any idea how to do it the right way for this
>> instruction?
>>
> 
> My impression was right. A simple "0-0" test makes this visible. The other two
> fixes seem to be correct, though.

Your description seems to indicate that you want carry output, which is
!borrow.  ARM represents things this way, but I didn't recall it for S390.

If you want to implement sub r,x,y with add r,x,~y, you also have to add one --
often times with the carry-in.  But since we don't have a carry-in here, I
wonder if it isn't easier to invert your result:

 tcg_gen_sub2_i64(tl, th, al, zero, bl, zero);
 tcg_gen_andi_i64(th, th, 1);
 tcg_gen_sub2_i64(tl, th, ah, zero, th, zero);
 tcg_gen_sub2_i64(tl, th, tl, th, bh, zero);
-tcg_gen_andi_i64(dl, th, 1);
+/* "invert" the result: -1 -> 0; 0 -> 1 */
+tcg_gen_addi_i64(dl, th, 1);


r~



Re: [PATCH] Fix unsigned integer underflow in fd-trans.c

2019-10-18 Thread Laurent Vivier
Le 18/10/2019 à 20:27, Shu-Chun Weng a écrit :
> (Re-sending to the list because I forgot to turn off HTML before and
> it was bounced.)
> 
> That does prevent the integer underflow, but it also changes the
> behavior and I don't think the new behavior is desirable.
> 
> If the extra payload has a smaller alignment than the header, it makes
> sense for the user program to generate a nlmsg_len that is not a
> multiple of the alignment. When it's the last entry, the new condition
> will it because NLMSG_ALIGN pushes the aligned length over `len`, yet
> the single entry processing function won't actually read beyond the
> buffer as long as it's bounded by nlmsg_len.

Yes, you're right.

So I think your patch is correct.

Reviewed-by: Laurent Vivier 

Thanks,
Laurent




Re: [PATCH v3 2/2] riscv: virt: Use Goldfish RTC device

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 01:35:42 PDT (-0700), Anup Patel wrote:

We extend QEMU RISC-V virt machine by adding Goldfish RTC device
to it. This will allow Guest Linux to sync it's local date/time
with Host date/time via RTC device.

Signed-off-by: Anup Patel 
---
 hw/riscv/Kconfig|  1 +
 hw/riscv/virt.c | 15 +++
 include/hw/riscv/virt.h |  2 ++
 3 files changed, 18 insertions(+)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index fb19b2df3a..b33753c780 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -34,6 +34,7 @@ config RISCV_VIRT
 select PCI
 select HART
 select SERIAL
+select GOLDFISH_RTC
 select VIRTIO_MMIO
 select PCI_EXPRESS_GENERIC_BRIDGE
 select SIFIVE
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index d36f5625ec..95c42ab993 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -57,6 +57,7 @@ static const struct MemmapEntry {
 [VIRT_DEBUG] =   {0x0, 0x100 },
 [VIRT_MROM] ={ 0x1000,   0x11000 },
 [VIRT_TEST] ={   0x10,0x1000 },
+[VIRT_RTC] = {   0x101000,0x1000 },
 [VIRT_CLINT] =   {  0x200,   0x1 },
 [VIRT_PLIC] ={  0xc00, 0x400 },
 [VIRT_UART0] =   { 0x1000, 0x100 },
@@ -310,6 +311,17 @@ static void create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", UART0_IRQ);
 
+nodename = g_strdup_printf("/rtc@%lx",

+(long)memmap[VIRT_RTC].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"google,goldfish-rtc");
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[VIRT_RTC].base,
+0x0, memmap[VIRT_RTC].size);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", RTC_IRQ);
+
 qemu_fdt_add_subnode(fdt, "/chosen");
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
 if (cmdline) {
@@ -496,6 +508,9 @@ static void riscv_virt_board_init(MachineState *machine)
 0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
 serial_hd(0), DEVICE_LITTLE_ENDIAN);
 
+sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,

+qdev_get_gpio_in(DEVICE(s->plic), RTC_IRQ));
+
 g_free(plic_hart_config);
 }
 
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h

index 6e5fbe5d3b..e6423258d3 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -37,6 +37,7 @@ enum {
 VIRT_DEBUG,
 VIRT_MROM,
 VIRT_TEST,
+VIRT_RTC,
 VIRT_CLINT,
 VIRT_PLIC,
 VIRT_UART0,
@@ -49,6 +50,7 @@ enum {
 
 enum {

 UART0_IRQ = 10,
+RTC_IRQ = 11,
 VIRTIO_IRQ = 1, /* 1 to 8 */
 VIRTIO_COUNT = 8,
 PCIE_IRQ = 0x20, /* 32 to 35 */


This is a wacky enum, but it's already there.  I'm going to assume this patch 
will get merged and then fix it later.



--
2.17.1


Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 

I think it's easier to just keep this with the goldfish implementation.  I'm 
assuming that will go in through a different tree, as per my comments on that 
patch.




Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 01:35:31 PDT (-0700), Anup Patel wrote:

This patch adds model for Google Goldfish virtual platform RTC device.

We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
for providing real date-time to Guest Linux. The corresponding Linux
driver for Goldfish RTC device is already available in upstream Linux.

For now, VM migration support is available but untested for Goldfish RTC
device. It will be hardened in-future when we implement VM migration for
KVM RISC-V.

Signed-off-by: Anup Patel 
---
 hw/rtc/Kconfig  |   3 +
 hw/rtc/Makefile.objs|   1 +
 hw/rtc/goldfish_rtc.c   | 278 
 include/hw/timer/goldfish_rtc.h |  46 ++
 4 files changed, 328 insertions(+)
 create mode 100644 hw/rtc/goldfish_rtc.c
 create mode 100644 include/hw/timer/goldfish_rtc.h


I'd be happy to take a look at this, but I don't have a hw/rtc directory in my 
QEMU.  IIRC there was a refactoring going on here, is there a tree this is 
based on?



diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
index 45daa8d655..bafe6ac2c9 100644
--- a/hw/rtc/Kconfig
+++ b/hw/rtc/Kconfig
@@ -21,3 +21,6 @@ config MC146818RTC
 
 config SUN4V_RTC

 bool
+
+config GOLDFISH_RTC
+bool
diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
index 8dc9fcd3a9..aa208d0d10 100644
--- a/hw/rtc/Makefile.objs
+++ b/hw/rtc/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
+common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
new file mode 100644
index 00..223616ed75
--- /dev/null
+++ b/hw/rtc/goldfish_rtc.c
@@ -0,0 +1,278 @@
+/*
+ * Goldfish virtual platform RTC
+ *
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ *
+ * For more details on Google Goldfish virtual platform refer:
+ * 
https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/timer/goldfish_rtc.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+
+#define RTC_TIME_LOW0x00
+#define RTC_TIME_HIGH   0x04
+#define RTC_ALARM_LOW   0x08
+#define RTC_ALARM_HIGH  0x0c
+#define RTC_IRQ_ENABLED 0x10
+#define RTC_CLEAR_ALARM 0x14
+#define RTC_ALARM_STATUS0x18
+#define RTC_CLEAR_INTERRUPT 0x1c
+
+static void goldfish_rtc_update(GoldfishRTCState *s)
+{
+qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
+}
+
+static void goldfish_rtc_interrupt(void *opaque)
+{
+GoldfishRTCState *s = (GoldfishRTCState *)opaque;
+
+s->alarm_running = 0;
+s->irq_pending = 1;
+goldfish_rtc_update(s);
+}
+
+static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s)
+{
+return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
+}
+
+static void goldfish_rtc_clear_alarm(GoldfishRTCState *s)
+{
+timer_del(s->timer);
+s->alarm_running = 0;
+}
+
+static void goldfish_rtc_set_alarm(GoldfishRTCState *s)
+{
+uint64_t ticks = goldfish_rtc_get_count(s);
+uint64_t event = s->alarm_next;
+
+if (event <= ticks) {
+goldfish_rtc_clear_alarm(s);
+goldfish_rtc_interrupt(s);
+} else {
+int64_t now = qemu_clock_get_ns(rtc_clock);
+timer_mod(s->timer, now + (event - ticks));
+s->alarm_running = 1;
+}
+}
+
+static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
+  unsigned size)
+{
+GoldfishRTCState *s = (GoldfishRTCState *)opaque;
+uint64_t r;
+
+switch (offset) {
+case RTC_TIME_LOW:
+r = goldfish_rtc_get_count(s) & 0x;
+break;
+case RTC_TIME_HIGH:
+r = goldfish_rtc_get_count(s) >> 32;
+break;
+case RTC_ALARM_LOW:
+r = s->alarm_next & 0x;
+break;
+case RTC_ALARM_HIGH:
+r = s->alarm_next >> 32;
+break;
+case RTC_IRQ_ENABLED:
+r = s->irq_enabled;
+break;
+case 

Re: [PATCH v6 1/4] block/replication.c: Ignore requests after failover

2019-10-18 Thread Lukas Straub
On Sat, 5 Oct 2019 15:05:23 +0200
Lukas Straub  wrote:

> After failover the Secondary side of replication shouldn't change state, 
> because
> it now functions as our primary disk.
>
> In replication_start, replication_do_checkpoint, replication_stop, ignore
> the request if current state is BLOCK_REPLICATION_DONE (sucessful failover) or
> BLOCK_REPLICATION_FAILOVER (failover in progres i.e. currently merging active
> and hidden images into the base image).
>
> Signed-off-by: Lukas Straub 
> Reviewed-by: Zhang Chen 
> ---
>  block/replication.c | 38 +++---
>  1 file changed, 35 insertions(+), 3 deletions(-)
>
> diff --git a/block/replication.c b/block/replication.c
> index 3d4dedddfc..97cc65c0cf 100644
> --- a/block/replication.c
> +++ b/block/replication.c
> @@ -454,6 +454,17 @@ static void replication_start(ReplicationState *rs, 
> ReplicationMode mode,
>  aio_context_acquire(aio_context);
>  s = bs->opaque;
>
> +if (s->stage == BLOCK_REPLICATION_DONE ||
> +s->stage == BLOCK_REPLICATION_FAILOVER) {
> +/*
> + * This case happens when a secondary is promoted to primary.
> + * Ignore the request because the secondary side of replication
> + * doesn't have to do anything anymore.
> + */
> +aio_context_release(aio_context);
> +return;
> +}
> +
>  if (s->stage != BLOCK_REPLICATION_NONE) {
>  error_setg(errp, "Block replication is running or done");
>  aio_context_release(aio_context);
> @@ -529,8 +540,7 @@ static void replication_start(ReplicationState *rs, 
> ReplicationMode mode,
> "Block device is in use by internal backup job");
>
>  top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL);
> -if (!top_bs || !bdrv_is_root_node(top_bs) ||
> -!check_top_bs(top_bs, bs)) {
> +if (!top_bs || !check_top_bs(top_bs, bs)) {
>  error_setg(errp, "No top_bs or it is invalid");
>  reopen_backing_file(bs, false, NULL);
>  aio_context_release(aio_context);
> @@ -577,6 +587,17 @@ static void replication_do_checkpoint(ReplicationState 
> *rs, Error **errp)
>  aio_context_acquire(aio_context);
>  s = bs->opaque;
>
> +if (s->stage == BLOCK_REPLICATION_DONE ||
> +s->stage == BLOCK_REPLICATION_FAILOVER) {
> +/*
> + * This case happens when a secondary was promoted to primary.
> + * Ignore the request because the secondary side of replication
> + * doesn't have to do anything anymore.
> + */
> +aio_context_release(aio_context);
> +return;
> +}
> +
>  if (s->mode == REPLICATION_MODE_SECONDARY) {
>  secondary_do_checkpoint(s, errp);
>  }
> @@ -593,7 +614,7 @@ static void replication_get_error(ReplicationState *rs, 
> Error **errp)
>  aio_context_acquire(aio_context);
>  s = bs->opaque;
>
> -if (s->stage != BLOCK_REPLICATION_RUNNING) {
> +if (s->stage == BLOCK_REPLICATION_NONE) {
>  error_setg(errp, "Block replication is not running");
>  aio_context_release(aio_context);
>  return;
> @@ -635,6 +656,17 @@ static void replication_stop(ReplicationState *rs, bool 
> failover, Error **errp)
>  aio_context_acquire(aio_context);
>  s = bs->opaque;
>
> +if (s->stage == BLOCK_REPLICATION_DONE ||
> +s->stage == BLOCK_REPLICATION_FAILOVER) {
> +/*
> + * This case happens when a secondary was promoted to primary.
> + * Ignore the request because the secondary side of replication
> + * doesn't have to do anything anymore.
> + */
> +aio_context_release(aio_context);
> +return;
> +}
> +
>  if (s->stage != BLOCK_REPLICATION_RUNNING) {
>  error_setg(errp, "Block replication is not running");
>  aio_context_release(aio_context);

Hello Everyone,
Could the block people have a look at this patch?

Regards,
Lukas Straub



Re: [PATCH v4 0/3] target/riscv: Expose "priv" register for GDB

2019-10-18 Thread Palmer Dabbelt

On Mon, 14 Oct 2019 08:45:26 PDT (-0700), jonat...@fintelia.io wrote:


This series adds a new "priv" virtual register that reports the current
privilege mode. This is helpful for debugging purposes because that information
is not actually available in any of the real CSRs.

The third patch in this series makes the priv virtual register writitable. I'm
not entirely sure this is a good idea, so I split it out into its own patch. In
particular, this change will conflict with the hypervisor extension work which
assumes that the privilege mode does not change in unexpected cases.

As pointed out in a previous version of this series, GDB actually contains some
support already for the accessing the privilege mode via a virtual "priv"
register, including to convert the values into human readable forms:

(gdb) info reg priv
priv   0x3  prv:3 [Machine]

Changlog V4:
- Fix typo in filename

Changlog V3:
- Break patch into series
- Make priv a virtual register

Changelog V2:
- Use PRV_H and PRV_S instead of integer literals

Jonathan Behrens (3)
  target/riscv: Tell gdbstub the correct number of CSRs
  target/riscv: Expose priv register for GDB for reads
  target/riscv: Make the priv register writable by GDB

 configure   |  4 ++--
 gdb-xml/riscv-32bit-virtual.xml | 11 +++
 gdb-xml/riscv-64bit-virtual.xml | 11 +++
 target/riscv/gdbstub.c  | 36 ++--
 4 files changed, 58 insertions(+), 4 deletions(-)


Thanks.  I've taken these into my patch queue, which I hope to submit soon!



Re: [PATCH v5 31/55] target/riscv: fetch code with translator_ld

2019-10-18 Thread Palmer Dabbelt

On Mon, 14 Oct 2019 10:59:07 PDT (-0700), alistai...@gmail.com wrote:

On Mon, Oct 14, 2019 at 4:20 AM Alex Bennée  wrote:


From: "Emilio G. Cota" 

Signed-off-by: Emilio G. Cota 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 


Reviewed-by: Alistair Francis 


and

Acked-by: Palmer Dabbelt 

as I'm assuming this will go in with the rest of the patch set.



Alistair


---
 target/riscv/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index adeddb85f6..b26533d4fd 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -779,7 +779,7 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 CPURISCVState *env = cpu->env_ptr;

-ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+ctx->opcode = translator_ldl(env, ctx->base.pc_next);
 decode_opc(ctx);
 ctx->base.pc_next = ctx->pc_succ_insn;

--
2.20.1






Re: [PATCH] Fix unsigned integer underflow in fd-trans.c

2019-10-18 Thread Shu-Chun Weng
(Re-sending to the list because I forgot to turn off HTML before and
it was bounced.)

That does prevent the integer underflow, but it also changes the
behavior and I don't think the new behavior is desirable.

If the extra payload has a smaller alignment than the header, it makes
sense for the user program to generate a nlmsg_len that is not a
multiple of the alignment. When it's the last entry, the new condition
will it because NLMSG_ALIGN pushes the aligned length over `len`, yet
the single entry processing function won't actually read beyond the
buffer as long as it's bounded by nlmsg_len.

Shu-Chun


On Fri, Oct 18, 2019 at 12:26 AM Laurent Vivier  wrote:
>
> Le 18/10/2019 à 02:19, Shu-Chun Weng a écrit :
> > In any of these `*_for_each_*` functions, the last entry in the buffer (so 
> > the
> > "remaining length in the buffer" `len` is equal to the length of the
> > entry `nlmsg_len`/`nla_len`/etc) has size that is not a multiple of the
> > alignment, the aligned lengths `*_ALIGN(*_len)` will be greater than `len`.
> > Since `len` is unsigned (`size_t`), it underflows and the loop will read
> > pass the buffer.
> >
> > This may manifest as random EINVAL or EOPNOTSUPP error on IO or network
> > system calls.
> >
> > Signed-off-by: Shu-Chun Weng 
> > ---
> >  linux-user/fd-trans.c | 51 +--
> >  1 file changed, 40 insertions(+), 11 deletions(-)
> >
> > diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c
> > index 60077ce531..9b92386abf 100644
> > --- a/linux-user/fd-trans.c
> > +++ b/linux-user/fd-trans.c
> > @@ -279,6 +279,7 @@ static abi_long host_to_target_for_each_nlmsg(struct 
> > nlmsghdr *nlh,
> > (struct nlmsghdr *))
> >  {
> >  uint32_t nlmsg_len;
> > +uint32_t aligned_nlmsg_len;
> >  abi_long ret;
> >
> >  while (len > sizeof(struct nlmsghdr)) {
> > @@ -312,8 +313,13 @@ static abi_long host_to_target_for_each_nlmsg(struct 
> > nlmsghdr *nlh,
> >  break;
> >  }
> >  tswap_nlmsghdr(nlh);
> > -len -= NLMSG_ALIGN(nlmsg_len);
> > -nlh = (struct nlmsghdr *)(((char*)nlh) + NLMSG_ALIGN(nlmsg_len));
> > +
> > +aligned_nlmsg_len = NLMSG_ALIGN(nlmsg_len);
> > +if (aligned_nlmsg_len >= len) {
> > +break;
> > +}
> > +len -= aligned_nlmsg_len;
> > +nlh = (struct nlmsghdr *)(((char*)nlh) + aligned_nlmsg_len);
> >  }
> >  return 0;
> >  }
>
> Nice catch.
>
> But the first "if" in the loop is already here for that, we only need to
> fix it with something like that in all the for_each functions:
>
> @@ -285,7 +285,7 @@ static abi_long host_to_target_for_each_nlmsg(struct
> nlmsghdr *nlh,
>
>  nlmsg_len = nlh->nlmsg_len;
>  if (nlmsg_len < sizeof(struct nlmsghdr) ||
> -nlmsg_len > len) {
> +NLMSG_ALIGN(nlmsg_len) > len) {
>  break;
>  }
>
> Thanks,
> Laurent
>


smime.p7s
Description: S/MIME Cryptographic Signature


[Bug 1848556] Re: qemu-img check failing on remote image in Eoan

2019-10-18 Thread Rod Smith
I tried qemu from git, but I get an "unknown protocol" error when I try
to access an image via HTTP:

$ ./qemu-img check http://10.193.37.117/cloud/eoan-server-cloudimg-amd64.img
qemu-img: Could not open 
'http://10.193.37.117/cloud/eoan-server-cloudimg-amd64.img': Unknown protocol 
'http'

Is there a development library or ./configure option I need to use to
add this support? I didn't see anything obvious in the ./configure
output.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1848556

Title:
  qemu-img check failing on remote image in Eoan

Status in QEMU:
  Confirmed
Status in qemu package in Ubuntu:
  New

Bug description:
  The "qemu-img check" function is failing on remote (HTTP-hosted)
  images, beginning with Ubuntu 19.10 (qemu-utils version 1:4.0+dfsg-
  0ubuntu9). With previous versions, through Ubuntu 19.04/qemu-utils
  version 1:3.1+dfsg-2ubuntu3.5, the following worked:

  $ /usr/bin/qemu-img check  
http://10.193.37.117/cloud/eoan-server-cloudimg-amd64.img
  No errors were found on the image.
  19778/36032 = 54.89% allocated, 90.34% fragmented, 89.90% compressed clusters
  Image end offset: 514064384

  The 10.193.37.117 server holds an Apache server that hosts the cloud
  images on a LAN. Beginning with Ubuntu 19.10/qemu-utils 1:4.0+dfsg-
  0ubuntu9, the same command never returns. (I've left it for up to an
  hour with no change.) I'm able to wget the image from the same server
  and installation on which qemu-img check fails. I've tried several
  .img files on the server, ranging from Bionic to Eoan, with the same
  results with all of them.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1848556/+subscriptions



Re: [PATCH v1 4/6] s390x/tcg: Fix VECTOR SUBTRACT COMPUTE BORROW INDICATION

2019-10-18 Thread David Hildenbrand

On 18.10.19 19:41, David Hildenbrand wrote:

On 18.10.19 18:10, David Hildenbrand wrote:

Looks like my idea of what a "borrow" is was wrong. We are dealing with
unsigned numbers. A subtraction is simply an addition with the bitwise
complement. If we get a carry during the addition, that's the borrow.
"The operands are treated as unsigned binary integers."

This is nice, as we can reuse the VECTOR ADD COMPUTE CARRY functions
and avoid helpers, all we have to do is compute the bitwise complement.

Fixes: 1ee2d7ba72f6 ("s390x/tcg: Implement VECTOR SUBTRACT COMPUTE BORROW 
INDICATION")
Signed-off-by: David Hildenbrand 
---
   target/s390x/helper.h   |  2 --
   target/s390x/translate_vx.inc.c | 45 -
   target/s390x/vec_int_helper.c   | 16 
   3 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 56e8149866..ca1e08100a 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -207,8 +207,6 @@ DEF_HELPER_FLAGS_4(gvec_verim16, TCG_CALL_NO_RWG, void, 
ptr, cptr, cptr, i32)
   DEF_HELPER_FLAGS_4(gvec_vsl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
   DEF_HELPER_FLAGS_4(gvec_vsra, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
   DEF_HELPER_FLAGS_4(gvec_vsrl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_vscbi8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
-DEF_HELPER_FLAGS_4(gvec_vscbi16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
   DEF_HELPER_4(gvec_vtm, void, ptr, cptr, env, i32)
   
   /* === Vector String Instructions === */

diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 5ce7bfb0af..40bcc1604e 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2130,14 +2130,40 @@ static DisasJumpType op_vs(DisasContext *s, DisasOps *o)
   return DISAS_NEXT;
   }
   
+static void gen_scbi8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)

+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_not_i64(t, b);
+gen_acc(d, a, t, ES_8);
+tcg_temp_free_i64(t);
+}


BTW, I would have thought that we need the 2nd complement in all these
cases. However, the description of the other functions confused me
(VECTOR SUBTRACT WITH BORROW INDICATION) - add bitwise complement and
add the borrow.

This passes my test cases (that are verified against real HW), but I am
not sure if I check all the corner cases.

@Richard, do you have any idea how to do it the right way for this
instruction?



My impression was right. A simple "0-0" test makes this visible. The 
other two fixes seem to be correct, though.


Will rework.

--

Thanks,

David / dhildenb



[PATCH v5 2/3] tests/vm: Let subclasses disable IPv6

2019-10-18 Thread Eduardo Habkost
The mechanism will be used to work around issues related to IPv6
on the netbsd image builder.

Signed-off-by: Eduardo Habkost 
---
 tests/vm/basevm.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index b5d1479bee..2929de23aa 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -57,6 +57,8 @@ class BaseVM(object):
 arch = "#arch"
 # command to halt the guest, can be overridden by subclasses
 poweroff = "poweroff"
+# enable IPv6 networking
+ipv6 = True
 def __init__(self, debug=False, vcpus=None):
 self._guest = None
 self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
@@ -81,7 +83,8 @@ class BaseVM(object):
 self._args = [ \
 "-nodefaults", "-m", "4G",
 "-cpu", "max",
-"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22",
+"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22" +
+   (",ipv6=no" if not self.ipv6 else ""),
 "-device", "virtio-net-pci,netdev=vnet",
 "-vnc", "127.0.0.1:0,to=20"]
 if vcpus and vcpus > 1:
-- 
2.21.0




[PATCH v5 3/3] tests/vm/netbsd: Disable IPv6

2019-10-18 Thread Eduardo Habkost
Workaround for issues when the host has no IPv6 connectivity.

Signed-off-by: Eduardo Habkost 
---
 tests/vm/netbsd | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index 49a99477f4..5e04dcd9b1 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -62,6 +62,13 @@ class NetBSDVM(basevm.BaseVM):
 """
 poweroff = "/sbin/poweroff"
 
+# Workaround for NetBSD + IPv6 + slirp issues.
+# NetBSD seems to ignore the ICMPv6 Destination Unreachable
+# messages generated by slirp.  When the host has no IPv6
+# connectivity, this causes every connection to ftp.NetBSD.org
+# take more than a minute to be established.
+ipv6 = False
+
 def build_image(self, img):
 cimg = self._download_with_cache(self.link)
 img_tmp = img + ".tmp"
-- 
2.21.0




qemu/powernv: coreboot support?

2019-10-18 Thread Marty E. Plummer
Hello,

First off, thank you for the work you've done on the ppc64 support, it
has been very useful. I'm currently working on a coreboot port for the
talos ii line of systems (which means more ppc64 support, support
specifically for the power9 sforza chip, and specific mainboard support.
My plate is very full lol) and have been using qemu to debug the
bootblock.

It has been very useful for that, but I'm now at the point where I need
to jump to romstage, and that's where it gets tricky. qemu parses the rom
image and looks for a ffs header, locates skiboot on it, and jumps straight
to that. Not exactly ideal for debugging something not produced from op-build.

Do you think it would be within your wheelhouse to provide a generic, non-ffs
pnor interface for loading arbitary rom images? It would be of great help if
you could. (This would still hopefully have the bmc support code as
well, as I'm still needing to support a system using one).

Regards,
Marty



Re: [PATCH] Fix unsigned integer underflow in fd-trans.c

2019-10-18 Thread Shu-Chun Weng
That does prevent the integer underflow, but it also changes the behavior
and I don't think the new behavior is desirable.

If the extra payload has a smaller alignment than the header, it makes
sense for the user program to generate a nlmsg_len that is not a multiple
of the alignment. When it's the last entry, the new condition will it
because NLMSG_ALIGN pushes the aligned length over `len`, yet the single
entry processing function won't actually read beyond the buffer as long as
it's bounded by nlmsg_len.

Shu-Chun

On Fri, Oct 18, 2019 at 12:26 AM Laurent Vivier  wrote:

> Le 18/10/2019 à 02:19, Shu-Chun Weng a écrit :
> > In any of these `*_for_each_*` functions, the last entry in the buffer
> (so the
> > "remaining length in the buffer" `len` is equal to the length of the
> > entry `nlmsg_len`/`nla_len`/etc) has size that is not a multiple of the
> > alignment, the aligned lengths `*_ALIGN(*_len)` will be greater than
> `len`.
> > Since `len` is unsigned (`size_t`), it underflows and the loop will read
> > pass the buffer.
> >
> > This may manifest as random EINVAL or EOPNOTSUPP error on IO or network
> > system calls.
> >
> > Signed-off-by: Shu-Chun Weng 
> > ---
> >  linux-user/fd-trans.c | 51 +--
> >  1 file changed, 40 insertions(+), 11 deletions(-)
> >
> > diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c
> > index 60077ce531..9b92386abf 100644
> > --- a/linux-user/fd-trans.c
> > +++ b/linux-user/fd-trans.c
> > @@ -279,6 +279,7 @@ static abi_long host_to_target_for_each_nlmsg(struct
> nlmsghdr *nlh,
> > (struct nlmsghdr
> *))
> >  {
> >  uint32_t nlmsg_len;
> > +uint32_t aligned_nlmsg_len;
> >  abi_long ret;
> >
> >  while (len > sizeof(struct nlmsghdr)) {
> > @@ -312,8 +313,13 @@ static abi_long
> host_to_target_for_each_nlmsg(struct nlmsghdr *nlh,
> >  break;
> >  }
> >  tswap_nlmsghdr(nlh);
> > -len -= NLMSG_ALIGN(nlmsg_len);
> > -nlh = (struct nlmsghdr *)(((char*)nlh) +
> NLMSG_ALIGN(nlmsg_len));
> > +
> > +aligned_nlmsg_len = NLMSG_ALIGN(nlmsg_len);
> > +if (aligned_nlmsg_len >= len) {
> > +break;
> > +}
> > +len -= aligned_nlmsg_len;
> > +nlh = (struct nlmsghdr *)(((char*)nlh) + aligned_nlmsg_len);
> >  }
> >  return 0;
> >  }
>
> Nice catch.
>
> But the first "if" in the loop is already here for that, we only need to
> fix it with something like that in all the for_each functions:
>
> @@ -285,7 +285,7 @@ static abi_long host_to_target_for_each_nlmsg(struct
> nlmsghdr *nlh,
>
>  nlmsg_len = nlh->nlmsg_len;
>  if (nlmsg_len < sizeof(struct nlmsghdr) ||
> -nlmsg_len > len) {
> +NLMSG_ALIGN(nlmsg_len) > len) {
>  break;
>  }
>
> Thanks,
> Laurent
>
>


smime.p7s
Description: S/MIME Cryptographic Signature


[PATCH v5 1/3] tests/vm: netbsd autoinstall, using serial console

2019-10-18 Thread Eduardo Habkost
From: Gerd Hoffmann 

Instead of fetching the prebuilt image from patchew download the install
iso and prepare the image locally.  Install to disk, using the serial
console.  Create qemu user, configure ssh login.  Install packages
needed for qemu builds.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Kamil Rytarowski 
Tested-by: Thomas Huth 
[ehabkost: rebased to latest qemu.git master]
Signed-off-by: Eduardo Habkost 
---
 tests/vm/netbsd | 189 +---
 1 file changed, 179 insertions(+), 10 deletions(-)

diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index ee9eaeab50..49a99477f4 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -2,10 +2,11 @@
 #
 # NetBSD VM image
 #
-# Copyright 2017 Red Hat Inc.
+# Copyright 2017-2019 Red Hat Inc.
 #
 # Authors:
 #  Fam Zheng 
+#  Gerd Hoffmann 
 #
 # This code is licensed under the GPL version 2 or later.  See
 # the COPYING file in the top-level directory.
@@ -13,30 +14,198 @@
 
 import os
 import sys
+import time
 import subprocess
 import basevm
 
 class NetBSDVM(basevm.BaseVM):
 name = "netbsd"
 arch = "x86_64"
+
+link = 
"https://cdn.netbsd.org/pub/NetBSD/NetBSD-8.0/images/NetBSD-8.0-amd64.iso;
+size = "20G"
+pkgs = [
+# tools
+"git-base",
+"pkgconf",
+"xz",
+"python37",
+
+# gnu tools
+"bash",
+"gmake",
+"gsed",
+"flex", "bison",
+
+# libs: crypto
+"gnutls",
+
+# libs: images
+"jpeg",
+"png",
+
+   # libs: ui
+"SDL2",
+"gtk3+",
+"libxkbcommon",
+]
+
 BUILD_SCRIPT = """
 set -e;
-rm -rf /var/tmp/qemu-test.*
-cd $(mktemp -d /var/tmp/qemu-test.XX);
+rm -rf /home/qemu/qemu-test.*
+cd $(mktemp -d /home/qemu/qemu-test.XX);
+mkdir src build; cd src;
 tar -xf /dev/rld1a;
-./configure --python=python2.7 {configure_opts};
+cd ../build
+../src/configure --python=python3.7 --disable-opengl {configure_opts};
 gmake --output-sync -j{jobs} {target} {verbose};
 """
+poweroff = "/sbin/poweroff"
 
 def build_image(self, img):
-cimg = 
self._download_with_cache("http://download.patchew.org/netbsd-7.1-amd64.img.xz;,
- 
sha256sum='b633d565b0eac3d02015cd0c81440bd8a7a8df8512615ac1ee05d318be015732')
-img_tmp_xz = img + ".tmp.xz"
+cimg = self._download_with_cache(self.link)
 img_tmp = img + ".tmp"
-sys.stderr.write("Extracting the image...\n")
-subprocess.check_call(["ln", "-f", cimg, img_tmp_xz])
-subprocess.check_call(["xz", "--keep", "-dvf", img_tmp_xz])
+iso = img + ".install.iso"
+
+self.print_step("Preparing iso and disk image")
+subprocess.check_call(["ln", "-f", cimg, iso])
+subprocess.check_call(["qemu-img", "create", "-f", "qcow2",
+   img_tmp, self.size])
+
+self.print_step("Booting installer")
+self.boot(img_tmp, extra_args = [
+"-bios", "pc-bios/bios-256k.bin",
+"-machine", "graphics=off",
+"-cdrom", iso
+])
+self.console_init()
+self.console_wait("Primary Bootstrap")
+
+# serial console boot menu output doesn't work for some
+# reason, so we have to fly blind ...
+for char in list("5consdev com0\n"):
+time.sleep(0.2)
+self.console_send(char)
+self.console_wait("")
+self.console_wait_send("> ", "boot\n")
+
+self.console_wait_send("Terminal type","xterm\n")
+self.console_wait_send("a: Installation messages", "a\n")
+self.console_wait_send("b: US-English","b\n")
+self.console_wait_send("a: Install NetBSD","a\n")
+self.console_wait("Shall we continue?")
+self.console_wait_send("b: Yes",   "b\n")
+
+self.console_wait_send("a: ld0",   "a\n")
+self.console_wait_send("a: This is the correct",   "a\n")
+self.console_wait_send("b: Use the entire disk",   "b\n")
+self.console_wait("NetBSD bootcode")
+self.console_wait_send("a: Yes",   "a\n")
+self.console_wait_send("b: Use existing part", "b\n")
+self.console_wait_send("x: Partition sizes ok","x\n")
+self.console_wait_send("for your NetBSD disk", "\n")
+self.console_wait("Shall we continue?")
+self.console_wait_send("b: Yes",   "b\n")
+
+self.console_wait_send("b: Use serial port com0",  "b\n")
+self.console_wait_send("f: Set serial baud rate",  "f\n")
+self.console_wait_send("a: 9600",  "a\n")
+self.console_wait_send("x: Exit",  "x\n")
+
+self.console_wait_send("a: Full installation", "a\n")
+

Re: [PATCH] hw/timer/exynos4210_mct: Initialize ptimer before starting it

2019-10-18 Thread Guenter Roeck
On Fri, Oct 18, 2019 at 03:31:49PM +0100, Peter Maydell wrote:
> From: Guenter Roeck 
> 
> When booting a recent Linux kernel, the qemu message "Timer with delta
> zero, disabling" is seen, apparently because a ptimer is started before
> being initialized.  Fix the problem by initializing the offending ptimer
> before starting it.
> 
> The bug is effectively harmless in the old QEMUBH setup
> because the sequence of events is:
>  * the delta zero means the timer expires immediately
>  * ptimer_reload() arranges for exynos4210_gfrc_event() to be called
>  * ptimer_reload() notices the zero delta and disables the timer
>  * later, the QEMUBH runs, and exynos4210_gfrc_event() correctly
>configures the timer and restarts it
> 
> In the new transaction based API the bug is still harmless,
> but differences of when the callback function runs mean the
> message is not printed any more:
>  * ptimer_run() does nothing as it's inside a transaction block
>  * ptimer_transaction_commit() sees it has work to do and
>calls ptimer_reload()
>  * the zero delta means the timer expires immediately
>  * ptimer_reload() calls exynos4210_gfrc_event() directly
>  * exynos4210_gfrc_event() configures the timer
>  * the delta is no longer zero so ptimer_reload() doesn't complain
>(the zero-delta test is after the trigger-callback in
>the ptimer_reload() function)
> 
> Regardless, the behaviour here was not intentional, and we should
> just program the ptimer correctly to start with.
> 
> Signed-off-by: Guenter Roeck 
> [PMM: Expansion/clarification of the commit message:
>  the message is about a zero delta, not a zero period;
>  added detail to the commit message of the analysis of what
>  is happening and why the kernel boots even with the message;
>  added note that the message goes away with the new ptimer API]
> Signed-off-by: Peter Maydell 
> ---
> Philippe pointed me at this bugfix from Guenter. At one point
> in my working on the ptimer API changes I thought this bugfix
> would be necessary as a prerequisite, but in fact the issue
> was in my ptimer changes, and it just happened that fixing
> the MCT bug was a workaround for my bug. Even though the
> ptimer API changes actually coincidentally now suppress the
> annoying message about a zero delta, the behaviour is definitely
> not intentional, and since I spent the time working through the
> analysis of what was actually going on here I don't want
> to waste it :-)
> ---

Thanks a lot for picking this up, and for the great analysis!

Guenter

>  hw/timer/exynos4210_mct.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
> index 72257584145..944120aea59 100644
> --- a/hw/timer/exynos4210_mct.c
> +++ b/hw/timer/exynos4210_mct.c
> @@ -1254,7 +1254,7 @@ static void exynos4210_mct_write(void *opaque, hwaddr 
> offset,
>  /* Start FRC if transition from disabled to enabled */
>  if ((value & G_TCON_TIMER_ENABLE) > (old_val &
>  G_TCON_TIMER_ENABLE)) {
> -exynos4210_gfrc_start(>g_timer);
> +exynos4210_gfrc_restart(s);
>  }
>  if ((value & G_TCON_TIMER_ENABLE) < (old_val &
>  G_TCON_TIMER_ENABLE)) {
> -- 
> 2.20.1
> 



[PATCH v5 0/3] tests/vm: netbsd autoinstall, with IPv6 disabled

2019-10-18 Thread Eduardo Habkost
I'm numbering this series v5 because it's a new version of the
patch sent by Gerd, at:

  Date: Mon, 17 Jun 2019 06:38:56 +0200
  Message-Id: <20190617043858.8290-10-kra...@redhat.com>
  Subject: [PATCH v4 09/11] tests/vm: netbsd autoinstall, using serial console

Changes v4 -> v5:
* Rebase to latest qemu.git master
* Disable IPv6 by default (see
  https://lore.kernel.org/qemu-devel/20191017225548.gl4...@habkost.net/ for 
context)

Eduardo Habkost (2):
  tests/vm: Let subclasses disable IPv6
  tests/vm/netbsd: Disable IPv6

Gerd Hoffmann (1):
  tests/vm: netbsd autoinstall, using serial console

 tests/vm/basevm.py |   5 +-
 tests/vm/netbsd| 196 ++---
 2 files changed, 190 insertions(+), 11 deletions(-)

-- 
2.21.0




Re: [PATCH 4/4] target/arm: Convert PMULL.8 to gvec

2019-10-18 Thread Alex Bennée


Richard Henderson  writes:

> We still need two different helpers, since NEON and SVE2 get the
> inputs from different locations within the source vector.  However,
> we can convert both to the same internal form for computation.
>
> The sve2 helper is not used yet, but adding it with this patch
> helps illustrate why the neon changes are helpful.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Alex Bennée 
Tested-by: Alex Bennée 

> ---
>  target/arm/helper-sve.h|  2 ++
>  target/arm/helper.h|  3 +-
>  target/arm/neon_helper.c   | 32 
>  target/arm/translate-a64.c | 27 +++--
>  target/arm/translate.c | 26 -
>  target/arm/vec_helper.c| 60 ++
>  6 files changed, 95 insertions(+), 55 deletions(-)
>
> diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
> index 9e79182ab4..2f47279155 100644
> --- a/target/arm/helper-sve.h
> +++ b/target/arm/helper-sve.h
> @@ -1574,3 +1574,5 @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd, TCG_CALL_NO_WG,
> void, env, ptr, ptr, ptr, tl, i32)
>  DEF_HELPER_FLAGS_6(sve_stdd_be_zd, TCG_CALL_NO_WG,
> void, env, ptr, ptr, ptr, tl, i32)
> +
> +DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
> diff --git a/target/arm/helper.h b/target/arm/helper.h
> index d954399b7e..8a8517cf34 100644
> --- a/target/arm/helper.h
> +++ b/target/arm/helper.h
> @@ -335,7 +335,6 @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
>  DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
>  DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
>  DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
> -DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
>
>  DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
>  DEF_HELPER_2(neon_tst_u16, i32, i32, i32)
> @@ -688,6 +687,8 @@ DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, 
> ptr, ptr, ptr, i32)
>  DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
>  DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
>
> +DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
> +
>  #ifdef TARGET_AARCH64
>  #include "helper-a64.h"
>  #include "helper-sve.h"
> diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
> index 6a107da0e1..c7a8438b42 100644
> --- a/target/arm/neon_helper.c
> +++ b/target/arm/neon_helper.c
> @@ -1129,38 +1129,6 @@ NEON_VOP(mul_u8, neon_u8, 4)
>  NEON_VOP(mul_u16, neon_u16, 2)
>  #undef NEON_FN
>
> -/* Polynomial multiplication is like integer multiplication except the
> -   partial products are XORed, not added.  */
> -uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
> -{
> -uint64_t result = 0;
> -uint64_t mask;
> -uint64_t op2ex = op2;
> -op2ex = (op2ex & 0xff) |
> -((op2ex & 0xff00) << 8) |
> -((op2ex & 0xff) << 16) |
> -((op2ex & 0xff00) << 24);
> -while (op1) {
> -mask = 0;
> -if (op1 & 1) {
> -mask |= 0x;
> -}
> -if (op1 & (1 << 8)) {
> -mask |= (0xU << 16);
> -}
> -if (op1 & (1 << 16)) {
> -mask |= (0xULL << 32);
> -}
> -if (op1 & (1 << 24)) {
> -mask |= (0xULL << 48);
> -}
> -result ^= op2ex & mask;
> -op1 = (op1 >> 1) & 0x7f7f7f7f;
> -op2ex <<= 1;
> -}
> -return result;
> -}
> -
>  #define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
>  NEON_VOP(tst_u8, neon_u8, 4)
>  NEON_VOP(tst_u16, neon_u16, 2)
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 12588d18df..2934e4fc16 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -10483,10 +10483,6 @@ static void handle_3rd_widening(DisasContext *s, int 
> is_q, int is_u, int size,
>  gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
>tcg_passres, tcg_passres);
>  break;
> -case 14: /* PMULL */
> -assert(size == 0);
> -gen_helper_neon_mull_p8(tcg_passres, tcg_op1, tcg_op2);
> -break;
>  default:
>  g_assert_not_reached();
>  }
> @@ -10650,11 +10646,21 @@ static void disas_simd_three_reg_diff(DisasContext 
> *s, uint32_t insn)
>  handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
>  break;
>  case 14: /* PMULL, PMULL2 */
> -if (is_u || size == 1 || size == 2) {
> +if (is_u) {
>  unallocated_encoding(s);
>  return;
>  }
> -if (size == 3) {
> +switch (size) {
> +case 0: /* PMULL.P8 */
> +if (!fp_access_check(s)) {
> +return;
> +}
> +/* The Q field specifies lo/hi half input for this insn.  */
> +gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
> +

Re: [PATCH 05/14] dp8393x: replace PROP_PTR with PROP_LINK

2019-10-18 Thread Aleksandar Markovic
On Friday, October 18, 2019, Marc-André Lureau 
wrote:

> Signed-off-by: Marc-André Lureau 
> ---
>  hw/mips/mips_jazz.c | 3 ++-
>  hw/net/dp8393x.c| 7 +++
>  2 files changed, 5 insertions(+), 5 deletions(-)
>
>
Marc-Andre,

Can you put together a paragraph on why we need this patch, and place it in
the commit message?

Thanks,

Aleksandar





> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index 8d010a0b6e..878925a963 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -284,7 +284,8 @@ static void mips_jazz_init(MachineState *machine,
>  dev = qdev_create(NULL, "dp8393x");
>  qdev_set_nic_properties(dev, nd);
>  qdev_prop_set_uint8(dev, "it_shift", 2);
> -qdev_prop_set_ptr(dev, "dma_mr", rc4030_dma_mr);
> +object_property_set_link(OBJECT(dev), OBJECT(rc4030_dma_mr),
> + "dma_mr", _abort);
>  qdev_init_nofail(dev);
>  sysbus = SYS_BUS_DEVICE(dev);
>  sysbus_mmio_map(sysbus, 0, 0x80001000);
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index a5678e11fa..946c7a8f64 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -173,7 +173,7 @@ typedef struct dp8393xState {
>  int loopback_packet;
>
>  /* Memory access */
> -void *dma_mr;
> +MemoryRegion *dma_mr;
>  AddressSpace as;
>  } dp8393xState;
>
> @@ -922,7 +922,8 @@ static const VMStateDescription vmstate_dp8393x = {
>
>  static Property dp8393x_properties[] = {
>  DEFINE_NIC_PROPERTIES(dp8393xState, conf),
> -DEFINE_PROP_PTR("dma_mr", dp8393xState, dma_mr),
> +DEFINE_PROP_LINK("dma_mr", dp8393xState, dma_mr,
> + TYPE_MEMORY_REGION, MemoryRegion *),
>  DEFINE_PROP_UINT8("it_shift", dp8393xState, it_shift, 0),
>  DEFINE_PROP_END_OF_LIST(),
>  };
> @@ -936,8 +937,6 @@ static void dp8393x_class_init(ObjectClass *klass,
> void *data)
>  dc->reset = dp8393x_reset;
>  dc->vmsd = _dp8393x;
>  dc->props = dp8393x_properties;
> -/* Reason: dma_mr property can't be set */
> -dc->user_creatable = false;
>  }
>
>  static const TypeInfo dp8393x_info = {
> --
> 2.23.0.606.g08da6496b6
>
>
>


[PATCH v8 20/22] target/arm: Rebuild hflags for M-profile

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
v7: Add rebuilds for v7m_msr and nvic_writel to v7m.ccr.
v8: Split nvic update to a new patch and generalize location.
---
 target/arm/m_helper.c  | 6 ++
 target/arm/translate.c | 5 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 27cd2f3f96..f2512e448e 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -494,6 +494,7 @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
 switch_v7m_security_state(env, dest & 1);
 env->thumb = 1;
 env->regs[15] = dest & ~1;
+arm_rebuild_hflags(env);
 }
 
 void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
@@ -555,6 +556,7 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
 switch_v7m_security_state(env, 0);
 env->thumb = 1;
 env->regs[15] = dest;
+arm_rebuild_hflags(env);
 }
 
 static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
@@ -895,6 +897,7 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, 
bool dotailchain,
 env->regs[14] = lr;
 env->regs[15] = addr & 0xfffe;
 env->thumb = addr & 1;
+arm_rebuild_hflags(env);
 }
 
 static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
@@ -1765,6 +1768,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
 
 /* Otherwise, we have a successful exception exit. */
 arm_clear_exclusive(env);
+arm_rebuild_hflags(env);
 qemu_log_mask(CPU_LOG_INT, "...successful exception return\n");
 }
 
@@ -1837,6 +1841,7 @@ static bool do_v7m_function_return(ARMCPU *cpu)
 xpsr_write(env, 0, XPSR_IT);
 env->thumb = newpc & 1;
 env->regs[15] = newpc & ~1;
+arm_rebuild_hflags(env);
 
 qemu_log_mask(CPU_LOG_INT, "...function return successful\n");
 return true;
@@ -1959,6 +1964,7 @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
 switch_v7m_security_state(env, true);
 xpsr_write(env, 0, XPSR_IT);
 env->regs[15] += 4;
+arm_rebuild_hflags(env);
 return true;
 
 gen_invep:
diff --git a/target/arm/translate.c b/target/arm/translate.c
index cb47cd9744..b3720cd59b 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8325,7 +8325,7 @@ static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
 
 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
 {
-TCGv_i32 addr, reg;
+TCGv_i32 addr, reg, el;
 
 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
 return false;
@@ -8335,6 +8335,9 @@ static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
 gen_helper_v7m_msr(cpu_env, addr, reg);
 tcg_temp_free_i32(addr);
 tcg_temp_free_i32(reg);
+el = tcg_const_i32(s->current_el);
+gen_helper_rebuild_hflags_m32(cpu_env, el);
+tcg_temp_free_i32(el);
 gen_lookup_tb(s);
 return true;
 }
-- 
2.17.1




[PATCH v8 16/22] target/arm: Rebuild hflags at EL changes

2019-10-18 Thread Richard Henderson
Begin setting, but not relying upon, env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c| 1 +
 target/arm/cpu.c| 1 +
 target/arm/helper-a64.c | 3 +++
 target/arm/helper.c | 2 ++
 target/arm/machine.c| 1 +
 target/arm/op_helper.c  | 1 +
 6 files changed, 9 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e2af3c1494..ebefd05140 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9982,6 +9982,7 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 aarch64_sve_narrow_vq(env, vq);
 }
 env->vfp.zcr_el[1] = vq - 1;
+arm_rebuild_hflags(env);
 ret = vq * 16;
 }
 return ret;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 13813fb213..ab3e1a0361 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -406,6 +406,7 @@ static void arm_cpu_reset(CPUState *s)
 
 hw_breakpoint_update_all(cpu);
 hw_watchpoint_update_all(cpu);
+arm_rebuild_hflags(env);
 }
 
 bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index bca80bdc38..b4cd680fc4 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -1025,6 +1025,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t 
new_pc)
 } else {
 env->regs[15] = new_pc & ~0x3;
 }
+helper_rebuild_hflags_a32(env, new_el);
 qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
   "AArch32 EL%d PC 0x%" PRIx32 "\n",
   cur_el, new_el, env->regs[15]);
@@ -1036,10 +1037,12 @@ void HELPER(exception_return)(CPUARMState *env, 
uint64_t new_pc)
 }
 aarch64_restore_sp(env, new_el);
 env->pc = new_pc;
+helper_rebuild_hflags_a64(env, new_el);
 qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
   "AArch64 EL%d PC 0x%" PRIx64 "\n",
   cur_el, new_el, env->pc);
 }
+
 /*
  * Note that cur_el can never be 0.  If new_el is 0, then
  * el0_a64 is return_to_aa64, else el0_a64 is ignored.
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b2d701cf00..aae7b62458 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7998,6 +7998,7 @@ static void take_aarch32_exception(CPUARMState *env, int 
new_mode,
 env->regs[14] = env->regs[15] + offset;
 }
 env->regs[15] = newpc;
+arm_rebuild_hflags(env);
 }
 
 static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
@@ -8345,6 +8346,7 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
 pstate_write(env, PSTATE_DAIF | new_mode);
 env->aarch64 = 1;
 aarch64_restore_sp(env, new_el);
+helper_rebuild_hflags_a64(env, new_el);
 
 env->pc = addr;
 
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 5c36707a7c..eb28b2381b 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -756,6 +756,7 @@ static int cpu_post_load(void *opaque, int version_id)
 if (!kvm_enabled()) {
 pmu_op_finish(>env);
 }
+arm_rebuild_hflags(>env);
 
 return 0;
 }
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index 0fd4bd0238..ccc2cecb46 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -404,6 +404,7 @@ void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
  * state. Do the masking now.
  */
 env->regs[15] &= (env->thumb ? ~1 : ~3);
+arm_rebuild_hflags(env);
 
 qemu_mutex_lock_iothread();
 arm_call_el_change_hook(env_archcpu(env));
-- 
2.17.1




[PATCH v8 14/22] target/arm: Hoist store to cs_base in cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
By performing this store early, we avoid having to save and restore
the register holding the address around any function calls.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3f7d3f257d..37424e3d4d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11225,6 +11225,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 {
 uint32_t flags, pstate_for_ss;
 
+*cs_base = 0;
 flags = rebuild_hflags_internal(env);
 
 if (is_a64(env)) {
@@ -11298,7 +11299,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 
 *pflags = flags;
-*cs_base = 0;
 }
 
 #ifdef TARGET_AARCH64
-- 
2.17.1




Re: [PATCH v32 04/13] target/avr: Add instruction translation - Registers definition

2019-10-18 Thread Aleksandar Markovic
On Friday, October 18, 2019, Aleksandar Markovic <
aleksandar.m.m...@gmail.com> wrote:

>
>
> On Friday, October 18, 2019, Michael Rolnik  wrote:
>
>> On Fri, Oct 18, 2019 at 4:23 PM Aleksandar Markovic
>>  wrote:
>> >
>> >
>> >
>> > On Friday, October 18, 2019, Michael Rolnik  wrote:
>> >>
>> >>
>> >>
>> >> On Fri, Oct 18, 2019 at 11:52 AM Aleksandar Markovic <
>> aleksandar.m.m...@gmail.com> wrote:
>> >>>
>> >>>
>> >>>
>> >>> On Thursday, October 17, 2019, Michael Rolnik 
>> wrote:
>> 
>>  On Thu, Oct 17, 2019 at 11:17 PM Aleksandar Markovic
>>   wrote:
>>  >>
>>  >>
>>  >> >> +static TCGv cpu_Cf;
>>  >> >> +static TCGv cpu_Zf;
>>  >> >> +static TCGv cpu_Nf;
>>  >> >> +static TCGv cpu_Vf;
>>  >> >> +static TCGv cpu_Sf;
>>  >> >> +static TCGv cpu_Hf;
>>  >> >> +static TCGv cpu_Tf;
>>  >> >> +static TCGv cpu_If;
>>  >> >> +
>>  >> >
>>  >> >
>>  >> > Hello, Michael,
>>  >> >
>>  >> > Is there any particular reason or motivation beyond modelling
>> status register flags as TCGv variables?
>>  >>
>>  >>
>>  >>
>>  >> I think it's easier this way as I don't need to convert flag
>> values to
>>  >> bits or bits to flag values.
>>  >
>>  >
>>  > Ok. But, how do you map 0/1 flag value to the value of a TCGv
>> variable and vice versa? In other words, what value or values (out of 2^32
>> vales) of a TCGv variable mean the flag is 1? And the same question for 0.
>>  >
>>  > Is 01111110100 one or zero?
>>  >
>>  > Besides, in such arrangement, how do you display the 8-bit status
>> register in gdb, if at all?
>> 
>>  each flag register is either 0 or 1,
>> 
>> 
>> 
>> >>>
>> >>> Michael,
>> >>>
>> >>> If this is true, why is there a special handling of two flags in the
>> following code:
>> >>>
>> >>>
>> >>> static inline uint8_t cpu_get_sreg(CPUAVRState *env)
>> >>> {
>> >>> uint8_t sreg;
>> >>> sreg = (env->sregC & 0x01) << 0
>> >>> | (env->sregZ == 0 ? 1 : 0) << 1
>> >>> | (env->sregN) << 2
>> >>> | (env->sregV) << 3
>> >>> | (env->sregS) << 4
>> >>> | (env->sregH) << 5
>> >>> | (env->sregT) << 6
>> >>> | (env->sregI) << 7;
>> >>> return sreg;
>> >>> }
>> >>> static inline void cpu_set_sreg(CPUAVRState *env, uint8_t sreg)
>> >>> {
>> >>> env->sregC = (sreg >> 0) & 0x01;
>> >>> env->sregZ = (sreg >> 1) & 0x01 ? 0 : 1;
>> >>> env->sregN = (sreg >> 2) & 0x01;
>> >>> env->sregV = (sreg >> 3) & 0x01;
>> >>> env->sregS = (sreg >> 4) & 0x01;
>> >>> env->sregH = (sreg >> 5) & 0x01;
>> >>> env->sregT = (sreg >> 6) & 0x01;
>> >>> env->sregI = (sreg >> 7) & 0x01;
>> >>> }
>> >>>  ?
>> >>>
>> >> Aleksandar,
>> >>
>> >> If I understand your question correctly cpu_get_sreg assembles SREG
>> value to be presented by GDB, and cpu_set_sreg sets flags values when GDB
>> modifies SREG.
>> >>
>> >> Michael
>> >
>> >
>> >
>> >
>
> Why is handling of sregC and sregZ flags different than handling of other
>> flags? This contradicts your previos statement that 1 (in TCGv) means 1
>> (flag), and 0 (in TCGv) means 0 (flag)?
>> >
>> >
>> > Whatever is the explanation, ot should be included, in my opinion, in
>> code comments.
>> >
>> > Please, Michael, let's first clarify the issue from the question above.
>> >
>> > Thanks, Aleksandar
>> >
>> >
>> there is a comment here
>> https://github.com/michaelrolnik/qemu-avr/blob/master/
>> target/avr/cpu.h#L122-L129
>> >
>
>
>
> ...but it does explain WHY of my question.
>

I meant to say  "does not", not "does".

Michael, don't be discouraged by lenghty review process, just be persistent
and available for communication with reviewers.

Sincerely,
Aleksandar



>
> The reason I insist on your explanation is that when we model a cpu or a
> device in QEMU, a goal is that the model is as close to the hardware as
> possible. One may not, for pletora of reasons, succeed in reaching that
> goal, or, I can imagine, on purpose depart from that goal for some reason -
> perhaps that was the case in your implementation, where you modelled a
> single 8-bit status register with 8 TCGv variables.
>
> But, even that way of modelling was done inconsistently across bits of the
> status register. In that light, I want to know the justification for that,
> so repeat my question: Why is handling of sregC and sregZ flags different
> than handling of other flags in functions cpu_get_sreg()
> and cpu_get_sreg()? This was not explained in any comment or commit
> message. And is in contradiction with one of your previous answers.
>
> Yours,
> Aleksandar
>
>
>> >
>> >
>> >>>
>> >>> Thanks,
>> >>> A.
>> 
>> 
>>   they are calculated here
>>  1. https://github.com/michaelrolnik/qemu-avr/blob/avr-v32/
>> target/avr/translate.c#L146-L148
>>  2. https://github.com/michaelrolnik/qemu-avr/blob/avr-v32/
>> target/avr/translate.c#L166
>>  3. https://github.com/michaelrolnik/qemu-avr/blob/avr-v32/
>> target/avr/translate.c#L185-L187
>>  4. 

[PATCH v8 11/22] target/arm: Hoist computation of TBFLAG_A32.VFPEN

2019-10-18 Thread Richard Henderson
There are 3 conditions that each enable this flag.  M-profile always
enables; A-profile with EL1 as AA64 always enables.  Both of these
conditions can easily be cached.  The final condition relies on the
FPEXC register which we are not prepared to cache.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h|  2 +-
 target/arm/helper.c | 14 ++
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 4d961474ce..9909ff89d4 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3192,7 +3192,7 @@ FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
  * the same thing as the current security state of the processor!
  */
 FIELD(TBFLAG_A32, NS, 6, 1)
-FIELD(TBFLAG_A32, VFPEN, 7, 1)  /* Not cached. */
+FIELD(TBFLAG_A32, VFPEN, 7, 1)  /* Partially cached, minus FPEXC. */
 FIELD(TBFLAG_A32, CONDEXEC, 8, 8)   /* Not cached. */
 FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
 /* For M profile only, set if FPCCR.LSPACT is set */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 398e5f5d6d..89aa6fd933 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11088,6 +11088,9 @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, 
int fp_el,
 {
 uint32_t flags = 0;
 
+/* v8M always enables the fpu.  */
+flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
+
 if (arm_v7m_is_handler_mode(env)) {
 flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
 }
@@ -9,6 +11122,10 @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, 
int fp_el,
ARMMMUIdx mmu_idx)
 {
 uint32_t flags = rebuild_hflags_aprofile(env);
+
+if (arm_el_is_aa64(env, 1)) {
+flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
+}
 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
 }
 
@@ -11250,14 +11257,13 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
env->vfp.vec_stride);
 }
+if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
+flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
+}
 }
 
 flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
 flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
-if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
-|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
-flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
-}
 pstate_for_ss = env->uncached_cpsr;
 }
 
-- 
2.17.1




[PATCH v8 22/22] target/arm: Rely on hflags correct in cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
This is the payoff.

>From perf record -g data of ubuntu 18 boot and shutdown:

BEFORE:

-   23.02% 2.82%  qemu-system-aar  [.] helper_lookup_tb_ptr
   - 20.22% helper_lookup_tb_ptr
  + 10.05% tb_htable_lookup
  - 9.13% cpu_get_tb_cpu_state
   3.20% aa64_va_parameters_both
   0.55% fp_exception_el

-   11.66% 4.74%  qemu-system-aar  [.] cpu_get_tb_cpu_state
   - 6.96% cpu_get_tb_cpu_state
3.63% aa64_va_parameters_both
0.60% fp_exception_el
0.53% sve_exception_el

AFTER:

-   16.40% 3.40%  qemu-system-aar  [.] helper_lookup_tb_ptr
   - 13.03% helper_lookup_tb_ptr
  + 11.19% tb_htable_lookup
0.55% cpu_get_tb_cpu_state

 0.98% 0.71%  qemu-system-aar  [.] cpu_get_tb_cpu_state

 0.87% 0.24%  qemu-system-aar  [.] rebuild_hflags_a64

Before, helper_lookup_tb_ptr is the second hottest function in the
application, consuming almost a quarter of the runtime.  Within the
entire execution, cpu_get_tb_cpu_state consumes about 12%.

After, helper_lookup_tb_ptr has dropped to the fourth hottest function,
with consumption dropping to a sixth of the runtime.  Within the
entire execution, cpu_get_tb_cpu_state has dropped below 1%, and the
supporting function to rebuild hflags also consumes about 1%.

Assertions are retained for --enable-debug-tcg.

Tested-by: Alex Bennée 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
v2: Retain asserts for future debugging.
---
 target/arm/helper.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index c55783e540..63815fc4cf 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11259,12 +11259,15 @@ void HELPER(rebuild_hflags_a64)(CPUARMState *env, int 
el)
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
-uint32_t flags, pstate_for_ss;
+uint32_t flags = env->hflags;
+uint32_t pstate_for_ss;
 
 *cs_base = 0;
-flags = rebuild_hflags_internal(env);
+#ifdef CONFIG_DEBUG_TCG
+assert(flags == rebuild_hflags_internal(env));
+#endif
 
-if (is_a64(env)) {
+if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
 *pc = env->pc;
 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
 flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
-- 
2.17.1




[PATCH v8 10/22] target/arm: Simplify set of PSTATE_SS in cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
Hoist the variable load for PSTATE into the existing test vs is_a64.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index e2a62cf19a..398e5f5d6d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11197,7 +11197,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 ARMMMUIdx mmu_idx = arm_mmu_idx(env);
 int current_el = arm_current_el(env);
 int fp_el = fp_exception_el(env, current_el);
-uint32_t flags;
+uint32_t flags, pstate_for_ss;
 
 if (is_a64(env)) {
 *pc = env->pc;
@@ -11205,6 +11205,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
 flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
 }
+pstate_for_ss = env->pstate;
 } else {
 *pc = env->regs[15];
 
@@ -11257,9 +11258,11 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
 }
+pstate_for_ss = env->uncached_cpsr;
 }
 
-/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
+/*
+ * The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
  * states defined in the ARM ARM for software singlestep:
  *  SS_ACTIVE   PSTATE.SS   State
  * 0x   Inactive (the TB flag for SS is always 0)
@@ -11267,16 +11270,9 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
  * 11   Active-not-pending
  * SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB.
  */
-if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE)) {
-if (is_a64(env)) {
-if (env->pstate & PSTATE_SS) {
-flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
-}
-} else {
-if (env->uncached_cpsr & PSTATE_SS) {
-flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
-}
-}
+if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
+(pstate_for_ss & PSTATE_SS)) {
+flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
 }
 
 *pflags = flags;
-- 
2.17.1




[PATCH v8 21/22] target/arm: Rebuild hflags for M-profile NVIC

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Suggested-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 hw/intc/armv7m_nvic.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 8e93e51e81..e8c74f9eba 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2251,7 +2251,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr 
addr,
 }
 }
 nvic_irq_update(s);
-return MEMTX_OK;
+goto exit_ok;
 case 0x200 ... 0x23f: /* NVIC Set pend */
 /* the special logic in armv7m_nvic_set_pending()
  * is not needed since IRQs are never escalated
@@ -2269,9 +2269,9 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr 
addr,
 }
 }
 nvic_irq_update(s);
-return MEMTX_OK;
+goto exit_ok;
 case 0x300 ... 0x33f: /* NVIC Active */
-return MEMTX_OK; /* R/O */
+goto exit_ok; /* R/O */
 case 0x400 ... 0x5ef: /* NVIC Priority */
 startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
 
@@ -2281,10 +2281,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, 
hwaddr addr,
 }
 }
 nvic_irq_update(s);
-return MEMTX_OK;
+goto exit_ok;
 case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
 if (!arm_feature(>cpu->env, ARM_FEATURE_M_MAIN)) {
-return MEMTX_OK;
+goto exit_ok;
 }
 /* fall through */
 case 0xd1c ... 0xd23: /* System Handler Priority (SHPR2, SHPR3) */
@@ -2299,10 +2299,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, 
hwaddr addr,
 set_prio(s, hdlidx, sbank, newprio);
 }
 nvic_irq_update(s);
-return MEMTX_OK;
+goto exit_ok;
 case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
 if (!arm_feature(>cpu->env, ARM_FEATURE_M_MAIN)) {
-return MEMTX_OK;
+goto exit_ok;
 }
 /* All bits are W1C, so construct 32 bit value with 0s in
  * the parts not written by the access size
@@ -2322,15 +2322,19 @@ static MemTxResult nvic_sysreg_write(void *opaque, 
hwaddr addr,
  */
 s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
 }
-return MEMTX_OK;
+goto exit_ok;
 }
 if (size == 4) {
 nvic_writel(s, offset, value, attrs);
-return MEMTX_OK;
+goto exit_ok;
 }
 qemu_log_mask(LOG_GUEST_ERROR,
   "NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
 /* This is UNPREDICTABLE; treat as RAZ/WI */
+
+ exit_ok:
+/* Ensure any changes made are reflected in the cached hflags.  */
+arm_rebuild_hflags(>cpu->env);
 return MEMTX_OK;
 }
 
-- 
2.17.1




Re: [PATCH 0/4] target/arm vector improvements

2019-10-18 Thread Alex Bennée


Richard Henderson  writes:

> The first patch has been seen before.
>
>   https://patchwork.ozlabs.org/patch/1115039/
>
> It had a bug and I didn't fix it right away and then forgot.
> Fixed now; I had mixed up the operand ordering for aarch32.
>
> The next 3 are something that I noticed while doing other stuff.
>
> In particular, pmull is used heavily during https transfers.
> While cloning a repository, the old code peaks at 27% of the
> total runtime, as measured by perf top.  The new code does
> not quite reach 3% repeating the same clone.
>
> In addition, the new helper functions are in the form that
> will be required for the implementation of SVE2.
>
> The comment in patch 2 about ARMv8.4-DIT is perhaps a stretch,
> but re-reading the pmull instruction description in the current
> ARM ARM brought it to mind.
>
> Since TCG is officially not in the security domain, it's
> probably not a bug to just claim to support DIT without
> actually doing anything to ensure the algorithms used are in
> fact timing independent of the data.
>
> On the other hand, I expect the bit distribution of stuff
> going through these sort of hashing algorithms to approach
> 50% 1's and 0's, so I also don't think we gain anything on
> average to terminate the loop early.
>
> Thoughts on DIT specifically?

It would be an interesting academic exercise to see if someone could
exploit the JIT from the guest but as you say not a security domain
so

>
>
> r~
>
>
> Richard Henderson (4):
>   target/arm: Vectorize USHL and SSHL
>   target/arm: Convert PMUL.8 to gvec
>   target/arm: Convert PMULL.64 to gvec
>   target/arm: Convert PMULL.8 to gvec
>
>  target/arm/helper-sve.h|   2 +
>  target/arm/helper.h|  21 ++-
>  target/arm/translate.h |   6 +
>  target/arm/neon_helper.c   | 117 -
>  target/arm/translate-a64.c |  83 -
>  target/arm/translate.c | 350 -
>  target/arm/vec_helper.c| 211 ++
>  7 files changed, 562 insertions(+), 228 deletions(-)


--
Alex Bennée



[PATCH v8 17/22] target/arm: Rebuild hflags at MSR writes

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 13 +++--
 target/arm/translate.c | 28 +++-
 2 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 2d6cd09634..d4bebbe629 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1789,8 +1789,17 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
 /* I/O operations must end the TB here (whether read or write) */
 s->base.is_jmp = DISAS_UPDATE;
-} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
-/* We default to ending the TB on a coprocessor register write,
+}
+if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
+/*
+ * A write to any coprocessor regiser that ends a TB
+ * must rebuild the hflags for the next TB.
+ */
+TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
+gen_helper_rebuild_hflags_a64(cpu_env, tcg_el);
+tcg_temp_free_i32(tcg_el);
+/*
+ * We default to ending the TB on a coprocessor register write,
  * but allow this to be suppressed by the register definition
  * (usually only necessary to work around guest bugs).
  */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 698c594e8c..cb47cd9744 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6890,6 +6890,8 @@ static int disas_coproc_insn(DisasContext *s, uint32_t 
insn)
 ri = get_arm_cp_reginfo(s->cp_regs,
 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
 if (ri) {
+bool need_exit_tb;
+
 /* Check access permissions */
 if (!cp_access_ok(s->current_el, ri, isread)) {
 return 1;
@@ -7068,14 +7070,30 @@ static int disas_coproc_insn(DisasContext *s, uint32_t 
insn)
 }
 }
 
-if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) 
{
-/* I/O operations must end the TB here (whether read or write) */
-gen_lookup_tb(s);
-} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
-/* We default to ending the TB on a coprocessor register write,
+/* I/O operations must end the TB here (whether read or write) */
+need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
+(ri->type & ARM_CP_IO));
+
+if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
+/*
+ * A write to any coprocessor regiser that ends a TB
+ * must rebuild the hflags for the next TB.
+ */
+TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
+if (arm_dc_feature(s, ARM_FEATURE_M)) {
+gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
+} else {
+gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
+}
+tcg_temp_free_i32(tcg_el);
+/*
+ * We default to ending the TB on a coprocessor register write,
  * but allow this to be suppressed by the register definition
  * (usually only necessary to work around guest bugs).
  */
+need_exit_tb = true;
+}
+if (need_exit_tb) {
 gen_lookup_tb(s);
 }
 
-- 
2.17.1




Re: [PATCH 05/14] dp8393x: replace PROP_PTR with PROP_LINK

2019-10-18 Thread Peter Maydell
On Fri, 18 Oct 2019 at 16:42, Marc-André Lureau
 wrote:
>
> Signed-off-by: Marc-André Lureau 
> ---
>  hw/mips/mips_jazz.c | 3 ++-
>  hw/net/dp8393x.c| 7 +++
>  2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index 8d010a0b6e..878925a963 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -284,7 +284,8 @@ static void mips_jazz_init(MachineState *machine,
>  dev = qdev_create(NULL, "dp8393x");
>  qdev_set_nic_properties(dev, nd);
>  qdev_prop_set_uint8(dev, "it_shift", 2);
> -qdev_prop_set_ptr(dev, "dma_mr", rc4030_dma_mr);
> +object_property_set_link(OBJECT(dev), OBJECT(rc4030_dma_mr),
> + "dma_mr", _abort);
>  qdev_init_nofail(dev);
>  sysbus = SYS_BUS_DEVICE(dev);
>  sysbus_mmio_map(sysbus, 0, 0x80001000);
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index a5678e11fa..946c7a8f64 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -173,7 +173,7 @@ typedef struct dp8393xState {
>  int loopback_packet;
>
>  /* Memory access */
> -void *dma_mr;
> +MemoryRegion *dma_mr;
>  AddressSpace as;
>  } dp8393xState;
>
> @@ -922,7 +922,8 @@ static const VMStateDescription vmstate_dp8393x = {
>
>  static Property dp8393x_properties[] = {
>  DEFINE_NIC_PROPERTIES(dp8393xState, conf),
> -DEFINE_PROP_PTR("dma_mr", dp8393xState, dma_mr),
> +DEFINE_PROP_LINK("dma_mr", dp8393xState, dma_mr,
> + TYPE_MEMORY_REGION, MemoryRegion *),
>  DEFINE_PROP_UINT8("it_shift", dp8393xState, it_shift, 0),
>  DEFINE_PROP_END_OF_LIST(),
>  };

Link property is the correct way to pass a MemoryRegion to
a device for DMA purposes, so this is a good cleanup.

> @@ -936,8 +937,6 @@ static void dp8393x_class_init(ObjectClass *klass, void 
> *data)
>  dc->reset = dp8393x_reset;
>  dc->vmsd = _dp8393x;
>  dc->props = dp8393x_properties;
> -/* Reason: dma_mr property can't be set */
> -dc->user_creatable = false;
>  }

Sidenote: as a sysbus device, this remains non-usercreatable
even though we can drop the specific flag here.


Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH v8 19/22] target/arm: Rebuild hflags at Xscale SCTLR writes

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index aae7b62458..c55783e540 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4174,6 +4174,16 @@ static void sctlr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 /* ??? Lots of these bits are not implemented.  */
 /* This may enable/disable the MMU, so do a TLB flush.  */
 tlb_flush(CPU(cpu));
+
+if (ri->type & ARM_CP_SUPPRESS_TB_END) {
+/*
+ * Normally we would always end the TB on an SCTLR write; see the
+ * comment in ARMCPRegInfo sctlr initialization below for why Xscale
+ * is special.  Setting ARM_CP_SUPPRESS_TB_END also stops the rebuild
+ * of hflags from the translator, so do it here.
+ */
+arm_rebuild_hflags(env);
+}
 }
 
 static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
-- 
2.17.1




[PATCH v8 08/22] target/arm: Split out rebuild_hflags_aprofile

2019-10-18 Thread Richard Henderson
Create a function to compute the values of the TBFLAG_ANY bits
that will be cached, and are used by A-profile.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index d1cd54cc93..ddd21edfcf 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11106,18 +11106,28 @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, 
int fp_el,
 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
 }
 
+static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
+{
+int flags = 0;
+
+flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL,
+   arm_debug_target_el(env));
+return flags;
+}
+
 static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
ARMMMUIdx mmu_idx)
 {
-return rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
+uint32_t flags = rebuild_hflags_aprofile(env);
+return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
 }
 
 static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
ARMMMUIdx mmu_idx)
 {
+uint32_t flags = rebuild_hflags_aprofile(env);
 ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
 ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
-uint32_t flags = 0;
 uint64_t sctlr;
 int tbii, tbid;
 
@@ -11262,12 +11272,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 }
 
-if (!arm_feature(env, ARM_FEATURE_M)) {
-int target_el = arm_debug_target_el(env);
-
-flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL, target_el);
-}
-
 *pflags = flags;
 *cs_base = 0;
 }
-- 
2.17.1




[PATCH v8 18/22] target/arm: Rebuild hflags at CPSR writes

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/op_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index ccc2cecb46..b529d6c1bf 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -224,6 +224,7 @@ uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, 
uint32_t shift)
 void HELPER(setend)(CPUARMState *env)
 {
 env->uncached_cpsr ^= CPSR_E;
+arm_rebuild_hflags(env);
 }
 
 /* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped.
@@ -387,6 +388,8 @@ uint32_t HELPER(cpsr_read)(CPUARMState *env)
 void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
 {
 cpsr_write(env, val, mask, CPSRWriteByInstr);
+/* TODO: Not all cpsr bits are relevant to hflags.  */
+arm_rebuild_hflags(env);
 }
 
 /* Write the CPSR for a 32-bit exception return */
-- 
2.17.1




[PATCH v8 04/22] target/arm: Split arm_cpu_data_is_big_endian

2019-10-18 Thread Richard Henderson
Set TBFLAG_ANY.BE_DATA in rebuild_hflags_common_32 and
rebuild_hflags_a64 instead of rebuild_hflags_common, where we do
not need to re-test is_a64() nor re-compute the various inputs.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h| 49 +++--
 target/arm/helper.c | 16 +++
 2 files changed, 42 insertions(+), 23 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ad79a6153b..4d961474ce 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3108,33 +3108,44 @@ static inline uint64_t arm_sctlr(CPUARMState *env, int 
el)
 }
 }
 
+static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
+  bool sctlr_b)
+{
+#ifdef CONFIG_USER_ONLY
+/*
+ * In system mode, BE32 is modelled in line with the
+ * architecture (as word-invariant big-endianness), where loads
+ * and stores are done little endian but from addresses which
+ * are adjusted by XORing with the appropriate constant. So the
+ * endianness to use for the raw data access is not affected by
+ * SCTLR.B.
+ * In user mode, however, we model BE32 as byte-invariant
+ * big-endianness (because user-only code cannot tell the
+ * difference), and so we need to use a data access endianness
+ * that depends on SCTLR.B.
+ */
+if (sctlr_b) {
+return true;
+}
+#endif
+/* In 32bit endianness is determined by looking at CPSR's E bit */
+return env->uncached_cpsr & CPSR_E;
+}
+
+static inline bool arm_cpu_data_is_big_endian_a64(int el, uint64_t sctlr)
+{
+return sctlr & (el ? SCTLR_EE : SCTLR_E0E);
+}
 
 /* Return true if the processor is in big-endian mode. */
 static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
 {
-/* In 32bit endianness is determined by looking at CPSR's E bit */
 if (!is_a64(env)) {
-return
-#ifdef CONFIG_USER_ONLY
-/* In system mode, BE32 is modelled in line with the
- * architecture (as word-invariant big-endianness), where loads
- * and stores are done little endian but from addresses which
- * are adjusted by XORing with the appropriate constant. So the
- * endianness to use for the raw data access is not affected by
- * SCTLR.B.
- * In user mode, however, we model BE32 as byte-invariant
- * big-endianness (because user-only code cannot tell the
- * difference), and so we need to use a data access endianness
- * that depends on SCTLR.B.
- */
-arm_sctlr_b(env) ||
-#endif
-((env->uncached_cpsr & CPSR_E) ? 1 : 0);
+return arm_cpu_data_is_big_endian_a32(env, arm_sctlr_b(env));
 } else {
 int cur_el = arm_current_el(env);
 uint64_t sctlr = arm_sctlr(env, cur_el);
-
-return (sctlr & (cur_el ? SCTLR_EE : SCTLR_E0E)) != 0;
+return arm_cpu_data_is_big_endian_a64(cur_el, sctlr);
 }
 }
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index f05d042474..4c65476d93 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11061,9 +11061,6 @@ static uint32_t rebuild_hflags_common(CPUARMState *env, 
int fp_el,
 flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
arm_to_core_mmu_idx(mmu_idx));
 
-if (arm_cpu_data_is_big_endian(env)) {
-flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
-}
 if (arm_singlestep_active(env)) {
 flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
 }
@@ -11073,7 +11070,14 @@ static uint32_t rebuild_hflags_common(CPUARMState 
*env, int fp_el,
 static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
  ARMMMUIdx mmu_idx, uint32_t flags)
 {
-flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
+bool sctlr_b = arm_sctlr_b(env);
+
+if (sctlr_b) {
+flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, 1);
+}
+if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
+flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
+}
 flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
 
 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
@@ -11122,6 +11126,10 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, 
int el, int fp_el,
 
 sctlr = arm_sctlr(env, el);
 
+if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
+flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
+}
+
 if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
 /*
  * In order to save space in flags, we record only whether
-- 
2.17.1




Re: [PATCH 06/14] leon3: replace PROP_PTR with PROP_LINK

2019-10-18 Thread Peter Maydell
On Fri, 18 Oct 2019 at 16:43, Marc-André Lureau
 wrote:
>
> "set_pil_in" and "set_pil_in" are used to set a callback, but have a
> single user and cannot be modified by the user.
>
> Simplify the code by calling directly into leon3_set_pil_in(), and use
> a "cpu" link property.
>
> Signed-off-by: Marc-André Lureau 
> ---
>  hw/intc/grlib_irqmp.c | 20 ++--
>  hw/sparc/leon3.c  |  7 +++
>  target/sparc/cpu.h|  1 +
>  3 files changed, 10 insertions(+), 18 deletions(-)
>
> diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c
> index bc78e1a14f..34b7e1b4e1 100644
> --- a/hw/intc/grlib_irqmp.c
> +++ b/hw/intc/grlib_irqmp.c
> @@ -58,10 +58,8 @@ typedef struct IRQMP {
>
>  MemoryRegion iomem;
>
> -void *set_pil_in;
> -void *set_pil_in_opaque;
> -
>  IRQMPState *state;
> +SPARCCPU *cpu;
>  } IRQMP;
>
>  struct IRQMPState {
> @@ -82,7 +80,6 @@ static void grlib_irqmp_check_irqs(IRQMPState *state)
>  uint32_t  pend   = 0;
>  uint32_t  level0 = 0;
>  uint32_t  level1 = 0;
> -set_pil_in_fn set_pil_in;
>
>  assert(state != NULL);
>  assert(state->parent != NULL);
> @@ -97,13 +94,11 @@ static void grlib_irqmp_check_irqs(IRQMPState *state)
>  trace_grlib_irqmp_check_irqs(state->pending, state->force[0],
>   state->mask[0], level1, level0);
>
> -set_pil_in = (set_pil_in_fn)state->parent->set_pil_in;
> -
>  /* Trigger level1 interrupt first and level0 if there is no level1 */
>  if (level1 != 0) {
> -set_pil_in(state->parent->set_pil_in_opaque, level1);
> +leon3_set_pil_in(state->parent->cpu, level1);
>  } else {
> -set_pil_in(state->parent->set_pil_in_opaque, level0);
> +leon3_set_pil_in(state->parent->cpu, level0);
>  }
>  }
>
> @@ -348,14 +343,13 @@ static void grlib_irqmp_realize(DeviceState *dev, Error 
> **errp)
>  IRQMP *irqmp = GRLIB_IRQMP(dev);
>
>  /* Check parameters */
> -if (irqmp->set_pil_in == NULL) {
> -error_setg(errp, "set_pil_in cannot be NULL.");
> +if (irqmp->cpu == NULL) {
> +error_setg(errp, "cpu cannot be NULL.");
>  }
>  }

>  static Property grlib_irqmp_properties[] = {
> -DEFINE_PROP_PTR("set_pil_in", IRQMP, set_pil_in),
> -DEFINE_PROP_PTR("set_pil_in_opaque", IRQMP, set_pil_in_opaque),
> +DEFINE_PROP_LINK("cpu", IRQMP, cpu, TYPE_SPARC_CPU, SPARCCPU *),
>  DEFINE_PROP_END_OF_LIST(),
>  };

This is using ptr properties to define a callback
mechanism where the device says "call the callback
function, passing it an opaque cookie and a
32-bit value". We already have a generic mechanism
for doing that, which is the qemu_irq. So we should
just use that instead of adding a link property between
the interrupt controller and the CPU.

(Bonus further cleanup: the code currently in
leon3_set_pil_in() should probably be part of the
SPARC CPU object itself, as a handler for an inbound
gpio line, as then you could just wire the qemu_irq
from the interrupt controller to the CPU. But you
can leave it as ad-hoc code in leon3.c for now.)

thanks
-- PMM



[PATCH v8 13/22] target/arm: Split out arm_mmu_idx_el

2019-10-18 Thread Richard Henderson
Avoid calling arm_current_el() twice.

Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/arm/internals.h |  9 +
 target/arm/helper.c| 12 +++-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 232d963875..f5313dd3d4 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -949,6 +949,15 @@ void arm_cpu_update_virq(ARMCPU *cpu);
  */
 void arm_cpu_update_vfiq(ARMCPU *cpu);
 
+/**
+ * arm_mmu_idx_el:
+ * @env: The cpu environment
+ * @el: The EL to use.
+ *
+ * Return the full ARMMMUIdx for the translation regime for EL.
+ */
+ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el);
+
 /**
  * arm_mmu_idx:
  * @env: The cpu environment
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 85de96d071..3f7d3f257d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11026,15 +11026,12 @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState 
*env, bool secstate)
 }
 #endif
 
-ARMMMUIdx arm_mmu_idx(CPUARMState *env)
+ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
 {
-int el;
-
 if (arm_feature(env, ARM_FEATURE_M)) {
 return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
 }
 
-el = arm_current_el(env);
 if (el < 2 && arm_is_secure_below_el3(env)) {
 return ARMMMUIdx_S1SE0 + el;
 } else {
@@ -11042,6 +11039,11 @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
 }
 }
 
+ARMMMUIdx arm_mmu_idx(CPUARMState *env)
+{
+return arm_mmu_idx_el(env, arm_current_el(env));
+}
+
 int cpu_mmu_index(CPUARMState *env, bool ifetch)
 {
 return arm_to_core_mmu_idx(arm_mmu_idx(env));
@@ -11202,7 +11204,7 @@ static uint32_t rebuild_hflags_internal(CPUARMState 
*env)
 {
 int el = arm_current_el(env);
 int fp_el = fp_exception_el(env, el);
-ARMMMUIdx mmu_idx = arm_mmu_idx(env);
+ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
 
 if (is_a64(env)) {
 return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
-- 
2.17.1




[PATCH v8 15/22] target/arm: Add HELPER(rebuild_hflags_{a32, a64, m32})

2019-10-18 Thread Richard Henderson
This functions are given the mode and el state of the cpu
and writes the computed value to env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |  4 
 target/arm/helper.c | 24 
 2 files changed, 28 insertions(+)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 1fb2cb5a77..3d4ec267a2 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -90,6 +90,10 @@ DEF_HELPER_4(msr_banked, void, env, i32, i32, i32)
 DEF_HELPER_2(get_user_reg, i32, env, i32)
 DEF_HELPER_3(set_user_reg, void, env, i32, i32)
 
+DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
+DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
+DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
+
 DEF_HELPER_1(vfp_get_fpscr, i32, env)
 DEF_HELPER_2(vfp_set_fpscr, void, env, i32)
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 37424e3d4d..b2d701cf00 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11220,6 +11220,30 @@ void arm_rebuild_hflags(CPUARMState *env)
 env->hflags = rebuild_hflags_internal(env);
 }
 
+void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
+{
+int fp_el = fp_exception_el(env, el);
+ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+
+env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
+}
+
+void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
+{
+int fp_el = fp_exception_el(env, el);
+ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+
+env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
+}
+
+void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
+{
+int fp_el = fp_exception_el(env, el);
+ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+
+env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
+}
+
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
-- 
2.17.1




[PATCH v8 12/22] target/arm: Add arm_rebuild_hflags

2019-10-18 Thread Richard Henderson
This function assumes nothing about the current state of the cpu,
and writes the computed value to env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h|  6 ++
 target/arm/helper.c | 30 ++
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9909ff89d4..d844ea21d8 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3297,6 +3297,12 @@ void arm_register_pre_el_change_hook(ARMCPU *cpu, 
ARMELChangeHookFn *hook,
 void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void
 *opaque);
 
+/**
+ * arm_rebuild_hflags:
+ * Rebuild the cached TBFLAGS for arbitrary changed processor state.
+ */
+void arm_rebuild_hflags(CPUARMState *env);
+
 /**
  * aa32_vfp_dreg:
  * Return a pointer to the Dn register within env in 32-bit mode.
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 89aa6fd933..85de96d071 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11198,17 +11198,35 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, 
int el, int fp_el,
 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
 }
 
+static uint32_t rebuild_hflags_internal(CPUARMState *env)
+{
+int el = arm_current_el(env);
+int fp_el = fp_exception_el(env, el);
+ARMMMUIdx mmu_idx = arm_mmu_idx(env);
+
+if (is_a64(env)) {
+return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
+} else if (arm_feature(env, ARM_FEATURE_M)) {
+return rebuild_hflags_m32(env, fp_el, mmu_idx);
+} else {
+return rebuild_hflags_a32(env, fp_el, mmu_idx);
+}
+}
+
+void arm_rebuild_hflags(CPUARMState *env)
+{
+env->hflags = rebuild_hflags_internal(env);
+}
+
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
-ARMMMUIdx mmu_idx = arm_mmu_idx(env);
-int current_el = arm_current_el(env);
-int fp_el = fp_exception_el(env, current_el);
 uint32_t flags, pstate_for_ss;
 
+flags = rebuild_hflags_internal(env);
+
 if (is_a64(env)) {
 *pc = env->pc;
-flags = rebuild_hflags_a64(env, current_el, fp_el, mmu_idx);
 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
 flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
 }
@@ -11217,8 +11235,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 *pc = env->regs[15];
 
 if (arm_feature(env, ARM_FEATURE_M)) {
-flags = rebuild_hflags_m32(env, fp_el, mmu_idx);
-
 if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
 FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
 != env->v7m.secure) {
@@ -11242,8 +11258,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
 }
 } else {
-flags = rebuild_hflags_a32(env, fp_el, mmu_idx);
-
 /*
  * Note that XSCALE_CPAR shares bits with VECSTRIDE.
  * Note that VECLEN+VECSTRIDE are RES0 for M-profile.
-- 
2.17.1




Re: [PATCH v1 1/1] target/riscv: Remove atomic accesses to MIP CSR

2019-10-18 Thread Alistair Francis
On Fri, Oct 18, 2019 at 9:51 AM Palmer Dabbelt  wrote:
>
> On Tue, 08 Oct 2019 15:04:18 PDT (-0700), Alistair Francis wrote:
> > Instead of relying on atomics to access the MIP register let's update
> > our helper function to instead just lock the IO mutex thread before
> > writing. This follows the same concept as used in PPC for handling
> > interrupts
> >
> > Signed-off-by: Alistair Francis 
> > ---
> >  target/riscv/cpu.c|  5 ++--
> >  target/riscv/cpu.h|  9 
> >  target/riscv/cpu_helper.c | 48 +++
> >  target/riscv/csr.c|  2 +-
> >  4 files changed, 21 insertions(+), 43 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index f13e298a36..e09dd7aa23 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -224,8 +224,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
> > int flags)
> >  #ifndef CONFIG_USER_ONLY
> >  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
> >  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
> > -qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ",
> > - (target_ulong)atomic_read(>mip));
> > +qemu_fprintf(f, " %s 0x%x\n", "mip ", env->mip);
> >  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
> >  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
> >  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
> > @@ -275,7 +274,7 @@ static bool riscv_cpu_has_work(CPUState *cs)
> >   * Definition of the WFI instruction requires it to ignore the 
> > privilege
> >   * mode and delegation registers, but respect individual enables
> >   */
> > -return (atomic_read(>mip) & env->mie) != 0;
> > +return (env->mip & env->mie) != 0;
> >  #else
> >  return true;
> >  #endif
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 124ed33ee4..a71473b243 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -121,15 +121,6 @@ struct CPURISCVState {
> >  target_ulong mhartid;
> >  target_ulong mstatus;
> >
> > -/*
> > - * CAUTION! Unlike the rest of this struct, mip is accessed 
> > asynchonously
> > - * by I/O threads. It should be read with atomic_read. It should be 
> > updated
> > - * using riscv_cpu_update_mip with the iothread mutex held. The 
> > iothread
> > - * mutex must be held because mip must be consistent with the CPU 
> > inturrept
> > - * state. riscv_cpu_update_mip calls cpu_interrupt or 
> > cpu_reset_interrupt
> > - * wuth the invariant that CPU_INTERRUPT_HARD is set iff mip is 
> > non-zero.
> > - * mip is 32-bits to allow atomic_read on 32-bit hosts.
> > - */
> >  uint32_t mip;
> >  uint32_t miclaim;
> >
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index 87dd6a6ece..4334978c2e 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -19,6 +19,7 @@
> >
> >  #include "qemu/osdep.h"
> >  #include "qemu/log.h"
> > +#include "qemu/main-loop.h"
> >  #include "cpu.h"
> >  #include "exec/exec-all.h"
> >  #include "tcg-op.h"
> > @@ -38,7 +39,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
> >  {
> >  target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
> >  target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
> > -target_ulong pending = atomic_read(>mip) & env->mie;
> > +target_ulong pending = env->mip & env->mie;
> >  target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && 
> > mstatus_mie);
> >  target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && 
> > mstatus_sie);
> >  target_ulong irqs = (pending & ~env->mideleg & -mie) |
> > @@ -92,42 +93,29 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t 
> > interrupts)
> >  }
> >  }
> >
> > -struct CpuAsyncInfo {
> > -uint32_t new_mip;
> > -};
> > -
> > -static void riscv_cpu_update_mip_irqs_async(CPUState *target_cpu_state,
> > -run_on_cpu_data data)
> > -{
> > -struct CpuAsyncInfo *info = (struct CpuAsyncInfo *) data.host_ptr;
> > -
> > -if (info->new_mip) {
> > -cpu_interrupt(target_cpu_state, CPU_INTERRUPT_HARD);
> > -} else {
> > -cpu_reset_interrupt(target_cpu_state, CPU_INTERRUPT_HARD);
> > -}
> > -
> > -g_free(info);
> > -}
> > -
> >  uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
> >  {
> >  CPURISCVState *env = >env;
> >  CPUState *cs = CPU(cpu);
> > -struct CpuAsyncInfo *info;
> > -uint32_t old, new, cmp = atomic_read(>mip);
> > +uint32_t old = env->mip;
> > +bool locked = false;
> > +
> > +if (!qemu_mutex_iothread_locked()) {
> > +locked = true;
> > +qemu_mutex_lock_iothread();
> > +}
>
> I must be lost here, because I have no idea what this is trying 

[PATCH v8 07/22] target/arm: Split out rebuild_hflags_a32

2019-10-18 Thread Richard Henderson
Currently a trivial wrapper for rebuild_hflags_common_32.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 296a4b2232..d1cd54cc93 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11106,6 +11106,12 @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, 
int fp_el,
 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
 }
 
+static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
+   ARMMMUIdx mmu_idx)
+{
+return rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
+}
+
 static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
ARMMMUIdx mmu_idx)
 {
@@ -11218,7 +11224,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
 }
 } else {
-flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
+flags = rebuild_hflags_a32(env, fp_el, mmu_idx);
 }
 
 flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
-- 
2.17.1




[PATCH v8 09/22] target/arm: Hoist XSCALE_CPAR, VECLEN, VECSTRIDE in cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
We do not need to compute any of these values for M-profile.
Further, XSCALE_CPAR overlaps VECSTRIDE so obviously the two
sets must be mutually exclusive.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index ddd21edfcf..e2a62cf19a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11235,21 +11235,28 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 } else {
 flags = rebuild_hflags_a32(env, fp_el, mmu_idx);
+
+/*
+ * Note that XSCALE_CPAR shares bits with VECSTRIDE.
+ * Note that VECLEN+VECSTRIDE are RES0 for M-profile.
+ */
+if (arm_feature(env, ARM_FEATURE_XSCALE)) {
+flags = FIELD_DP32(flags, TBFLAG_A32,
+   XSCALE_CPAR, env->cp15.c15_cpar);
+} else {
+flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN,
+   env->vfp.vec_len);
+flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
+   env->vfp.vec_stride);
+}
 }
 
 flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
-flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len);
-flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_stride);
 flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
 if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
 || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
 }
-/* Note that XSCALE_CPAR shares bits with VECSTRIDE */
-if (arm_feature(env, ARM_FEATURE_XSCALE)) {
-flags = FIELD_DP32(flags, TBFLAG_A32,
-   XSCALE_CPAR, env->cp15.c15_cpar);
-}
 }
 
 /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
-- 
2.17.1




[PATCH v8 01/22] target/arm: Split out rebuild_hflags_common

2019-10-18 Thread Richard Henderson
Create a function to compute the values of the TBFLAG_ANY bits
that will be cached.  For now, the env->hflags variable is not
used, and the results are fed back to cpu_get_tb_cpu_state.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h| 29 ++---
 target/arm/helper.c | 26 +++---
 2 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 297ad5e47a..ad79a6153b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -231,6 +231,9 @@ typedef struct CPUARMState {
 uint32_t pstate;
 uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */
 
+/* Cached TBFLAGS state.  See below for which bits are included.  */
+uint32_t hflags;
+
 /* Frequently accessed CPSR bits are stored separately for efficiency.
This contains all the other bits.  Use cpsr_{read,write} to access
the whole CPSR.  */
@@ -3140,15 +3143,18 @@ typedef ARMCPU ArchCPU;
 
 #include "exec/cpu-all.h"
 
-/* Bit usage in the TB flags field: bit 31 indicates whether we are
+/*
+ * Bit usage in the TB flags field: bit 31 indicates whether we are
  * in 32 or 64 bit mode. The meaning of the other bits depends on that.
  * We put flags which are shared between 32 and 64 bit mode at the top
  * of the word, and flags which apply to only one mode at the bottom.
+ *
+ * Unless otherwise noted, these bits are cached in env->hflags.
  */
 FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
 FIELD(TBFLAG_ANY, MMUIDX, 28, 3)
 FIELD(TBFLAG_ANY, SS_ACTIVE, 27, 1)
-FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1)
+FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1) /* Not cached. */
 /* Target EL if we take a floating-point-disabled exception */
 FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2)
 FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
@@ -3159,13 +3165,14 @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
 FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 21, 2)
 
 /* Bit usage when in AArch32 state: */
-FIELD(TBFLAG_A32, THUMB, 0, 1)
-FIELD(TBFLAG_A32, VECLEN, 1, 3)
-FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
+FIELD(TBFLAG_A32, THUMB, 0, 1)  /* Not cached. */
+FIELD(TBFLAG_A32, VECLEN, 1, 3) /* Not cached. */
+FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)  /* Not cached. */
 /*
  * We store the bottom two bits of the CPAR as TB flags and handle
  * checks on the other bits at runtime. This shares the same bits as
  * VECSTRIDE, which is OK as no XScale CPU has VFP.
+ * Not cached, because VECLEN+VECSTRIDE are not cached.
  */
 FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
 /*
@@ -3174,15 +3181,15 @@ FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
  * the same thing as the current security state of the processor!
  */
 FIELD(TBFLAG_A32, NS, 6, 1)
-FIELD(TBFLAG_A32, VFPEN, 7, 1)
-FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
+FIELD(TBFLAG_A32, VFPEN, 7, 1)  /* Not cached. */
+FIELD(TBFLAG_A32, CONDEXEC, 8, 8)   /* Not cached. */
 FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
 /* For M profile only, set if FPCCR.LSPACT is set */
-FIELD(TBFLAG_A32, LSPACT, 18, 1)
+FIELD(TBFLAG_A32, LSPACT, 18, 1)/* Not cached. */
 /* For M profile only, set if we must create a new FP context */
-FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1) /* Not cached. */
 /* For M profile only, set if FPCCR.S does not match current security state */
-FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1) /* Not cached. */
 /* For M profile only, Handler (ie not Thread) mode */
 FIELD(TBFLAG_A32, HANDLER, 21, 1)
 /* For M profile only, whether we should generate stack-limit checks */
@@ -3194,7 +3201,7 @@ FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
 FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
 FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
 FIELD(TBFLAG_A64, BT, 9, 1)
-FIELD(TBFLAG_A64, BTYPE, 10, 2)
+FIELD(TBFLAG_A64, BTYPE, 10, 2) /* Not cached. */
 FIELD(TBFLAG_A64, TBID, 12, 2)
 
 static inline bool bswap_code(bool sctlr_b)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0d9a2d2ab7..8829d91ae1 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11054,6 +11054,22 @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
 }
 #endif
 
+static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
+  ARMMMUIdx mmu_idx, uint32_t flags)
+{
+flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
+flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
+   arm_to_core_mmu_idx(mmu_idx));
+
+if (arm_cpu_data_is_big_endian(env)) {
+flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
+}
+if (arm_singlestep_active(env)) {
+flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
+}
+return flags;
+}
+
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
@@ -11145,7 +11161,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 }
 
-flags = FIELD_DP32(flags, TBFLAG_ANY, 

[PATCH v8 06/22] target/arm: Reduce tests vs M-profile in cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
Hoist the computation of some TBFLAG_A32 bits that only apply to
M-profile under a single test for ARM_FEATURE_M.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 49 +
 1 file changed, 23 insertions(+), 26 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index d4303420da..296a4b2232 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11194,6 +11194,29 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 
 if (arm_feature(env, ARM_FEATURE_M)) {
 flags = rebuild_hflags_m32(env, fp_el, mmu_idx);
+
+if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
+FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
+!= env->v7m.secure) {
+flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
+}
+
+if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
+(!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
+ (env->v7m.secure &&
+  !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK {
+/*
+ * ASPEN is set, but FPCA/SFPA indicate that there is no
+ * active FP context; we must create a new FP context before
+ * executing any FP insn.
+ */
+flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
+}
+
+bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
+if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
+flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
+}
 } else {
 flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
 }
@@ -11233,32 +11256,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 }
 
-if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
-FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
-flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
-}
-
-if (arm_feature(env, ARM_FEATURE_M) &&
-(env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
-(!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
- (env->v7m.secure &&
-  !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK {
-/*
- * ASPEN is set, but FPCA/SFPA indicate that there is no active
- * FP context; we must create a new FP context before executing
- * any FP insn.
- */
-flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
-}
-
-if (arm_feature(env, ARM_FEATURE_M)) {
-bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
-
-if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
-flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
-}
-}
-
 if (!arm_feature(env, ARM_FEATURE_M)) {
 int target_el = arm_debug_target_el(env);
 
-- 
2.17.1




[PATCH v8 02/22] target/arm: Split out rebuild_hflags_a64

2019-10-18 Thread Richard Henderson
Create a function to compute the values of the TBFLAG_A64 bits
that will be cached.  For now, the env->hflags variable is not
used, and the results are fed back to cpu_get_tb_cpu_state.

Note that not all BTI related flags are cached, so we have to
test the BTI feature twice -- once for those bits moved out to
rebuild_hflags_a64 and once for those bits that remain in
cpu_get_tb_cpu_state.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 131 +++-
 1 file changed, 69 insertions(+), 62 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8829d91ae1..69da04786e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11070,6 +11070,71 @@ static uint32_t rebuild_hflags_common(CPUARMState 
*env, int fp_el,
 return flags;
 }
 
+static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
+   ARMMMUIdx mmu_idx)
+{
+ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
+ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
+uint32_t flags = 0;
+uint64_t sctlr;
+int tbii, tbid;
+
+flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
+
+/* FIXME: ARMv8.1-VHE S2 translation regime.  */
+if (regime_el(env, stage1) < 2) {
+ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
+tbid = (p1.tbi << 1) | p0.tbi;
+tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
+} else {
+tbid = p0.tbi;
+tbii = tbid & !p0.tbid;
+}
+
+flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
+flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
+
+if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
+int sve_el = sve_exception_el(env, el);
+uint32_t zcr_len;
+
+/*
+ * If SVE is disabled, but FP is enabled,
+ * then the effective len is 0.
+ */
+if (sve_el != 0 && fp_el == 0) {
+zcr_len = 0;
+} else {
+zcr_len = sve_zcr_len_for_el(env, el);
+}
+flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
+flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
+}
+
+sctlr = arm_sctlr(env, el);
+
+if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
+/*
+ * In order to save space in flags, we record only whether
+ * pauth is "inactive", meaning all insns are implemented as
+ * a nop, or "active" when some action must be performed.
+ * The decision of which action to take is left to a helper.
+ */
+if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
+flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
+}
+}
+
+if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
+/* Note that SCTLR_EL[23].BT == SCTLR_BT1.  */
+if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
+flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
+}
+}
+
+return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
+}
+
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
@@ -11079,67 +11144,9 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 uint32_t flags = 0;
 
 if (is_a64(env)) {
-ARMCPU *cpu = env_archcpu(env);
-uint64_t sctlr;
-
 *pc = env->pc;
-flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
-
-/* Get control bits for tagged addresses.  */
-{
-ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
-ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
-int tbii, tbid;
-
-/* FIXME: ARMv8.1-VHE S2 translation regime.  */
-if (regime_el(env, stage1) < 2) {
-ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
-tbid = (p1.tbi << 1) | p0.tbi;
-tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
-} else {
-tbid = p0.tbi;
-tbii = tbid & !p0.tbid;
-}
-
-flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
-flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
-}
-
-if (cpu_isar_feature(aa64_sve, cpu)) {
-int sve_el = sve_exception_el(env, current_el);
-uint32_t zcr_len;
-
-/* If SVE is disabled, but FP is enabled,
- * then the effective len is 0.
- */
-if (sve_el != 0 && fp_el == 0) {
-zcr_len = 0;
-} else {
-zcr_len = sve_zcr_len_for_el(env, current_el);
-}
-flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
-flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
-}
-
-sctlr = arm_sctlr(env, current_el);
-
-if (cpu_isar_feature(aa64_pauth, cpu)) {
- 

[PATCH v8 05/22] target/arm: Split out rebuild_hflags_m32

2019-10-18 Thread Richard Henderson
Create a function to compute the values of the TBFLAG_A32 bits
that will be cached, and are used by M-profile.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 45 ++---
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 4c65476d93..d4303420da 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11083,6 +11083,29 @@ static uint32_t rebuild_hflags_common_32(CPUARMState 
*env, int fp_el,
 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
 }
 
+static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
+   ARMMMUIdx mmu_idx)
+{
+uint32_t flags = 0;
+
+if (arm_v7m_is_handler_mode(env)) {
+flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
+}
+
+/*
+ * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN
+ * is suppressing them because the requested execution priority
+ * is less than 0.
+ */
+if (arm_feature(env, ARM_FEATURE_V8) &&
+!((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
+  (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
+flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
+}
+
+return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
+}
+
 static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
ARMMMUIdx mmu_idx)
 {
@@ -11168,7 +11191,13 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 } else {
 *pc = env->regs[15];
-flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
+
+if (arm_feature(env, ARM_FEATURE_M)) {
+flags = rebuild_hflags_m32(env, fp_el, mmu_idx);
+} else {
+flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
+}
+
 flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
 flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len);
 flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_stride);
@@ -11204,20 +11233,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 }
 
-if (arm_v7m_is_handler_mode(env)) {
-flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
-}
-
-/* v8M always applies stack limit checks unless CCR.STKOFHFNMIGN is
- * suppressing them because the requested execution priority is less than 
0.
- */
-if (arm_feature(env, ARM_FEATURE_V8) &&
-arm_feature(env, ARM_FEATURE_M) &&
-!((mmu_idx  & ARM_MMU_IDX_M_NEGPRI) &&
-  (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
-flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
-}
-
 if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
 FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
 flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
-- 
2.17.1




[PATCH v8 00/22] target/arm: Reduce overhead of cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
Changes since v7:
  * Rebuild hflags for all successful nvic writes (Peter).
  * Rebuild hflags for Xscale sctlr writes (Peter).

Changes since v6:
  * Regen hflags in two more places for m-profile (patch 19).

Changes since v5:
  * Fix the debug assertion ifdef in the final patch.
  * Add more calls to arm_rebuild_hflags: CPSR and M-profile
These become two new patches, 18 & 19.
  * Update some comments per review. (Alex)

Changes since v4:
  * Split patch 1 into 15 smaller patches.
  * Cache the new DEBUG_TARGET_EL field.
  * Split out m-profile hflags separately from a-profile 32-bit.
  * Move around non-cached tb flags as well, avoiding repetitive
checks for m-profile or other mutually exclusive conditions.

  I haven't officially re-run the performance test quoted in the
  last patch, but I have eyeballed "perf top", and have dug into
  the compiled code a bit, which resulted in a few of the new
  cleanup patches (e.g. cs_base, arm_mmu_idx_el, and
  arm_cpu_data_is_big_endian).
...


r~


Richard Henderson (22):
  target/arm: Split out rebuild_hflags_common
  target/arm: Split out rebuild_hflags_a64
  target/arm: Split out rebuild_hflags_common_32
  target/arm: Split arm_cpu_data_is_big_endian
  target/arm: Split out rebuild_hflags_m32
  target/arm: Reduce tests vs M-profile in cpu_get_tb_cpu_state
  target/arm: Split out rebuild_hflags_a32
  target/arm: Split out rebuild_hflags_aprofile
  target/arm: Hoist XSCALE_CPAR, VECLEN, VECSTRIDE in
cpu_get_tb_cpu_state
  target/arm: Simplify set of PSTATE_SS in cpu_get_tb_cpu_state
  target/arm: Hoist computation of TBFLAG_A32.VFPEN
  target/arm: Add arm_rebuild_hflags
  target/arm: Split out arm_mmu_idx_el
  target/arm: Hoist store to cs_base in cpu_get_tb_cpu_state
  target/arm: Add HELPER(rebuild_hflags_{a32,a64,m32})
  target/arm: Rebuild hflags at EL changes
  target/arm: Rebuild hflags at MSR writes
  target/arm: Rebuild hflags at CPSR writes
  target/arm: Rebuild hflags at Xscale SCTLR writes
  target/arm: Rebuild hflags for M-profile
  target/arm: Rebuild hflags for M-profile NVIC
  target/arm: Rely on hflags correct in cpu_get_tb_cpu_state

 target/arm/cpu.h   |  84 +---
 target/arm/helper.h|   4 +
 target/arm/internals.h |   9 +
 hw/intc/armv7m_nvic.c  |  22 ++-
 linux-user/syscall.c   |   1 +
 target/arm/cpu.c   |   1 +
 target/arm/helper-a64.c|   3 +
 target/arm/helper.c| 393 -
 target/arm/m_helper.c  |   6 +
 target/arm/machine.c   |   1 +
 target/arm/op_helper.c |   4 +
 target/arm/translate-a64.c |  13 +-
 target/arm/translate.c |  33 +++-
 13 files changed, 390 insertions(+), 184 deletions(-)

-- 
2.17.1




[PATCH v8 03/22] target/arm: Split out rebuild_hflags_common_32

2019-10-18 Thread Richard Henderson
Create a function to compute the values of the TBFLAG_A32 bits
that will be cached, and are used by all profiles.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 69da04786e..f05d042474 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11070,6 +11070,15 @@ static uint32_t rebuild_hflags_common(CPUARMState 
*env, int fp_el,
 return flags;
 }
 
+static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
+ ARMMMUIdx mmu_idx, uint32_t flags)
+{
+flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
+flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
+
+return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
+}
+
 static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
ARMMMUIdx mmu_idx)
 {
@@ -11141,7 +11150,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 ARMMMUIdx mmu_idx = arm_mmu_idx(env);
 int current_el = arm_current_el(env);
 int fp_el = fp_exception_el(env, current_el);
-uint32_t flags = 0;
+uint32_t flags;
 
 if (is_a64(env)) {
 *pc = env->pc;
@@ -11151,12 +11160,11 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 } else {
 *pc = env->regs[15];
+flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
 flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
 flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len);
 flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_stride);
 flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
-flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
-flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
 if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
 || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
@@ -11166,8 +11174,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 flags = FIELD_DP32(flags, TBFLAG_A32,
XSCALE_CPAR, env->cp15.c15_cpar);
 }
-
-flags = rebuild_hflags_common(env, fp_el, mmu_idx, flags);
 }
 
 /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
-- 
2.17.1




Re: [PATCH for 4.2 v6 00/54] Support for TCG plugins

2019-10-18 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20191017131615.19660-1-alex.ben...@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [PATCH for 4.2 v6 00/54] Support for TCG plugins
Type: series
Message-id: 20191017131615.19660-1-alex.ben...@linaro.org

=== 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 ===

Switched to a new branch 'test'
d836eae scripts/checkpatch.pl: don't complain about (foo, /* empty */)
6a6189b .travis.yml: add --enable-plugins tests
b648611 include/exec: wrap cpu_ldst.h in CONFIG_TCG
52b9c19 accel/stubs: reduce headers from tcg-stub
4d74b4e tests/plugin: add hotpages to analyse memory access patterns
8ef1ff4 tests/plugin: add instruction execution breakdown
abb472d tests/plugin: add a hotblocks plugin
20457aa tests/tcg: enable plugin testing
7b1a7a4 tests/tcg: drop test-i386-fprem from TESTS when not SLOW
4cb0cf5 tests/tcg: move "virtual" tests to EXTRA_TESTS
81c8812 tests/tcg: set QEMU_OPTS for all cris runs
0a8a37a tests/tcg/Makefile.target: fix path to config-host.mak
18cb7f9 tests/plugin: add sample plugins
bc1a966 linux-user: support -plugin option
089f2f2 vl: support -plugin option
bf99ebb plugin: add qemu_plugin_outs helper
ee2763a plugin: add qemu_plugin_insn_disas helper
9f3330f plugin: expand the plugin_init function to include an info block
f0f4fc1 plugin: add API symbols to qemu-plugins.symbols
1ec6198 configure: add --enable-plugins
1e03ebf translator: inject instrumentation from plugins
82417cf target/openrisc: fetch code with translator_ld
00499c8 target/xtensa: fetch code with translator_ld
f876786 target/sparc: fetch code with translator_ld
a85500f target/riscv: fetch code with translator_ld
ff9b482 target/alpha: fetch code with translator_ld
cd5e198 target/m68k: fetch code with translator_ld
0dd9382 target/hppa: fetch code with translator_ld
abddb18 target/i386: fetch code with translator_ld
cf525e9 target/sh4: fetch code with translator_ld
21f7317 target/ppc: fetch code with translator_ld
e57f15c target/arm: fetch code with translator_ld
7268524 translator: add translator_ld{ub,sw,uw,l,q}
bb715ab plugin-gen: add plugin_insn_append
a99cb36 cpu: hook plugin vcpu events
87f6ee8 *-user: plugin syscalls
d1149f5 *-user: notify plugin of exit
d04ce7b translate-all: notify plugin code of tb_flush
80caa08 plugins: implement helpers for resolving hwaddr
9639665 tcg: let plugins instrument virtual memory accesses
3a440fd atomic_template: add inline trace/plugin helpers
3075615 plugin-gen: add module for TCG-related code
d12bc8c tcg: add tcg_gen_st_ptr
0acadc3 cputlb: introduce get_page_addr_code_hostp
a1d7d7f cputlb: document get_page_addr_code
ae7c047 queue: add QTAILQ_REMOVE_SEVERAL
d7b743f plugin: add implementation of the api
fdcaec1 plugin: add core code
9aa3f8b plugin: add user-facing API
274e91a docs/devel: add plugins.rst design document
dcbc372 translate-all: use cpu_in_exclusive_work_context() in tb_flush
9ef9697 cpu: introduce cpu_in_exclusive_context()
5f2168d trace: add mmu_index to mem_info
ec66990 trace: expand mem_info:size_shift to 4 bits

=== OUTPUT BEGIN ===
1/54 Checking commit ec6699058f0d (trace: expand mem_info:size_shift to 4 bits)
2/54 Checking commit 5f2168d69198 (trace: add mmu_index to mem_info)
3/54 Checking commit 9ef9697395c6 (cpu: introduce cpu_in_exclusive_context())
4/54 Checking commit dcbc37211913 (translate-all: use 
cpu_in_exclusive_work_context() in tb_flush)
5/54 Checking commit 274e91ac8058 (docs/devel: add plugins.rst design document)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#24: 
new file mode 100644

total: 0 errors, 1 warnings, 116 lines checked

Patch 5/54 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
6/54 Checking commit 9aa3f8bc190f (plugin: add user-facing API)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#15: 
new file mode 100644

WARNING: architecture specific defines should be avoided
#41: FILE: include/qemu/qemu-plugin.h:22:
+#if defined _WIN32 || defined __CYGWIN__

WARNING: architecture specific defines should be avoided
#49: FILE: include/qemu/qemu-plugin.h:30:
+  #if __GNUC__ >= 4

total: 0 errors, 3 warnings, 351 lines checked

Patch 6/54 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
7/54 Checking commit fdcaec175fc9 (plugin: add core code)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#99: 
new file mode 100644

ERROR: externs should be avoided in .c files
#947: FILE: plugins/loader.c:63:
+extern struct qemu_plugin_state plugin;

total: 1 errors, 1 warnings, 1284 lines 

Re: [PATCH 07/14] RFC: mips/cps: fix setting saar property

2019-10-18 Thread Aleksandar Markovic
On Friday, October 18, 2019, Marc-André Lureau 
wrote:

> There is no "saar" property. Note: I haven't been able to test this
> code. Help welcome.
>
> May fix commit 043715d1e0fbb3e3411be3f898c5b77b7f90327a ("target/mips:
> Update ITU to utilize SAARI and SAAR CP0 registers")
>
> Signed-off-by: Marc-André Lureau 
> ---
>  hw/mips/cps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
>
This was a part of larger body code that is still in process of upstreaming
(and testing). I'll try to take a closer look in next few days. But, for
4.2, only minor changes are acceptable (like this patch). I'll get back to
you when I get more info on all options. Thank you anyway!

Aleksandar



> diff --git a/hw/mips/cps.c b/hw/mips/cps.c
> index 1660f86908..c49868d5da 100644
> --- a/hw/mips/cps.c
> +++ b/hw/mips/cps.c
> @@ -106,7 +106,7 @@ static void mips_cps_realize(DeviceState *dev, Error
> **errp)
>  object_property_set_bool(OBJECT(>itu), saar_present,
> "saar-present",
>   );
>  if (saar_present) {
> -qdev_prop_set_ptr(DEVICE(>itu), "saar", (void
> *)>CP0_SAAR);
> +s->itu.saar = >CP0_SAAR;
>  }
>  object_property_set_bool(OBJECT(>itu), true, "realized",
> );
>  if (err != NULL) {
> --
> 2.23.0.606.g08da6496b6
>
>
>


Re: [PATCH v1 4/6] s390x/tcg: Fix VECTOR SUBTRACT COMPUTE BORROW INDICATION

2019-10-18 Thread David Hildenbrand

On 18.10.19 18:10, David Hildenbrand wrote:

Looks like my idea of what a "borrow" is was wrong. We are dealing with
unsigned numbers. A subtraction is simply an addition with the bitwise
complement. If we get a carry during the addition, that's the borrow.
"The operands are treated as unsigned binary integers."

This is nice, as we can reuse the VECTOR ADD COMPUTE CARRY functions
and avoid helpers, all we have to do is compute the bitwise complement.

Fixes: 1ee2d7ba72f6 ("s390x/tcg: Implement VECTOR SUBTRACT COMPUTE BORROW 
INDICATION")
Signed-off-by: David Hildenbrand 
---
  target/s390x/helper.h   |  2 --
  target/s390x/translate_vx.inc.c | 45 -
  target/s390x/vec_int_helper.c   | 16 
  3 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 56e8149866..ca1e08100a 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -207,8 +207,6 @@ DEF_HELPER_FLAGS_4(gvec_verim16, TCG_CALL_NO_RWG, void, 
ptr, cptr, cptr, i32)
  DEF_HELPER_FLAGS_4(gvec_vsl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
  DEF_HELPER_FLAGS_4(gvec_vsra, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
  DEF_HELPER_FLAGS_4(gvec_vsrl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_vscbi8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
-DEF_HELPER_FLAGS_4(gvec_vscbi16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
  DEF_HELPER_4(gvec_vtm, void, ptr, cptr, env, i32)
  
  /* === Vector String Instructions === */

diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 5ce7bfb0af..40bcc1604e 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2130,14 +2130,40 @@ static DisasJumpType op_vs(DisasContext *s, DisasOps *o)
  return DISAS_NEXT;
  }
  
+static void gen_scbi8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)

+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_not_i64(t, b);
+gen_acc(d, a, t, ES_8);
+tcg_temp_free_i64(t);
+}


BTW, I would have thought that we need the 2nd complement in all these 
cases. However, the description of the other functions confused me 
(VECTOR SUBTRACT WITH BORROW INDICATION) - add bitwise complement and 
add the borrow.


This passes my test cases (that are verified against real HW), but I am 
not sure if I check all the corner cases.


@Richard, do you have any idea how to do it the right way for this 
instruction?


--

Thanks,

David / dhildenb



Re: [PATCH 08/14] cris: replace PROP_PTR with PROP_LINK for interrupt vector

2019-10-18 Thread Peter Maydell
On Fri, 18 Oct 2019 at 16:43, Marc-André Lureau
 wrote:
>
> Instead of using raw interrupt vector pointer, store the associated
> CPU with a link property.
>
> Signed-off-by: Marc-André Lureau 

A link property is reasonable for a tightly coupled CPU and
interrupt-controller. But in this case the binding is not
actually very tight, and we can avoid it.

> @@ -298,7 +296,7 @@ void axisdev88_init(MachineState *machine)
>
>  dev = qdev_create(NULL, "etraxfs,pic");
>  /* FIXME: Is there a proper way to signal vectors to the CPU core?  */
> -qdev_prop_set_ptr(dev, "interrupt_vector", >interrupt_vector);
> +object_property_set_link(OBJECT(dev), OBJECT(cpu), "cpu", _abort);

Rather than using a link property like this, we could
instead make use of the fact that a qemu_irq line is
actually capable of passing an arbitrary "int" value,
not merely a bool. To do this we would:

 * remove the FIXME comment and the ptr prop/link prop code here
 * remove the definition of the property from the PIC device

> @@ -79,9 +78,10 @@ static void pic_update(struct etrax_pic *fs)
>  }
>  }
>
> -if (fs->interrupt_vector) {
> -/* hack alert: ptr property */
> -*(uint32_t*)(fs->interrupt_vector) = vector;
> +if (fs->cpu) {
> +/* hack alert: cpu link property */
> +int32_t *int_vec = >cpu->env.interrupt_vector;
> +*int_vec = (uint32_t)vector;
>  }
>  qemu_set_irq(fs->parent_irq, !!vector);

 * here, instead of setting the CPU interrupt_vector field
   and passing !!vector to qemu_set_irq, we just pass "vector",
   so the other end gets the whole integer

 * in target/cris/cpu.c:cris_cpu_set_irq(), we add something like
   if (irq == CRIS_CPU_IRQ) {
   /*
* The PIC passes us the vector for the IRQ as the value it sends
* over the qemu_irq line
*/
   cpu->interrupt_vector = value;
   }
   at the top of the function.

It would also be nice somewhere to have a comment documenting
that this is the semantics the CPU expects for its incoming
IRQ line. Unless anybody has a better place, then perhaps
in the part of target/cris/cpu.h that defines CRIS_CPU_IRQ.
(If the PIC followed the just-recently-invented qdev convention
of having a .h file with a comment defining the "QEMU interface"
to the device, as eg include/hw/misc/armsse-mhu.h, then that
comment would be a good place to note that its sysbus IRQ 0
has these value-is-the-vector semantics. But it doesn't.)

>  }
> @@ -164,7 +164,7 @@ static void etraxfs_pic_init(Object *obj)
>  }
>
>  static Property etraxfs_pic_properties[] = {
> -DEFINE_PROP_PTR("interrupt_vector", struct etrax_pic, interrupt_vector),
> +DEFINE_PROP_LINK("cpu", struct etrax_pic, cpu, TYPE_CRIS_CPU, CRISCPU *),
>  DEFINE_PROP_END_OF_LIST(),
>  };
>
> @@ -173,10 +173,6 @@ static void etraxfs_pic_class_init(ObjectClass *klass, 
> void *data)
>  DeviceClass *dc = DEVICE_CLASS(klass);
>
>  dc->props = etraxfs_pic_properties;
> -/*
> - * Note: pointer property "interrupt_vector" may remain null, thus
> - * no need for dc->user_creatable = false;
> - */
>  }

Incidentally this is a sysbus device, so it's not user
creatable anyway.

thanks
-- PMM



Re: [PATCH v2 2/2] migration: savevm_state_handler_insert: constant-time element insertion

2019-10-18 Thread Dr. David Alan Gilbert
* Michael Roth (mdr...@linux.vnet.ibm.com) wrote:
> Quoting Dr. David Alan Gilbert (2019-10-18 04:43:52)
> > * Laurent Vivier (lviv...@redhat.com) wrote:
> > > On 18/10/2019 10:16, Dr. David Alan Gilbert wrote:
> > > > * Scott Cheloha (chel...@linux.vnet.ibm.com) wrote:
> > > >> savevm_state's SaveStateEntry TAILQ is a priority queue.  Priority
> > > >> sorting is maintained by searching from head to tail for a suitable
> > > >> insertion spot.  Insertion is thus an O(n) operation.
> > > >>
> > > >> If we instead keep track of the head of each priority's subqueue
> > > >> within that larger queue we can reduce this operation to O(1) time.
> > > >>
> > > >> savevm_state_handler_remove() becomes slightly more complex to
> > > >> accomodate these gains: we need to replace the head of a priority's
> > > >> subqueue when removing it.
> > > >>
> > > >> With O(1) insertion, booting VMs with many SaveStateEntry objects is
> > > >> more plausible.  For example, a ppc64 VM with maxmem=8T has 4 such
> > > >> objects to insert.
> > > > 
> > > > Separate from reviewing this patch, I'd like to understand why you've
> > > > got 4 objects.  This feels very very wrong and is likely to cause
> > > > problems to random other bits of qemu as well.
> > > 
> > > I think the 4 objects are the "dr-connectors" that are used to plug
> > > peripherals (memory, pci card, cpus, ...).
> > 
> > Yes, Scott confirmed that in the reply to the previous version.
> > IMHO nothing in qemu is designed to deal with that many devices/objects
> > - I'm sure that something other than the migration code is going to get 
> > upset.
> 
> The device/object management aspect seems to handle things *mostly* okay, at
> least ever since QOM child properties started being tracked by a hash table
> instead of a linked list. It's worth noting that that change (b604a854) was
> done to better handle IRQ pins for ARM guests with lots of CPUs. I think it is
> inevitable that certain machine types/configurations will call for large
> numbers of objects and I think it is fair to improve things to allow for this
> sort of scalability.
> 
> But I agree it shouldn't be abused, and you're right that there are some
> problem areas that arise. Trying to outline them:
> 
>  a) introspection commands like 'info qom-tree' become pretty unwieldly,
> and with large enough numbers of objects might even break things (QMP
> response size limits maybe?)
>  b) various related lists like reset handlers, vmstate/savevm handlers might
> grow quite large
> 
> I think we could work around a) with maybe flagging certain
> "internally-only" objects as 'hidden'. Introspection routines could then
> filter these out, and routines like qom-set/qom-get could return report
> something similar to EACCESS so they are never used/useful to management
> tools.
> 
> In cases like b) we can optimize things where it makes sense like with
> Scott's patch here. In most cases these lists need to be walked one way
> or another, whether it's done internally by the object or through common
> interfaces provided by QEMU. It's really just the O(n^2) type handling
> where relying on common interfaces becomes drastically less efficient,
> but I think we should avoid implementing things in that way anyway, or
> improve them as needed.
> 
> > 
> > Is perhaps the structure wrong somewhere - should there be a single DRC
> > device that knows about all DRCs?
> 
> That's an interesting proposition, I think it's worth exploring further,
> but from a high level:
> 
>  - each SpaprDrc has migration state, and some sub-classes SpaprDrc (e.g.
>SpaprDrcPhysical) have additional migration state. These are sent
>as-needed as separate VMState entries in the migration stream.
>Moving to a single DRC means we're either sending them as an flat
>array or a sparse list, which would put just as much load on the
>migration code (at least, with Scott's changes in place). It would
>also be difficult to do all this in a way which maintains migration
>compatibility with older machine types.

Having sparse arrays etc within a vmstate isn't as bad; none of
them actually need to be 'objects' as such - even if you have
separate chunks of VMState.

>  - other aspects of modeling these as QOM objects, such as look-ups,
>reset-handling, and memory allocations, wouldn't be dramatically
>improved upon by handling it all internally within the object
> 
> AFAICT the biggest issue with modeling the DRCs as individual objects
> is actually how we deal with introspection, and we should try to
> improve. What do you think of the alternative suggestion above of
> marking certain objects as 'hidden' from various introspection
> interfaces?

That's one for someone who knows/cares about QOM more than me;
Paolo, Dan Berrange, or Eduardo Habkost are QOM people.

Dave

> > 
> > Dave
> > 
> > 
> > > https://github.com/qemu/qemu/blob/master/hw/ppc/spapr_drc.c
> > > 
> > > They are part of SPAPR 

[PATCH v2 2/2] spapr/xive: Set the OS CAM line at reset

2019-10-18 Thread Cédric Le Goater
When a Virtual Processor is scheduled to run on a HW thread, the
hypervisor pushes its identifier in the OS CAM line. When running with
kernel_irqchip=off, QEMU needs to emulate the same behavior.

Set the OS CAM line when the interrupt presenter of the sPAPR core is
reseted. This will also cover the case of hot-plugged CPUs.

This change also has the benefit to remove the use of CPU_FOREACH()
which can be unsafe.

Signed-off-by: Cédric Le Goater 
---
 include/hw/ppc/spapr_xive.h |  1 -
 hw/intc/spapr_xive.c| 18 +++---
 2 files changed, 3 insertions(+), 16 deletions(-)

diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index d84bd5c229f0..742b7e834f2a 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -57,7 +57,6 @@ typedef struct SpaprXive {
 void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
 
 void spapr_xive_hcall_init(SpaprMachineState *spapr);
-void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx);
 void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable);
 void spapr_xive_map_mmio(SpaprXive *xive);
 
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 258b1c5fb5ff..4f584e582b6c 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -210,7 +210,7 @@ void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool 
enable)
  * hypervisor pushes its identifier in the OS CAM line. Emulate the
  * same behavior under QEMU.
  */
-void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx)
+static void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx)
 {
 uint8_t  nvt_blk;
 uint32_t nvt_idx;
@@ -544,12 +544,6 @@ static int 
spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
 }
 
 spapr_cpu->tctx = XIVE_TCTX(obj);
-
-/*
- * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
- * don't beneficiate from the reset of the XIVE IRQ backend
- */
-spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
 return 0;
 }
 
@@ -557,6 +551,8 @@ static void 
spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
  PowerPCCPU *cpu)
 {
 xive_tctx_reset(spapr_cpu_state(cpu)->tctx);
+
+spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
 }
 
 static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int 
val)
@@ -649,14 +645,6 @@ static void spapr_xive_dt(SpaprInterruptController *intc, 
uint32_t nr_servers,
 static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
 {
 SpaprXive *xive = SPAPR_XIVE(intc);
-CPUState *cs;
-
-CPU_FOREACH(cs) {
-PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-/* (TCG) Set the OS CAM line of the thread interrupt context. */
-spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
-}
 
 if (kvm_enabled()) {
 int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp);
-- 
2.21.0




[PATCH v2 0/2] spapr: interrupt presenter fixes

2019-10-18 Thread Cédric Le Goater
Hello,

The interrupt presenters are created by a machine handler at the core
level and are reseted independently. This is not consistent and it
raises some issues when it comes to handle hot-plugged CPUs. These are
reseted from the realize handler of the core and the presenters are
not. This is less of an issue in XICS, although a zero MFFR could be a
concern, but in XIVE, the OS CAM line is not set and this breaks the
presenting algorithm. The current code has workarounds which need a
global cleanup.

Extend the sPAPR IRQ backend with a new cpu_intc_reset() handler which
will be called by the CPU reset handler and remove the XiveTCTX reset
handler which is redundant.

Set the OS CAM line when the interrupt presenter of the sPAPR core is
reseted. This will also cover the case of hot-plugged CPUs.


These changes do not address the root problem: the reset of the core
at realize time which hides the fact that hot-plugged CPUs are not
reseted. Anyhow, they do fix the presenter reset and remove a
workaround of workaround in the case of XIVE.

Thanks,

C.

Changes inv v2:

 - removed property
 - simplified reset handlers

Cédric Le Goater (2):
  spapr: Introduce a interrupt presenter reset handler
  spapr/xive: Set the OS CAM line at reset

 include/hw/ppc/spapr_irq.h  |  2 ++
 include/hw/ppc/spapr_xive.h |  1 -
 include/hw/ppc/xics.h   |  1 +
 include/hw/ppc/xive.h   |  1 +
 hw/intc/spapr_xive.c| 25 ++---
 hw/intc/xics.c  |  8 ++--
 hw/intc/xics_spapr.c|  7 +++
 hw/intc/xive.c  | 12 +---
 hw/ppc/spapr_cpu_core.c | 14 ++
 hw/ppc/spapr_irq.c  | 14 ++
 10 files changed, 48 insertions(+), 37 deletions(-)

-- 
2.21.0




[PATCH v2 1/2] spapr: Introduce a interrupt presenter reset handler

2019-10-18 Thread Cédric Le Goater
The interrupt presenters are created by a machine handler at the core
level and are reseted independently. This is not consistent and it
raises some issues when it comes to handle hot-plugged CPUs. These are
reseted from the realize handler of the core and the presenters are
not. This is less of an issue in XICS, although a zero MFFR could be a
concern, but in XIVE, the OS CAM line is not set and this breaks the
presenting algorithm. The current code has workarounds which need a
global cleanup.

Extend the sPAPR IRQ backend with a new cpu_intc_reset() handler which
will be called by the CPU reset handler and remove the XiveTCTX reset
handler which is redundant.

spapr_realize_vcpu() is modified to call the CPU reset only after the
intc presenter has been created.

Signed-off-by: Cédric Le Goater 
---

 The change of order of the CPU reset and the intc creation could be
 in its own patch for bisect. This is fragile.
 
 include/hw/ppc/spapr_irq.h |  2 ++
 include/hw/ppc/xics.h  |  1 +
 include/hw/ppc/xive.h  |  1 +
 hw/intc/spapr_xive.c   |  7 +++
 hw/intc/xics.c |  8 ++--
 hw/intc/xics_spapr.c   |  7 +++
 hw/intc/xive.c | 12 +---
 hw/ppc/spapr_cpu_core.c| 14 ++
 hw/ppc/spapr_irq.c | 14 ++
 9 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 5e150a667902..09232999b07e 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -52,6 +52,7 @@ typedef struct SpaprInterruptControllerClass {
  */
 int (*cpu_intc_create)(SpaprInterruptController *intc,
 PowerPCCPU *cpu, Error **errp);
+void (*cpu_intc_reset)(SpaprInterruptController *intc, PowerPCCPU *cpu);
 int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
  Error **errp);
 void (*free_irq)(SpaprInterruptController *intc, int irq);
@@ -68,6 +69,7 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr);
 
 int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
   PowerPCCPU *cpu, Error **errp);
+void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu);
 void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
 void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
   void *fdt, uint32_t phandle);
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 1e6a9300eb2b..602173c12250 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -161,6 +161,7 @@ void icp_set_mfrr(ICPState *icp, uint8_t mfrr);
 uint32_t icp_accept(ICPState *ss);
 uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
 void icp_eoi(ICPState *icp, uint32_t xirr);
+void icp_reset(ICPState *icp);
 
 void ics_write_xive(ICSState *ics, int nr, int server,
 uint8_t priority, uint8_t saved_priority);
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index fd3319bd3202..99381639f50c 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -415,6 +415,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, 
unsigned size);
 
 void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
 Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
+void xive_tctx_reset(XiveTCTX *tctx);
 
 static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
 {
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index ba32d2cc5b0f..258b1c5fb5ff 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -553,6 +553,12 @@ static int 
spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
 return 0;
 }
 
+static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
+ PowerPCCPU *cpu)
+{
+xive_tctx_reset(spapr_cpu_state(cpu)->tctx);
+}
+
 static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int 
val)
 {
 SpaprXive *xive = SPAPR_XIVE(intc);
@@ -697,6 +703,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void 
*data)
 sicc->activate = spapr_xive_activate;
 sicc->deactivate = spapr_xive_deactivate;
 sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
+sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset;
 sicc->claim_irq = spapr_xive_claim_irq;
 sicc->free_irq = spapr_xive_free_irq;
 sicc->set_irq = spapr_xive_set_irq;
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index b5ac408f7b74..6da05763f9db 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -274,10 +274,8 @@ static const VMStateDescription vmstate_icp_server = {
 },
 };
 
-static void icp_reset_handler(void *dev)
+void icp_reset(ICPState *icp)
 {
-ICPState *icp = ICP(dev);
-
 icp->xirr = 0;
 icp->pending_priority = 0xff;
 icp->mfrr = 0xff;
@@ -288,7 +286,7 @@ static void icp_reset_handler(void *dev)
 if (kvm_irqchip_in_kernel()) {
 Error *local_err = NULL;
 
-

  1   2   3   4   5   >