[Bug 1885247] [NEW] Build error in Intel 32-bit hosts

2020-06-26 Thread Aleksandar Markovic
Public bug reported:

The code base is on master, checked out on Thursday June25th 2020,
0250c595c9d. The build procedure:

$ mkdir build-gcc
$ cd build-gcc
$ ../configure
$ make

The build error message is:

  CC  x86_64-softmmu/hw/hyperv/hyperv.o
  CC  x86_64-softmmu/hw/hyperv/hyperv_testdev.o
  CC  x86_64-softmmu/hw/hyperv/vmbus.o
/home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c: In function ‘gpadl_iter_io’:
/home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c:386:13: error: cast to pointer 
from integer of different size [-Werror=int-to-pointer-cast]
 p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) | off_in_page);
 ^
cc1: all warnings being treated as errors
make[1]: *** [/home/rtrk/Build/qemu-master/rules.mak:69: hw/hyperv/vmbus.o] 
Error 1
make: *** [Makefile:527: x86_64-softmmu/all] Error 2

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  Build error in Intel 32-bit hosts

Status in QEMU:
  New

Bug description:
  The code base is on master, checked out on Thursday June25th 2020,
  0250c595c9d. The build procedure:

  $ mkdir build-gcc
  $ cd build-gcc
  $ ../configure
  $ make

  The build error message is:

CC  x86_64-softmmu/hw/hyperv/hyperv.o
CC  x86_64-softmmu/hw/hyperv/hyperv_testdev.o
CC  x86_64-softmmu/hw/hyperv/vmbus.o
  /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c: In function ‘gpadl_iter_io’:
  /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c:386:13: error: cast to pointer 
from integer of different size [-Werror=int-to-pointer-cast]
   p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) | 
off_in_page);
   ^
  cc1: all warnings being treated as errors
  make[1]: *** [/home/rtrk/Build/qemu-master/rules.mak:69: hw/hyperv/vmbus.o] 
Error 1
  make: *** [Makefile:527: x86_64-softmmu/all] Error 2

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



Re: [PATCH v2 00/22] ADB: fix autopoll issues and rework mac_via state machine

2020-06-26 Thread Laurent Vivier
Le 23/06/2020 à 22:49, Mark Cave-Ayland a écrit :
> This patchset is something I have been chipping away at for a while since
> spending some time over the Christmas holidays trying to boot the MacOS
> toolbox ROM on the new q800 machine.
> 
> Initially I discovered that there were some problems when the MacOS ROM was
> enumerating ADB devices due to multiple meanings of the vADBInt bit. After
> fixing this there were still issues with keys being dropped during autopoll
> which were eventually traced back to the autopoll timer re-firing before
> the host had managed to read back the previous response.
> 
> At this point I noticed that CUDA/PMU/mac_via all had their own 
> implementations
> of ADB autopoll, and that it would make sense to consolidate the autopoll 
> timer,
> mask, interval and locking into the ADB bus. This would allow the logic to be
> removed from each separate device and managed in just one place.
> 
> Finally I updated the trace-events to allow separate tracing of bus requests
> and device responses which makes it easier to follow the ADB enumeration 
> process.
> 
> The breakdown of the patchset is as follows:
> 
> - Patch 1 keeps checkpatch happy for the remainder of the patchset whilst 
> patch
>   2 is the proper fix for a spurious ADB register 3 write during enumeration
>   caused by ignoring the request length which I had tried to work around 
> earlier.
> 
> - Patches 3 to 10 are part of the autopoll consolidation process which moves 
> the
>   separate autopoll implementations into a single implementation within
>   ADBBusState.
> 
> - Patches 11 to 13 update the ADB implementation to hold a status variable
>   indicating the result of the last request and allow devices to indicate
>   whether they have data to send. This extra information is required by the
>   upcoming mac_via state machine changes.
> 
> - Patches 14 to 17 add a variable and functions to block and unblock ADB
>   autopoll at bus level, adding the functions at the correct places within
>   CUDA and PMU.
> 
> - Patches 18 and 19 rework the mac_via ADB state machine so that the bus
>   can be enumerated correctly, and both explicit and autopoll requests work
>   under both MacOS and Linux.
> 
> - Patch 20 enforces the blocking and unblocking of autopoll at the ADB
>   level, including adding an assert() to prevent developers from trying to
>   make an ADB request whilst autopoll is in progress.
>   
> - Patches 21 and 22 update the trace-events to separate out ADB device and
>   ADB bus events.
> 
> The patch has been tested by myself and a couple of others during the 
> development
> process across the PPC g3beige/mac99 and 68K q800 machine so it should be 
> quite
> solid.
> 
> One thing to indicate is that the patchset bumps the VMState versions for the
> affected devices but does not allow older versions to load. This is a 
> conscious
> decision given that for the mac_via device used in the q800 machine it would 
> be
> just about impossible to map this in a way that would work for all cases. 
> Similarly
> for the Mac PPC machines migration is already hit/miss due to timebase issues 
> so
> I don't see this as being a big loss.
> 
> To finish off I'd also like to say a big thank-you to both Laurent Vivier and
> Finn Thain who both took time to answer my questions, dump information from a
> real q800, and analyse it in very fine detail. Without them this patchset 
> would
> still be several months away.
> 
> Signed-off-by: Mark Cave-Ayland 
> 
> 
> v2:
> - Rebased onto master
> - Added R-B tags from Philippe
> - Fixed byte discrepency at end of bus timeout spotted by Finn
> - Added Tested-by tag from Finn
> 
> 
> Mark Cave-Ayland (22):
>   adb: coding style update to fix checkpatch errors
>   adb: fix adb-mouse read length and revert disable-reg3-direct-writes
> workaround
>   cuda: convert ADB autopoll timer from ns to ms
>   pmu: fix duplicate autopoll mask variable
>   pmu: honour autopoll_rate_ms when rearming the ADB autopoll timer
>   adb: introduce realize/unrealize and VMStateDescription for ADB bus
>   adb: create autopoll variables directly within ADBBusState
>   cuda: convert to use ADBBusState internal autopoll variables
>   pmu: convert to use ADBBusState internal autopoll variables
>   mac_via: convert to use ADBBusState internal autopoll variables
>   adb: introduce new ADBDeviceHasData method to ADBDeviceClass
>   adb: keep track of devices with pending data
>   adb: add status field for holding information about the last ADB
> request
>   adb: use adb_request() only for explicit requests
>   adb: add autopoll_blocked variable to block autopoll
>   cuda: add adb_autopoll_block() and adb_autopoll_unblock() functions
>   pmu: add adb_autopoll_block() and adb_autopoll_unblock() functions
>   mac_via: move VIA1 portB write logic into mos6522_q800_via1_write()
>   mac_via: rework ADB state machine to be compatible with both MacOS and
> Linux
>   adb: only call autopoll callbacks when a

[PATCH v5 01/21] pc: Support coldplugging of virtio-pmem-pci devices on all buses

2020-06-26 Thread David Hildenbrand
E.g., with "pc-q35-4.2", trying to coldplug a virtio-pmem-pci devices
results in
"virtio-pmem-pci not supported on this bus"

Reasons is, that the bus does not support hotplug and, therefore, does
not have a hotplug handler. Let's allow coldplugging virtio-pmem devices
on such buses. The hotplug order is only relevant for virtio-pmem-pci
when the guest is already alive and the device is visible before
memory_device_plug() wired up the memory device bits.

Hotplug attempts will still fail with:
"Error: Bus 'pcie.0' does not support hotplugging"

Hotunplug attempts will still fail with:
"Error: Bus 'pcie.0' does not support hotplugging"

Reported-by: Vivek Goyal 
Reviewed-by: Pankaj Gupta 
Cc: Pankaj Gupta 
Cc: Igor Mammedov 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Signed-off-by: David Hildenbrand 
---
 hw/i386/pc.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 803bd52ca4..2dfd69b973 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1643,13 +1643,13 @@ static void pc_virtio_pmem_pci_pre_plug(HotplugHandler 
*hotplug_dev,
 HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
 Error *local_err = NULL;
 
-if (!hotplug_dev2) {
+if (!hotplug_dev2 && dev->hotplugged) {
 /*
  * Without a bus hotplug handler, we cannot control the plug/unplug
- * order. This should never be the case on x86, however better add
- * a safety net.
+ * order. We should never reach this point when hotplugging on x86,
+ * however, better add a safety net.
  */
-error_setg(errp, "virtio-pmem-pci not supported on this bus.");
+error_setg(errp, "virtio-pmem-pci hotplug not supported on this bus.");
 return;
 }
 /*
@@ -1658,7 +1658,7 @@ static void pc_virtio_pmem_pci_pre_plug(HotplugHandler 
*hotplug_dev,
  */
 memory_device_pre_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev), NULL,
&local_err);
-if (!local_err) {
+if (!local_err && hotplug_dev2) {
 hotplug_handler_pre_plug(hotplug_dev2, dev, &local_err);
 }
 error_propagate(errp, local_err);
@@ -1676,9 +1676,11 @@ static void pc_virtio_pmem_pci_plug(HotplugHandler 
*hotplug_dev,
  * device bits.
  */
 memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
-hotplug_handler_plug(hotplug_dev2, dev, &local_err);
-if (local_err) {
-memory_device_unplug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
+if (hotplug_dev2) {
+hotplug_handler_plug(hotplug_dev2, dev, &local_err);
+if (local_err) {
+memory_device_unplug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
+}
 }
 error_propagate(errp, local_err);
 }
-- 
2.26.2




[PATCH v5 02/21] exec: Introduce ram_block_discard_(disable|require)()

2020-06-26 Thread David Hildenbrand
We want to replace qemu_balloon_inhibit() by something more generic.
Especially, we want to make sure that technologies that really rely on
RAM block discards to work reliably to run mutual exclusive with
technologies that effectively break it.

E.g., vfio will usually pin all guest memory, turning the virtio-balloon
basically useless and make the VM consume more memory than reported via
the balloon. While the balloon is special already (=> no guarantees, same
behavior possible afer reboots and with huge pages), this will be
different, especially, with virtio-mem.

Let's implement a way such that we can make both types of technology run
mutually exclusive. We'll convert existing balloon inhibitors in successive
patches and add some new ones. Add the check to
qemu_balloon_is_inhibited() for now. We might want to make
virtio-balloon an acutal inhibitor in the future - however, that
requires more thought to not break existing setups.

Reviewed-by: Dr. David Alan Gilbert 
Cc: "Michael S. Tsirkin" 
Cc: Richard Henderson 
Cc: Paolo Bonzini 
Signed-off-by: David Hildenbrand 
---
 balloon.c |  3 ++-
 exec.c| 52 +++
 include/exec/memory.h | 41 ++
 3 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/balloon.c b/balloon.c
index f104b42961..5fff79523a 100644
--- a/balloon.c
+++ b/balloon.c
@@ -40,7 +40,8 @@ static int balloon_inhibit_count;
 
 bool qemu_balloon_is_inhibited(void)
 {
-return atomic_read(&balloon_inhibit_count) > 0;
+return atomic_read(&balloon_inhibit_count) > 0 ||
+   ram_block_discard_is_disabled();
 }
 
 void qemu_balloon_inhibit(bool state)
diff --git a/exec.c b/exec.c
index d6712fba7e..b15187d9ab 100644
--- a/exec.c
+++ b/exec.c
@@ -4063,4 +4063,56 @@ void mtree_print_dispatch(AddressSpaceDispatch *d, 
MemoryRegion *root)
 }
 }
 
+/*
+ * If positive, discarding RAM is disabled. If negative, discarding RAM is
+ * required to work and cannot be disabled.
+ */
+static int ram_block_discard_disabled;
+
+int ram_block_discard_disable(bool state)
+{
+int old;
+
+if (!state) {
+atomic_dec(&ram_block_discard_disabled);
+return 0;
+}
+
+do {
+old = atomic_read(&ram_block_discard_disabled);
+if (old < 0) {
+return -EBUSY;
+}
+} while (atomic_cmpxchg(&ram_block_discard_disabled, old, old + 1) != old);
+return 0;
+}
+
+int ram_block_discard_require(bool state)
+{
+int old;
+
+if (!state) {
+atomic_inc(&ram_block_discard_disabled);
+return 0;
+}
+
+do {
+old = atomic_read(&ram_block_discard_disabled);
+if (old > 0) {
+return -EBUSY;
+}
+} while (atomic_cmpxchg(&ram_block_discard_disabled, old, old - 1) != old);
+return 0;
+}
+
+bool ram_block_discard_is_disabled(void)
+{
+return atomic_read(&ram_block_discard_disabled) > 0;
+}
+
+bool ram_block_discard_is_required(void)
+{
+return atomic_read(&ram_block_discard_disabled) < 0;
+}
+
 #endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 7207025bd4..38ec38b9a8 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -2472,6 +2472,47 @@ static inline MemOp devend_memop(enum device_endian end)
 }
 #endif
 
+/*
+ * Inhibit technologies that require discarding of pages in RAM blocks, e.g.,
+ * to manage the actual amount of memory consumed by the VM (then, the memory
+ * provided by RAM blocks might be bigger than the desired memory consumption).
+ * This *must* be set if:
+ * - Discarding parts of a RAM blocks does not result in the change being
+ *   reflected in the VM and the pages getting freed.
+ * - All memory in RAM blocks is pinned or duplicated, invaldiating any 
previous
+ *   discards blindly.
+ * - Discarding parts of a RAM blocks will result in integrity issues (e.g.,
+ *   encrypted VMs).
+ * Technologies that only temporarily pin the current working set of a
+ * driver are fine, because we don't expect such pages to be discarded
+ * (esp. based on guest action like balloon inflation).
+ *
+ * This is *not* to be used to protect from concurrent discards (esp.,
+ * postcopy).
+ *
+ * Returns 0 if successful. Returns -EBUSY if a technology that relies on
+ * discards to work reliably is active.
+ */
+int ram_block_discard_disable(bool state);
+
+/*
+ * Inhibit technologies that disable discarding of pages in RAM blocks.
+ *
+ * Returns 0 if successful. Returns -EBUSY if discards are already set to
+ * broken.
+ */
+int ram_block_discard_require(bool state);
+
+/*
+ * Test if discarding of memory in ram blocks is disabled.
+ */
+bool ram_block_discard_is_disabled(void);
+
+/*
+ * Test if discarding of memory in ram blocks is required to work reliably.
+ */
+bool ram_block_discard_is_required(void);
+
 #endif
 
 #endif
-- 
2.26.2




[PATCH v5 00/21] virtio-mem: Paravirtualized memory hot(un)plug

2020-06-26 Thread David Hildenbrand
This is the very basic, initial version of virtio-mem. More info on
virtio-mem in general can be found in the Linux kernel driver v2 posting
[1] and in patch #10. The Linux driver is now upstream.

This series now contains a resend of [3]:
"[PATCH v1] pc: Support coldplugging of virtio-pmem-pci devices on all
 buses"

The patches can be found at:
https://github.com/davidhildenbrand/qemu.git virtio-mem-v5

"The basic idea of virtio-mem is to provide a flexible,
cross-architecture memory hot(un)plug solution that avoids many limitations
imposed by existing technologies, architectures, and interfaces."

There are a lot of addons in the works (esp. protection of unplugged
memory, better hugepage support (esp. when reading unplugged memory),
resizeable memory backends, support for more architectures, ...), this is
the very basic version to get the ball rolling.

The first patch is a resend. Patches #2-#9 make sure we don't have any
sudden surprises e.g., if somebody tries to pin all memory in RAM blocks,
resulting in a higher memory consumption than desired. The remaining
patches add basic virtio-mem along with support for x86-64. The last patch
indicates to the guest OS the maximum possible PFN using ACPI SRAT, such
that Linux can properly enable the swiotlb when booting only with DMA
memory.

[1] https://lkml.kernel.org/r/20200311171422.10484-1-da...@redhat.com
[2] https://lkml.kernel.org/r/20200507140139.17083-1-da...@redhat.com
[3] https://lkml.kernel.org/r/20200525084511.51379-1-da...@redhat.com
[3] https://lkml.kernel.org/r/20200610075153.33892-1-da...@redhat.com

Cc: teawater 
Cc: Pankaj Gupta 

v4 -> v5:
- Rebased, added acks/rb's
- "pc: Support coldplugging of virtio-pmem-pci devices on all buses"
-- Included it now, for simplicity
- "linux-headers: update to contain virtio-mem"
-- Dropped, because header changes are already upstream now
- "MAINTAINERS: Add myself as virtio-mem maintainer"
-- Reference status page

v3 -> v4
- Adapt to virtio-mem config layout change (block size now is 64bit)
- Added "numa: Auto-enable NUMA when any memory devices are possible"

v2 -> v3:
- Rebased on upstream/[3]
- "virtio-mem: Exclude unplugged memory during migration"
-- Added
- "virtio-mem: Paravirtualized memory hot(un)plug"
-- Simplify bitmap operations, find consecutive areas
-- Tweak error messages
-- Reshuffle some checks
-- Minor cleanups
- "accel/kvm: Convert to ram_block_discard_disable()"
- "target/i386: sev: Use ram_block_discard_disable()"
-- Keep asserts clean of functional things

v1 -> v2:
- Rebased to object_property_*() changes
- "exec: Introduce ram_block_discard_(disable|require)()"
-- Change the function names and rephrase/add comments
- "virtio-balloon: Rip out qemu_balloon_inhibit()"
-- Add and use "migration_in_incoming_postcopy()"
- "migration/rdma: Use ram_block_discard_disable()"
-- Add a comment regarding pin_all vs. !pin_all
- "virtio-mem: Paravirtualized memory hot(un)plug"
-- Replace virtio_mem_discard_inhibited() by
   migration_in_incoming_postcopy()
-- Drop some asserts
-- Drop virtio_mem_bad_request(), use virtio_error() directly, printing
   more information
-- Replace "Note: Discarding should never fail ..." comments by
   error_report()
-- Replace virtio_stw_p() by cpu_to_le16()
-- Drop migration_addr and migration_block_size
-- Minor cleanups
- "linux-headers: update to contain virtio-mem"
-- Updated to latest v4 in Linux
- General changes
-- Fixup the users of the renamed ram_block_discard_(disable|require)
-- Use "X: cannot disable RAM discard"-styled error messages
- Added
-- "virtio-mem: Migration sanity checks"
-- "virtio-mem: Add trace events"

David Hildenbrand (21):
  pc: Support coldplugging of virtio-pmem-pci devices on all buses
  exec: Introduce ram_block_discard_(disable|require)()
  vfio: Convert to ram_block_discard_disable()
  accel/kvm: Convert to ram_block_discard_disable()
  s390x/pv: Convert to ram_block_discard_disable()
  virtio-balloon: Rip out qemu_balloon_inhibit()
  target/i386: sev: Use ram_block_discard_disable()
  migration/rdma: Use ram_block_discard_disable()
  migration/colo: Use ram_block_discard_disable()
  virtio-mem: Paravirtualized memory hot(un)plug
  virtio-pci: Proxy for virtio-mem
  MAINTAINERS: Add myself as virtio-mem maintainer
  hmp: Handle virtio-mem when printing memory device info
  numa: Handle virtio-mem in NUMA stats
  pc: Support for virtio-mem-pci
  virtio-mem: Allow notifiers for size changes
  virtio-pci: Send qapi events when the virtio-mem size changes
  virtio-mem: Migration sanity checks
  virtio-mem: Add trace events
  virtio-mem: Exclude unplugged memory during migration
  numa: Auto-enable NUMA when any memory devices are possible

 MAINTAINERS|   9 +
 accel/kvm/kvm-all.c|   4 +-
 balloon.c  |  17 -
 exec.c |  52 ++
 hw/arm/virt.c  |   2 +
 hw/core/numa.c |  17 +-
 hw/i386/Kconfig|   1

[PATCH v5 03/21] vfio: Convert to ram_block_discard_disable()

2020-06-26 Thread David Hildenbrand
VFIO is (except devices without a physical IOMMU or some mediated devices)
incompatible with discarding of RAM. The kernel will pin basically all VM
memory. Let's convert to ram_block_discard_disable(), which can now
fail, in contrast to qemu_balloon_inhibit().

Leave "x-balloon-allowed" named as it is for now.

Reviewed-by: Tony Krowiak 
Acked-by: Cornelia Huck 
Cc: Cornelia Huck 
Cc: Alex Williamson 
Cc: Christian Borntraeger 
Cc: Tony Krowiak 
Cc: Halil Pasic 
Cc: Pierre Morel 
Cc: Eric Farman 
Signed-off-by: David Hildenbrand 
---
 hw/vfio/ap.c  |  8 +++---
 hw/vfio/ccw.c | 11 
 hw/vfio/common.c  | 53 +++
 hw/vfio/pci.c |  6 ++--
 include/hw/vfio/vfio-common.h |  4 +--
 5 files changed, 44 insertions(+), 38 deletions(-)

diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 95564c17ed..b9330a8e6f 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -105,12 +105,12 @@ static void vfio_ap_realize(DeviceState *dev, Error 
**errp)
 vapdev->vdev.dev = dev;
 
 /*
- * vfio-ap devices operate in a way compatible with
- * memory ballooning, as no pages are pinned in the host.
+ * vfio-ap devices operate in a way compatible with discarding of
+ * memory in RAM blocks, as no pages are pinned in the host.
  * This needs to be set before vfio_get_device() for vfio common to
- * handle the balloon inhibitor.
+ * handle ram_block_discard_disable().
  */
-vapdev->vdev.balloon_allowed = true;
+vapdev->vdev.ram_block_discard_allowed = true;
 
 ret = vfio_get_device(vfio_group, mdevid, &vapdev->vdev, errp);
 if (ret) {
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 06e69d7066..ff7f369779 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -574,12 +574,13 @@ static void vfio_ccw_get_device(VFIOGroup *group, 
VFIOCCWDevice *vcdev,
 
 /*
  * All vfio-ccw devices are believed to operate in a way compatible with
- * memory ballooning, ie. pages pinned in the host are in the current
- * working set of the guest driver and therefore never overlap with pages
- * available to the guest balloon driver.  This needs to be set before
- * vfio_get_device() for vfio common to handle the balloon inhibitor.
+ * discarding of memory in RAM blocks, ie. pages pinned in the host are
+ * in the current working set of the guest driver and therefore never
+ * overlap e.g., with pages available to the guest balloon driver.  This
+ * needs to be set before vfio_get_device() for vfio common to handle
+ * ram_block_discard_disable().
  */
-vcdev->vdev.balloon_allowed = true;
+vcdev->vdev.ram_block_discard_allowed = true;
 
 if (vfio_get_device(group, vcdev->cdev.mdevid, &vcdev->vdev, errp)) {
 goto out_err;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 0b3593b3c0..33357140b8 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -33,7 +33,6 @@
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 #include "qemu/range.h"
-#include "sysemu/balloon.h"
 #include "sysemu/kvm.h"
 #include "sysemu/reset.h"
 #include "trace.h"
@@ -1215,31 +1214,36 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 space = vfio_get_address_space(as);
 
 /*
- * VFIO is currently incompatible with memory ballooning insofar as the
+ * VFIO is currently incompatible with discarding of RAM insofar as the
  * madvise to purge (zap) the page from QEMU's address space does not
  * interact with the memory API and therefore leaves stale virtual to
  * physical mappings in the IOMMU if the page was previously pinned.  We
- * therefore add a balloon inhibit for each group added to a container,
+ * therefore set discarding broken for each group added to a container,
  * whether the container is used individually or shared.  This provides
  * us with options to allow devices within a group to opt-in and allow
- * ballooning, so long as it is done consistently for a group (for instance
+ * discarding, so long as it is done consistently for a group (for instance
  * if the device is an mdev device where it is known that the host vendor
  * driver will never pin pages outside of the working set of the guest
- * driver, which would thus not be ballooning candidates).
+ * driver, which would thus not be discarding candidates).
  *
  * The first opportunity to induce pinning occurs here where we attempt to
  * attach the group to existing containers within the AddressSpace.  If any
- * pages are already zapped from the virtual address space, such as from a
- * previous ballooning opt-in, new pinning will cause valid mappings to be
+ * pages are already zapped from the virtual address space, such as from
+ * previous discards, new pinning will cause valid mappings to be
  * re-established.  Likewise, when the overall MemoryListener for a new

[PATCH v5 10/21] virtio-mem: Paravirtualized memory hot(un)plug

2020-06-26 Thread David Hildenbrand
This is the very basic/initial version of virtio-mem. An introduction to
virtio-mem can be found in the Linux kernel driver [1]. While it can be
used in the current state for hotplug of a smaller amount of memory, it
will heavily benefit from resizeable memory regions in the future.

Each virtio-mem device manages a memory region (provided via a memory
backend). After requested by the hypervisor ("requested-size"), the
guest can try to plug/unplug blocks of memory within that region, in order
to reach the requested size. Initially, and after a reboot, all memory is
unplugged (except in special cases - reboot during postcopy).

The guest may only try to plug/unplug blocks of memory within the usable
region size. The usable region size is a little bigger than the
requested size, to give the device driver some flexibility. The usable
region size will only grow, except on reboots or when all memory is
requested to get unplugged. The guest can never plug more memory than
requested. Unplugged memory will get zapped/discarded, similar to in a
balloon device.

The block size is variable, however, it is always chosen in a way such that
THP splits are avoided (e.g., 2MB). The state of each block
(plugged/unplugged) is tracked in a bitmap.

As virtio-mem devices (e.g., virtio-mem-pci) will be memory devices, we now
expose "VirtioMEMDeviceInfo" via "query-memory-devices".

--

There are two important follow-up items that are in the works:
1. Resizeable memory regions: Use resizeable allocations/RAM blocks to
   grow/shrink along with the usable region size. This avoids creating
   initially very big VMAs, RAM blocks, and KVM slots.
2. Protection of unplugged memory: Make sure the gust cannot actually
   make use of unplugged memory.

Other follow-up items that are in the works:
1. Exclude unplugged memory during migration (via precopy notifier).
2. Handle remapping of memory.
3. Support for other architectures.

--

Example usage (virtio-mem-pci is introduced in follow-up patches):

Start QEMU with two virtio-mem devices (one per NUMA node):
 $ qemu-system-x86_64 -m 4G,maxmem=20G \
  -smp sockets=2,cores=2 \
  -numa node,nodeid=0,cpus=0-1 -numa node,nodeid=1,cpus=2-3 \
  [...]
  -object memory-backend-ram,id=mem0,size=8G \
  -device virtio-mem-pci,id=vm0,memdev=mem0,node=0,requested-size=0M \
  -object memory-backend-ram,id=mem1,size=8G \
  -device virtio-mem-pci,id=vm1,memdev=mem1,node=1,requested-size=1G

Query the configuration:
 (qemu) info memory-devices
 Memory device [virtio-mem]: "vm0"
   memaddr: 0x14000
   node: 0
   requested-size: 0
   size: 0
   max-size: 8589934592
   block-size: 2097152
   memdev: /objects/mem0
 Memory device [virtio-mem]: "vm1"
   memaddr: 0x34000
   node: 1
   requested-size: 1073741824
   size: 1073741824
   max-size: 8589934592
   block-size: 2097152
   memdev: /objects/mem1

Add some memory to node 0:
 (qemu) qom-set vm0 requested-size 500M

Remove some memory from node 1:
 (qemu) qom-set vm1 requested-size 200M

Query the configuration again:
 (qemu) info memory-devices
 Memory device [virtio-mem]: "vm0"
   memaddr: 0x14000
   node: 0
   requested-size: 524288000
   size: 524288000
   max-size: 8589934592
   block-size: 2097152
   memdev: /objects/mem0
 Memory device [virtio-mem]: "vm1"
   memaddr: 0x34000
   node: 1
   requested-size: 209715200
   size: 209715200
   max-size: 8589934592
   block-size: 2097152
   memdev: /objects/mem1

[1] https://lkml.kernel.org/r/20200311171422.10484-1-da...@redhat.com

Cc: "Michael S. Tsirkin" 
Cc: Eric Blake 
Cc: Markus Armbruster 
Cc: "Dr. David Alan Gilbert" 
Cc: Igor Mammedov 
Signed-off-by: David Hildenbrand 
---
 hw/virtio/Kconfig  |  11 +
 hw/virtio/Makefile.objs|   1 +
 hw/virtio/virtio-mem.c | 724 +
 include/hw/virtio/virtio-mem.h |  78 
 qapi/misc.json |  39 +-
 5 files changed, 852 insertions(+), 1 deletion(-)
 create mode 100644 hw/virtio/virtio-mem.c
 create mode 100644 include/hw/virtio/virtio-mem.h

diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index 83122424fa..0eda25c4e1 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -47,3 +47,14 @@ config VIRTIO_PMEM
 depends on VIRTIO
 depends on VIRTIO_PMEM_SUPPORTED
 select MEM_DEVICE
+
+config VIRTIO_MEM_SUPPORTED
+bool
+
+config VIRTIO_MEM
+bool
+default y
+depends on VIRTIO
+depends on LINUX
+depends on VIRTIO_MEM_SUPPORTED
+select MEM_DEVICE
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 13e75f171f..f3a65e01b7 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -19,6 +19,7 @@ obj-$(call land,$(CONFIG_VHOST_USER_FS),$(CONFIG_VIRTIO_PCI)) 
+= vhost-user-fs-p
 obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
 obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock-common.o vhost

[PATCH v5 09/21] migration/colo: Use ram_block_discard_disable()

2020-06-26 Thread David Hildenbrand
COLO will copy all memory in a RAM block, disable discarding of RAM.

Reviewed-by: Dr. David Alan Gilbert 
Tested-by: Lukas Straub 
Cc: "Michael S. Tsirkin" 
Cc: Hailiang Zhang 
Cc: Juan Quintela 
Cc: "Dr. David Alan Gilbert" 
Signed-off-by: David Hildenbrand 
---
 include/migration/colo.h |  2 +-
 migration/migration.c|  8 +++-
 migration/savevm.c   | 11 +--
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/include/migration/colo.h b/include/migration/colo.h
index 1636e6f907..768e1f04c3 100644
--- a/include/migration/colo.h
+++ b/include/migration/colo.h
@@ -25,7 +25,7 @@ void migrate_start_colo_process(MigrationState *s);
 bool migration_in_colo_state(void);
 
 /* loadvm */
-void migration_incoming_enable_colo(void);
+int migration_incoming_enable_colo(void);
 void migration_incoming_disable_colo(void);
 bool migration_incoming_colo_enabled(void);
 void *colo_process_incoming_thread(void *opaque);
diff --git a/migration/migration.c b/migration/migration.c
index d365d82209..92e44e021e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -338,12 +338,18 @@ bool migration_incoming_colo_enabled(void)
 
 void migration_incoming_disable_colo(void)
 {
+ram_block_discard_disable(false);
 migration_colo_enabled = false;
 }
 
-void migration_incoming_enable_colo(void)
+int migration_incoming_enable_colo(void)
 {
+if (ram_block_discard_disable(true)) {
+error_report("COLO: cannot disable RAM discard");
+return -EBUSY;
+}
 migration_colo_enabled = true;
+return 0;
 }
 
 void migrate_add_address(SocketAddress *address)
diff --git a/migration/savevm.c b/migration/savevm.c
index b979ea6e7f..6e01724605 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2111,8 +2111,15 @@ static int 
loadvm_handle_recv_bitmap(MigrationIncomingState *mis,
 
 static int loadvm_process_enable_colo(MigrationIncomingState *mis)
 {
-migration_incoming_enable_colo();
-return colo_init_ram_cache();
+int ret = migration_incoming_enable_colo();
+
+if (!ret) {
+ret = colo_init_ram_cache();
+if (ret) {
+migration_incoming_disable_colo();
+}
+}
+return ret;
 }
 
 /*
-- 
2.26.2




[PATCH v5 06/21] virtio-balloon: Rip out qemu_balloon_inhibit()

2020-06-26 Thread David Hildenbrand
The only remaining special case is postcopy. It cannot handle
concurrent discards yet, which would result in requesting already sent
pages from the source. Special-case it in virtio-balloon instead.

Introduce migration_in_incoming_postcopy(), to find out if incoming
postcopy is active.

Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Michael S. Tsirkin 
Cc: "Michael S. Tsirkin" 
Cc: Juan Quintela 
Cc: "Dr. David Alan Gilbert" 
Signed-off-by: David Hildenbrand 
---
 balloon.c  | 18 --
 hw/virtio/virtio-balloon.c | 10 --
 include/migration/misc.h   |  2 ++
 include/sysemu/balloon.h   |  2 --
 migration/migration.c  |  7 +++
 migration/postcopy-ram.c   | 23 ---
 6 files changed, 17 insertions(+), 45 deletions(-)

diff --git a/balloon.c b/balloon.c
index 5fff79523a..354408c6ea 100644
--- a/balloon.c
+++ b/balloon.c
@@ -36,24 +36,6 @@
 static QEMUBalloonEvent *balloon_event_fn;
 static QEMUBalloonStatus *balloon_stat_fn;
 static void *balloon_opaque;
-static int balloon_inhibit_count;
-
-bool qemu_balloon_is_inhibited(void)
-{
-return atomic_read(&balloon_inhibit_count) > 0 ||
-   ram_block_discard_is_disabled();
-}
-
-void qemu_balloon_inhibit(bool state)
-{
-if (state) {
-atomic_inc(&balloon_inhibit_count);
-} else {
-atomic_dec(&balloon_inhibit_count);
-}
-
-assert(atomic_read(&balloon_inhibit_count) >= 0);
-}
 
 static bool have_balloon(Error **errp)
 {
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 10507b2a43..5faa9de558 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -63,6 +63,12 @@ static bool 
virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp,
 return pbp->base_gpa == base_gpa;
 }
 
+static bool virtio_balloon_inhibited(void)
+{
+/* Postcopy cannot deal with concurrent discards, so it's special. */
+return ram_block_discard_is_disabled() || migration_in_incoming_postcopy();
+}
+
 static void balloon_inflate_page(VirtIOBalloon *balloon,
  MemoryRegion *mr, hwaddr mr_offset,
  PartiallyBalloonedPage *pbp)
@@ -336,7 +342,7 @@ static void virtio_balloon_handle_report(VirtIODevice 
*vdev, VirtQueue *vq)
  * accessible by another device or process, or if the guest is
  * expecting it to retain a non-zero value.
  */
-if (qemu_balloon_is_inhibited() || dev->poison_val) {
+if (virtio_balloon_inhibited() || dev->poison_val) {
 goto skip_element;
 }
 
@@ -421,7 +427,7 @@ static void virtio_balloon_handle_output(VirtIODevice 
*vdev, VirtQueue *vq)
 
 trace_virtio_balloon_handle_output(memory_region_name(section.mr),
pa);
-if (!qemu_balloon_is_inhibited()) {
+if (!virtio_balloon_inhibited()) {
 if (vq == s->ivq) {
 balloon_inflate_page(s, section.mr,
  section.offset_within_region, &pbp);
diff --git a/include/migration/misc.h b/include/migration/misc.h
index d2762257aa..34e7d75713 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -69,6 +69,8 @@ bool migration_has_failed(MigrationState *);
 /* ...and after the device transmission */
 bool migration_in_postcopy_after_devices(MigrationState *);
 void migration_global_dump(Monitor *mon);
+/* True if incomming migration entered POSTCOPY_INCOMING_DISCARD */
+bool migration_in_incoming_postcopy(void);
 
 /* migration/block-dirty-bitmap.c */
 void dirty_bitmap_mig_init(void);
diff --git a/include/sysemu/balloon.h b/include/sysemu/balloon.h
index aea0c44985..20a2defe3a 100644
--- a/include/sysemu/balloon.h
+++ b/include/sysemu/balloon.h
@@ -23,7 +23,5 @@ typedef void (QEMUBalloonStatus)(void *opaque, BalloonInfo 
*info);
 int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
  QEMUBalloonStatus *stat_func, void *opaque);
 void qemu_remove_balloon_handler(void *opaque);
-bool qemu_balloon_is_inhibited(void);
-void qemu_balloon_inhibit(bool state);
 
 #endif
diff --git a/migration/migration.c b/migration/migration.c
index 481a590f72..d365d82209 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1772,6 +1772,13 @@ bool migration_in_postcopy_after_devices(MigrationState 
*s)
 return migration_in_postcopy() && s->postcopy_after_devices;
 }
 
+bool migration_in_incoming_postcopy(void)
+{
+PostcopyState ps = postcopy_state_get();
+
+return ps >= POSTCOPY_INCOMING_DISCARD && ps < POSTCOPY_INCOMING_END;
+}
+
 bool migration_is_idle(void)
 {
 MigrationState *s = current_migration;
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index a36402722b..b41a9fe2fd 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -27,7 +27,6 @@
 #include "qemu/notify.h"
 #include "qemu/rcu.h"
 #include "sysemu/sysemu.h"
-

[PATCH v5 04/21] accel/kvm: Convert to ram_block_discard_disable()

2020-06-26 Thread David Hildenbrand
Discarding memory does not work as expected. At the time this is called,
we cannot have anyone active that relies on discards to work properly.

Reviewed-by: Dr. David Alan Gilbert 
Cc: Paolo Bonzini 
Signed-off-by: David Hildenbrand 
---
 accel/kvm/kvm-all.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f24d7da783..4751ce67a9 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -40,7 +40,6 @@
 #include "trace.h"
 #include "hw/irq.h"
 #include "sysemu/sev.h"
-#include "sysemu/balloon.h"
 #include "qapi/visitor.h"
 #include "qapi/qapi-types-common.h"
 #include "qapi/qapi-visit-common.h"
@@ -,7 +2221,8 @@ static int kvm_init(MachineState *ms)
 
 s->sync_mmu = !!kvm_vm_check_extension(kvm_state, KVM_CAP_SYNC_MMU);
 if (!s->sync_mmu) {
-qemu_balloon_inhibit(true);
+ret = ram_block_discard_disable(true);
+assert(!ret);
 }
 
 return 0;
-- 
2.26.2




[PATCH v5 12/21] MAINTAINERS: Add myself as virtio-mem maintainer

2020-06-26 Thread David Hildenbrand
Let's make sure patches/bug reports find the right person.

Reviewed-by: Dr. David Alan Gilbert 
Cc: "Michael S. Tsirkin" 
Cc: Peter Maydell 
Cc: Markus Armbruster 
Signed-off-by: David Hildenbrand 
---
 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1b40446c73..3f7f583436 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1784,6 +1784,15 @@ F: hw/virtio/virtio-crypto.c
 F: hw/virtio/virtio-crypto-pci.c
 F: include/hw/virtio/virtio-crypto.h
 
+virtio-mem
+M: David Hildenbrand 
+S: Supported
+W: https://virtio-mem.gitlab.io/
+F: hw/virtio/virtio-mem.c
+F: hw/virtio/virtio-mem-pci.h
+F: hw/virtio/virtio-mem-pci.c
+F: include/hw/virtio/virtio-mem.h
+
 nvme
 M: Keith Busch 
 L: qemu-bl...@nongnu.org
-- 
2.26.2




[PATCH v5 07/21] target/i386: sev: Use ram_block_discard_disable()

2020-06-26 Thread David Hildenbrand
AMD SEV will pin all guest memory, mark discarding of RAM broken. At the
time this is called, we cannot have anyone active that relies on discards
to work properly - let's still implement error handling.

Reviewed-by: Dr. David Alan Gilbert 
Cc: "Michael S. Tsirkin" 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Signed-off-by: David Hildenbrand 
---
 target/i386/sev.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index d273174ad3..f100a53231 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -680,6 +680,12 @@ sev_guest_init(const char *id)
 uint32_t host_cbitpos;
 struct sev_user_data_status status = {};
 
+ret = ram_block_discard_disable(true);
+if (ret) {
+error_report("%s: cannot disable RAM discard", __func__);
+return NULL;
+}
+
 sev = lookup_sev_guest_info(id);
 if (!sev) {
 error_report("%s: '%s' is not a valid '%s' object",
@@ -751,6 +757,7 @@ sev_guest_init(const char *id)
 return sev;
 err:
 sev_guest = NULL;
+ram_block_discard_disable(false);
 return NULL;
 }
 
-- 
2.26.2




[PATCH v5 11/21] virtio-pci: Proxy for virtio-mem

2020-06-26 Thread David Hildenbrand
Let's add a proxy for virtio-mem, make it a memory device, and
pass-through the properties.

Reviewed-by: Pankaj Gupta 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: "Dr. David Alan Gilbert" 
Cc: Igor Mammedov 
Signed-off-by: David Hildenbrand 
---
 hw/virtio/Makefile.objs|   1 +
 hw/virtio/virtio-mem-pci.c | 129 +
 hw/virtio/virtio-mem-pci.h |  33 ++
 include/hw/pci/pci.h   |   1 +
 4 files changed, 164 insertions(+)
 create mode 100644 hw/virtio/virtio-mem-pci.c
 create mode 100644 hw/virtio/virtio-mem-pci.h

diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index f3a65e01b7..a986708186 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -20,6 +20,7 @@ obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
 obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock-common.o vhost-vsock.o
 obj-$(CONFIG_VHOST_USER_VSOCK) += vhost-vsock-common.o vhost-user-vsock.o
 obj-$(CONFIG_VIRTIO_MEM) += virtio-mem.o
+common-obj-$(call land,$(CONFIG_VIRTIO_MEM),$(CONFIG_VIRTIO_PCI)) += 
virtio-mem-pci.o
 
 ifeq ($(CONFIG_VIRTIO_PCI),y)
 obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock-pci.o
diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c
new file mode 100644
index 00..b325303b32
--- /dev/null
+++ b/hw/virtio/virtio-mem-pci.c
@@ -0,0 +1,129 @@
+/*
+ * Virtio MEM PCI device
+ *
+ * Copyright (C) 2020 Red Hat, Inc.
+ *
+ * Authors:
+ *  David Hildenbrand 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "virtio-mem-pci.h"
+#include "hw/mem/memory-device.h"
+#include "qapi/error.h"
+
+static void virtio_mem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VirtIOMEMPCI *mem_pci = VIRTIO_MEM_PCI(vpci_dev);
+DeviceState *vdev = DEVICE(&mem_pci->vdev);
+
+qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+}
+
+static void virtio_mem_pci_set_addr(MemoryDeviceState *md, uint64_t addr,
+Error **errp)
+{
+object_property_set_uint(OBJECT(md), addr, VIRTIO_MEM_ADDR_PROP, errp);
+}
+
+static uint64_t virtio_mem_pci_get_addr(const MemoryDeviceState *md)
+{
+return object_property_get_uint(OBJECT(md), VIRTIO_MEM_ADDR_PROP,
+&error_abort);
+}
+
+static MemoryRegion *virtio_mem_pci_get_memory_region(MemoryDeviceState *md,
+  Error **errp)
+{
+VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md);
+VirtIOMEM *vmem = VIRTIO_MEM(&pci_mem->vdev);
+VirtIOMEMClass *vmc = VIRTIO_MEM_GET_CLASS(vmem);
+
+return vmc->get_memory_region(vmem, errp);
+}
+
+static uint64_t virtio_mem_pci_get_plugged_size(const MemoryDeviceState *md,
+Error **errp)
+{
+return object_property_get_uint(OBJECT(md), VIRTIO_MEM_SIZE_PROP,
+errp);
+}
+
+static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md,
+MemoryDeviceInfo *info)
+{
+VirtioMEMDeviceInfo *vi = g_new0(VirtioMEMDeviceInfo, 1);
+VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md);
+VirtIOMEM *vmem = VIRTIO_MEM(&pci_mem->vdev);
+VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem);
+DeviceState *dev = DEVICE(md);
+
+if (dev->id) {
+vi->has_id = true;
+vi->id = g_strdup(dev->id);
+}
+
+/* let the real device handle everything else */
+vpc->fill_device_info(vmem, vi);
+
+info->u.virtio_mem.data = vi;
+info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM;
+}
+
+static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(klass);
+
+k->realize = virtio_mem_pci_realize;
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_MEM;
+pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+pcidev_k->class_id = PCI_CLASS_OTHERS;
+
+mdc->get_addr = virtio_mem_pci_get_addr;
+mdc->set_addr = virtio_mem_pci_set_addr;
+mdc->get_plugged_size = virtio_mem_pci_get_plugged_size;
+mdc->get_memory_region = virtio_mem_pci_get_memory_region;
+mdc->fill_device_info = virtio_mem_pci_fill_device_info;
+}
+
+static void virtio_mem_pci_instance_init(Object *obj)
+{
+VirtIOMEMPCI *dev = VIRTIO_MEM_PCI(obj);
+
+virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+TYPE_VIRTIO_MEM);
+object_property_add_alias(obj, VIRTIO_MEM_BLOCK_SIZE_PROP,
+  OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP);
+object_property_add_alias(ob

[PATCH v5 05/21] s390x/pv: Convert to ram_block_discard_disable()

2020-06-26 Thread David Hildenbrand
Discarding RAM does not work as expected with protected VMs. Let's
switch to ram_block_discard_disable() for now, as we want to get rid
of qemu_balloon_inhibit(). Note that it will currently never fail, but
might fail in the future with new technologies (e.g., virtio-mem).

Acked-by: Cornelia Huck 
Cc: Richard Henderson 
Cc: Cornelia Huck 
Cc: Halil Pasic 
Cc: Christian Borntraeger 
Cc: Janosch Frank 
Signed-off-by: David Hildenbrand 
---
 hw/s390x/s390-virtio-ccw.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index b111406d56..023fd25f2b 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -43,7 +43,6 @@
 #include "hw/qdev-properties.h"
 #include "hw/s390x/tod.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/balloon.h"
 #include "hw/s390x/pv.h"
 #include "migration/blocker.h"
 
@@ -329,7 +328,7 @@ static void s390_machine_unprotect(S390CcwMachineState *ms)
 ms->pv = false;
 migrate_del_blocker(pv_mig_blocker);
 error_free_or_abort(&pv_mig_blocker);
-qemu_balloon_inhibit(false);
+ram_block_discard_disable(false);
 }
 
 static int s390_machine_protect(S390CcwMachineState *ms)
@@ -338,17 +337,22 @@ static int s390_machine_protect(S390CcwMachineState *ms)
 int rc;
 
/*
-* Ballooning on protected VMs needs support in the guest for
-* sharing and unsharing balloon pages. Block ballooning for
-* now, until we have a solution to make at least Linux guests
-* either support it or fail gracefully.
+* Discarding of memory in RAM blocks does not work as expected with
+* protected VMs. Sharing and unsharing pages would be required. Disable
+* it for now, until until we have a solution to make at least Linux
+* guests either support it (e.g., virtio-balloon) or fail gracefully.
 */
-qemu_balloon_inhibit(true);
+rc = ram_block_discard_disable(true);
+if (rc) {
+error_report("protected VMs: cannot disable RAM discard");
+return rc;
+}
+
 error_setg(&pv_mig_blocker,
"protected VMs are currently not migrateable.");
 rc = migrate_add_blocker(pv_mig_blocker, &local_err);
 if (rc) {
-qemu_balloon_inhibit(false);
+ram_block_discard_disable(false);
 error_report_err(local_err);
 error_free_or_abort(&pv_mig_blocker);
 return rc;
@@ -357,7 +361,7 @@ static int s390_machine_protect(S390CcwMachineState *ms)
 /* Create SE VM */
 rc = s390_pv_vm_enable();
 if (rc) {
-qemu_balloon_inhibit(false);
+ram_block_discard_disable(false);
 migrate_del_blocker(pv_mig_blocker);
 error_free_or_abort(&pv_mig_blocker);
 return rc;
-- 
2.26.2




[PATCH v5 08/21] migration/rdma: Use ram_block_discard_disable()

2020-06-26 Thread David Hildenbrand
RDMA will pin all guest memory (as documented in docs/rdma.txt). We want
to disable RAM block discards - however, to keep it simple use
ram_block_discard_is_required() instead of inhibiting.

Note: It is not sufficient to limit disabling to pin_all. Even when only
conditionally pinning 1 MB chunks, as soon as one page within such a
chunk was discarded and one page not, the discarded pages will be pinned
as well.

Reviewed-by: Dr. David Alan Gilbert 
Cc: "Michael S. Tsirkin" 
Cc: Juan Quintela 
Cc: "Dr. David Alan Gilbert" 
Signed-off-by: David Hildenbrand 
---
 migration/rdma.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/migration/rdma.c b/migration/rdma.c
index ec45d33ba3..bbe6f36627 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -29,6 +29,7 @@
 #include "qemu/sockets.h"
 #include "qemu/bitmap.h"
 #include "qemu/coroutine.h"
+#include "exec/memory.h"
 #include 
 #include 
 #include 
@@ -4017,8 +4018,14 @@ void rdma_start_incoming_migration(const char 
*host_port, Error **errp)
 Error *local_err = NULL;
 
 trace_rdma_start_incoming_migration();
-rdma = qemu_rdma_data_init(host_port, &local_err);
 
+/* Avoid ram_block_discard_disable(), cannot change during migration. */
+if (ram_block_discard_is_required()) {
+error_setg(errp, "RDMA: cannot disable RAM discard");
+return;
+}
+
+rdma = qemu_rdma_data_init(host_port, &local_err);
 if (rdma == NULL) {
 goto err;
 }
@@ -4067,10 +4074,17 @@ void rdma_start_outgoing_migration(void *opaque,
 const char *host_port, Error **errp)
 {
 MigrationState *s = opaque;
-RDMAContext *rdma = qemu_rdma_data_init(host_port, errp);
 RDMAContext *rdma_return_path = NULL;
+RDMAContext *rdma;
 int ret = 0;
 
+/* Avoid ram_block_discard_disable(), cannot change during migration. */
+if (ram_block_discard_is_required()) {
+error_setg(errp, "RDMA: cannot disable RAM discard");
+return;
+}
+
+rdma = qemu_rdma_data_init(host_port, errp);
 if (rdma == NULL) {
 goto err;
 }
-- 
2.26.2




[PATCH v5 16/21] virtio-mem: Allow notifiers for size changes

2020-06-26 Thread David Hildenbrand
We want to send qapi events in case the size of a virtio-mem device
changes. This allows upper layers to always know how much memory is
actually currently consumed via a virtio-mem device.

Unfortuantely, we have to report the id of our proxy device. Let's provide
an easy way for our proxy device to register, so it can send the qapi
events. Piggy-backing on the notifier infrastructure (although we'll
only ever have one notifier registered) seems to be an easy way.

Reviewed-by: Dr. David Alan Gilbert 
Cc: "Michael S. Tsirkin" 
Cc: "Dr. David Alan Gilbert" 
Cc: Igor Mammedov 
Signed-off-by: David Hildenbrand 
---
 hw/virtio/virtio-mem.c | 21 -
 include/hw/virtio/virtio-mem.h |  5 +
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index d8a0c974d3..2df33f9125 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -184,6 +184,7 @@ static int virtio_mem_state_change_request(VirtIOMEM *vmem, 
uint64_t gpa,
 } else {
 vmem->size -= size;
 }
+notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
 return VIRTIO_MEM_RESP_ACK;
 }
 
@@ -242,7 +243,10 @@ static int virtio_mem_unplug_all(VirtIOMEM *vmem)
 return -EBUSY;
 }
 bitmap_clear(vmem->bitmap, 0, vmem->bitmap_size);
-vmem->size = 0;
+if (vmem->size) {
+vmem->size = 0;
+notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
+}
 
 virtio_mem_resize_usable_region(vmem, vmem->requested_size, true);
 return 0;
@@ -561,6 +565,18 @@ static MemoryRegion 
*virtio_mem_get_memory_region(VirtIOMEM *vmem, Error **errp)
 return &vmem->memdev->mr;
 }
 
+static void virtio_mem_add_size_change_notifier(VirtIOMEM *vmem,
+Notifier *notifier)
+{
+notifier_list_add(&vmem->size_change_notifiers, notifier);
+}
+
+static void virtio_mem_remove_size_change_notifier(VirtIOMEM *vmem,
+   Notifier *notifier)
+{
+notifier_remove(notifier);
+}
+
 static void virtio_mem_get_size(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp)
 {
@@ -668,6 +684,7 @@ static void virtio_mem_instance_init(Object *obj)
 VirtIOMEM *vmem = VIRTIO_MEM(obj);
 
 vmem->block_size = VIRTIO_MEM_MIN_BLOCK_SIZE;
+notifier_list_init(&vmem->size_change_notifiers);
 
 object_property_add(obj, VIRTIO_MEM_SIZE_PROP, "size", virtio_mem_get_size,
 NULL, NULL, NULL);
@@ -705,6 +722,8 @@ static void virtio_mem_class_init(ObjectClass *klass, void 
*data)
 
 vmc->fill_device_info = virtio_mem_fill_device_info;
 vmc->get_memory_region = virtio_mem_get_memory_region;
+vmc->add_size_change_notifier = virtio_mem_add_size_change_notifier;
+vmc->remove_size_change_notifier = virtio_mem_remove_size_change_notifier;
 }
 
 static const TypeInfo virtio_mem_info = {
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
index 6981096f7c..b74c77cd42 100644
--- a/include/hw/virtio/virtio-mem.h
+++ b/include/hw/virtio/virtio-mem.h
@@ -64,6 +64,9 @@ typedef struct VirtIOMEM {
 
 /* block size and alignment */
 uint64_t block_size;
+
+/* notifiers to notify when "size" changes */
+NotifierList size_change_notifiers;
 } VirtIOMEM;
 
 typedef struct VirtIOMEMClass {
@@ -73,6 +76,8 @@ typedef struct VirtIOMEMClass {
 /* public */
 void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
 MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp);
+void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
+void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
 } VirtIOMEMClass;
 
 #endif
-- 
2.26.2




[PATCH v5 13/21] hmp: Handle virtio-mem when printing memory device info

2020-06-26 Thread David Hildenbrand
Print the memory device info just like for other memory devices.

Reviewed-by: Dr. David Alan Gilbert 
Cc: "Dr. David Alan Gilbert" 
Cc: "Michael S. Tsirkin" 
Signed-off-by: David Hildenbrand 
---
 monitor/hmp-cmds.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 2b0b58a336..2ec13e4cc3 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1821,6 +1821,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict 
*qdict)
 MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
 MemoryDeviceInfoList *info;
 VirtioPMEMDeviceInfo *vpi;
+VirtioMEMDeviceInfo *vmi;
 MemoryDeviceInfo *value;
 PCDIMMDeviceInfo *di;
 
@@ -1855,6 +1856,21 @@ void hmp_info_memory_devices(Monitor *mon, const QDict 
*qdict)
 monitor_printf(mon, "  size: %" PRIu64 "\n", vpi->size);
 monitor_printf(mon, "  memdev: %s\n", vpi->memdev);
 break;
+case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM:
+vmi = value->u.virtio_mem.data;
+monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
+   MemoryDeviceInfoKind_str(value->type),
+   vmi->id ? vmi->id : "");
+monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", 
vmi->memaddr);
+monitor_printf(mon, "  node: %" PRId64 "\n", vmi->node);
+monitor_printf(mon, "  requested-size: %" PRIu64 "\n",
+   vmi->requested_size);
+monitor_printf(mon, "  size: %" PRIu64 "\n", vmi->size);
+monitor_printf(mon, "  max-size: %" PRIu64 "\n", 
vmi->max_size);
+monitor_printf(mon, "  block-size: %" PRIu64 "\n",
+   vmi->block_size);
+monitor_printf(mon, "  memdev: %s\n", vmi->memdev);
+break;
 default:
 g_assert_not_reached();
 }
-- 
2.26.2




[PATCH v5 14/21] numa: Handle virtio-mem in NUMA stats

2020-06-26 Thread David Hildenbrand
Account the memory to the configured nid.

Reviewed-by: Pankaj Gupta 
Cc: Eduardo Habkost 
Cc: Marcel Apfelbaum 
Cc: "Michael S. Tsirkin" 
Signed-off-by: David Hildenbrand 
---
 hw/core/numa.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/core/numa.c b/hw/core/numa.c
index 5f81900f88..ca0b2e5fa7 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -817,6 +817,7 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[])
 MemoryDeviceInfoList *info;
 PCDIMMDeviceInfo *pcdimm_info;
 VirtioPMEMDeviceInfo *vpi;
+VirtioMEMDeviceInfo *vmi;
 
 for (info = info_list; info; info = info->next) {
 MemoryDeviceInfo *value = info->value;
@@ -837,6 +838,11 @@ static void numa_stat_memory_devices(NumaNodeMem 
node_mem[])
 node_mem[0].node_mem += vpi->size;
 node_mem[0].node_plugged_mem += vpi->size;
 break;
+case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM:
+vmi = value->u.virtio_mem.data;
+node_mem[vmi->node].node_mem += vmi->size;
+node_mem[vmi->node].node_plugged_mem += vmi->size;
+break;
 default:
 g_assert_not_reached();
 }
-- 
2.26.2




[PATCH v5 19/21] virtio-mem: Add trace events

2020-06-26 Thread David Hildenbrand
Let's add some trace events that might come in handy later.

Cc: "Michael S. Tsirkin" 
Cc: "Dr. David Alan Gilbert" 
Signed-off-by: David Hildenbrand 
---
 hw/virtio/trace-events | 10 ++
 hw/virtio/virtio-mem.c | 10 +-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 6427a0047d..292fc15e29 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -74,3 +74,13 @@ virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=%d"
 virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d"
 virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t 
sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d"
 virtio_iommu_report_fault(uint8_t reason, uint32_t flags, uint32_t endpoint, 
uint64_t addr) "FAULT reason=%d flags=%d endpoint=%d address =0x%"PRIx64
+
+# virtio-mem.c
+virtio_mem_send_response(uint16_t type) "type=%" PRIu16
+virtio_mem_plug_request(uint64_t addr, uint16_t nb_blocks) "addr=0x%" PRIx64 " 
nb_blocks=%" PRIu16
+virtio_mem_unplug_request(uint64_t addr, uint16_t nb_blocks) "addr=0x%" PRIx64 
" nb_blocks=%" PRIu16
+virtio_mem_unplugged_all(void) ""
+virtio_mem_unplug_all_request(void) ""
+virtio_mem_resized_usable_region(uint64_t old_size, uint64_t new_size) 
"old_size=0x%" PRIx64 "new_size=0x%" PRIx64
+virtio_mem_state_request(uint64_t addr, uint16_t nb_blocks) "addr=0x%" PRIx64 
" nb_blocks=%" PRIu16
+virtio_mem_state_response(uint16_t state) "state=%" PRIu16
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index 6ed5409669..fdd4dbb42c 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -30,6 +30,7 @@
 #include "hw/boards.h"
 #include "hw/qdev-properties.h"
 #include "config-devices.h"
+#include "trace.h"
 
 /*
  * Use QEMU_VMALLOC_ALIGN, so no THP will have to be split when unplugging
@@ -100,6 +101,7 @@ static void virtio_mem_send_response(VirtIOMEM *vmem, 
VirtQueueElement *elem,
 VirtIODevice *vdev = VIRTIO_DEVICE(vmem);
 VirtQueue *vq = vmem->vq;
 
+trace_virtio_mem_send_response(le16_to_cpu(resp->type));
 iov_from_buf(elem->in_sg, elem->in_num, 0, resp, sizeof(*resp));
 
 virtqueue_push(vq, elem, sizeof(*resp));
@@ -195,6 +197,7 @@ static void virtio_mem_plug_request(VirtIOMEM *vmem, 
VirtQueueElement *elem,
 const uint16_t nb_blocks = le16_to_cpu(req->u.plug.nb_blocks);
 uint16_t type;
 
+trace_virtio_mem_plug_request(gpa, nb_blocks);
 type = virtio_mem_state_change_request(vmem, gpa, nb_blocks, true);
 virtio_mem_send_response_simple(vmem, elem, type);
 }
@@ -206,6 +209,7 @@ static void virtio_mem_unplug_request(VirtIOMEM *vmem, 
VirtQueueElement *elem,
 const uint16_t nb_blocks = le16_to_cpu(req->u.unplug.nb_blocks);
 uint16_t type;
 
+trace_virtio_mem_unplug_request(gpa, nb_blocks);
 type = virtio_mem_state_change_request(vmem, gpa, nb_blocks, false);
 virtio_mem_send_response_simple(vmem, elem, type);
 }
@@ -225,6 +229,7 @@ static void virtio_mem_resize_usable_region(VirtIOMEM *vmem,
 return;
 }
 
+trace_virtio_mem_resized_usable_region(vmem->usable_region_size, newsize);
 vmem->usable_region_size = newsize;
 }
 
@@ -247,7 +252,7 @@ static int virtio_mem_unplug_all(VirtIOMEM *vmem)
 vmem->size = 0;
 notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
 }
-
+trace_virtio_mem_unplugged_all();
 virtio_mem_resize_usable_region(vmem, vmem->requested_size, true);
 return 0;
 }
@@ -255,6 +260,7 @@ static int virtio_mem_unplug_all(VirtIOMEM *vmem)
 static void virtio_mem_unplug_all_request(VirtIOMEM *vmem,
   VirtQueueElement *elem)
 {
+trace_virtio_mem_unplug_all_request();
 if (virtio_mem_unplug_all(vmem)) {
 virtio_mem_send_response_simple(vmem, elem, VIRTIO_MEM_RESP_BUSY);
 } else {
@@ -272,6 +278,7 @@ static void virtio_mem_state_request(VirtIOMEM *vmem, 
VirtQueueElement *elem,
 .type = cpu_to_le16(VIRTIO_MEM_RESP_ACK),
 };
 
+trace_virtio_mem_state_request(gpa, nb_blocks);
 if (!virtio_mem_valid_range(vmem, gpa, size)) {
 virtio_mem_send_response_simple(vmem, elem, VIRTIO_MEM_RESP_ERROR);
 return;
@@ -284,6 +291,7 @@ static void virtio_mem_state_request(VirtIOMEM *vmem, 
VirtQueueElement *elem,
 } else {
 resp.u.state.state = cpu_to_le16(VIRTIO_MEM_STATE_MIXED);
 }
+trace_virtio_mem_state_response(le16_to_cpu(resp.u.state.state));
 virtio_mem_send_response(vmem, elem, &resp);
 }
 
-- 
2.26.2




[PATCH v5 17/21] virtio-pci: Send qapi events when the virtio-mem size changes

2020-06-26 Thread David Hildenbrand
Let's register the notifier and trigger the qapi event with the right
device id.

MEMORY_DEVICE_SIZE_CHANGE is similar to BALLOON_CHANGE, however on a
memory device level.

Don't unregister the notifier (we neither have finalize() nor unrealize()
for VirtIOPCIProxy, so it's not that simple to do it) - both devices are
expected to vanish at the same time.

Cc: "Michael S. Tsirkin" 
Cc: Markus Armbruster 
Cc: "Dr. David Alan Gilbert" 
Cc: Eric Blake 
Cc: Igor Mammedov 
Signed-off-by: David Hildenbrand 
---
 hw/virtio/virtio-mem-pci.c | 28 
 hw/virtio/virtio-mem-pci.h |  1 +
 monitor/monitor.c  |  1 +
 qapi/misc.json | 25 +
 4 files changed, 55 insertions(+)

diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c
index b325303b32..1a8e854123 100644
--- a/hw/virtio/virtio-mem-pci.c
+++ b/hw/virtio/virtio-mem-pci.c
@@ -14,6 +14,7 @@
 #include "virtio-mem-pci.h"
 #include "hw/mem/memory-device.h"
 #include "qapi/error.h"
+#include "qapi/qapi-events-misc.h"
 
 static void virtio_mem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
 {
@@ -74,6 +75,21 @@ static void virtio_mem_pci_fill_device_info(const 
MemoryDeviceState *md,
 info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM;
 }
 
+static void virtio_mem_pci_size_change_notify(Notifier *notifier, void *data)
+{
+VirtIOMEMPCI *pci_mem = container_of(notifier, VirtIOMEMPCI,
+ size_change_notifier);
+DeviceState *dev = DEVICE(pci_mem);
+const uint64_t * const size_p = data;
+const char *id = NULL;
+
+if (dev->id) {
+id = g_strdup(dev->id);
+}
+
+qapi_event_send_memory_device_size_change(!!id, id, *size_p);
+}
+
 static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -98,9 +114,21 @@ static void virtio_mem_pci_class_init(ObjectClass *klass, 
void *data)
 static void virtio_mem_pci_instance_init(Object *obj)
 {
 VirtIOMEMPCI *dev = VIRTIO_MEM_PCI(obj);
+VirtIOMEMClass *vmc;
+VirtIOMEM *vmem;
 
 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
 TYPE_VIRTIO_MEM);
+
+dev->size_change_notifier.notify = virtio_mem_pci_size_change_notify;
+vmem = VIRTIO_MEM(&dev->vdev);
+vmc = VIRTIO_MEM_GET_CLASS(vmem);
+/*
+ * We never remove the notifier again, as we expect both devices to
+ * disappear at the same time.
+ */
+vmc->add_size_change_notifier(vmem, &dev->size_change_notifier);
+
 object_property_add_alias(obj, VIRTIO_MEM_BLOCK_SIZE_PROP,
   OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP);
 object_property_add_alias(obj, VIRTIO_MEM_SIZE_PROP, OBJECT(&dev->vdev),
diff --git a/hw/virtio/virtio-mem-pci.h b/hw/virtio/virtio-mem-pci.h
index 8820cd6628..b51a28b275 100644
--- a/hw/virtio/virtio-mem-pci.h
+++ b/hw/virtio/virtio-mem-pci.h
@@ -28,6 +28,7 @@ typedef struct VirtIOMEMPCI VirtIOMEMPCI;
 struct VirtIOMEMPCI {
 VirtIOPCIProxy parent_obj;
 VirtIOMEM vdev;
+Notifier size_change_notifier;
 };
 
 #endif /* QEMU_VIRTIO_MEM_PCI_H */
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 125494410a..19dcb8fbe3 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -235,6 +235,7 @@ static MonitorQAPIEventConf 
monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
 [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
 [QAPI_EVENT_QUORUM_FAILURE]= { 1000 * SCALE_MS },
 [QAPI_EVENT_VSERPORT_CHANGE]   = { 1000 * SCALE_MS },
+[QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS },
 };
 
 /*
diff --git a/qapi/misc.json b/qapi/misc.json
index 65ca3edf32..149c925246 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -1434,6 +1434,31 @@
 ##
 { 'command': 'query-memory-devices', 'returns': ['MemoryDeviceInfo'] }
 
+##
+# @MEMORY_DEVICE_SIZE_CHANGE:
+#
+# Emitted when the size of a memory device changes. Only emitted for memory
+# devices that can actually change the size (e.g., virtio-mem due to guest
+# action).
+#
+# @id: device's ID
+# @size: the new size of memory that the device provides
+#
+# Note: this event is rate-limited.
+#
+# Since: 5.1
+#
+# Example:
+#
+# <- { "event": "MEMORY_DEVICE_SIZE_CHANGE",
+#  "data": { "id": "vm0", "size": 1073741824},
+#  "timestamp": { "seconds": 1588168529, "microseconds": 201316 } }
+#
+##
+{ 'event': 'MEMORY_DEVICE_SIZE_CHANGE',
+  'data': { '*id': 'str', 'size': 'size' } }
+
+
 ##
 # @MEM_UNPLUG_ERROR:
 #
-- 
2.26.2




[PATCH v5 15/21] pc: Support for virtio-mem-pci

2020-06-26 Thread David Hildenbrand
Let's wire it up similar to virtio-pmem. Also disallow unplug, so it's
harder for users to shoot themselves into the foot.

Reviewed-by: Pankaj Gupta 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: Eric Blake 
Cc: Markus Armbruster 
Signed-off-by: David Hildenbrand 
---
 hw/i386/Kconfig |  1 +
 hw/i386/pc.c| 49 -
 2 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index c93f32f657..03e347b207 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -35,6 +35,7 @@ config PC
 select ACPI_PCI
 select ACPI_VMGENID
 select VIRTIO_PMEM_SUPPORTED
+select VIRTIO_MEM_SUPPORTED
 
 config PC_PCI
 bool
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 2dfd69b973..f2a18a3276 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -88,6 +88,7 @@
 #include "hw/net/ne2000-isa.h"
 #include "standard-headers/asm-x86/bootparam.h"
 #include "hw/virtio/virtio-pmem-pci.h"
+#include "hw/virtio/virtio-mem-pci.h"
 #include "hw/mem/memory-device.h"
 #include "sysemu/replay.h"
 #include "qapi/qmp/qerror.h"
@@ -1637,8 +1638,8 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 numa_cpu_pre_plug(cpu_slot, dev, errp);
 }
 
-static void pc_virtio_pmem_pci_pre_plug(HotplugHandler *hotplug_dev,
-DeviceState *dev, Error **errp)
+static void pc_virtio_md_pci_pre_plug(HotplugHandler *hotplug_dev,
+  DeviceState *dev, Error **errp)
 {
 HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
 Error *local_err = NULL;
@@ -1649,7 +1650,8 @@ static void pc_virtio_pmem_pci_pre_plug(HotplugHandler 
*hotplug_dev,
  * order. We should never reach this point when hotplugging on x86,
  * however, better add a safety net.
  */
-error_setg(errp, "virtio-pmem-pci hotplug not supported on this bus.");
+error_setg(errp, "hotplug of virtio based memory devices not supported"
+   " on this bus.");
 return;
 }
 /*
@@ -1664,8 +1666,8 @@ static void pc_virtio_pmem_pci_pre_plug(HotplugHandler 
*hotplug_dev,
 error_propagate(errp, local_err);
 }
 
-static void pc_virtio_pmem_pci_plug(HotplugHandler *hotplug_dev,
-DeviceState *dev, Error **errp)
+static void pc_virtio_md_pci_plug(HotplugHandler *hotplug_dev,
+  DeviceState *dev, Error **errp)
 {
 HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
 Error *local_err = NULL;
@@ -1685,17 +1687,17 @@ static void pc_virtio_pmem_pci_plug(HotplugHandler 
*hotplug_dev,
 error_propagate(errp, local_err);
 }
 
-static void pc_virtio_pmem_pci_unplug_request(HotplugHandler *hotplug_dev,
-  DeviceState *dev, Error **errp)
+static void pc_virtio_md_pci_unplug_request(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
 {
-/* We don't support virtio pmem hot unplug */
-error_setg(errp, "virtio pmem device unplug not supported.");
+/* We don't support hot unplug of virtio based memory devices */
+error_setg(errp, "virtio based memory devices cannot be unplugged.");
 }
 
-static void pc_virtio_pmem_pci_unplug(HotplugHandler *hotplug_dev,
-  DeviceState *dev, Error **errp)
+static void pc_virtio_md_pci_unplug(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
 {
-/* We don't support virtio pmem hot unplug */
+/* We don't support hot unplug of virtio based memory devices */
 }
 
 static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
@@ -1705,8 +1707,9 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler 
*hotplug_dev,
 pc_memory_pre_plug(hotplug_dev, dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
 pc_cpu_pre_plug(hotplug_dev, dev, errp);
-} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI)) {
-pc_virtio_pmem_pci_pre_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
+   object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
+pc_virtio_md_pci_pre_plug(hotplug_dev, dev, errp);
 }
 }
 
@@ -1717,8 +1720,9 @@ static void pc_machine_device_plug_cb(HotplugHandler 
*hotplug_dev,
 pc_memory_plug(hotplug_dev, dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
 pc_cpu_plug(hotplug_dev, dev, errp);
-} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI)) {
-pc_virtio_pmem_pci_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
+   object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
+pc_virtio_md_p

[PATCH v5 18/21] virtio-mem: Migration sanity checks

2020-06-26 Thread David Hildenbrand
We want to make sure that certain properties don't change during
migration, especially to catch user errors in a nice way. Let's migrate
a temporary structure and validate that the properties didn't change.

Reviewed-by: Dr. David Alan Gilbert 
Cc: "Michael S. Tsirkin" 
Cc: "Dr. David Alan Gilbert" 
Signed-off-by: David Hildenbrand 
---
 hw/virtio/virtio-mem.c | 70 ++
 1 file changed, 70 insertions(+)

diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index 2df33f9125..6ed5409669 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -519,12 +519,82 @@ static int virtio_mem_post_load(void *opaque, int 
version_id)
 return virtio_mem_restore_unplugged(VIRTIO_MEM(opaque));
 }
 
+typedef struct VirtIOMEMMigSanityChecks {
+VirtIOMEM *parent;
+uint64_t addr;
+uint64_t region_size;
+uint64_t block_size;
+uint32_t node;
+} VirtIOMEMMigSanityChecks;
+
+static int virtio_mem_mig_sanity_checks_pre_save(void *opaque)
+{
+VirtIOMEMMigSanityChecks *tmp = opaque;
+VirtIOMEM *vmem = tmp->parent;
+
+tmp->addr = vmem->addr;
+tmp->region_size = memory_region_size(&vmem->memdev->mr);
+tmp->block_size = vmem->block_size;
+tmp->node = vmem->node;
+return 0;
+}
+
+static int virtio_mem_mig_sanity_checks_post_load(void *opaque, int version_id)
+{
+VirtIOMEMMigSanityChecks *tmp = opaque;
+VirtIOMEM *vmem = tmp->parent;
+const uint64_t new_region_size = memory_region_size(&vmem->memdev->mr);
+
+if (tmp->addr != vmem->addr) {
+error_report("Property '%s' changed from 0x%" PRIx64 " to 0x%" PRIx64,
+ VIRTIO_MEM_ADDR_PROP, tmp->addr, vmem->addr);
+return -EINVAL;
+}
+/*
+ * Note: Preparation for resizeable memory regions. The maximum size
+ * of the memory region must not change during migration.
+ */
+if (tmp->region_size != new_region_size) {
+error_report("Property '%s' size changed from 0x%" PRIx64 " to 0x%"
+ PRIx64, VIRTIO_MEM_MEMDEV_PROP, tmp->region_size,
+ new_region_size);
+return -EINVAL;
+}
+if (tmp->block_size != vmem->block_size) {
+error_report("Property '%s' changed from 0x%" PRIx64 " to 0x%" PRIx64,
+ VIRTIO_MEM_BLOCK_SIZE_PROP, tmp->block_size,
+ vmem->block_size);
+return -EINVAL;
+}
+if (tmp->node != vmem->node) {
+error_report("Property '%s' changed from %" PRIu32 " to %" PRIu32,
+ VIRTIO_MEM_NODE_PROP, tmp->node, vmem->node);
+return -EINVAL;
+}
+return 0;
+}
+
+static const VMStateDescription vmstate_virtio_mem_sanity_checks = {
+.name = "virtio-mem-device/sanity-checks",
+.pre_save = virtio_mem_mig_sanity_checks_pre_save,
+.post_load = virtio_mem_mig_sanity_checks_post_load,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(addr, VirtIOMEMMigSanityChecks),
+VMSTATE_UINT64(region_size, VirtIOMEMMigSanityChecks),
+VMSTATE_UINT64(block_size, VirtIOMEMMigSanityChecks),
+VMSTATE_UINT32(node, VirtIOMEMMigSanityChecks),
+VMSTATE_END_OF_LIST(),
+},
+};
+
 static const VMStateDescription vmstate_virtio_mem_device = {
 .name = "virtio-mem-device",
 .minimum_version_id = 1,
 .version_id = 1,
 .post_load = virtio_mem_post_load,
 .fields = (VMStateField[]) {
+VMSTATE_WITH_TMP(VirtIOMEM, VirtIOMEMMigSanityChecks,
+ vmstate_virtio_mem_sanity_checks),
 VMSTATE_UINT64(usable_region_size, VirtIOMEM),
 VMSTATE_UINT64(size, VirtIOMEM),
 VMSTATE_UINT64(requested_size, VirtIOMEM),
-- 
2.26.2




[PATCH v5 20/21] virtio-mem: Exclude unplugged memory during migration

2020-06-26 Thread David Hildenbrand
The content of unplugged memory is undefined and should not be migrated,
ever. Exclude all unplugged memory during precopy using the precopy notifier
infrastructure introduced for free page hinting in virtio-balloon.

Unplugged memory is marked as "not dirty", meaning it won't be
considered for migration.

Cc: "Michael S. Tsirkin" 
Cc: "Dr. David Alan Gilbert" 
Signed-off-by: David Hildenbrand 
---
 hw/virtio/virtio-mem.c | 54 +-
 include/hw/virtio/virtio-mem.h |  3 ++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index fdd4dbb42c..bf9b414522 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -62,8 +62,14 @@ static bool virtio_mem_is_busy(void)
 /*
  * Postcopy cannot handle concurrent discards and we don't want to migrate
  * pages on-demand with stale content when plugging new blocks.
+ *
+ * For precopy, we don't want unplugged blocks in our migration stream, and
+ * when plugging new blocks, the page content might differ between source
+ * and destination (observable by the guest when not initializing pages
+ * after plugging them) until we're running on the destination (as we 
didn't
+ * migrate these blocks when they were unplugged).
  */
-return migration_in_incoming_postcopy();
+return migration_in_incoming_postcopy() || !migration_is_idle();
 }
 
 static bool virtio_mem_test_bitmap(VirtIOMEM *vmem, uint64_t start_gpa,
@@ -475,6 +481,7 @@ static void virtio_mem_device_realize(DeviceState *dev, 
Error **errp)
 host_memory_backend_set_mapped(vmem->memdev, true);
 vmstate_register_ram(&vmem->memdev->mr, DEVICE(vmem));
 qemu_register_reset(virtio_mem_system_reset, vmem);
+precopy_add_notifier(&vmem->precopy_notifier);
 }
 
 static void virtio_mem_device_unrealize(DeviceState *dev)
@@ -482,6 +489,7 @@ static void virtio_mem_device_unrealize(DeviceState *dev)
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
 VirtIOMEM *vmem = VIRTIO_MEM(dev);
 
+precopy_remove_notifier(&vmem->precopy_notifier);
 qemu_unregister_reset(virtio_mem_system_reset, vmem);
 vmstate_unregister_ram(&vmem->memdev->mr, DEVICE(vmem));
 host_memory_backend_set_mapped(vmem->memdev, false);
@@ -757,12 +765,56 @@ static void virtio_mem_set_block_size(Object *obj, 
Visitor *v, const char *name,
 vmem->block_size = value;
 }
 
+static void virtio_mem_precopy_exclude_unplugged(VirtIOMEM *vmem)
+{
+void * const host = qemu_ram_get_host_addr(vmem->memdev->mr.ram_block);
+unsigned long first_zero_bit, last_zero_bit;
+uint64_t offset, length;
+
+/*
+ * Find consecutive unplugged blocks and exclude them from migration.
+ *
+ * Note: Blocks cannot get (un)plugged during precopy, no locking needed.
+ */
+first_zero_bit = find_first_zero_bit(vmem->bitmap, vmem->bitmap_size);
+while (first_zero_bit < vmem->bitmap_size) {
+offset = first_zero_bit * vmem->block_size;
+last_zero_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size,
+  first_zero_bit + 1) - 1;
+length = (last_zero_bit - first_zero_bit + 1) * vmem->block_size;
+
+qemu_guest_free_page_hint(host + offset, length);
+first_zero_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size,
+last_zero_bit + 2);
+}
+}
+
+static int virtio_mem_precopy_notify(NotifierWithReturn *n, void *data)
+{
+VirtIOMEM *vmem = container_of(n, VirtIOMEM, precopy_notifier);
+PrecopyNotifyData *pnd = data;
+
+switch (pnd->reason) {
+case PRECOPY_NOTIFY_SETUP:
+precopy_enable_free_page_optimization();
+break;
+case PRECOPY_NOTIFY_AFTER_BITMAP_SYNC:
+virtio_mem_precopy_exclude_unplugged(vmem);
+break;
+default:
+break;
+}
+
+return 0;
+}
+
 static void virtio_mem_instance_init(Object *obj)
 {
 VirtIOMEM *vmem = VIRTIO_MEM(obj);
 
 vmem->block_size = VIRTIO_MEM_MIN_BLOCK_SIZE;
 notifier_list_init(&vmem->size_change_notifiers);
+vmem->precopy_notifier.notify = virtio_mem_precopy_notify;
 
 object_property_add(obj, VIRTIO_MEM_SIZE_PROP, "size", virtio_mem_get_size,
 NULL, NULL, NULL);
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
index b74c77cd42..0778224964 100644
--- a/include/hw/virtio/virtio-mem.h
+++ b/include/hw/virtio/virtio-mem.h
@@ -67,6 +67,9 @@ typedef struct VirtIOMEM {
 
 /* notifiers to notify when "size" changes */
 NotifierList size_change_notifiers;
+
+/* don't migrate unplugged memory */
+NotifierWithReturn precopy_notifier;
 } VirtIOMEM;
 
 typedef struct VirtIOMEMClass {
-- 
2.26.2




[PATCH v5 21/21] numa: Auto-enable NUMA when any memory devices are possible

2020-06-26 Thread David Hildenbrand
Let's auto-enable it also when maxmem is specified but no slots are
defined. This will result in us properly creating ACPI srat tables,
indicating the maximum possible PFN to the guest OS. Based on this, e.g.,
Linux will enable the swiotlb properly.

This avoids having to manually force the switolb on (swiotlb=force) in
Linux in case we're booting only using DMA memory (e.g., 2GB on x86-64),
and virtio-mem adds memory later on that really needs the swiotlb to be
used for DMA.

Let's take care of backwards compatibility if somebody has a setup that
specifies "maxram" without "slots".

Reported-by: Alex Shi 
Cc: Peter Maydell 
Cc: Eduardo Habkost 
Cc: Marcel Apfelbaum 
Cc: Sergio Lopez 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: "Michael S. Tsirkin" 
Cc: Igor Mammedov 
Cc: qemu-...@nongnu.org 
Signed-off-by: David Hildenbrand 
---
 hw/arm/virt.c   |  2 ++
 hw/core/numa.c  | 11 ++-
 hw/i386/microvm.c   |  1 +
 hw/i386/pc.c|  1 +
 hw/i386/pc_piix.c   |  1 +
 hw/i386/pc_q35.c|  1 +
 include/hw/boards.h |  1 +
 7 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 402c362c14..3865804681 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2323,6 +2323,7 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 mc->numa_mem_supported = true;
 mc->nvdimm_supported = true;
 mc->auto_enable_numa_with_memhp = true;
+mc->auto_enable_numa_with_memdev = true;
 mc->default_ram_id = "mach-virt.ram";
 
 object_class_property_add(oc, "acpi", "OnOffAuto",
@@ -2434,6 +2435,7 @@ static void virt_machine_5_0_options(MachineClass *mc)
 {
 virt_machine_5_1_options(mc);
 compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
+mc->auto_enable_numa_with_memdev = false;
 }
 DEFINE_VIRT_MACHINE(5, 0)
 
diff --git a/hw/core/numa.c b/hw/core/numa.c
index ca0b2e5fa7..a78fc4e59e 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -681,8 +681,9 @@ void numa_complete_configuration(MachineState *ms)
 NodeInfo *numa_info = ms->numa_state->nodes;
 
 /*
- * If memory hotplug is enabled (slots > 0) but without '-numa'
- * options explicitly on CLI, guestes will break.
+ * If memory hotplug is enabled (slot > 0) or memory devices are enabled
+ * (ms->maxram_size > ram_size) but without '-numa' options explicitly on
+ * CLI, guests will break.
  *
  *   Windows: won't enable memory hotplug without SRAT table at all
  *
@@ -697,9 +698,9 @@ void numa_complete_configuration(MachineState *ms)
  * assume there is just one node with whole RAM.
  */
 if (ms->numa_state->num_nodes == 0 &&
-((ms->ram_slots > 0 &&
-mc->auto_enable_numa_with_memhp) ||
-mc->auto_enable_numa)) {
+((ms->ram_slots && mc->auto_enable_numa_with_memhp) ||
+ (ms->maxram_size > ms->ram_size && mc->auto_enable_numa_with_memdev) 
||
+ mc->auto_enable_numa)) {
 NumaNodeOptions node = { };
 parse_numa_node(ms, &node, &error_abort);
 numa_info[0].node_mem = ram_size;
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 5e931975a0..81d0888930 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -464,6 +464,7 @@ static void microvm_class_init(ObjectClass *oc, void *data)
 mc->max_cpus = 288;
 mc->has_hotpluggable_cpus = false;
 mc->auto_enable_numa_with_memhp = false;
+mc->auto_enable_numa_with_memdev = false;
 mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE;
 mc->nvdimm_supported = false;
 mc->default_ram_id = "microvm.ram";
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f2a18a3276..bc36a4efe7 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1975,6 +1975,7 @@ static void pc_machine_class_init(ObjectClass *oc, void 
*data)
 mc->get_default_cpu_node_id = x86_get_default_cpu_node_id;
 mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids;
 mc->auto_enable_numa_with_memhp = true;
+mc->auto_enable_numa_with_memdev = true;
 mc->has_hotpluggable_cpus = true;
 mc->default_boot_order = "cad";
 mc->hot_add_cpu = pc_hot_add_cpu;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1497d0e4ae..33f3b58f3d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -443,6 +443,7 @@ static void pc_i440fx_5_0_machine_options(MachineClass *m)
 m->is_default = false;
 compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
 compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
+m->auto_enable_numa_with_memdev = false;
 }
 
 DEFINE_I440FX_MACHINE(v5_0, "pc-i440fx-5.0", NULL,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 46cd06524c..d831b3359a 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -371,6 +371,7 @@ static void pc_q35_5_0_machine_options(MachineClass *m)
 m->alias = NULL;
 compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
 compat_props_add(m->compat_props, pc_compat_5_0, pc_com

Re: [Bug 1885247] [NEW] Build error in Intel 32-bit hosts

2020-06-26 Thread Aleksandar Markovic
пет, 26. јун 2020. у 09:11 Aleksandar Markovic
<1885...@bugs.launchpad.net> је написао/ла:
>
> Public bug reported:
>
> The code base is on master, checked out on Thursday June25th 2020,
> 0250c595c9d. The build procedure:
>
> $ mkdir build-gcc
> $ cd build-gcc
> $ ../configure
> $ make
>
> The build error message is:
>
>   CC  x86_64-softmmu/hw/hyperv/hyperv.o
>   CC  x86_64-softmmu/hw/hyperv/hyperv_testdev.o
>   CC  x86_64-softmmu/hw/hyperv/vmbus.o
> /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c: In function ‘gpadl_iter_io’:
> /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c:386:13: error: cast to pointer 
> from integer of different size [-Werror=int-to-pointer-cast]
>  p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) | 
> off_in_page);
>  ^
> cc1: all warnings being treated as errors
> make[1]: *** [/home/rtrk/Build/qemu-master/rules.mak:69: hw/hyperv/vmbus.o] 
> Error 1
> make: *** [Makefile:527: x86_64-softmmu/all] Error 2
>

Jon,

Do arilyou have any comment or insight on this?

Thanks,
Aleksandar

> ** Affects: qemu
>  Importance: Undecided
>  Status: New
>
> --
> You received this bug notification because you are a member of qemu-
> devel-ml, which is subscribed to QEMU.
> https://bugs.launchpad.net/bugs/1885247
>
> Title:
>   Build error in Intel 32-bit hosts
>
> Status in QEMU:
>   New
>
> Bug description:
>   The code base is on master, checked out on Thursday June25th 2020,
>   0250c595c9d. The build procedure:
>
>   $ mkdir build-gcc
>   $ cd build-gcc
>   $ ../configure
>   $ make
>
>   The build error message is:
>
> CC  x86_64-softmmu/hw/hyperv/hyperv.o
> CC  x86_64-softmmu/hw/hyperv/hyperv_testdev.o
> CC  x86_64-softmmu/hw/hyperv/vmbus.o
>   /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c: In function ‘gpadl_iter_io’:
>   /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c:386:13: error: cast to 
> pointer from integer of different size [-Werror=int-to-pointer-cast]
>p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) | 
> off_in_page);
>^
>   cc1: all warnings being treated as errors
>   make[1]: *** [/home/rtrk/Build/qemu-master/rules.mak:69: hw/hyperv/vmbus.o] 
> Error 1
>   make: *** [Makefile:527: x86_64-softmmu/all] Error 2
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/qemu/+bug/1885247/+subscriptions
>



Re: [PATCH] hw/virtio/virtio-iommu-pci.c: Fix typo in error message

2020-06-26 Thread Auger Eric
Hi Peter,

On 6/25/20 12:08 PM, Peter Maydell wrote:
> Fix a typo in an error message in virtio_iommu_pci_realize():
> "Check you machine" should be "Check your machine".
> 
> Reported-by: Markus Armbruster 
> Signed-off-by: Peter Maydell 
Reviewed-by: Eric Auger 

Thanks

Eric

> ---
>  hw/virtio/virtio-iommu-pci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
> index 632533abaf7..32e3215d1df 100644
> --- a/hw/virtio/virtio-iommu-pci.c
> +++ b/hw/virtio/virtio-iommu-pci.c
> @@ -48,7 +48,7 @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy 
> *vpci_dev, Error **errp)
> "%s machine fails to create iommu-map device tree 
> bindings",
> mc->name);
>  error_append_hint(errp,
> -  "Check you machine implements a hotplug handler "
> +  "Check your machine implements a hotplug handler "
>"for the virtio-iommu-pci device\n");
>  error_append_hint(errp, "Check the guest is booted without FW or 
> with "
>"-no-acpi\n");
> 




Re: [PATCH v5 2/5] virtio-iommu: Implement RESV_MEM probe request

2020-06-26 Thread Auger Eric
Hi Markus,
On 6/25/20 9:05 AM, Markus Armbruster wrote:
> Eric Auger  writes:
> 
>> This patch implements the PROBE request. At the moment,
>> only THE RESV_MEM property is handled. The first goal is
>> to report iommu wide reserved regions such as the MSI regions
>> set by the machine code. On x86 this will be the IOAPIC MSI
>> region, [0xFEE0 - 0xFEEF], on ARM this may be the ITS
>> doorbell.
>>
>> In the future we may introduce per device reserved regions.
>> This will be useful when protecting host assigned devices
>> which may expose their own reserved regions
>>
>> Signed-off-by: Eric Auger 
>> Reviewed-by: Jean-Philippe Brucker 
>>
>> ---
>>
>> v4 -> v5:
>> - assert if reserved region type is different from RESERVED or
>>   MSI
>>
>> v3 -> v4:
>> - removed any reference to the NONE property that does not
>>   exist anymore.
>>
>> v2 -> v3:
>> - on probe, do not fill the reminder of the buffer with zeroes
>>   as the buffer was already zero initialized (Bharat)
>>
>> v1 -> v2:
>> - move the unlock back to the same place
>> - remove the push label and factorize the code after the out label
>> - fix a bunch of cpu_to_leX according to the latest spec revision
>> - do not remove sizeof(last) from free space
>> - check the ep exists
>> ---
>>  include/hw/virtio/virtio-iommu.h |  2 +
>>  hw/virtio/virtio-iommu.c | 92 ++--
>>  hw/virtio/trace-events   |  1 +
>>  3 files changed, 91 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/hw/virtio/virtio-iommu.h 
>> b/include/hw/virtio/virtio-iommu.h
>> index e653004d7c..49eb105cd8 100644
>> --- a/include/hw/virtio/virtio-iommu.h
>> +++ b/include/hw/virtio/virtio-iommu.h
>> @@ -53,6 +53,8 @@ typedef struct VirtIOIOMMU {
>>  GHashTable *as_by_busptr;
>>  IOMMUPciBus *iommu_pcibus_by_bus_num[PCI_BUS_MAX];
>>  PCIBus *primary_bus;
>> +ReservedRegion *reserved_regions;
>> +uint32_t nb_reserved_regions;
>>  GTree *domains;
>>  QemuMutex mutex;
>>  GTree *endpoints;
>> diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
>> index 483883ec1d..aabc3e36b1 100644
>> --- a/hw/virtio/virtio-iommu.c
>> +++ b/hw/virtio/virtio-iommu.c
>> @@ -38,6 +38,7 @@
>>  
>>  /* Max size */
>>  #define VIOMMU_DEFAULT_QUEUE_SIZE 256
>> +#define VIOMMU_PROBE_SIZE 512
>>  
>>  typedef struct VirtIOIOMMUDomain {
>>  uint32_t id;
>> @@ -378,6 +379,63 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
>>  return ret;
>>  }
>>  
>> +static ssize_t virtio_iommu_fill_resv_mem_prop(VirtIOIOMMU *s, uint32_t ep,
>> +   uint8_t *buf, size_t free)
>> +{
>> +struct virtio_iommu_probe_resv_mem prop = {};
>> +size_t size = sizeof(prop), length = size - sizeof(prop.head), total;
>> +int i;
>> +
>> +total = size * s->nb_reserved_regions;
>> +
>> +if (total > free) {
>> +return -ENOSPC;
>> +}
>> +
>> +for (i = 0; i < s->nb_reserved_regions; i++) {
>> +prop.head.type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM);
>> +prop.head.length = cpu_to_le16(length);
>> +prop.subtype = s->reserved_regions[i].type;
>> +assert(prop.subtype == VIRTIO_IOMMU_RESV_MEM_T_RESERVED ||
>> +   prop.subtype == VIRTIO_IOMMU_RESV_MEM_T_MSI);
> 
> The assertion makes sense here: we're mapping from the generic
> ReservedRegion type (which is unsigned) to the specific
> virtio_iommu_probe_resv_mem subtype (which is uint8_t, but only these
> two values are valid).
> 
> Howver, the assertion should test s->reserved_regions[i].type and go
> before the assignment, to ensure it doesn't truncate!
OK I will do.
> 
> Can I trigger the assertion with -device?  My try to find the answer
> myself failed:
At the moment the virtio-iommu-pci device only can be instantiated with
machvirt, booting in dt mode.
> 
> $ qemu-system-x86_64 -nodefaults -S -display none -device 
> virtio-iommu-pci,len-reserved-regions=1,reserved-regions[0]=0xfee0:0xfeef:99
> qemu-system-x86_64: -device 
> virtio-iommu-pci,len-reserved-regions=1,reserved-regions[0]=0xfee0:0xfeef:99:
>  pc-i440fx-5.1 machine fails to create iommu-map device tree bindings
> Check you machine implements a hotplug handler for the virtio-iommu-pci 
> device
> Check the guest is booted without FW or with -no-acpi
> 
> By the way: s/Check you machine/Check your machine/.

Thanks

Eric
> 
> [...]
> 




Re: [PATCH v5 5/5] hw/arm/virt: Let the virtio-iommu bypass MSIs

2020-06-26 Thread Auger Eric
Hi Peter,

On 6/25/20 12:01 PM, Peter Maydell wrote:
> On Wed, 24 Jun 2020 at 14:27, Eric Auger  wrote:
>>
>> At the moment the virtio-iommu translates MSI transactions.
>> This behavior is inherited from ARM SMMU. The virt machine
>> code knows where the guest MSI doorbells are so we can easily
>> declare those regions as VIRTIO_IOMMU_RESV_MEM_T_MSI. With that
>> setting the guest will not map MSIs through the IOMMU and those
>> transactions will be simply bypassed.
>>
>> Depending on which MSI controller is in use (ITS or GICV2M),
>> we declare either:
>> - the ITS interrupt translation space (ITS_base + 0x1),
>>   containing the GITS_TRANSLATOR or
>> - The GICV2M single frame, containing the MSI_SETSP_NS register.
>>
>> Signed-off-by: Eric Auger 
>> Reviewed-by: Jean-Philippe Brucker 
>>
> 
>>  static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
>>  DeviceState *dev, Error **errp)
>>  {
>> +VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
>> +
>>  if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>>  virt_memory_pre_plug(hotplug_dev, dev, errp);
>> +} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
>> +/* we declare a VIRTIO_IOMMU_RESV_MEM_T_MSI region */
>> +
>> +if (vms->msi_controller == VIRT_MSI_CTRL_ITS) {
>> +/* GITS_TRANSLATER page */
>> +qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
>> +qdev_prop_set_string(dev, "reserved-regions[0]",
>> + "0x809:0x809:1");
>> +} else if (vms->msi_controller == VIRT_MSI_CTRL_GICV2M) {
>> +/* MSI_SETSPI_NS page */
>> +qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
>> +qdev_prop_set_string(dev, "reserved-regions[0]",
>> + "0x802:0x8020FFF:1");
> 
> This hardcodes addresses and lengths that are in the
> base_memmap[] array for VIRT_GIC_ITS and VIRT_GIC_V2M,
> so it's setting up a bear trap if we ever decide to
> move those. Could we construct the string from the
> base_memmap[] array entry values instead, please ?
Sure

Eric
> 
> thanks
> -- PMM
> 




Re: [PATCH v5 2/5] virtio-iommu: Implement RESV_MEM probe request

2020-06-26 Thread Auger Eric
Hi Peter,

On 6/25/20 12:12 PM, Peter Maydell wrote:
> On Thu, 25 Jun 2020 at 08:06, Markus Armbruster  wrote:
>> $ qemu-system-x86_64 -nodefaults -S -display none -device 
>> virtio-iommu-pci,len-reserved-regions=1,reserved-regions[0]=0xfee0:0xfeef:99
>> qemu-system-x86_64: -device 
>> virtio-iommu-pci,len-reserved-regions=1,reserved-regions[0]=0xfee0:0xfeef:99:
>>  pc-i440fx-5.1 machine fails to create iommu-map device tree bindings
>> Check you machine implements a hotplug handler for the virtio-iommu-pci 
>> device
>> Check the guest is booted without FW or with -no-acpi
>>
>> By the way: s/Check you machine/Check your machine/.
> 
> Patch sent:
> https://patchew.org/QEMU/20200625100811.12690-1-peter.mayd...@linaro.org/

Thank you for the typo fix.

Eric
> 
> thanks
> -- PMM
> 




Re: [PATCH v2 00/22] ADB: fix autopoll issues and rework mac_via state machine

2020-06-26 Thread Mark Cave-Ayland
On 26/06/2020 08:14, Laurent Vivier wrote:

> Le 23/06/2020 à 22:49, Mark Cave-Ayland a écrit :
>> This patchset is something I have been chipping away at for a while since
>> spending some time over the Christmas holidays trying to boot the MacOS
>> toolbox ROM on the new q800 machine.
>>
>> Initially I discovered that there were some problems when the MacOS ROM was
>> enumerating ADB devices due to multiple meanings of the vADBInt bit. After
>> fixing this there were still issues with keys being dropped during autopoll
>> which were eventually traced back to the autopoll timer re-firing before
>> the host had managed to read back the previous response.
>>
>> At this point I noticed that CUDA/PMU/mac_via all had their own 
>> implementations
>> of ADB autopoll, and that it would make sense to consolidate the autopoll 
>> timer,
>> mask, interval and locking into the ADB bus. This would allow the logic to be
>> removed from each separate device and managed in just one place.
>>
>> Finally I updated the trace-events to allow separate tracing of bus requests
>> and device responses which makes it easier to follow the ADB enumeration 
>> process.
>>
>> The breakdown of the patchset is as follows:
>>
>> - Patch 1 keeps checkpatch happy for the remainder of the patchset whilst 
>> patch
>>   2 is the proper fix for a spurious ADB register 3 write during enumeration
>>   caused by ignoring the request length which I had tried to work around 
>> earlier.
>>
>> - Patches 3 to 10 are part of the autopoll consolidation process which moves 
>> the
>>   separate autopoll implementations into a single implementation within
>>   ADBBusState.
>>
>> - Patches 11 to 13 update the ADB implementation to hold a status variable
>>   indicating the result of the last request and allow devices to indicate
>>   whether they have data to send. This extra information is required by the
>>   upcoming mac_via state machine changes.
>>
>> - Patches 14 to 17 add a variable and functions to block and unblock ADB
>>   autopoll at bus level, adding the functions at the correct places within
>>   CUDA and PMU.
>>
>> - Patches 18 and 19 rework the mac_via ADB state machine so that the bus
>>   can be enumerated correctly, and both explicit and autopoll requests work
>>   under both MacOS and Linux.
>>
>> - Patch 20 enforces the blocking and unblocking of autopoll at the ADB
>>   level, including adding an assert() to prevent developers from trying to
>>   make an ADB request whilst autopoll is in progress.
>>   
>> - Patches 21 and 22 update the trace-events to separate out ADB device and
>>   ADB bus events.
>>
>> The patch has been tested by myself and a couple of others during the 
>> development
>> process across the PPC g3beige/mac99 and 68K q800 machine so it should be 
>> quite
>> solid.
>>
>> One thing to indicate is that the patchset bumps the VMState versions for the
>> affected devices but does not allow older versions to load. This is a 
>> conscious
>> decision given that for the mac_via device used in the q800 machine it would 
>> be
>> just about impossible to map this in a way that would work for all cases. 
>> Similarly
>> for the Mac PPC machines migration is already hit/miss due to timebase 
>> issues so
>> I don't see this as being a big loss.
>>
>> To finish off I'd also like to say a big thank-you to both Laurent Vivier and
>> Finn Thain who both took time to answer my questions, dump information from a
>> real q800, and analyse it in very fine detail. Without them this patchset 
>> would
>> still be several months away.
>>
>> Signed-off-by: Mark Cave-Ayland 
>>
>>
>> v2:
>> - Rebased onto master
>> - Added R-B tags from Philippe
>> - Fixed byte discrepency at end of bus timeout spotted by Finn
>> - Added Tested-by tag from Finn
>>
>>
>> Mark Cave-Ayland (22):
>>   adb: coding style update to fix checkpatch errors
>>   adb: fix adb-mouse read length and revert disable-reg3-direct-writes
>> workaround
>>   cuda: convert ADB autopoll timer from ns to ms
>>   pmu: fix duplicate autopoll mask variable
>>   pmu: honour autopoll_rate_ms when rearming the ADB autopoll timer
>>   adb: introduce realize/unrealize and VMStateDescription for ADB bus
>>   adb: create autopoll variables directly within ADBBusState
>>   cuda: convert to use ADBBusState internal autopoll variables
>>   pmu: convert to use ADBBusState internal autopoll variables
>>   mac_via: convert to use ADBBusState internal autopoll variables
>>   adb: introduce new ADBDeviceHasData method to ADBDeviceClass
>>   adb: keep track of devices with pending data
>>   adb: add status field for holding information about the last ADB
>> request
>>   adb: use adb_request() only for explicit requests
>>   adb: add autopoll_blocked variable to block autopoll
>>   cuda: add adb_autopoll_block() and adb_autopoll_unblock() functions
>>   pmu: add adb_autopoll_block() and adb_autopoll_unblock() functions
>>   mac_via: move VIA1 portB write logic into mos6522_q800_via1_wri

Re: [PATCH v5 0/5] VIRTIO-IOMMU probe request support and MSI bypass on ARM

2020-06-26 Thread Jean-Philippe Brucker
On Wed, Jun 24, 2020 at 09:47:59AM -0400, Michael S. Tsirkin wrote:
> On Wed, Jun 24, 2020 at 03:26:20PM +0200, Eric Auger wrote:
> > By default the virtio-iommu translates MSI transactions. This
> > behavior is inherited from ARM SMMU. However the virt machine
> > code knows where the MSI doorbells are, so we can easily
> > declare those regions as VIRTIO_IOMMU_RESV_MEM_T_MSI. With that
> > setting the guest iommu subsystem will not need to map MSIs.
> > This setup will simplify the VFIO integration.
> > 
> > In this series, the ITS or GICV2M doorbells are declared as
> > HW MSI regions to be bypassed by the VIRTIO-IOMMU.
> 
> 
> > This also paves the way to the x86 integration where the MSI
> > region, [0xFEE0,0xFEEF], will be exposed by the q35
> > machine.  However this will be handled in a separate series
> > when not-DT support gets resolved.
> 
> What's going on with that btw?
> I think the next step is to put the spec up for virtio tc vote,
> then we can merge that, right? acpi parts will need to be
> ratified by the acpi sig.

Yes I'm being unreasonably slow on this. I'll look at both the virtio spec
and ACPI after coming back from Holiday in July. I'm afraid the situation
for the built-in description will be the same on the Linux side (asked to
use ACPI instead), but it's worth retrying as we have some progress on
ACPI support.

Thanks,
Jean

> 
> > Best Regards
> > 
> > Eric
> > 
> > This series can be found at:
> > https://github.com/eauger/qemu/tree/v5.0.0-virtio-iommu-msi-bypass-v5
> > 
> > History:
> > 
> > v4 -> v5:
> > - Take into account some additional comments from Markus:
> >   - reserved region type becomes an unsigned + some comment/desc
> > rewording
> >   - assert if the type is not RESERVED or MSI
> > 
> > v3 -> v4:
> > - collected Jean and markus's R-bs
> > - tool into account all Markus' comments in [1/5] (except removal of
> >   goto)
> > - use ':' as delimitor instead of commas
> > - add example in 4/5 commit message as suggested by Markus
> > 
> > v2 -> v3:
> > - Introduce VIRT_MSI_CTRL_NONE in VirtMSIControllerType
> > - do not fill the remainder of the probe buffer
> > 
> > v1 -> v2:
> > - check which MSI controller is in use and advertise the
> >   corresponding MSI doorbell
> > - managed for both ITS and GICv2M
> > - various fixes spotted by Peter and Jean-Philippe, see
> >   individual logs
> > 
> > v1: Most of those patches were respinned from
> >   [PATCH for-5.0 v11 00/20] VIRTIO-IOMMU device
> >   except the last one which is new
> > 
> > 
> > Eric Auger (5):
> >   qdev: Introduce DEFINE_PROP_RESERVED_REGION
> >   virtio-iommu: Implement RESV_MEM probe request
> >   virtio-iommu: Handle reserved regions in the translation process
> >   virtio-iommu-pci: Add array of Interval properties
> >   hw/arm/virt: Let the virtio-iommu bypass MSIs
> > 
> >  include/exec/memory.h|   6 ++
> >  include/hw/arm/virt.h|   7 ++
> >  include/hw/qdev-properties.h |   3 +
> >  include/hw/virtio/virtio-iommu.h |   2 +
> >  include/qemu/typedefs.h  |   1 +
> >  hw/arm/virt.c|  18 +
> >  hw/core/qdev-properties.c|  89 
> >  hw/virtio/virtio-iommu-pci.c |   3 +
> >  hw/virtio/virtio-iommu.c | 112 +--
> >  hw/virtio/trace-events   |   1 +
> >  10 files changed, 238 insertions(+), 4 deletions(-)
> > 
> > -- 
> > 2.20.1
> 



Re: [PATCH v5 11/12] pc-bios: s390x: Fix bootmap.c passing PSWs as addresses

2020-06-26 Thread Janosch Frank
On 6/25/20 2:46 PM, Thomas Huth wrote:
> On 24/06/2020 09.52, Janosch Frank wrote:
>> The component entries written by zipl contain short PSWs, not
>> addresses. Let's mask them and only pass the address part to
>> jump_to_IPL_code(uint64_t address) because it expects an address as
>> visible by the name of the argument.
>>
>> Signed-off-by: Janosch Frank 
>> ---
>>   pc-bios/s390-ccw/bootmap.c | 5 +++--
>>   pc-bios/s390-ccw/bootmap.h | 2 +-
>>   2 files changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
>> index 97205674e5..8547a140df 100644
>> --- a/pc-bios/s390-ccw/bootmap.c
>> +++ b/pc-bios/s390-ccw/bootmap.c
>> @@ -10,6 +10,7 @@
>>   
>>   #include "libc.h"
>>   #include "s390-ccw.h"
>> +#include "s390-arch.h"
>>   #include "bootmap.h"
>>   #include "virtio.h"
>>   #include "bswap.h"
>> @@ -436,7 +437,7 @@ static void zipl_load_segment(ComponentEntry *entry)
>>   char *blk_no = &err_msg[30]; /* where to print blockno in (those ZZs) 
>> */
>>   
>>   blockno = entry->data.blockno;
>> -address = entry->load_address;
>> +address = entry->psw & PSW_MASK_SHORT_ADDR;
> 
> Are you really sure about this one here? The address does not seem to be 
> used for any of the jump_to_IPL() functions. And in the zipl sources, I 
> can also see spots like this:

This one slipped through and is indeed wrong.

> 
> entry->compdat.load_address = data.load_address;
> 
> ... without any further short mask bits. So I somehow doubt that this 
> change is really ok?
> 
>>   debug_print_int("loading segment at block", blockno);
>>   debug_print_int("addr", address);
>> @@ -514,7 +515,7 @@ static void zipl_run(ScsiBlockPtr *pte)
>>   IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC 
>> entry");
>>   
>>   /* should not return */
>> -jump_to_IPL_code(entry->load_address);
>> +jump_to_IPL_code(entry->psw & PSW_MASK_SHORT_ADDR);
> 
> That one should be fine, I think.

Yes, as it is a execute type entry, this needs to be a PSW and therefore
needs to be masked.

> 
>>   }
>>   
>>   static void ipl_scsi(void)
>> diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
>> index 12a0166aae..e07f87e690 100644
>> --- a/pc-bios/s390-ccw/bootmap.h
>> +++ b/pc-bios/s390-ccw/bootmap.h
>> @@ -68,7 +68,7 @@ typedef struct ComponentEntry {
>>   ScsiBlockPtr data;
>>   uint8_t pad[7];
>>   uint8_t component_type;
>> -uint64_t load_address;
>> +uint64_t psw;
> 
> I'd recommend to keep the load_address name. It's the same name as used 
> in the zipl sources, and as far as I can see, the field does not always 
> contain a PSW.

The problem is that this is a union in zipl containing an address, psw
or signature header.

I guess we should also make it a union and use the proper members so it
is clear what we retrieve from the entry. If it is a PSW we need to mask
it if it is a component address masking might be a bad idea.

But I absolutely do not want to have this named PSW and then being used
like a normal address. It took me way too long to figure out why my
guest wasn't booting anymore.

Time for a new series of patches :)

> 
>>   } __attribute((packed)) ComponentEntry;
>>   
>>   typedef struct ComponentHeader {
>>
> 
>   Thomas
> 




signature.asc
Description: OpenPGP digital signature


Re: [RFC v5 12/12] pc-bios: s390x: Cleanup jump to ipl code

2020-06-26 Thread Janosch Frank
On 6/25/20 2:58 PM, Thomas Huth wrote:
> On 24/06/2020 09.52, Janosch Frank wrote:
>> jump_to_IPL_code takes a 64 bit address, masks it with the short psw
>> address mask and later branches to it using a full 64 bit register.
>>
>> * As the masking is not necessary, let's remove it
>> * Without the mask we can save the ipl address to a static 64 bit
>>function ptr as we later branch to it
>> * Let's also clean up the variable names and remove the now unneeded
>>ResetInfo
>>
>> Signed-off-by: Janosch Frank 
>> ---
>>   pc-bios/s390-ccw/jump2ipl.c | 27 +++
>>   1 file changed, 11 insertions(+), 16 deletions(-)
>>
>> diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
>> index 767012bf0c..aef37cea76 100644
>> --- a/pc-bios/s390-ccw/jump2ipl.c
>> +++ b/pc-bios/s390-ccw/jump2ipl.c
>> @@ -13,20 +13,15 @@
>>   #define KERN_IMAGE_START 0x01UL
>>   #define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_64)
>>   
>> -typedef struct ResetInfo {
>> -uint64_t ipl_psw;
>> -uint32_t ipl_continue;
>> -} ResetInfo;
>> -
>> -static ResetInfo save;
>> +static void (*ipl_continue)(void);
>> +static uint64_t psw_save;
> 
> I wonder whether there was a reason for having ipl_continue in the 
> lowcore instead of using a simple static function pointer... Christian, 
> do you remember?
> 
>>   static void jump_to_IPL_2(void)
>>   {
>> -ResetInfo *current = 0;
>> +uint64_t *psw_current = 0;
> 
> Mhh, what about using uint64_t *psw_current = (uint64_t *)lowcore 
> instead, to make it more more explicit?

Sure, that would make it way better to read.

> 
>> -void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue;
>> -*current = save;
>> -ipl(); /* should not return */
>> +*psw_current = psw_save;
>> +ipl_continue(); /* should not return */
>>   }
>>   
>>   void jump_to_IPL_code(uint64_t address)
>> @@ -46,15 +41,15 @@ void jump_to_IPL_code(uint64_t address)
>>* content of non-BIOS memory after we loaded the guest, so we
>>* save the original content and restore it in jump_to_IPL_2.
>>*/
>> -ResetInfo *current = 0;
>> +uint64_t *psw_current = 0;
> 
> dito.
> 
>> -save = *current;
>> +psw_save = *psw_current;
>>   
>> -current->ipl_psw = (uint64_t) &jump_to_IPL_2;
>> -current->ipl_psw |= RESET_PSW_MASK;
>> -current->ipl_continue = address & PSW_MASK_SHORT_ADDR;
>> +*psw_current = (uint64_t) &jump_to_IPL_2;
>> +*psw_current |= RESET_PSW_MASK;
>> +ipl_continue = (void *)address;
>>   
>> -debug_print_int("set IPL addr to", current->ipl_continue);
>> +debug_print_int("set IPL addr to", (uint64_t)ipl_continue);
>>   
>>   /* Ensure the guest output starts fresh */
>>   sclp_print("\n");
>>
> 
> The patch sounds like a good idea to me ... but since this code proofed 
> to be very fragile in the past, let's wait for Christian to say whether 
> there was a good reason for ipl_continue in the lowcore or not.

This is a RFC and will need a lot of testing.
I guess I'll move patch 11 and 12 of this series into a new one and also
fix some more boot related stuff so this becomes less maze like.

> 
>   Thomas
> 
> 




signature.asc
Description: OpenPGP digital signature


Re: [PATCH 0/2] block: propagate discard alignment from format drivers to the guest

2020-06-26 Thread Denis V. Lunev
On 6/11/20 8:16 PM, Denis V. Lunev wrote:
> Nowaday SCSI drivers in guests are able to align UNMAP requests before
> sending to the device. Right now QEMU provides an ability to set
> this via "discard_granularity" property of the block device which could
> be used by management layer.
>
> Though, in particular, from the point of QEMU, there is
> pdiscard_granularity on the format driver level, f.e. on QCOW2 or iSCSI.
> It would be beneficial to pass this value as a default for this
> property.
>
> Technically this should reduce the amount of use less UNMAP requests
> from the guest to the host. Basic test confirms this. Fedora 31 guest
> during 'fstrim /' on 32 Gb disk has issued 401/415 requests with/without
> proper alignment to QEMU.
>
> Changes from v2:
> - 172 iotest fixed
>
> Changes from v1:
> - fixed typos in description
> - added machine type compatibility layer as suggested by Kevin
>
> Signed-off-by: Denis V. Lunev 
> CC: Kevin Wolf 
> CC: Max Reitz 
> CC: Eduardo Habkost 
> CC: Marcel Apfelbaum 
> CC: John Snow 
> CC: Paolo Bonzini 
> CC: Fam Zheng 
>
>
ping v2



Re: [PULL 0/4] target/xtensa fixes

2020-06-26 Thread Peter Maydell
On Thu, 25 Jun 2020 at 09:11, Max Filippov  wrote:
>
> Hi Peter,
>
> please pull the following batch of fixes for the target/xtensa.
>
> The following changes since commit 648db19685b7030aa558a4ddbd3a8e53d8c9a062:
>
>   Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2020-04-29' 
> into staging (2020-04-29 15:07:33 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/OSLL/qemu-xtensa.git tags/20200625-xtensa
>
> for you to fetch changes up to 8a3a81478dcc592518069125a6ad271fe5511b95:
>
>   target/xtensa: drop gen_io_end call (2020-06-22 03:38:30 -0700)
>
> 
> target/xtensa fixes for 5.1:
>
> - fix access to special registers missing in the core configuration;
> - fix simcall opcode behavior for new hardware;
> - drop gen_io_end call from xtensa translator.
>
> 


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.1
for any user-visible changes.

-- PMM



Re: [PATCH] hw/arm: Add 'virtm' hardware

2020-06-26 Thread Peter Maydell
On Fri, 26 Jun 2020 at 00:07, Keith Packard  wrote:
>
> 'virtm' is a hardware target that is designed to be used for compiler
> and library testing on Cortex-M processors. It supports all cortex-m
> processors and includes sufficient memory to run even large test
> cases.
>
> Signed-off-by: Keith Packard 

So, I'm really dubious about adding more "virtual"
not-real-hardware boards. We have "virt" because we
absolutely have to have it for KVM purposes; but otherwise
"emulate real hardware" gives us a concrete specification
of what we're trying to do and tends to lead us into fewer
messy swamps than making up virtual platforms does.

For instance, this board model claims to handle the M33
but makes no attempt to set up any of the TrustZone
related components like the IDAU, so it isn't really
a useful platform for that CPU. You also enable bitband,
which is maybe plausible for Cortex-M3/M4 but not for the
others. This is the kind of area where having a real
hardware system to check against means we make the
right choices about what does or doesn't need to be
present.

thanks
-- PMM



Re: [PATCH v3] build: Haiku build fix

2020-06-26 Thread Peter Maydell
On Thu, 25 Jun 2020 at 22:31, David CARLIER  wrote:
>
> From 78706a28c6aa8b5e522b5781588b38961d79d6f6 Mon Sep 17 00:00:00 2001
> From: David Carlier 
> Date: Thu, 25 Jun 2020 19:32:42 +
> Subject: [PATCH] build: haiku system build fix
>
> Most of missing features resides in the bsd library.
> Also defining constant equivalence.
>
> Signed-off-by: David Carlier 
> ---
>  configure| 34 --
>  include/qemu/bswap.h |  2 ++
>  include/qemu/osdep.h |  4 
>  os-posix.c   |  4 
>  util/Makefile.objs   |  2 +-
>  util/compatfd.c  |  2 ++
>  util/main-loop.c |  1 +
>  util/oslib-posix.c   | 20 
>  util/qemu-openpty.c  |  2 +-
>  9 files changed, 67 insertions(+), 4 deletions(-)

Would you mind splitting this into a patchset which has
one patch for each fix, please? So a patch which makes
configure probe for openpty-in-pty.h and use it,
another patch for the mlockall change, another patch
for haiku-implementation-of-qemu_init_exec_dir, and so on.
We generally prefer each commit to do one thing; it's
easier to review.

thanks
-- PMM



Re: [PATCH v5 2/5] virtio-iommu: Implement RESV_MEM probe request

2020-06-26 Thread Markus Armbruster
Auger Eric  writes:

> Hi Markus,
> On 6/25/20 9:05 AM, Markus Armbruster wrote:
>> Eric Auger  writes:
>> 
>>> This patch implements the PROBE request. At the moment,
>>> only THE RESV_MEM property is handled. The first goal is
>>> to report iommu wide reserved regions such as the MSI regions
>>> set by the machine code. On x86 this will be the IOAPIC MSI
>>> region, [0xFEE0 - 0xFEEF], on ARM this may be the ITS
>>> doorbell.
>>>
>>> In the future we may introduce per device reserved regions.
>>> This will be useful when protecting host assigned devices
>>> which may expose their own reserved regions
>>>
>>> Signed-off-by: Eric Auger 
>>> Reviewed-by: Jean-Philippe Brucker 
>>>
>>> ---
>>>
>>> v4 -> v5:
>>> - assert if reserved region type is different from RESERVED or
>>>   MSI
>>>
>>> v3 -> v4:
>>> - removed any reference to the NONE property that does not
>>>   exist anymore.
>>>
>>> v2 -> v3:
>>> - on probe, do not fill the reminder of the buffer with zeroes
>>>   as the buffer was already zero initialized (Bharat)
>>>
>>> v1 -> v2:
>>> - move the unlock back to the same place
>>> - remove the push label and factorize the code after the out label
>>> - fix a bunch of cpu_to_leX according to the latest spec revision
>>> - do not remove sizeof(last) from free space
>>> - check the ep exists
>>> ---
>>>  include/hw/virtio/virtio-iommu.h |  2 +
>>>  hw/virtio/virtio-iommu.c | 92 ++--
>>>  hw/virtio/trace-events   |  1 +
>>>  3 files changed, 91 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/include/hw/virtio/virtio-iommu.h 
>>> b/include/hw/virtio/virtio-iommu.h
>>> index e653004d7c..49eb105cd8 100644
>>> --- a/include/hw/virtio/virtio-iommu.h
>>> +++ b/include/hw/virtio/virtio-iommu.h
>>> @@ -53,6 +53,8 @@ typedef struct VirtIOIOMMU {
>>>  GHashTable *as_by_busptr;
>>>  IOMMUPciBus *iommu_pcibus_by_bus_num[PCI_BUS_MAX];
>>>  PCIBus *primary_bus;
>>> +ReservedRegion *reserved_regions;
>>> +uint32_t nb_reserved_regions;
>>>  GTree *domains;
>>>  QemuMutex mutex;
>>>  GTree *endpoints;
>>> diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
>>> index 483883ec1d..aabc3e36b1 100644
>>> --- a/hw/virtio/virtio-iommu.c
>>> +++ b/hw/virtio/virtio-iommu.c
>>> @@ -38,6 +38,7 @@
>>>  
>>>  /* Max size */
>>>  #define VIOMMU_DEFAULT_QUEUE_SIZE 256
>>> +#define VIOMMU_PROBE_SIZE 512
>>>  
>>>  typedef struct VirtIOIOMMUDomain {
>>>  uint32_t id;
>>> @@ -378,6 +379,63 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
>>>  return ret;
>>>  }
>>>  
>>> +static ssize_t virtio_iommu_fill_resv_mem_prop(VirtIOIOMMU *s, uint32_t ep,
>>> +   uint8_t *buf, size_t free)
>>> +{
>>> +struct virtio_iommu_probe_resv_mem prop = {};
>>> +size_t size = sizeof(prop), length = size - sizeof(prop.head), total;
>>> +int i;
>>> +
>>> +total = size * s->nb_reserved_regions;
>>> +
>>> +if (total > free) {
>>> +return -ENOSPC;
>>> +}
>>> +
>>> +for (i = 0; i < s->nb_reserved_regions; i++) {
>>> +prop.head.type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM);
>>> +prop.head.length = cpu_to_le16(length);
>>> +prop.subtype = s->reserved_regions[i].type;
>>> +assert(prop.subtype == VIRTIO_IOMMU_RESV_MEM_T_RESERVED ||
>>> +   prop.subtype == VIRTIO_IOMMU_RESV_MEM_T_MSI);
>> 
>> The assertion makes sense here: we're mapping from the generic
>> ReservedRegion type (which is unsigned) to the specific
>> virtio_iommu_probe_resv_mem subtype (which is uint8_t, but only these
>> two values are valid).
>> 
>> Howver, the assertion should test s->reserved_regions[i].type and go
>> before the assignment, to ensure it doesn't truncate!
> OK I will do.
>> 
>> Can I trigger the assertion with -device?  My try to find the answer
>> myself failed:
> At the moment the virtio-iommu-pci device only can be instantiated with
> machvirt, booting in dt mode.

I asked because if I can, then invalid types need to be rejected
cleanly.

Invalid property values can be rejected by the setter, or by the realize
method.  Since this setter by design accepts anything that fits into
unsigned, it's realize.

[...]




Re: [PATCH v6 1/2] target/arm: kvm: Handle DABT with no valid ISS

2020-06-26 Thread Andrew Jones
On Thu, Jun 25, 2020 at 11:03:35PM +0100, Beata Michalska wrote:
> On ARMv7 & ARMv8 some load/store instructions might trigger a data abort
> exception with no valid ISS info to be decoded. The lack of decode info
> makes it at least tricky to emulate those instruction which is one of the
> (many) reasons why KVM will not even try to do so.
> 
> Add support for handling those by requesting KVM to inject external
> dabt into the quest.
> 
> Signed-off-by: Beata Michalska 
> ---
>  target/arm/kvm.c | 59 
> +++-
>  1 file changed, 58 insertions(+), 1 deletion(-)
> 
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index eef3bbd..265c4b8 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -39,6 +39,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>  
>  static bool cap_has_mp_state;
>  static bool cap_has_inject_serror_esr;
> +static bool cap_has_inject_ext_dabt;
>  
>  static ARMHostCPUFeatures arm_host_cpu_features;
>  
> @@ -245,6 +246,16 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
>  ret = -EINVAL;
>  }
>  
> +if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
> +if (kvm_vm_enable_cap(s, KVM_CAP_ARM_NISV_TO_USER, 0)) {
> +error_report("Failed to enable KVM_CAP_ARM_NISV_TO_USER cap");
> +} else {
> +/* Set status for supporting the external dabt injection */
> +cap_has_inject_ext_dabt = kvm_check_extension(s,
> +KVM_CAP_ARM_INJECT_EXT_DABT);
> +}
> +}
> +
>  return ret;
>  }
>  
> @@ -810,6 +821,47 @@ void kvm_arm_vm_state_change(void *opaque, int running, 
> RunState state)
>  }
>  }
>  
> +/**
> + * kvm_arm_handle_dabt_nisv:
> + * @cs: CPUState
> + * @esr_iss: ISS encoding (limited) for the exception from Data Abort
> + *   ISV bit set to '0b0' -> no valid instruction syndrome
> + * @fault_ipa: faulting address for the synchronous data abort
> + *
> + * Returns: 0 if the exception has been handled, < 0 otherwise
> + */
> +static int kvm_arm_handle_dabt_nisv(CPUState *cs, uint64_t esr_iss,
> + uint64_t fault_ipa)
> +{
> +/*
> + * Request KVM to inject the external data abort into the guest
> + */
> +if (cap_has_inject_ext_dabt) {
> +struct kvm_vcpu_events events;
> +/*
> + * KVM_CAP_ARM_INJECT_EXT_DABT support implies one for
> + * KVM_CAP_VCPU_EVENTS

KVM_CAP_ARM_INJECT_EXT_DABT implies KVM_CAP_VCPU_EVENTS

And this comment should probably come just before the
KVM_SET_VCPU_EVENTS ioctl.

> + */
> +memset(&events, 0, sizeof(events));

nit: How about using '= {0}' when declaring the variable, rather than this
memset?

> +/*
> + * Skipping all the overhead of syncing vcpu regs back and forth
> + * and messing around with the vcpu_dirty flag to avoid
> + * overwriting changes done by KVM : directly calling
> + * the associated ioctl with the status set for external data abort,
> + * which, in turn, will be directly delivered to the affected vcpu.

The external data abort event will be handled immediately by KVM and does
not need any other CPU state. This means we can skip CPU synchronization
and set this event, but only this event, here.

> + */
> +events.exception.ext_dabt_pending = 1;
> +
> +return kvm_vcpu_ioctl(cs, KVM_SET_VCPU_EVENTS, &events);
> +} else {
> +error_report("Data abort exception triggered by guest memory access "
> + "at physical address: 0x"  TARGET_FMT_lx,
> + (target_ulong)fault_ipa);
> +error_printf("KVM unable to emulate faulting instruction.\n");
> +}
> +return -1;
> +}
> +
>  int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
>  {
>  int ret = 0;
> @@ -820,7 +872,12 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
> *run)
>  ret = EXCP_DEBUG;
>  } /* otherwise return to guest */
>  break;
> -default:
> +case KVM_EXIT_ARM_NISV:
> +/* External DABT with no valid iss to decode */
> +ret = kvm_arm_handle_dabt_nisv(cs, run->arm_nisv.esr_iss,
> +   run->arm_nisv.fault_ipa);
> +break;
> + default:
>  qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
>__func__, run->exit_reason);
>  break;
> -- 
> 2.7.4
> 
> 

Besides the suggested comment changes and the memset nit

Reviewed-by: Andrew Jones 

Thanks,
drew




Re: [PATCH v3 0/9] Generalize memory encryption models

2020-06-26 Thread Janosch Frank
On 6/26/20 8:53 AM, David Hildenbrand wrote:
> Does this have any implications when probing with the 'none' machine?

 I'm not sure.  In your case, I guess the cpu bit would still show up
 as before, so it would tell you base feature availability, but not
 whether you can use the new configuration option.

 Since the HTL option is generic, you could still set it on the "none"
 machine, though it wouldn't really have any effect.  That is, if you
 could create a suitable object to point it at, which would depend on
 ... details.

>>>
>>> The important point is that we never want the (expanded) host cpu model
>>> look different when either specifying or not specifying the HTL
>>> property.
>>
>> Ah, yes, I see your point.  So my current suggestion will satisfy
>> that, basically it is:
>>
>> cpu has unpack (inc. by default) && htl specified
>>  => works (allowing secure), as expected
> 
> ack
> 
>>
>> !cpu has unpack && htl specified
>>  => bails out with an error
> 
> ack
> 
>>
>> !cpu has unpack && !htl specified
>>  => works for a non-secure guest, as expected
>>  => guest will fail if it attempts to go secure
> 
> ack, behavior just like running on older hw without unpack
> 
>>
>> cpu has unpack && !htl specified
>>  => works as expected for a non-secure guest (unpack feature is
>> present, but unused)
>>  => secure guest may work "by accident", but only if all virtio
>> properties have the right values, which is the user's
>> problem
>>
>> That last case is kinda ugly, but I think it's tolerable.
> 
> Right, we must not affect non-secure guests, and existing secure setups
> (e.g., older qemu machines). Will have to think about this some more,
> but does not sound too crazy.

I severely dislike having to specify things to make PV work.
The IOMMU is already a thorn in our side and we're working on making the
whole ordeal completely transparent so the only requirement to make this
work is the right machine, kernel, qemu and kernel cmd line option
"prot_virt=1". That's why we do the reboot into PV mode in the first place.

I.e. the goal is that if customers convert compatible guests into
protected ones and start them up on a z15 on a distro with PV support
they can just use the guest without having to change XML or command line
parameters.

Internal customers have already created bugs because they did not follow
the documentation and the more cmd options we bring the more bugzillas
we'll get.

PV is already in the field/GA and can be ordered, as is our documentation.

@Christian: Please chime in here

> 
> Thanks!
> 




signature.asc
Description: OpenPGP digital signature


Re: [PATCH v5 2/5] virtio-iommu: Implement RESV_MEM probe request

2020-06-26 Thread Auger Eric
Hi Markus

On 6/26/20 10:53 AM, Markus Armbruster wrote:
> Auger Eric  writes:
> 
>> Hi Markus,
>> On 6/25/20 9:05 AM, Markus Armbruster wrote:
>>> Eric Auger  writes:
>>>
 This patch implements the PROBE request. At the moment,
 only THE RESV_MEM property is handled. The first goal is
 to report iommu wide reserved regions such as the MSI regions
 set by the machine code. On x86 this will be the IOAPIC MSI
 region, [0xFEE0 - 0xFEEF], on ARM this may be the ITS
 doorbell.

 In the future we may introduce per device reserved regions.
 This will be useful when protecting host assigned devices
 which may expose their own reserved regions

 Signed-off-by: Eric Auger 
 Reviewed-by: Jean-Philippe Brucker 

 ---

 v4 -> v5:
 - assert if reserved region type is different from RESERVED or
   MSI

 v3 -> v4:
 - removed any reference to the NONE property that does not
   exist anymore.

 v2 -> v3:
 - on probe, do not fill the reminder of the buffer with zeroes
   as the buffer was already zero initialized (Bharat)

 v1 -> v2:
 - move the unlock back to the same place
 - remove the push label and factorize the code after the out label
 - fix a bunch of cpu_to_leX according to the latest spec revision
 - do not remove sizeof(last) from free space
 - check the ep exists
 ---
  include/hw/virtio/virtio-iommu.h |  2 +
  hw/virtio/virtio-iommu.c | 92 ++--
  hw/virtio/trace-events   |  1 +
  3 files changed, 91 insertions(+), 4 deletions(-)

 diff --git a/include/hw/virtio/virtio-iommu.h 
 b/include/hw/virtio/virtio-iommu.h
 index e653004d7c..49eb105cd8 100644
 --- a/include/hw/virtio/virtio-iommu.h
 +++ b/include/hw/virtio/virtio-iommu.h
 @@ -53,6 +53,8 @@ typedef struct VirtIOIOMMU {
  GHashTable *as_by_busptr;
  IOMMUPciBus *iommu_pcibus_by_bus_num[PCI_BUS_MAX];
  PCIBus *primary_bus;
 +ReservedRegion *reserved_regions;
 +uint32_t nb_reserved_regions;
  GTree *domains;
  QemuMutex mutex;
  GTree *endpoints;
 diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
 index 483883ec1d..aabc3e36b1 100644
 --- a/hw/virtio/virtio-iommu.c
 +++ b/hw/virtio/virtio-iommu.c
 @@ -38,6 +38,7 @@
  
  /* Max size */
  #define VIOMMU_DEFAULT_QUEUE_SIZE 256
 +#define VIOMMU_PROBE_SIZE 512
  
  typedef struct VirtIOIOMMUDomain {
  uint32_t id;
 @@ -378,6 +379,63 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
  return ret;
  }
  
 +static ssize_t virtio_iommu_fill_resv_mem_prop(VirtIOIOMMU *s, uint32_t 
 ep,
 +   uint8_t *buf, size_t free)
 +{
 +struct virtio_iommu_probe_resv_mem prop = {};
 +size_t size = sizeof(prop), length = size - sizeof(prop.head), total;
 +int i;
 +
 +total = size * s->nb_reserved_regions;
 +
 +if (total > free) {
 +return -ENOSPC;
 +}
 +
 +for (i = 0; i < s->nb_reserved_regions; i++) {
 +prop.head.type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM);
 +prop.head.length = cpu_to_le16(length);
 +prop.subtype = s->reserved_regions[i].type;
 +assert(prop.subtype == VIRTIO_IOMMU_RESV_MEM_T_RESERVED ||
 +   prop.subtype == VIRTIO_IOMMU_RESV_MEM_T_MSI);
>>>
>>> The assertion makes sense here: we're mapping from the generic
>>> ReservedRegion type (which is unsigned) to the specific
>>> virtio_iommu_probe_resv_mem subtype (which is uint8_t, but only these
>>> two values are valid).
>>>
>>> Howver, the assertion should test s->reserved_regions[i].type and go
>>> before the assignment, to ensure it doesn't truncate!
>> OK I will do.
>>>
>>> Can I trigger the assertion with -device?  My try to find the answer
>>> myself failed:
>> At the moment the virtio-iommu-pci device only can be instantiated with
>> machvirt, booting in dt mode.
> 
> I asked because if I can, then invalid types need to be rejected
> cleanly.
> 
> Invalid property values can be rejected by the setter, or by the realize
> method.  Since this setter by design accepts anything that fits into
> unsigned, it's realize.

OK. Then the place where I do the assert is not the right one as this
will happen later. Probe request is triggered by the guest virtio-iommu
driver.

Thanks

Eric
> 
> [...]
> 




Re: [Bug 1885247] [NEW] Build error in Intel 32-bit hosts

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/26/20 9:37 AM, Aleksandar Markovic wrote:
> пет, 26. јун 2020. у 09:11 Aleksandar Markovic
> <1885...@bugs.launchpad.net> је написао/ла:
>>
>> Public bug reported:
>>
>> The code base is on master, checked out on Thursday June25th 2020,
>> 0250c595c9d. The build procedure:
>>
>> $ mkdir build-gcc
>> $ cd build-gcc
>> $ ../configure
>> $ make
>>
>> The build error message is:
>>
>>   CC  x86_64-softmmu/hw/hyperv/hyperv.o
>>   CC  x86_64-softmmu/hw/hyperv/hyperv_testdev.o
>>   CC  x86_64-softmmu/hw/hyperv/vmbus.o
>> /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c: In function ‘gpadl_iter_io’:
>> /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c:386:13: error: cast to 
>> pointer from integer of different size [-Werror=int-to-pointer-cast]
>>  p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) | 
>> off_in_page);
>>  ^
>> cc1: all warnings being treated as errors
>> make[1]: *** [/home/rtrk/Build/qemu-master/rules.mak:69: hw/hyperv/vmbus.o] 
>> Error 1
>> make: *** [Makefile:527: x86_64-softmmu/all] Error 2

FWIW there is no CI job covering x86 KVM on 32-bit host build.
Should this be covered? I guess the problem is no CI services
provide 32-bit x86...




Re: [PATCH v6 2/2] target/arm: kvm: Handle misconfigured dabt injection

2020-06-26 Thread Andrew Jones
On Thu, Jun 25, 2020 at 11:03:36PM +0100, Beata Michalska wrote:
> Injecting external data abort through KVM might trigger
> an issue on kernels that do not get updated to include the KVM fix.
> For those and aarch32 guests, the injected abort gets misconfigured
> to be an implementation defined exception. This leads to the guest
> repeatedly re-running the faulting instruction.
> 
> Add support for handling that case.
> 
> [
>   Fixed-by: 018f22f95e8a
>   ('KVM: arm: Fix DFSR setting for non-LPAE aarch32 guests')
>   Fixed-by: 21aecdbd7f3a
>   ('KVM: arm: Make inject_abt32() inject an external abort instead')
> ]
> 
> Signed-off-by: Beata Michalska 
> ---
>  target/arm/cpu.h |  2 ++
>  target/arm/kvm.c | 30 +-
>  target/arm/kvm32.c   | 34 ++
>  target/arm/kvm64.c   | 49 +
>  target/arm/kvm_arm.h | 10 ++
>  5 files changed, 124 insertions(+), 1 deletion(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 677584e..ed0ff09 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -570,6 +570,8 @@ typedef struct CPUARMState {
>  uint64_t esr;
>  } serror;
>  
> +uint8_t ext_dabt_raised; /* Tracking/verifying injection of ext DABT */
> +
>  /* State of our input IRQ/FIQ/VIRQ/VFIQ lines */
>  uint32_t irq_line_state;
>  
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 265c4b8..85a09ea 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -749,6 +749,29 @@ int kvm_get_vcpu_events(ARMCPU *cpu)
>  
>  void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
>  {
> +ARMCPU *cpu = ARM_CPU(cs);
> +CPUARMState *env = &cpu->env;
> +
> +if (unlikely(env->ext_dabt_raised)) {
> +/*
> + * Verifying that the ext DABT has been properly injected,
> + * otherwise risking indefinitely re-running the faulting instruction
> + * Covering a very narrow case for kernels 5.5..5.5.4
> + * when injected abort was misconfigured to be
> + * an IMPLEMENTATION DEFINED exception (for 32-bit EL1)
> + */
> +if (!arm_feature(env, ARM_FEATURE_AARCH64) &&
> +unlikely(!kvm_arm_verify_ext_dabt_pending(cs))) {
> +
> +error_report("Data abort exception with no valid ISS generated 
> by "
> +   "guest memory access. KVM unable to emulate faulting "
> +   "instruction. Failed to inject an external data abort "
> +   "into the guest.");
> +abort();
> +   }
> +   /* Clear the status */
> +   env->ext_dabt_raised = 0;
> +}
>  }
>  
>  MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
> @@ -833,6 +856,8 @@ void kvm_arm_vm_state_change(void *opaque, int running, 
> RunState state)
>  static int kvm_arm_handle_dabt_nisv(CPUState *cs, uint64_t esr_iss,
>   uint64_t fault_ipa)
>  {
> +ARMCPU *cpu = ARM_CPU(cs);
> +CPUARMState *env = &cpu->env;
>  /*
>   * Request KVM to inject the external data abort into the guest
>   */
> @@ -852,7 +877,10 @@ static int kvm_arm_handle_dabt_nisv(CPUState *cs, 
> uint64_t esr_iss,
>   */
>  events.exception.ext_dabt_pending = 1;
>  
> -return kvm_vcpu_ioctl(cs, KVM_SET_VCPU_EVENTS, &events);
> +if (!kvm_vcpu_ioctl(cs, KVM_SET_VCPU_EVENTS, &events)) {
> +env->ext_dabt_raised = 1;
> +return 0;
> +}
>  } else {
>  error_report("Data abort exception triggered by guest memory access "
>   "at physical address: 0x"  TARGET_FMT_lx,
> diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
> index 7b3a19e..0af46b4 100644
> --- a/target/arm/kvm32.c
> +++ b/target/arm/kvm32.c
> @@ -559,3 +559,37 @@ void kvm_arm_pmu_init(CPUState *cs)
>  {
>  qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
>  }
> +
> +#define ARM_REG_DFSR  ARM_CP15_REG32(0, 5, 0, 0)
> +#define ARM_REG_TTBCR ARM_CP15_REG32(0, 2, 0, 2)
> +/*
> + *DFSR:
> + *  TTBCR.EAE == 0
> + *  FS[4]   - DFSR[10]
> + *  FS[3:0] - DFSR[3:0]
> + *  TTBCR.EAE == 1
> + *  FS, bits [5:0]
> + */
> +#define DFSR_FSC(lpae, v) \
> +((lpae) ? ((v) & 0x3F) : (((v) >> 6) | ((v) & 0x1F)))
> +
> +#define DFSC_EXTABT(lpae) ((lpae) ? 0x10 : 0x08)
> +
> +bool kvm_arm_verify_ext_dabt_pending(CPUState *cs)
> +{
> +uint32_t dfsr_val;
> +
> +if (!kvm_get_one_reg(cs, ARM_REG_DFSR, &dfsr_val)) {
> +ARMCPU *cpu = ARM_CPU(cs);
> +CPUARMState *env = &cpu->env;
> +uint32_t ttbcr;
> +int lpae = 0;
> +
> +if (!kvm_get_one_reg(cs, ARM_REG_TTBCR, &ttbcr)) {
> +lpae = arm_feature(env, ARM_FEATURE_LPAE) && (ttbcr & TTBCR_EAE);
> +}
> +/* The verification is based on FS filed of the DFSR reg only*/
> +return (DFSR_FSC(lpae, dfsr_val) == DFSC_EXTABT(lpae));
> +}
> +   

[Bug 1885247] Re: Build error in Intel 32-bit hosts

2020-06-26 Thread Peter Maydell
I suspect an extra uintptr_t cast will fix this:

p = (void *)(uintptr_t)(((uintptr_t)iter->map & TARGET_PAGE_MASK) |
off_in_page);

Which looks kind of ugly but then the code is taking a host void*
(iter->map), casting it to integer to do arithmetic on and then wanting
to get it back to a void* which is inherently going to result in a mess
of casting...

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

Title:
  Build error in Intel 32-bit hosts

Status in QEMU:
  New

Bug description:
  The code base is on master, checked out on Thursday June25th 2020,
  0250c595c9d. The build procedure:

  $ mkdir build-gcc
  $ cd build-gcc
  $ ../configure
  $ make

  The build error message is:

CC  x86_64-softmmu/hw/hyperv/hyperv.o
CC  x86_64-softmmu/hw/hyperv/hyperv_testdev.o
CC  x86_64-softmmu/hw/hyperv/vmbus.o
  /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c: In function ‘gpadl_iter_io’:
  /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c:386:13: error: cast to pointer 
from integer of different size [-Werror=int-to-pointer-cast]
   p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) | 
off_in_page);
   ^
  cc1: all warnings being treated as errors
  make[1]: *** [/home/rtrk/Build/qemu-master/rules.mak:69: hw/hyperv/vmbus.o] 
Error 1
  make: *** [Makefile:527: x86_64-softmmu/all] Error 2

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



Re: [PATCH 00/17] block/nvme: Various cleanups required to use multiple queues

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/25/20 9:27 PM, no-re...@patchew.org wrote:
> Patchew URL: 
> https://patchew.org/QEMU/20200625184838.28172-1-phi...@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  block/write-threshold.o
>   CC  block/backup.o
> /tmp/qemu-test/src/block/nvme.c: In function 'nvme_identify':
> /tmp/qemu-test/src/block/nvme.c:455:5: error: implicit declaration of 
> function 'MAX_CONST' [-Werror=implicit-function-declaration]
>  idsz_max = MAX_CONST(sizeof(NvmeIdCtrl), sizeof(NvmeIdNs));
>  ^

I include in the cover:

Based-on: <20200625162602.700741-1-ebl...@redhat.com>

Is patchew confused?

Ah, I get 404 on:
https://patchew.org/QEMU/20200625162602.700741-1-ebl...@redhat.com/

So the mail got lost, 'Based-on' tag is ignored and the series still
applied?




Re: [Bug 1885247] [NEW] Build error in Intel 32-bit hosts

2020-06-26 Thread Thomas Huth

On 26/06/2020 11.13, Philippe Mathieu-Daudé wrote:

On 6/26/20 9:37 AM, Aleksandar Markovic wrote:

пет, 26. јун 2020. у 09:11 Aleksandar Markovic
<1885...@bugs.launchpad.net> је написао/ла:


Public bug reported:

The code base is on master, checked out on Thursday June25th 2020,
0250c595c9d. The build procedure:

$ mkdir build-gcc
$ cd build-gcc
$ ../configure
$ make

The build error message is:

   CC  x86_64-softmmu/hw/hyperv/hyperv.o
   CC  x86_64-softmmu/hw/hyperv/hyperv_testdev.o
   CC  x86_64-softmmu/hw/hyperv/vmbus.o
/home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c: In function ‘gpadl_iter_io’:
/home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c:386:13: error: cast to pointer 
from integer of different size [-Werror=int-to-pointer-cast]
  p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) | off_in_page);
  ^
cc1: all warnings being treated as errors
make[1]: *** [/home/rtrk/Build/qemu-master/rules.mak:69: hw/hyperv/vmbus.o] 
Error 1
make: *** [Makefile:527: x86_64-softmmu/all] Error 2


FWIW there is no CI job covering x86 KVM on 32-bit host build.
Should this be covered? I guess the problem is no CI services
provide 32-bit x86...


You can certainly provide either a container, or install the 32-bit 
libraries in a 64-bit environment. Then run


PKG_CONFIG_LIBDIR=... ./configure --extra-cflags=-m32

and it should be possible to build 32-bit binaries, too.

Alternatively, we could add a cross-compilation job that builds with 
i686-w64-mingw32 in 32-bit.


 Thomas




[PULL 02/22] adb: fix adb-mouse read length and revert disable-reg3-direct-writes workaround

2020-06-26 Thread Mark Cave-Ayland
Commit 84051eb400 "adb: add property to disable direct reg 3 writes" introduced
a workaround for spurious writes to ADB register 3 when MacOS 9 enables
autopoll on the mouse device. Further analysis shows that the problem is that
only a partial request is sent, and since the len parameter is ignored then
stale data from the previous request is used causing the incorrect address
assignment.

Remove the disable-reg3-direct-writes workaround and instead check the length
parameter when the write is attempted, discarding the invalid request.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-3-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb-kbd.c | 26 +++
 hw/input/adb-mouse.c   | 48 --
 hw/input/adb.c |  7 --
 hw/ppc/mac_newworld.c  |  2 --
 include/hw/input/adb.h |  1 -
 5 files changed, 40 insertions(+), 44 deletions(-)

diff --git a/hw/input/adb-kbd.c b/hw/input/adb-kbd.c
index a6d5c9b7c9..027dd3e531 100644
--- a/hw/input/adb-kbd.c
+++ b/hw/input/adb-kbd.c
@@ -259,21 +259,19 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
 trace_adb_kbd_request_change_addr(d->devaddr);
 break;
 default:
-if (!d->disable_direct_reg3_writes) {
-d->devaddr = buf[1] & 0xf;
-
-/* we support handlers:
- * 1: Apple Standard Keyboard
- * 2: Apple Extended Keyboard (LShift = RShift)
- * 3: Apple Extended Keyboard (LShift != RShift)
- */
-if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) {
-d->handler = buf[2];
-}
-
-trace_adb_kbd_request_change_addr_and_handler(d->devaddr,
-  d->handler);
+d->devaddr = buf[1] & 0xf;
+/*
+ * we support handlers:
+ * 1: Apple Standard Keyboard
+ * 2: Apple Extended Keyboard (LShift = RShift)
+ * 3: Apple Extended Keyboard (LShift != RShift)
+ */
+if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) {
+d->handler = buf[2];
 }
+
+trace_adb_kbd_request_change_addr_and_handler(d->devaddr,
+  d->handler);
 break;
 }
 }
diff --git a/hw/input/adb-mouse.c b/hw/input/adb-mouse.c
index aeba41bddd..78b6f5030c 100644
--- a/hw/input/adb-mouse.c
+++ b/hw/input/adb-mouse.c
@@ -135,6 +135,16 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 case 2:
 break;
 case 3:
+/*
+ * MacOS 9 has a bug in its ADB driver whereby after configuring
+ * the ADB bus devices it sends another write of invalid length
+ * to reg 3. Make sure we ignore it to prevent an address clash
+ * with the previous device.
+ */
+if (len != 3) {
+return 0;
+}
+
 switch (buf[2]) {
 case ADB_CMD_SELF_TEST:
 break;
@@ -145,27 +155,25 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 trace_adb_mouse_request_change_addr(d->devaddr);
 break;
 default:
-if (!d->disable_direct_reg3_writes) {
-d->devaddr = buf[1] & 0xf;
-
-/* we support handlers:
- * 0x01: Classic Apple Mouse Protocol / 100 cpi operations
- * 0x02: Classic Apple Mouse Protocol / 200 cpi operations
- * we don't support handlers (at least):
- * 0x03: Mouse systems A3 trackball
- * 0x04: Extended Apple Mouse Protocol
- * 0x2f: Microspeed mouse
- * 0x42: Macally
- * 0x5f: Microspeed mouse
- * 0x66: Microspeed mouse
- */
-if (buf[2] == 1 || buf[2] == 2) {
-d->handler = buf[2];
-}
-
-trace_adb_mouse_request_change_addr_and_handler(
-d->devaddr, d->handler);
+d->devaddr = buf[1] & 0xf;
+/*
+ * we support handlers:
+ * 0x01: Classic Apple Mouse Protocol / 100 cpi operations
+ * 0x02: Classic Apple Mouse Protocol / 200 cpi operations
+ * we don't support handlers (at least):
+ * 0x03: Mouse systems A3 trackball
+ * 0x04: Extended Apple Mouse Protocol
+ * 0x2f: Microspeed mouse
+ * 0x42: Macally
+  

[PULL 01/22] adb: coding style update to fix checkpatch errors

2020-06-26 Thread Mark Cave-Ayland
This will help ensure that style guidelines are being maintained during
subsequent changes.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-2-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index b1ac4a3852..bf1bc30d19 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -44,14 +44,14 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const 
uint8_t *buf, int len)
 
 cmd = buf[0] & 0xf;
 if (cmd == ADB_BUSRESET) {
-for(i = 0; i < s->nb_devices; i++) {
+for (i = 0; i < s->nb_devices; i++) {
 d = s->devices[i];
 adb_device_reset(d);
 }
 return 0;
 }
 devaddr = buf[0] >> 4;
-for(i = 0; i < s->nb_devices; i++) {
+for (i = 0; i < s->nb_devices; i++) {
 d = s->devices[i];
 if (d->devaddr == devaddr) {
 ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
@@ -69,9 +69,10 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t 
poll_mask)
 uint8_t buf[1];
 
 olen = 0;
-for(i = 0; i < s->nb_devices; i++) {
-if (s->poll_index >= s->nb_devices)
+for (i = 0; i < s->nb_devices; i++) {
+if (s->poll_index >= s->nb_devices) {
 s->poll_index = 0;
+}
 d = s->devices[s->poll_index];
 if ((1 << d->devaddr) & poll_mask) {
 buf[0] = ADB_READREG | (d->devaddr << 4);
-- 
2.20.1




[PULL 00/22] qemu-macppc queue 20200626

2020-06-26 Thread Mark Cave-Ayland
The following changes since commit 5acc270a355120ce967ca1f1eeca0abbdb9303c8:

  Merge remote-tracking branch 'remotes/xtensa/tags/20200625-xtensa' into 
staging (2020-06-25 21:20:45 +0100)

are available in the Git repository at:

  git://github.com/mcayland/qemu.git tags/qemu-macppc-20200626

for you to fetch changes up to e590e7f01479a1d4544aac062fe9fdb986502294:

  adb: add ADB bus trace events (2020-06-26 10:13:52 +0100)


qemu-macppc patches


Mark Cave-Ayland (22):
  adb: coding style update to fix checkpatch errors
  adb: fix adb-mouse read length and revert disable-reg3-direct-writes 
workaround
  cuda: convert ADB autopoll timer from ns to ms
  pmu: fix duplicate autopoll mask variable
  pmu: honour autopoll_rate_ms when rearming the ADB autopoll timer
  adb: introduce realize/unrealize and VMStateDescription for ADB bus
  adb: create autopoll variables directly within ADBBusState
  cuda: convert to use ADBBusState internal autopoll variables
  pmu: convert to use ADBBusState internal autopoll variables
  mac_via: convert to use ADBBusState internal autopoll variables
  adb: introduce new ADBDeviceHasData method to ADBDeviceClass
  adb: keep track of devices with pending data
  adb: add status field for holding information about the last ADB request
  adb: use adb_request() only for explicit requests
  adb: add autopoll_blocked variable to block autopoll
  cuda: add adb_autopoll_block() and adb_autopoll_unblock() functions
  pmu: add adb_autopoll_block() and adb_autopoll_unblock() functions
  mac_via: move VIA1 portB write logic into mos6522_q800_via1_write()
  mac_via: rework ADB state machine to be compatible with both MacOS and 
Linux
  adb: only call autopoll callbacks when autopoll is not blocked
  adb: use adb_device prefix for ADB device trace events
  adb: add ADB bus trace events

 hw/input/adb-kbd.c   |  42 +++--
 hw/input/adb-mouse.c |  65 ---
 hw/input/adb.c   | 210 --
 hw/input/trace-events|  27 +--
 hw/misc/mac_via.c| 411 ---
 hw/misc/macio/cuda.c |  60 +++
 hw/misc/macio/pmu.c  |  47 +++--
 hw/misc/trace-events |   3 +
 hw/ppc/mac_newworld.c|   2 -
 include/hw/input/adb.h   |  26 ++-
 include/hw/misc/mac_via.h|   2 +-
 include/hw/misc/macio/cuda.h |   4 -
 include/hw/misc/macio/pmu.h  |   4 -
 13 files changed, 620 insertions(+), 283 deletions(-)



[PULL 06/22] adb: introduce realize/unrealize and VMStateDescription for ADB bus

2020-06-26 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-7-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index d85278a7b7..21a9b3aa96 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -89,10 +89,42 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t 
poll_mask)
 return olen;
 }
 
+static const VMStateDescription vmstate_adb_bus = {
+.name = "adb_bus",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void adb_bus_realize(BusState *qbus, Error **errp)
+{
+ADBBusState *adb_bus = ADB_BUS(qbus);
+
+vmstate_register(NULL, -1, &vmstate_adb_bus, adb_bus);
+}
+
+static void adb_bus_unrealize(BusState *qbus)
+{
+ADBBusState *adb_bus = ADB_BUS(qbus);
+
+vmstate_unregister(NULL, &vmstate_adb_bus, adb_bus);
+}
+
+static void adb_bus_class_init(ObjectClass *klass, void *data)
+{
+BusClass *k = BUS_CLASS(klass);
+
+k->realize = adb_bus_realize;
+k->unrealize = adb_bus_unrealize;
+}
+
 static const TypeInfo adb_bus_type_info = {
 .name = TYPE_ADB_BUS,
 .parent = TYPE_BUS,
 .instance_size = sizeof(ADBBusState),
+.class_init = adb_bus_class_init,
 };
 
 const VMStateDescription vmstate_adb_device = {
-- 
2.20.1




[PULL 09/22] pmu: convert to use ADBBusState internal autopoll variables

2020-06-26 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-10-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/macio/pmu.c | 39 ++---
 include/hw/misc/macio/pmu.h |  3 ---
 2 files changed, 15 insertions(+), 27 deletions(-)

diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
index bae0b440d0..01d49e6695 100644
--- a/hw/misc/macio/pmu.c
+++ b/hw/misc/macio/pmu.c
@@ -92,10 +92,11 @@ static void pmu_update_extirq(PMUState *s)
 static void pmu_adb_poll(void *opaque)
 {
 PMUState *s = opaque;
+ADBBusState *adb_bus = &s->adb_bus;
 int olen;
 
 if (!(s->intbits & PMU_INT_ADB)) {
-olen = adb_poll(&s->adb_bus, s->adb_reply, s->adb_poll_mask);
+olen = adb_poll(adb_bus, s->adb_reply, adb_bus->autopoll_mask);
 trace_pmu_adb_poll(olen);
 
 if (olen > 0) {
@@ -104,9 +105,6 @@ static void pmu_adb_poll(void *opaque)
 pmu_update_extirq(s);
 }
 }
-
-timer_mod(s->adb_poll_timer,
-  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->autopoll_rate_ms);
 }
 
 static void pmu_one_sec_timer(void *opaque)
@@ -173,18 +171,15 @@ static void pmu_cmd_set_int_mask(PMUState *s,
 
 static void pmu_cmd_set_adb_autopoll(PMUState *s, uint16_t mask)
 {
-trace_pmu_cmd_set_adb_autopoll(mask);
+ADBBusState *adb_bus = &s->adb_bus;
 
-if (s->adb_poll_mask == mask) {
-return;
-}
+trace_pmu_cmd_set_adb_autopoll(mask);
 
-s->adb_poll_mask = mask;
 if (mask) {
-timer_mod(s->adb_poll_timer,
-  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->autopoll_rate_ms);
+adb_set_autopoll_mask(adb_bus, mask);
+adb_set_autopoll_enabled(adb_bus, true);
 } else {
-timer_del(s->adb_poll_timer);
+adb_set_autopoll_enabled(adb_bus, false);
 }
 }
 
@@ -267,6 +262,8 @@ static void pmu_cmd_adb_poll_off(PMUState *s,
  const uint8_t *in_data, uint8_t in_len,
  uint8_t *out_data, uint8_t *out_len)
 {
+ADBBusState *adb_bus = &s->adb_bus;
+
 if (in_len != 0) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "PMU: ADB POLL OFF command, invalid len: %d want: 0\n",
@@ -274,9 +271,8 @@ static void pmu_cmd_adb_poll_off(PMUState *s,
 return;
 }
 
-if (s->has_adb && s->adb_poll_mask) {
-timer_del(s->adb_poll_timer);
-s->adb_poll_mask = 0;
+if (s->has_adb) {
+adb_set_autopoll_enabled(adb_bus, false);
 }
 }
 
@@ -684,12 +680,10 @@ static bool pmu_adb_state_needed(void *opaque)
 
 static const VMStateDescription vmstate_pmu_adb = {
 .name = "pmu/adb",
-.version_id = 0,
-.minimum_version_id = 0,
+.version_id = 1,
+.minimum_version_id = 1,
 .needed = pmu_adb_state_needed,
 .fields = (VMStateField[]) {
-VMSTATE_UINT16(adb_poll_mask, PMUState),
-VMSTATE_TIMER_PTR(adb_poll_timer, PMUState),
 VMSTATE_UINT8(adb_reply_size, PMUState),
 VMSTATE_BUFFER(adb_reply, PMUState),
 VMSTATE_END_OF_LIST()
@@ -714,7 +708,6 @@ static const VMStateDescription vmstate_pmu = {
 VMSTATE_BUFFER(cmd_rsp, PMUState),
 VMSTATE_UINT8(intbits, PMUState),
 VMSTATE_UINT8(intmask, PMUState),
-VMSTATE_UINT8(autopoll_rate_ms, PMUState),
 VMSTATE_UINT32(tick_offset, PMUState),
 VMSTATE_TIMER_PTR(one_sec_timer, PMUState),
 VMSTATE_INT64(one_sec_target, PMUState),
@@ -734,7 +727,6 @@ static void pmu_reset(DeviceState *dev)
 s->intbits = 0;
 
 s->cmd_state = pmu_state_idle;
-s->adb_poll_mask = 0;
 }
 
 static void pmu_realize(DeviceState *dev, Error **errp)
@@ -742,6 +734,7 @@ static void pmu_realize(DeviceState *dev, Error **errp)
 PMUState *s = VIA_PMU(dev);
 Error *err = NULL;
 SysBusDevice *sbd;
+ADBBusState *adb_bus = &s->adb_bus;
 struct tm tm;
 
 sysbus_realize(SYS_BUS_DEVICE(&s->mos6522_pmu), &err);
@@ -763,9 +756,7 @@ static void pmu_realize(DeviceState *dev, Error **errp)
 if (s->has_adb) {
 qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
 dev, "adb.0");
-s->adb_poll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, pmu_adb_poll, s);
-s->adb_poll_mask = 0x;
-s->autopoll_rate_ms = 20;
+adb_register_autopoll_callback(adb_bus, pmu_adb_poll, s);
 }
 }
 
diff --git a/include/hw/misc/macio/pmu.h b/include/hw/misc/macio/pmu.h
index 4f34b6f9e7..72f75612b6 100644
--- a/include/hw/misc/macio/pmu.h
+++ b/include/hw/misc/macio/pmu.h
@@ -218,9 +218,6 @@ typedef struct PMUState {
 /* ADB */
 bool has_adb;
 ADBBusState adb_bus;
-uint16_t adb_poll_mask;
-uint8_t autopoll_rate_ms;
-QEMUTimer *adb_poll_timer;
 uint8_t adb_reply_size;
 uint8_t adb_reply[ADB_MAX_OUT_LEN];
 
-- 
2.20.1




[PULL 03/22] cuda: convert ADB autopoll timer from ns to ms

2020-06-26 Thread Mark Cave-Ayland
This is in preparation for consolidating all of the ADB autopoll management
in one place.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-4-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/macio/cuda.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 47aa3b0552..01bf47327c 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -210,8 +210,9 @@ static void cuda_adb_poll(void *opaque)
 obuf[1] = 0x40; /* polled data */
 cuda_send_packet_to_host(s, obuf, olen + 2);
 }
-timer_mod(s->adb_poll_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-  (NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms)));
+
+timer_mod(s->adb_poll_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+  s->autopoll_rate_ms);
 }
 
 /* description of commands */
@@ -238,8 +239,8 @@ static bool cuda_cmd_autopoll(CUDAState *s,
 s->autopoll = autopoll;
 if (autopoll) {
 timer_mod(s->adb_poll_timer,
-  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-  (NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms)));
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+  s->autopoll_rate_ms);
 } else {
 timer_del(s->adb_poll_timer);
 }
@@ -264,8 +265,8 @@ static bool cuda_cmd_set_autorate(CUDAState *s,
 s->autopoll_rate_ms = in_data[0];
 if (s->autopoll) {
 timer_mod(s->adb_poll_timer,
-  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-  (NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms)));
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+  s->autopoll_rate_ms);
 }
 return true;
 }
@@ -544,7 +545,7 @@ static void cuda_realize(DeviceState *dev, Error **errp)
 s->sr_delay_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_set_sr_int, s);
 s->sr_delay_ns = 20 * SCALE_US;
 
-s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
+s->adb_poll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
 s->adb_poll_mask = 0x;
 s->autopoll_rate_ms = 20;
 }
-- 
2.20.1




[PULL 08/22] cuda: convert to use ADBBusState internal autopoll variables

2020-06-26 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-9-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/macio/cuda.c | 56 +++-
 include/hw/misc/macio/cuda.h |  4 ---
 2 files changed, 23 insertions(+), 37 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 01bf47327c..b7071e89d5 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -201,18 +201,16 @@ static void cuda_send_packet_to_host(CUDAState *s,
 static void cuda_adb_poll(void *opaque)
 {
 CUDAState *s = opaque;
+ADBBusState *adb_bus = &s->adb_bus;
 uint8_t obuf[ADB_MAX_OUT_LEN + 2];
 int olen;
 
-olen = adb_poll(&s->adb_bus, obuf + 2, s->adb_poll_mask);
+olen = adb_poll(adb_bus, obuf + 2, adb_bus->autopoll_mask);
 if (olen > 0) {
 obuf[0] = ADB_PACKET;
 obuf[1] = 0x40; /* polled data */
 cuda_send_packet_to_host(s, obuf, olen + 2);
 }
-
-timer_mod(s->adb_poll_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
-  s->autopoll_rate_ms);
 }
 
 /* description of commands */
@@ -228,23 +226,16 @@ static bool cuda_cmd_autopoll(CUDAState *s,
   const uint8_t *in_data, int in_len,
   uint8_t *out_data, int *out_len)
 {
-int autopoll;
+ADBBusState *adb_bus = &s->adb_bus;
+bool autopoll;
 
 if (in_len != 1) {
 return false;
 }
 
-autopoll = (in_data[0] != 0);
-if (autopoll != s->autopoll) {
-s->autopoll = autopoll;
-if (autopoll) {
-timer_mod(s->adb_poll_timer,
-  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
-  s->autopoll_rate_ms);
-} else {
-timer_del(s->adb_poll_timer);
-}
-}
+autopoll = (in_data[0] != 0) ? true : false;
+
+adb_set_autopoll_enabled(adb_bus, autopoll);
 return true;
 }
 
@@ -252,6 +243,8 @@ static bool cuda_cmd_set_autorate(CUDAState *s,
   const uint8_t *in_data, int in_len,
   uint8_t *out_data, int *out_len)
 {
+ADBBusState *adb_bus = &s->adb_bus;
+
 if (in_len != 1) {
 return false;
 }
@@ -262,12 +255,7 @@ static bool cuda_cmd_set_autorate(CUDAState *s,
 return false;
 }
 
-s->autopoll_rate_ms = in_data[0];
-if (s->autopoll) {
-timer_mod(s->adb_poll_timer,
-  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
-  s->autopoll_rate_ms);
-}
+adb_set_autopoll_rate_ms(adb_bus, in_data[0]);
 return true;
 }
 
@@ -275,11 +263,16 @@ static bool cuda_cmd_set_device_list(CUDAState *s,
  const uint8_t *in_data, int in_len,
  uint8_t *out_data, int *out_len)
 {
+ADBBusState *adb_bus = &s->adb_bus;
+uint16_t mask;
+
 if (in_len != 2) {
 return false;
 }
 
-s->adb_poll_mask = (((uint16_t)in_data[0]) << 8) | in_data[1];
+mask = (((uint16_t)in_data[0]) << 8) | in_data[1];
+
+adb_set_autopoll_mask(adb_bus, mask);
 return true;
 }
 
@@ -490,8 +483,8 @@ static const MemoryRegionOps mos6522_cuda_ops = {
 
 static const VMStateDescription vmstate_cuda = {
 .name = "cuda",
-.version_id = 5,
-.minimum_version_id = 5,
+.version_id = 6,
+.minimum_version_id = 6,
 .fields = (VMStateField[]) {
 VMSTATE_STRUCT(mos6522_cuda.parent_obj, CUDAState, 0, vmstate_mos6522,
MOS6522State),
@@ -500,13 +493,9 @@ static const VMStateDescription vmstate_cuda = {
 VMSTATE_INT32(data_in_size, CUDAState),
 VMSTATE_INT32(data_in_index, CUDAState),
 VMSTATE_INT32(data_out_index, CUDAState),
-VMSTATE_UINT8(autopoll, CUDAState),
-VMSTATE_UINT8(autopoll_rate_ms, CUDAState),
-VMSTATE_UINT16(adb_poll_mask, CUDAState),
 VMSTATE_BUFFER(data_in, CUDAState),
 VMSTATE_BUFFER(data_out, CUDAState),
 VMSTATE_UINT32(tick_offset, CUDAState),
-VMSTATE_TIMER_PTR(adb_poll_timer, CUDAState),
 VMSTATE_TIMER_PTR(sr_delay_timer, CUDAState),
 VMSTATE_END_OF_LIST()
 }
@@ -515,11 +504,13 @@ static const VMStateDescription vmstate_cuda = {
 static void cuda_reset(DeviceState *dev)
 {
 CUDAState *s = CUDA(dev);
+ADBBusState *adb_bus = &s->adb_bus;
 
 s->data_in_size = 0;
 s->data_in_index = 0;
 s->data_out_index = 0;
-s->autopoll = 0;
+
+adb_set_autopoll_enabled(adb_bus, false);
 }
 
 static void cuda_realize(DeviceState *dev, Error **errp)
@@ -527,6 +518,7 @@ static void cuda_realize(DeviceState *dev, Error **errp)
 CUDAState *s = CUDA(dev);
 Error *err = NULL;
 SysBusDevice *sbd;
+ADBBusState *adb_bus = &s->adb_bus;
 struct tm tm;
 
 sysbus_realize(SYS_BUS_DEVICE(&s->mos6522_cuda), &err);
@@ -545,9 +537,7 @@ static void cuda_realize(DeviceState *dev, Error **err

[PULL 04/22] pmu: fix duplicate autopoll mask variable

2020-06-26 Thread Mark Cave-Ayland
It seems that during the initial work to introduce the via-pmu ADB support a
duplicate autopoll mask variable was accidentally left in place.

Remove the duplicate autopoll_mask variable and switch everything over to
use adb_poll_mask instead.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-5-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/macio/pmu.c | 15 +++
 include/hw/misc/macio/pmu.h |  1 -
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
index 41b626c46c..cae2845936 100644
--- a/hw/misc/macio/pmu.c
+++ b/hw/misc/macio/pmu.c
@@ -175,11 +175,11 @@ static void pmu_cmd_set_adb_autopoll(PMUState *s, 
uint16_t mask)
 {
 trace_pmu_cmd_set_adb_autopoll(mask);
 
-if (s->autopoll_mask == mask) {
+if (s->adb_poll_mask == mask) {
 return;
 }
 
-s->autopoll_mask = mask;
+s->adb_poll_mask = mask;
 if (mask) {
 timer_mod(s->adb_poll_timer,
   qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 30);
@@ -274,9 +274,9 @@ static void pmu_cmd_adb_poll_off(PMUState *s,
 return;
 }
 
-if (s->has_adb && s->autopoll_mask) {
+if (s->has_adb && s->adb_poll_mask) {
 timer_del(s->adb_poll_timer);
-s->autopoll_mask = false;
+s->adb_poll_mask = 0;
 }
 }
 
@@ -698,8 +698,8 @@ static const VMStateDescription vmstate_pmu_adb = {
 
 static const VMStateDescription vmstate_pmu = {
 .name = "pmu",
-.version_id = 0,
-.minimum_version_id = 0,
+.version_id = 1,
+.minimum_version_id = 1,
 .fields = (VMStateField[]) {
 VMSTATE_STRUCT(mos6522_pmu.parent_obj, PMUState, 0, vmstate_mos6522,
MOS6522State),
@@ -715,7 +715,6 @@ static const VMStateDescription vmstate_pmu = {
 VMSTATE_UINT8(intbits, PMUState),
 VMSTATE_UINT8(intmask, PMUState),
 VMSTATE_UINT8(autopoll_rate_ms, PMUState),
-VMSTATE_UINT8(autopoll_mask, PMUState),
 VMSTATE_UINT32(tick_offset, PMUState),
 VMSTATE_TIMER_PTR(one_sec_timer, PMUState),
 VMSTATE_INT64(one_sec_target, PMUState),
@@ -735,7 +734,7 @@ static void pmu_reset(DeviceState *dev)
 s->intbits = 0;
 
 s->cmd_state = pmu_state_idle;
-s->autopoll_mask = 0;
+s->adb_poll_mask = 0;
 }
 
 static void pmu_realize(DeviceState *dev, Error **errp)
diff --git a/include/hw/misc/macio/pmu.h b/include/hw/misc/macio/pmu.h
index 7ef83dee4c..4f34b6f9e7 100644
--- a/include/hw/misc/macio/pmu.h
+++ b/include/hw/misc/macio/pmu.h
@@ -220,7 +220,6 @@ typedef struct PMUState {
 ADBBusState adb_bus;
 uint16_t adb_poll_mask;
 uint8_t autopoll_rate_ms;
-uint8_t autopoll_mask;
 QEMUTimer *adb_poll_timer;
 uint8_t adb_reply_size;
 uint8_t adb_reply[ADB_MAX_OUT_LEN];
-- 
2.20.1




[PULL 11/22] adb: introduce new ADBDeviceHasData method to ADBDeviceClass

2020-06-26 Thread Mark Cave-Ayland
This is required later to allow devices to assert a service request (SRQ)
signal to indicate that it has data to send, without having to consume it.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-12-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb-kbd.c | 8 
 hw/input/adb-mouse.c   | 9 +
 include/hw/input/adb.h | 3 +++
 3 files changed, 20 insertions(+)

diff --git a/hw/input/adb-kbd.c b/hw/input/adb-kbd.c
index 027dd3e531..23760ecf7b 100644
--- a/hw/input/adb-kbd.c
+++ b/hw/input/adb-kbd.c
@@ -300,6 +300,13 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
 return olen;
 }
 
+static bool adb_kbd_has_data(ADBDevice *d)
+{
+KBDState *s = ADB_KEYBOARD(d);
+
+return s->count > 0;
+}
+
 /* This is where keyboard events enter this file */
 static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
InputEvent *evt)
@@ -382,6 +389,7 @@ static void adb_kbd_class_init(ObjectClass *oc, void *data)
 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 
 adc->devreq = adb_kbd_request;
+adc->devhasdata = adb_kbd_has_data;
 dc->reset = adb_kbd_reset;
 dc->vmsd = &vmstate_adb_kbd;
 }
diff --git a/hw/input/adb-mouse.c b/hw/input/adb-mouse.c
index 78b6f5030c..e2359fd74d 100644
--- a/hw/input/adb-mouse.c
+++ b/hw/input/adb-mouse.c
@@ -197,6 +197,14 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 return olen;
 }
 
+static bool adb_mouse_has_data(ADBDevice *d)
+{
+MouseState *s = ADB_MOUSE(d);
+
+return !(s->last_buttons_state == s->buttons_state &&
+ s->dx == 0 && s->dy == 0);
+}
+
 static void adb_mouse_reset(DeviceState *dev)
 {
 ADBDevice *d = ADB_DEVICE(dev);
@@ -252,6 +260,7 @@ static void adb_mouse_class_init(ObjectClass *oc, void 
*data)
 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 
 adc->devreq = adb_mouse_request;
+adc->devhasdata = adb_mouse_has_data;
 dc->reset = adb_mouse_reset;
 dc->vmsd = &vmstate_adb_mouse;
 }
diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
index 15b1874a3d..9b80204e43 100644
--- a/include/hw/input/adb.h
+++ b/include/hw/input/adb.h
@@ -39,6 +39,8 @@ typedef struct ADBDevice ADBDevice;
 typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
   const uint8_t *buf, int len);
 
+typedef bool ADBDeviceHasData(ADBDevice *d);
+
 #define TYPE_ADB_DEVICE "adb-device"
 #define ADB_DEVICE(obj) OBJECT_CHECK(ADBDevice, (obj), TYPE_ADB_DEVICE)
 
@@ -62,6 +64,7 @@ typedef struct ADBDeviceClass {
 /*< public >*/
 
 ADBDeviceRequest *devreq;
+ADBDeviceHasData *devhasdata;
 } ADBDeviceClass;
 
 #define TYPE_ADB_BUS "apple-desktop-bus"
-- 
2.20.1




[PULL 05/22] pmu: honour autopoll_rate_ms when rearming the ADB autopoll timer

2020-06-26 Thread Mark Cave-Ayland
Don't use a fixed value but instead use the default value from the ADB bus
state.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-6-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/macio/pmu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
index cae2845936..bae0b440d0 100644
--- a/hw/misc/macio/pmu.c
+++ b/hw/misc/macio/pmu.c
@@ -106,7 +106,7 @@ static void pmu_adb_poll(void *opaque)
 }
 
 timer_mod(s->adb_poll_timer,
-  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 30);
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->autopoll_rate_ms);
 }
 
 static void pmu_one_sec_timer(void *opaque)
@@ -182,7 +182,7 @@ static void pmu_cmd_set_adb_autopoll(PMUState *s, uint16_t 
mask)
 s->adb_poll_mask = mask;
 if (mask) {
 timer_mod(s->adb_poll_timer,
-  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 30);
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->autopoll_rate_ms);
 } else {
 timer_del(s->adb_poll_timer);
 }
-- 
2.20.1




[PULL 10/22] mac_via: convert to use ADBBusState internal autopoll variables

2020-06-26 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-11-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/mac_via.c | 22 ++
 include/hw/misc/mac_via.h |  1 -
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 9cd313c812..7a28bb37ac 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -601,6 +601,8 @@ static void via1_rtc_update(MacVIAState *m)
 
 static int adb_via_poll(MacVIAState *s, int state, uint8_t *data)
 {
+ADBBusState *adb_bus = &s->adb_bus;
+
 if (state != ADB_STATE_IDLE) {
 return 0;
 }
@@ -615,7 +617,8 @@ static int adb_via_poll(MacVIAState *s, int state, uint8_t 
*data)
 
 s->adb_data_in_index = 0;
 s->adb_data_out_index = 0;
-s->adb_data_in_size = adb_poll(&s->adb_bus, s->adb_data_in, 0x);
+s->adb_data_in_size = adb_poll(adb_bus, s->adb_data_in,
+   adb_bus->autopoll_mask);
 
 if (s->adb_data_in_size) {
 *data = s->adb_data_in[s->adb_data_in_index++];
@@ -768,10 +771,6 @@ static void via_adb_poll(void *opaque)
 s->b &= ~VIA1B_vADBInt;
 }
 }
-
-timer_mod(m->adb_poll_timer,
-  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-  (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
 }
 
 static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned 
size)
@@ -854,10 +853,9 @@ static void mac_via_reset(DeviceState *dev)
 {
 MacVIAState *m = MAC_VIA(dev);
 MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
+ADBBusState *adb_bus = &m->adb_bus;
 
-timer_mod(m->adb_poll_timer,
-  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-  (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
+adb_set_autopoll_enabled(adb_bus, true);
 
 timer_del(v1s->VBL_timer);
 v1s->next_VBL = 0;
@@ -872,6 +870,7 @@ static void mac_via_realize(DeviceState *dev, Error **errp)
 {
 MacVIAState *m = MAC_VIA(dev);
 MOS6522State *ms;
+ADBBusState *adb_bus = &m->adb_bus;
 struct tm tm;
 int ret;
 
@@ -907,7 +906,7 @@ static void mac_via_realize(DeviceState *dev, Error **errp)
 qemu_get_timedate(&tm, 0);
 m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
 
-m->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via_adb_poll, m);
+adb_register_autopoll_callback(adb_bus, via_adb_poll, m);
 m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq",
VIA1_IRQ_ADB_READY_BIT);
 
@@ -980,8 +979,8 @@ static int mac_via_post_load(void *opaque, int version_id)
 
 static const VMStateDescription vmstate_mac_via = {
 .name = "mac-via",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .post_load = mac_via_post_load,
 .fields = (VMStateField[]) {
 /* VIAs */
@@ -1005,7 +1004,6 @@ static const VMStateDescription vmstate_mac_via = {
 VMSTATE_INT32(wprotect, MacVIAState),
 VMSTATE_INT32(alt, MacVIAState),
 /* ADB */
-VMSTATE_TIMER_PTR(adb_poll_timer, MacVIAState),
 VMSTATE_INT32(adb_data_in_size, MacVIAState),
 VMSTATE_INT32(adb_data_in_index, MacVIAState),
 VMSTATE_INT32(adb_data_out_index, MacVIAState),
diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h
index e74f85be0f..2aaf9e27bf 100644
--- a/include/hw/misc/mac_via.h
+++ b/include/hw/misc/mac_via.h
@@ -106,7 +106,6 @@ typedef struct MacVIAState {
 
 /* ADB */
 ADBBusState adb_bus;
-QEMUTimer *adb_poll_timer;
 qemu_irq adb_data_ready;
 int adb_data_in_size;
 int adb_data_in_index;
-- 
2.20.1




[PULL 13/22] adb: add status field for holding information about the last ADB request

2020-06-26 Thread Mark Cave-Ayland
Currently only 2 bits are defined: one to indicate if the request timed out (no
reply) and another to indicate whether the request was the result of an autopoll
operation.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-14-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c | 14 +++---
 include/hw/input/adb.h |  4 
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index c1adb21e6b..a7a482fdfa 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -42,7 +42,7 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t 
*buf, int len)
 {
 ADBDevice *d;
 ADBDeviceClass *adc;
-int devaddr, cmd, i;
+int devaddr, cmd, olen, i;
 
 cmd = buf[0] & 0xf;
 if (cmd == ADB_BUSRESET) {
@@ -50,6 +50,7 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t 
*buf, int len)
 d = s->devices[i];
 adb_device_reset(d);
 }
+s->status = 0;
 return 0;
 }
 
@@ -63,16 +64,22 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const 
uint8_t *buf, int len)
 }
 }
 
+s->status = 0;
 devaddr = buf[0] >> 4;
 for (i = 0; i < s->nb_devices; i++) {
 d = s->devices[i];
 adc = ADB_DEVICE_GET_CLASS(d);
 
 if (d->devaddr == devaddr) {
-return adc->devreq(d, obuf, buf, len);
+olen = adc->devreq(d, obuf, buf, len);
+if (!olen) {
+s->status |= ADB_STATUS_BUSTIMEOUT;
+}
+return olen;
 }
 }
 
+s->status |= ADB_STATUS_BUSTIMEOUT;
 return ADB_RET_NOTPRESENT;
 }
 
@@ -94,9 +101,10 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t 
poll_mask)
 olen = adb_request(s, obuf + 1, buf, 1);
 /* if there is data, we poll again the same device */
 if (olen > 0) {
+s->status |= ADB_STATUS_POLLREPLY;
 obuf[0] = buf[0];
 olen++;
-break;
+return olen;
 }
 }
 s->poll_index++;
diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
index f1bc358d8e..cff264739c 100644
--- a/include/hw/input/adb.h
+++ b/include/hw/input/adb.h
@@ -70,6 +70,9 @@ typedef struct ADBDeviceClass {
 #define TYPE_ADB_BUS "apple-desktop-bus"
 #define ADB_BUS(obj) OBJECT_CHECK(ADBBusState, (obj), TYPE_ADB_BUS)
 
+#define ADB_STATUS_BUSTIMEOUT  0x1
+#define ADB_STATUS_POLLREPLY   0x2
+
 struct ADBBusState {
 /*< private >*/
 BusState parent_obj;
@@ -79,6 +82,7 @@ struct ADBBusState {
 uint16_t pending;
 int nb_devices;
 int poll_index;
+uint8_t status;
 
 QEMUTimer *autopoll_timer;
 bool autopoll_enabled;
-- 
2.20.1




[PULL 12/22] adb: keep track of devices with pending data

2020-06-26 Thread Mark Cave-Ayland
Add a new pending variable to ADBBusState which is a bitmask indicating which
ADB devices have data to send. Update the bitmask every time that an ADB
request is executed.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-13-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c | 16 +++-
 include/hw/input/adb.h |  1 +
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index bb36ce6fad..c1adb21e6b 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -41,6 +41,7 @@ static void adb_device_reset(ADBDevice *d)
 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
 {
 ADBDevice *d;
+ADBDeviceClass *adc;
 int devaddr, cmd, i;
 
 cmd = buf[0] & 0xf;
@@ -51,14 +52,27 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const 
uint8_t *buf, int len)
 }
 return 0;
 }
+
+s->pending = 0;
+for (i = 0; i < s->nb_devices; i++) {
+d = s->devices[i];
+adc = ADB_DEVICE_GET_CLASS(d);
+
+if (adc->devhasdata(d)) {
+s->pending |= (1 << d->devaddr);
+}
+}
+
 devaddr = buf[0] >> 4;
 for (i = 0; i < s->nb_devices; i++) {
 d = s->devices[i];
+adc = ADB_DEVICE_GET_CLASS(d);
+
 if (d->devaddr == devaddr) {
-ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
 return adc->devreq(d, obuf, buf, len);
 }
 }
+
 return ADB_RET_NOTPRESENT;
 }
 
diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
index 9b80204e43..f1bc358d8e 100644
--- a/include/hw/input/adb.h
+++ b/include/hw/input/adb.h
@@ -76,6 +76,7 @@ struct ADBBusState {
 /*< public >*/
 
 ADBDevice *devices[MAX_ADB_DEVICES];
+uint16_t pending;
 int nb_devices;
 int poll_index;
 
-- 
2.20.1




[PULL 07/22] adb: create autopoll variables directly within ADBBusState

2020-06-26 Thread Mark Cave-Ayland
Rather than each ADB implementation requiring its own functions to manage
autopoll state, timers, and autopoll masks prepare to move this information
directly into ADBBusState.

Add external functions within adb.h to allow each ADB implementation to
manage the new autopoll variables.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-8-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c | 77 ++
 include/hw/input/adb.h | 13 +++
 2 files changed, 90 insertions(+)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index 21a9b3aa96..bb36ce6fad 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -27,6 +27,7 @@
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "qemu/module.h"
+#include "qemu/timer.h"
 #include "adb-internal.h"
 
 /* error codes */
@@ -89,19 +90,92 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t 
poll_mask)
 return olen;
 }
 
+void adb_set_autopoll_enabled(ADBBusState *s, bool enabled)
+{
+if (s->autopoll_enabled != enabled) {
+s->autopoll_enabled = enabled;
+if (s->autopoll_enabled) {
+timer_mod(s->autopoll_timer,
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+  s->autopoll_rate_ms);
+} else {
+timer_del(s->autopoll_timer);
+}
+}
+}
+
+void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms)
+{
+s->autopoll_rate_ms = rate_ms;
+
+if (s->autopoll_enabled) {
+timer_mod(s->autopoll_timer,
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+  s->autopoll_rate_ms);
+}
+}
+
+void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask)
+{
+if (s->autopoll_mask != mask) {
+s->autopoll_mask = mask;
+if (s->autopoll_enabled && s->autopoll_mask) {
+timer_mod(s->autopoll_timer,
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+  s->autopoll_rate_ms);
+} else {
+timer_del(s->autopoll_timer);
+}
+}
+}
+
+static void adb_autopoll(void *opaque)
+{
+ADBBusState *s = opaque;
+
+s->autopoll_cb(s->autopoll_cb_opaque);
+
+timer_mod(s->autopoll_timer,
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+  s->autopoll_rate_ms);
+}
+
+void adb_register_autopoll_callback(ADBBusState *s, void (*cb)(void *opaque),
+void *opaque)
+{
+s->autopoll_cb = cb;
+s->autopoll_cb_opaque = opaque;
+}
+
 static const VMStateDescription vmstate_adb_bus = {
 .name = "adb_bus",
 .version_id = 0,
 .minimum_version_id = 0,
 .fields = (VMStateField[]) {
+VMSTATE_TIMER_PTR(autopoll_timer, ADBBusState),
+VMSTATE_BOOL(autopoll_enabled, ADBBusState),
+VMSTATE_UINT8(autopoll_rate_ms, ADBBusState),
+VMSTATE_UINT16(autopoll_mask, ADBBusState),
 VMSTATE_END_OF_LIST()
 }
 };
 
+static void adb_bus_reset(BusState *qbus)
+{
+ADBBusState *adb_bus = ADB_BUS(qbus);
+
+adb_bus->autopoll_enabled = false;
+adb_bus->autopoll_mask = 0x;
+adb_bus->autopoll_rate_ms = 20;
+}
+
 static void adb_bus_realize(BusState *qbus, Error **errp)
 {
 ADBBusState *adb_bus = ADB_BUS(qbus);
 
+adb_bus->autopoll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, adb_autopoll,
+   adb_bus);
+
 vmstate_register(NULL, -1, &vmstate_adb_bus, adb_bus);
 }
 
@@ -109,6 +183,8 @@ static void adb_bus_unrealize(BusState *qbus)
 {
 ADBBusState *adb_bus = ADB_BUS(qbus);
 
+timer_del(adb_bus->autopoll_timer);
+
 vmstate_unregister(NULL, &vmstate_adb_bus, adb_bus);
 }
 
@@ -118,6 +194,7 @@ static void adb_bus_class_init(ObjectClass *klass, void 
*data)
 
 k->realize = adb_bus_realize;
 k->unrealize = adb_bus_unrealize;
+k->reset = adb_bus_reset;
 }
 
 static const TypeInfo adb_bus_type_info = {
diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
index 4d2c565f54..15b1874a3d 100644
--- a/include/hw/input/adb.h
+++ b/include/hw/input/adb.h
@@ -75,12 +75,25 @@ struct ADBBusState {
 ADBDevice *devices[MAX_ADB_DEVICES];
 int nb_devices;
 int poll_index;
+
+QEMUTimer *autopoll_timer;
+bool autopoll_enabled;
+uint8_t autopoll_rate_ms;
+uint16_t autopoll_mask;
+void (*autopoll_cb)(void *opaque);
+void *autopoll_cb_opaque;
 };
 
 int adb_request(ADBBusState *s, uint8_t *buf_out,
 const uint8_t *buf, int len);
 int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
 
+void adb_set_autopoll_enabled(ADBBusState *s, bool enabled);
+void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms);
+void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask);
+void adb_register_autopoll_callback(ADBBusState *s, void (*cb)(void *opaque),
+void *opaque);
+
 #define TYPE_ADB_KEYBOARD "adb-keyboard"
 #define TYPE_AD

[PULL 16/22] cuda: add adb_autopoll_block() and adb_autopoll_unblock() functions

2020-06-26 Thread Mark Cave-Ayland
Ensure that the CUDA buffer is protected from autopoll requests overwriting
its contents whilst existing CUDA requests are in progress.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-17-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/macio/cuda.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index b7071e89d5..5bbc7770fa 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -116,6 +116,7 @@ static void cuda_update(CUDAState *s)
 {
 MOS6522CUDAState *mcs = &s->mos6522_cuda;
 MOS6522State *ms = MOS6522(mcs);
+ADBBusState *adb_bus = &s->adb_bus;
 int packet_received, len;
 
 packet_received = 0;
@@ -126,6 +127,9 @@ static void cuda_update(CUDAState *s)
 /* data output */
 if ((ms->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
 if (s->data_out_index < sizeof(s->data_out)) {
+if (s->data_out_index == 0) {
+adb_autopoll_block(adb_bus);
+}
 trace_cuda_data_send(ms->sr);
 s->data_out[s->data_out_index++] = ms->sr;
 cuda_delay_set_sr_int(s);
@@ -140,6 +144,7 @@ static void cuda_update(CUDAState *s)
 /* indicate end of transfer */
 if (s->data_in_index >= s->data_in_size) {
 ms->b = (ms->b | TREQ);
+adb_autopoll_unblock(adb_bus);
 }
 cuda_delay_set_sr_int(s);
 }
-- 
2.20.1




[PULL 20/22] adb: only call autopoll callbacks when autopoll is not blocked

2020-06-26 Thread Mark Cave-Ayland
Handle this at the ADB bus level so that individual implementations do not need
to handle this themselves.

Finally add an assert() into adb_request() to prevent developers from 
accidentally
making an explicit ADB request without blocking autopoll.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-21-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c| 7 +--
 hw/misc/mac_via.c | 6 +-
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index 70aa1f4570..fe0f6c7ef3 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -86,10 +86,11 @@ static int do_adb_request(ADBBusState *s, uint8_t *obuf, 
const uint8_t *buf,
 
 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
 {
+assert(s->autopoll_blocked);
+
 return do_adb_request(s, obuf, buf, len);
 }
 
-/* XXX: move that to cuda ? */
 int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
 {
 ADBDevice *d;
@@ -181,7 +182,9 @@ static void adb_autopoll(void *opaque)
 {
 ADBBusState *s = opaque;
 
-s->autopoll_cb(s->autopoll_cb_opaque);
+if (!s->autopoll_blocked) {
+s->autopoll_cb(s->autopoll_cb_opaque);
+}
 
 timer_mod(s->autopoll_timer,
   qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 71b6f92645..d76d7b28d3 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -615,11 +615,7 @@ static void adb_via_poll(void *opaque)
  * received, however we must block autopoll until the point where
  * the entire reply has been read back to the host
  */
-if (adb_bus->autopoll_blocked) {
-return;
-} else {
-adb_autopoll_block(adb_bus);
-}
+adb_autopoll_block(adb_bus);
 
 m->adb_data_in_index = 0;
 m->adb_data_out_index = 0;
-- 
2.20.1




[PULL 17/22] pmu: add adb_autopoll_block() and adb_autopoll_unblock() functions

2020-06-26 Thread Mark Cave-Ayland
Ensure that the PMU buffer is protected from autopoll requests overwriting
its contents whilst existing PMU requests are in progress.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-18-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/macio/pmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
index 01d49e6695..598d8e7517 100644
--- a/hw/misc/macio/pmu.c
+++ b/hw/misc/macio/pmu.c
@@ -517,6 +517,7 @@ static void pmu_update(PMUState *s)
 {
 MOS6522PMUState *mps = &s->mos6522_pmu;
 MOS6522State *ms = MOS6522(mps);
+ADBBusState *adb_bus = &s->adb_bus;
 
 /* Only react to changes in reg B */
 if (ms->b == s->last_b) {
@@ -578,6 +579,7 @@ static void pmu_update(PMUState *s)
 s->cmd_rsp_pos = 0;
 s->cmd_state = pmu_state_cmd;
 
+adb_autopoll_block(adb_bus);
 trace_pmu_debug_protocol_cmd(s->cmd, s->cmdlen, s->rsplen);
 break;
 
@@ -636,6 +638,7 @@ static void pmu_update(PMUState *s)
 if (s->cmd_state == pmu_state_rsp && s->rsplen == s->cmd_rsp_pos) {
 trace_pmu_debug_protocol_cmd_resp_complete(ms->ier);
 
+adb_autopoll_unblock(adb_bus);
 s->cmd_state = pmu_state_idle;
 }
 }
-- 
2.20.1




[PULL 22/22] adb: add ADB bus trace events

2020-06-26 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-23-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c| 21 -
 hw/input/trace-events |  7 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index fe0f6c7ef3..013fcc9c54 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -29,10 +29,18 @@
 #include "qemu/module.h"
 #include "qemu/timer.h"
 #include "adb-internal.h"
+#include "trace.h"
 
 /* error codes */
 #define ADB_RET_NOTPRESENT (-2)
 
+static const char *adb_commands[] = {
+"RESET", "FLUSH", "(Reserved 0x2)", "(Reserved 0x3)",
+"Reserved (0x4)", "(Reserved 0x5)", "(Reserved 0x6)", "(Reserved 0x7)",
+"LISTEN r0", "LISTEN r1", "LISTEN r2", "LISTEN r3",
+"TALK r0", "TALK r1", "TALK r2", "TALK r3",
+};
+
 static void adb_device_reset(ADBDevice *d)
 {
 qdev_reset_all(DEVICE(d));
@@ -86,9 +94,16 @@ static int do_adb_request(ADBBusState *s, uint8_t *obuf, 
const uint8_t *buf,
 
 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
 {
+int ret;
+
+trace_adb_bus_request(buf[0] >> 4, adb_commands[buf[0] & 0xf], len);
+
 assert(s->autopoll_blocked);
 
-return do_adb_request(s, obuf, buf, len);
+ret = do_adb_request(s, obuf, buf, len);
+
+trace_adb_bus_request_done(buf[0] >> 4, adb_commands[buf[0] & 0xf], ret);
+return ret;
 }
 
 int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
@@ -161,6 +176,7 @@ void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask)
 void adb_autopoll_block(ADBBusState *s)
 {
 s->autopoll_blocked = true;
+trace_adb_bus_autopoll_block(s->autopoll_blocked);
 
 if (s->autopoll_enabled) {
 timer_del(s->autopoll_timer);
@@ -170,6 +186,7 @@ void adb_autopoll_block(ADBBusState *s)
 void adb_autopoll_unblock(ADBBusState *s)
 {
 s->autopoll_blocked = false;
+trace_adb_bus_autopoll_block(s->autopoll_blocked);
 
 if (s->autopoll_enabled) {
 timer_mod(s->autopoll_timer,
@@ -183,7 +200,9 @@ static void adb_autopoll(void *opaque)
 ADBBusState *s = opaque;
 
 if (!s->autopoll_blocked) {
+trace_adb_bus_autopoll_cb(s->autopoll_mask);
 s->autopoll_cb(s->autopoll_cb_opaque);
+trace_adb_bus_autopoll_cb_done(s->autopoll_mask);
 }
 
 timer_mod(s->autopoll_timer,
diff --git a/hw/input/trace-events b/hw/input/trace-events
index 6f0d78241c..1dd8ad6018 100644
--- a/hw/input/trace-events
+++ b/hw/input/trace-events
@@ -14,6 +14,13 @@ adb_device_mouse_readreg(int reg, uint8_t val0, uint8_t 
val1) "reg %d obuf[0] 0x
 adb_device_mouse_request_change_addr(int devaddr) "change addr to 0x%x"
 adb_device_mouse_request_change_addr_and_handler(int devaddr, int handler) 
"change addr and handler to 0x%x, 0x%x"
 
+# adb.c
+adb_bus_request(uint8_t addr, const char *cmd, int size) "device 0x%x %s 
cmdsize=%d"
+adb_bus_request_done(uint8_t addr, const char *cmd, int size) "device 0x%x %s 
replysize=%d"
+adb_bus_autopoll_block(bool blocked) "blocked: %d"
+adb_bus_autopoll_cb(uint16_t mask) "executing autopoll_cb with autopoll mask 
0x%x"
+adb_bus_autopoll_cb_done(uint16_t mask) "done executing autopoll_cb with 
autopoll mask 0x%x"
+
 # pckbd.c
 pckbd_kbd_read_data(uint32_t val) "0x%02x"
 pckbd_kbd_read_status(int status) "0x%02x"
-- 
2.20.1




[PULL 14/22] adb: use adb_request() only for explicit requests

2020-06-26 Thread Mark Cave-Ayland
Currently adb_request() is called both for explicit ADB requests and internal
autopoll requests via adb_poll().

Move the current functionality into do_adb_request() to be used internally and
add a simple adb_request() wrapper for explicit requests.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-15-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index a7a482fdfa..b3ad7c5fca 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -38,7 +38,8 @@ static void adb_device_reset(ADBDevice *d)
 qdev_reset_all(DEVICE(d));
 }
 
-int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
+static int do_adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf,
+  int len)
 {
 ADBDevice *d;
 ADBDeviceClass *adc;
@@ -83,6 +84,11 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t 
*buf, int len)
 return ADB_RET_NOTPRESENT;
 }
 
+int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
+{
+return do_adb_request(s, obuf, buf, len);
+}
+
 /* XXX: move that to cuda ? */
 int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
 {
@@ -98,7 +104,7 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t 
poll_mask)
 d = s->devices[s->poll_index];
 if ((1 << d->devaddr) & poll_mask) {
 buf[0] = ADB_READREG | (d->devaddr << 4);
-olen = adb_request(s, obuf + 1, buf, 1);
+olen = do_adb_request(s, obuf + 1, buf, 1);
 /* if there is data, we poll again the same device */
 if (olen > 0) {
 s->status |= ADB_STATUS_POLLREPLY;
-- 
2.20.1




[PULL 15/22] adb: add autopoll_blocked variable to block autopoll

2020-06-26 Thread Mark Cave-Ayland
Whilst autopoll is enabled it is necessary to prevent the ADB buffer contents
from being overwritten until the host has read back the response in its
entirety.

Add adb_autopoll_block() and adb_autopoll_unblock() functions in preparation
for ensuring that the ADB buffer contents are protected for explicit ADB
requests.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-16-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb.c | 21 +
 include/hw/input/adb.h |  4 
 2 files changed, 25 insertions(+)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index b3ad7c5fca..70aa1f4570 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -157,6 +157,26 @@ void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask)
 }
 }
 
+void adb_autopoll_block(ADBBusState *s)
+{
+s->autopoll_blocked = true;
+
+if (s->autopoll_enabled) {
+timer_del(s->autopoll_timer);
+}
+}
+
+void adb_autopoll_unblock(ADBBusState *s)
+{
+s->autopoll_blocked = false;
+
+if (s->autopoll_enabled) {
+timer_mod(s->autopoll_timer,
+  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+  s->autopoll_rate_ms);
+}
+}
+
 static void adb_autopoll(void *opaque)
 {
 ADBBusState *s = opaque;
@@ -184,6 +204,7 @@ static const VMStateDescription vmstate_adb_bus = {
 VMSTATE_BOOL(autopoll_enabled, ADBBusState),
 VMSTATE_UINT8(autopoll_rate_ms, ADBBusState),
 VMSTATE_UINT16(autopoll_mask, ADBBusState),
+VMSTATE_BOOL(autopoll_blocked, ADBBusState),
 VMSTATE_END_OF_LIST()
 }
 };
diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
index cff264739c..bb75a7b1e3 100644
--- a/include/hw/input/adb.h
+++ b/include/hw/input/adb.h
@@ -86,6 +86,7 @@ struct ADBBusState {
 
 QEMUTimer *autopoll_timer;
 bool autopoll_enabled;
+bool autopoll_blocked;
 uint8_t autopoll_rate_ms;
 uint16_t autopoll_mask;
 void (*autopoll_cb)(void *opaque);
@@ -96,6 +97,9 @@ int adb_request(ADBBusState *s, uint8_t *buf_out,
 const uint8_t *buf, int len);
 int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
 
+void adb_autopoll_block(ADBBusState *s);
+void adb_autopoll_unblock(ADBBusState *s);
+
 void adb_set_autopoll_enabled(ADBBusState *s, bool enabled);
 void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms);
 void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask);
-- 
2.20.1




[PULL 18/22] mac_via: move VIA1 portB write logic into mos6522_q800_via1_write()

2020-06-26 Thread Mark Cave-Ayland
Currently the logic is split between the mos6522 portB_write() callback and
the memory region used to capture the VIA1 MMIO accesses. Move everything
into the latter mos6522_q800_via1_write() function to keep all the logic in
one place to make it easier to follow.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-19-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/mac_via.c | 24 ++--
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 7a28bb37ac..a1dc00d9f6 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -801,11 +801,21 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr 
addr, uint64_t val,
 unsigned size)
 {
 MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
+MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
 MOS6522State *ms = MOS6522(v1s);
 
 addr = (addr >> 9) & 0xf;
 mos6522_write(ms, addr, val, size);
 
+switch (addr) {
+case VIA_REG_B:
+via1_rtc_update(m);
+via1_adb_update(m);
+
+v1s->last_b = ms->b;
+break;
+}
+
 via1_one_second_update(v1s);
 via1_VBL_update(v1s);
 }
@@ -1037,18 +1047,6 @@ static TypeInfo mac_via_info = {
 };
 
 /* VIA 1 */
-static void mos6522_q800_via1_portB_write(MOS6522State *s)
-{
-MOS6522Q800VIA1State *v1s = container_of(s, MOS6522Q800VIA1State,
- parent_obj);
-MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
-
-via1_rtc_update(m);
-via1_adb_update(m);
-
-v1s->last_b = s->b;
-}
-
 static void mos6522_q800_via1_reset(DeviceState *dev)
 {
 MOS6522State *ms = MOS6522(dev);
@@ -1071,10 +1069,8 @@ static void mos6522_q800_via1_init(Object *obj)
 static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
-MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc);
 
 dc->reset = mos6522_q800_via1_reset;
-mdc->portB_write = mos6522_q800_via1_portB_write;
 }
 
 static const TypeInfo mos6522_q800_via1_type_info = {
-- 
2.20.1




[PULL 21/22] adb: use adb_device prefix for ADB device trace events

2020-06-26 Thread Mark Cave-Ayland
This is to allow us to distinguish between ADB device events and ADB
bus events separately.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-22-mark.cave-ayl...@ilande.co.uk>
---
 hw/input/adb-kbd.c| 12 ++--
 hw/input/adb-mouse.c  | 12 ++--
 hw/input/trace-events | 20 ++--
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/hw/input/adb-kbd.c b/hw/input/adb-kbd.c
index 23760ecf7b..3cfb6a7a20 100644
--- a/hw/input/adb-kbd.c
+++ b/hw/input/adb-kbd.c
@@ -243,7 +243,7 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
 olen = 0;
 switch (cmd) {
 case ADB_WRITEREG:
-trace_adb_kbd_writereg(reg, buf[1]);
+trace_adb_device_kbd_writereg(reg, buf[1]);
 switch (reg) {
 case 2:
 /* LED status */
@@ -256,7 +256,7 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
 case ADB_CMD_CHANGE_ID_AND_ACT:
 case ADB_CMD_CHANGE_ID_AND_ENABLE:
 d->devaddr = buf[1] & 0xf;
-trace_adb_kbd_request_change_addr(d->devaddr);
+trace_adb_device_kbd_request_change_addr(d->devaddr);
 break;
 default:
 d->devaddr = buf[1] & 0xf;
@@ -270,8 +270,8 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
 d->handler = buf[2];
 }
 
-trace_adb_kbd_request_change_addr_and_handler(d->devaddr,
-  d->handler);
+trace_adb_device_kbd_request_change_addr_and_handler(
+d->devaddr, d->handler);
 break;
 }
 }
@@ -294,7 +294,7 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
 olen = 2;
 break;
 }
-trace_adb_kbd_readreg(reg, obuf[0], obuf[1]);
+trace_adb_device_kbd_readreg(reg, obuf[0], obuf[1]);
 break;
 }
 return olen;
@@ -321,7 +321,7 @@ static void adb_keyboard_event(DeviceState *dev, 
QemuConsole *src,
 /* FIXME: take handler into account when translating qcode */
 keycode = qcode_to_adb_keycode[qcode];
 if (keycode == NO_KEY) {  /* We don't want to send this to the guest */
-trace_adb_kbd_no_key();
+trace_adb_device_kbd_no_key();
 return;
 }
 if (evt->u.key.data->down == false) { /* if key release event */
diff --git a/hw/input/adb-mouse.c b/hw/input/adb-mouse.c
index e2359fd74d..577a38ff2e 100644
--- a/hw/input/adb-mouse.c
+++ b/hw/input/adb-mouse.c
@@ -121,7 +121,7 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 s->dx = 0;
 s->dy = 0;
 s->dz = 0;
-trace_adb_mouse_flush();
+trace_adb_device_mouse_flush();
 return 0;
 }
 
@@ -130,7 +130,7 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 olen = 0;
 switch (cmd) {
 case ADB_WRITEREG:
-trace_adb_mouse_writereg(reg, buf[1]);
+trace_adb_device_mouse_writereg(reg, buf[1]);
 switch (reg) {
 case 2:
 break;
@@ -152,7 +152,7 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 case ADB_CMD_CHANGE_ID_AND_ACT:
 case ADB_CMD_CHANGE_ID_AND_ENABLE:
 d->devaddr = buf[1] & 0xf;
-trace_adb_mouse_request_change_addr(d->devaddr);
+trace_adb_device_mouse_request_change_addr(d->devaddr);
 break;
 default:
 d->devaddr = buf[1] & 0xf;
@@ -172,8 +172,8 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 d->handler = buf[2];
 }
 
-trace_adb_mouse_request_change_addr_and_handler(d->devaddr,
-d->handler);
+trace_adb_device_mouse_request_change_addr_and_handler(
+d->devaddr, d->handler);
 break;
 }
 }
@@ -191,7 +191,7 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 olen = 2;
 break;
 }
-trace_adb_mouse_readreg(reg, obuf[0], obuf[1]);
+trace_adb_device_mouse_readreg(reg, obuf[0], obuf[1]);
 break;
 }
 return olen;
diff --git a/hw/input/trace-events b/hw/input/trace-events
index a2888fd10c..6f0d78241c 100644
--- a/hw/input/trace-events
+++ b/hw/input/trace-events
@@ -1,18 +1,18 @@
 # See docs/devel/tracing.txt for syntax documentation.
 
 # adb-kbd.c
-adb_kbd_no_key(void) "Ignoring NO_KEY"
-adb_kbd_writereg(int reg, uint8_t val) "reg %d val 0x%2.2x"
-adb_kbd_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf[0] 0x%2.2x 
obuf[1] 0x%2.2x"
-adb_kbd_request_change_addr(int devaddr) "change addr to 0x%x"
-adb_kbd_request_change_addr_and_handler(int devaddr, int handler) "

Re: [Bug 1885247] [NEW] Build error in Intel 32-bit hosts

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/26/20 11:20 AM, Thomas Huth wrote:
> On 26/06/2020 11.13, Philippe Mathieu-Daudé wrote:
>> On 6/26/20 9:37 AM, Aleksandar Markovic wrote:
>>> пет, 26. јун 2020. у 09:11 Aleksandar Markovic
>>> <1885...@bugs.launchpad.net> је написао/ла:

 Public bug reported:

 The code base is on master, checked out on Thursday June25th 2020,
 0250c595c9d. The build procedure:

 $ mkdir build-gcc
 $ cd build-gcc
 $ ../configure
 $ make

 The build error message is:

    CC  x86_64-softmmu/hw/hyperv/hyperv.o
    CC  x86_64-softmmu/hw/hyperv/hyperv_testdev.o
    CC  x86_64-softmmu/hw/hyperv/vmbus.o
 /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c: In function
 ‘gpadl_iter_io’:
 /home/rtrk/Build/qemu-master/hw/hyperv/vmbus.c:386:13: error: cast
 to pointer from integer of different size [-Werror=int-to-pointer-cast]
   p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) |
 off_in_page);
   ^
 cc1: all warnings being treated as errors
 make[1]: *** [/home/rtrk/Build/qemu-master/rules.mak:69:
 hw/hyperv/vmbus.o] Error 1
 make: *** [Makefile:527: x86_64-softmmu/all] Error 2
>>
>> FWIW there is no CI job covering x86 KVM on 32-bit host build.
>> Should this be covered? I guess the problem is no CI services
>> provide 32-bit x86...
> 
> You can certainly provide either a container, or install the 32-bit
> libraries in a 64-bit environment. Then run
> 
> PKG_CONFIG_LIBDIR=... ./configure --extra-cflags=-m32
> 
> and it should be possible to build 32-bit binaries, too.
> 
> Alternatively, we could add a cross-compilation job that builds with
> i686-w64-mingw32 in 32-bit.

Oh, this case is covered:
https://app.shippable.com/github/qemu/qemu/runs/2437/2/console

But this doesn't use KVM ;)




[PULL 19/22] mac_via: rework ADB state machine to be compatible with both MacOS and Linux

2020-06-26 Thread Mark Cave-Ayland
The existing ADB state machine is designed to work with Linux which has a 
different
interpretation of the state machine detailed in "Guide to the Macintosh Family
Hardware". In particular the current Linux implementation includes an extra 
change
to IDLE state when switching the VIA between send and receive modes which does 
not
occur in MacOS, and omitting this transition causes the current mac_via ADB 
state
machine to fail.

Rework the ADB state machine accordingly so that it can enumerate and autopoll 
the
ADB under both Linux and MacOS, including the addition of the new 
adb_autopoll_block()
and adb_autopoll_unblock() functions.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Finn Thain 
Acked-by: Laurent Vivier 
Message-Id: <20200623204936.24064-20-mark.cave-ayl...@ilande.co.uk>
---
 hw/misc/mac_via.c | 375 ++
 hw/misc/trace-events  |   3 +
 include/hw/misc/mac_via.h |   1 +
 3 files changed, 260 insertions(+), 119 deletions(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index a1dc00d9f6..71b6f92645 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -599,176 +599,312 @@ static void via1_rtc_update(MacVIAState *m)
 m->cmd = REG_EMPTY;
 }
 
-static int adb_via_poll(MacVIAState *s, int state, uint8_t *data)
+static void adb_via_poll(void *opaque)
 {
-ADBBusState *adb_bus = &s->adb_bus;
+MacVIAState *m = opaque;
+MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
+MOS6522State *s = MOS6522(v1s);
+ADBBusState *adb_bus = &m->adb_bus;
+uint8_t obuf[9];
+uint8_t *data = &s->sr;
+int olen;
+uint16_t pending;
 
-if (state != ADB_STATE_IDLE) {
-return 0;
+/*
+ * Setting vADBInt below indicates that an autopoll reply has been
+ * received, however we must block autopoll until the point where
+ * the entire reply has been read back to the host
+ */
+if (adb_bus->autopoll_blocked) {
+return;
+} else {
+adb_autopoll_block(adb_bus);
 }
 
-if (s->adb_data_in_size < s->adb_data_in_index) {
-return 0;
-}
+m->adb_data_in_index = 0;
+m->adb_data_out_index = 0;
+olen = adb_poll(adb_bus, obuf, adb_bus->autopoll_mask);
+
+if (olen > 0) {
+/* Autopoll response */
+*data = obuf[0];
+olen--;
+memcpy(m->adb_data_in, &obuf[1], olen);
+m->adb_data_in_size = olen;
+
+s->b &= ~VIA1B_vADBInt;
+qemu_irq_raise(m->adb_data_ready);
+} else if (olen < 0) {
+/* Bus timeout (device does not exist) */
+*data = 0xff;
+s->b |= VIA1B_vADBInt;
+adb_autopoll_unblock(adb_bus);
+} else {
+pending = adb_bus->pending & ~(1 << (m->adb_autopoll_cmd >> 4));
+
+if (pending) {
+/*
+ * Bus timeout (device exists but another device has data). Block
+ * autopoll so the OS can read out the first EVEN and first ODD
+ * byte to determine bus timeout and SRQ status
+ */
+*data = m->adb_autopoll_cmd;
+s->b &= ~VIA1B_vADBInt;
 
-if (s->adb_data_out_index != 0) {
-return 0;
-}
+obuf[0] = 0xff;
+obuf[1] = 0xff;
+olen = 2;
 
-s->adb_data_in_index = 0;
-s->adb_data_out_index = 0;
-s->adb_data_in_size = adb_poll(adb_bus, s->adb_data_in,
-   adb_bus->autopoll_mask);
+memcpy(m->adb_data_in, obuf, olen);
+m->adb_data_in_size = olen;
 
-if (s->adb_data_in_size) {
-*data = s->adb_data_in[s->adb_data_in_index++];
-qemu_irq_raise(s->adb_data_ready);
+qemu_irq_raise(m->adb_data_ready);
+} else {
+/* Bus timeout (device exists but no other device has data) */
+*data = 0;
+s->b |= VIA1B_vADBInt;
+adb_autopoll_unblock(adb_bus);
+}
 }
 
-return s->adb_data_in_size;
+trace_via1_adb_poll(*data, (s->b & VIA1B_vADBInt) ? "+" : "-",
+adb_bus->status, m->adb_data_in_index, olen);
 }
 
-static int adb_via_send(MacVIAState *s, int state, uint8_t data)
+static int adb_via_send_len(uint8_t data)
 {
-switch (state) {
-case ADB_STATE_NEW:
-s->adb_data_out_index = 0;
-break;
-case ADB_STATE_EVEN:
-if ((s->adb_data_out_index & 1) == 0) {
-return 0;
-}
-break;
-case ADB_STATE_ODD:
-if (s->adb_data_out_index & 1) {
-return 0;
+/* Determine the send length from the given ADB command */
+uint8_t cmd = data & 0xc;
+uint8_t reg = data & 0x3;
+
+switch (cmd) {
+case 0x8:
+/* Listen command */
+switch (reg) {
+case 2:
+/* Register 2 is only used for the keyboard */
+return 3;
+case 3:
+/*
+ * Fortunately our devices only implement writes
+ * to register 3 which i

Re: [PATCH v3 0/9] Generalize memory encryption models

2020-06-26 Thread Daniel P . Berrangé
On Fri, Jun 26, 2020 at 11:01:58AM +0200, Janosch Frank wrote:
> On 6/26/20 8:53 AM, David Hildenbrand wrote:
> > Does this have any implications when probing with the 'none' machine?
> 
>  I'm not sure.  In your case, I guess the cpu bit would still show up
>  as before, so it would tell you base feature availability, but not
>  whether you can use the new configuration option.
> 
>  Since the HTL option is generic, you could still set it on the "none"
>  machine, though it wouldn't really have any effect.  That is, if you
>  could create a suitable object to point it at, which would depend on
>  ... details.
> 
> >>>
> >>> The important point is that we never want the (expanded) host cpu model
> >>> look different when either specifying or not specifying the HTL
> >>> property.
> >>
> >> Ah, yes, I see your point.  So my current suggestion will satisfy
> >> that, basically it is:
> >>
> >> cpu has unpack (inc. by default) && htl specified
> >>=> works (allowing secure), as expected
> > 
> > ack
> > 
> >>
> >> !cpu has unpack && htl specified
> >>=> bails out with an error
> > 
> > ack
> > 
> >>
> >> !cpu has unpack && !htl specified
> >>=> works for a non-secure guest, as expected
> >>=> guest will fail if it attempts to go secure
> > 
> > ack, behavior just like running on older hw without unpack
> > 
> >>
> >> cpu has unpack && !htl specified
> >>=> works as expected for a non-secure guest (unpack feature is
> >>   present, but unused)
> >>=> secure guest may work "by accident", but only if all virtio
> >>   properties have the right values, which is the user's
> >>   problem
> >>
> >> That last case is kinda ugly, but I think it's tolerable.
> > 
> > Right, we must not affect non-secure guests, and existing secure setups
> > (e.g., older qemu machines). Will have to think about this some more,
> > but does not sound too crazy.
> 
> I severely dislike having to specify things to make PV work.
> The IOMMU is already a thorn in our side and we're working on making the
> whole ordeal completely transparent so the only requirement to make this
> work is the right machine, kernel, qemu and kernel cmd line option
> "prot_virt=1". That's why we do the reboot into PV mode in the first place.
> 
> I.e. the goal is that if customers convert compatible guests into
> protected ones and start them up on a z15 on a distro with PV support
> they can just use the guest without having to change XML or command line
> parameters.

If you're exposing new features to the guest machine, then it is usually
to be expected that XML and QEMU command line will change. Some simple
things might be hidable behind a new QEMU machine type or CPU model, but
there's a limit to how much should be hidden that way while staying sane.

I'd really expect the configuration to change when switching a guest to
a new hardware platform and wanting major new functionality to be enabled.
The XML / QEMU config is a low level instantiation of a particular feature
set, optimized for a specific machine, rather than a high level description
of ideal "best" config independent of host machine.

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH v4 4/8] hw/misc/pca9552: Add a 'description' property for debugging purpose

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/26/20 7:49 AM, Markus Armbruster wrote:
> Philippe Mathieu-Daudé  writes:
> 
>> On 6/25/20 10:12 AM, Philippe Mathieu-Daudé wrote:
>>> On 6/25/20 8:37 AM, Markus Armbruster wrote:
 Cédric Le Goater  writes:

> On 6/22/20 10:31 AM, Philippe Mathieu-Daudé wrote:
>> On 6/22/20 8:27 AM, Cédric Le Goater wrote:
>>> On 6/21/20 12:58 AM, Philippe Mathieu-Daudé wrote:
 Add a description field to distinguish between multiple devices.

 Pardon my lack of imagination: how does this help you with debugging?
>>>
>>> Ah, the patch subject is indeed incorrect, this should be:
>>> "... for *tracing* purpose" (I use tracing when debugging).
>>>
>>> In the next patch, we use the 'description' property:
>>>
>>> +# pca9552.c
>>> +pca9552_gpio_status(const char *description, const char *buf) "%s GPIOs
>>> 0-15 [%s]"
>>>
>>> So when the machine has multiple PCA9552 and guest accesses both,
>>> we can distinct which one is used. For me having "pca1" / "pca0"
>>> is easier to follow than the address of the QOM object.
>>>

>>> Reviewed-by: Cédric Le Goater 
>>>
>>> Could it be a QOM attribute ? 
>>
>> What do you call a 'QOM attribute'?
>> Is it what qdev properties implement?
>> (in this case via DEFINE_PROP_STRING).
>
> I meant a default Object property, which would apply to all Objects. 

 Good point.  Many devices have multiple component objects of the same
 type.

> What you did is fine, so :
>
> Reviewed-by: Cédric Le Goater 
>
> but, may be, a well defined child name is enough for the purpose.

 object_get_canonical_path() returns a distinct path for each (component)
 object.  The path components are the child property names.

 Properties can have descriptions: object_property_set_description().
>>>
>>> TIL object_property_set_description :>
>>>
>>> Ah, there is no equivalent object_property_get_description(),
>>> we have to use object_get_canonical_path(). Hmm, not obvious.
>>>

 Sufficient?
>>>
>>> I don't know... This seems a complex way to do something simple...
>>> This is already a QDEV. Having to use QOM API seems going
>>> backward, since we have the DEFINE_PROP_STRING() macros available
>>> in "hw/qdev-properties.h".
>>>
>>> Maybe I'm not seeing the advantages clearly. I'll try later.
>>
>> The canonical path is not very helpful in trace log...
> 
> Why?
> 
> Okay, I checked the code.  Since the devices in question don't get a
> composition tree parent assigned, realize puts them in the
> /machine/unattached orphanage.  The canonical path is something like
> "/machine/unattached/device[6]", which is less than clear.
> 
> The components of the canonical path are the names of the QOM child
> properties.  object_get_canonical_path_component() returns the last one,
> in this case "device[6]".
> 
> If we made the devices QOM children of some other device, we could name
> the child properties "pca0" and "pca1".
> object_get_canonical_path_component() would then return the strings you
> want to see.
> 
> We make a device a QOM child of some QOM parent device only if the child
> is a component device of the parent (hence the name "composition
> tree").
> 
> Are these devices integral components of something else, or are they
> separate chips?

Separate chips in the machine (actually not even on the machine mother
board where is the CPU, but on a daughter board card).

So in the composition tree I expect to see them as

  /machine/pca0
  /machine/pca1

>> The description I set matches the hardware definitions
>> and is easier to follow, see patch #6 (where it is set)
>> where the description comes from:
>>
>> https://www.mail-archive.com/qemu-devel@nongnu.org/msg714658.html
>>
>>   Description name taken from:
>>   https://github.com/open-power/witherspoon-xml/blob/master/witherspoon.xml
>>
>> So in this particular case I don't find the canonical pathname
>> practical (from an hardware debugging perspective).
> 
> Personally, I'd be content with i2c bus and address for debugging
> purposes.
> 
> The i2c buses *are* components: canonical paths look like
> "/machine/soc/i2c/aspeed.i2c.3".  The combination of
> object_get_canonical_path_component(dev) and
> object_property_get_uint(dev, "address", &error_abort) identifies any
> i2c device on this machine, not just the two you decorate with a
> description string.

The I2C busses is provided by Aspeed peripherals. I counted 19 different
I2C busses on this machine.

"pca0" is connected to i2c bus #11, "pca1" to bus #3.

I still don't think this will be practical, but I'll try your
suggestion.

Regards,

Phil.



Re: [PATCH v3 0/9] Generalize memory encryption models

2020-06-26 Thread Janosch Frank
On 6/26/20 11:32 AM, Daniel P. Berrangé wrote:
> On Fri, Jun 26, 2020 at 11:01:58AM +0200, Janosch Frank wrote:
>> On 6/26/20 8:53 AM, David Hildenbrand wrote:
>>> Does this have any implications when probing with the 'none' machine?
>>
>> I'm not sure.  In your case, I guess the cpu bit would still show up
>> as before, so it would tell you base feature availability, but not
>> whether you can use the new configuration option.
>>
>> Since the HTL option is generic, you could still set it on the "none"
>> machine, though it wouldn't really have any effect.  That is, if you
>> could create a suitable object to point it at, which would depend on
>> ... details.
>>
>
> The important point is that we never want the (expanded) host cpu model
> look different when either specifying or not specifying the HTL
> property.

 Ah, yes, I see your point.  So my current suggestion will satisfy
 that, basically it is:

 cpu has unpack (inc. by default) && htl specified
=> works (allowing secure), as expected
>>>
>>> ack
>>>

 !cpu has unpack && htl specified
=> bails out with an error
>>>
>>> ack
>>>

 !cpu has unpack && !htl specified
=> works for a non-secure guest, as expected
=> guest will fail if it attempts to go secure
>>>
>>> ack, behavior just like running on older hw without unpack
>>>

 cpu has unpack && !htl specified
=> works as expected for a non-secure guest (unpack feature is
   present, but unused)
=> secure guest may work "by accident", but only if all virtio
   properties have the right values, which is the user's
   problem

 That last case is kinda ugly, but I think it's tolerable.
>>>
>>> Right, we must not affect non-secure guests, and existing secure setups
>>> (e.g., older qemu machines). Will have to think about this some more,
>>> but does not sound too crazy.
>>
>> I severely dislike having to specify things to make PV work.
>> The IOMMU is already a thorn in our side and we're working on making the
>> whole ordeal completely transparent so the only requirement to make this
>> work is the right machine, kernel, qemu and kernel cmd line option
>> "prot_virt=1". That's why we do the reboot into PV mode in the first place.
>>
>> I.e. the goal is that if customers convert compatible guests into
>> protected ones and start them up on a z15 on a distro with PV support
>> they can just use the guest without having to change XML or command line
>> parameters.
> 
> If you're exposing new features to the guest machine, then it is usually
> to be expected that XML and QEMU command line will change. Some simple
> things might be hidable behind a new QEMU machine type or CPU model, but
> there's a limit to how much should be hidden that way while staying sane.
> 
> I'd really expect the configuration to change when switching a guest to
> a new hardware platform and wanting major new functionality to be enabled.
> The XML / QEMU config is a low level instantiation of a particular feature
> set, optimized for a specific machine, rather than a high level description
> of ideal "best" config independent of host machine.

You still have to set the host command line and make sure that unpack is
available. Currently you also have to specify the IOMMU which we like to
drop as a requirement. Everything else is dependent on runtime
information which tells us if we need to take a PV or non-PV branch.
Having the unpack facility should be enough to use the unpack facility.

Keep in mind that we have no real concept of a special protected VM to
begin with. If the VM never boots into a protected kernel it will never
be protected. On a reboot it drops from protected into unprotected mode
to execute the bios and boot loader and then may or may not move back
into a protected state.

> 
> Regards,
> Daniel
> 




signature.asc
Description: OpenPGP digital signature


[PATCH v1] virtio-balloon: always indicate S_DONE when migration fails

2020-06-26 Thread David Hildenbrand
If something goes wrong during precopy, before stopping the VM, we will
never send a S_DONE indication to the VM, resulting in the hinted pages
not getting released to be used by the guest OS (e.g., Linux).

Easy to reproduce:
1. Start migration (e.g., HMP "migrate -d 'exec:gzip -c > STATEFILE.gz'")
2. Cancel migration (e.g., HMP "migrate_cancel")
3. Oberve in the guest (e.g., cat /proc/meminfo) that there is basically
   no free memory left.

While at it, add similar locking to virtio_balloon_free_page_done() as
done in virtio_balloon_free_page_stop. Locking is still weird, but that
has to be sorted out separately.

There is nothing to do in the PRECOPY_NOTIFY_COMPLETE case. Add some
comments regarding S_DONE handling.

Fixes: c13c4153f76d ("virtio-balloon: VIRTIO_BALLOON_F_FREE_PAGE_HINT")
Cc: Wei Wang 
Cc: Alexander Duyck 
Signed-off-by: David Hildenbrand 
---
 hw/virtio/virtio-balloon.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 10507b2a43..13ba208694 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -628,8 +628,13 @@ static void virtio_balloon_free_page_done(VirtIOBalloon *s)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(s);
 
-s->free_page_report_status = FREE_PAGE_REPORT_S_DONE;
-virtio_notify_config(vdev);
+if (s->free_page_report_status != FREE_PAGE_REPORT_S_DONE) {
+/* See virtio_balloon_free_page_stop() */
+qemu_mutex_lock(&s->free_page_lock);
+s->free_page_report_status = FREE_PAGE_REPORT_S_DONE;
+qemu_mutex_unlock(&s->free_page_lock);
+virtio_notify_config(vdev);
+}
 }
 
 static int
@@ -653,8 +658,6 @@ virtio_balloon_free_page_report_notify(NotifierWithReturn 
*n, void *data)
 case PRECOPY_NOTIFY_SETUP:
 precopy_enable_free_page_optimization();
 break;
-case PRECOPY_NOTIFY_COMPLETE:
-case PRECOPY_NOTIFY_CLEANUP:
 case PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC:
 virtio_balloon_free_page_stop(dev);
 break;
@@ -662,9 +665,22 @@ virtio_balloon_free_page_report_notify(NotifierWithReturn 
*n, void *data)
 if (vdev->vm_running) {
 virtio_balloon_free_page_start(dev);
 } else {
+/*
+ * Set S_DONE before migrating the vmstate, so the guest will reuse
+ * all hinted pages once running on the destination.
+ */
 virtio_balloon_free_page_done(dev);
 }
 break;
+case PRECOPY_NOTIFY_CLEANUP:
+/*
+ * Especially, if something goes wrong during precopy or if migration
+ * is canceled, we have to properly communicate S_DONE to the VM.
+ */
+virtio_balloon_free_page_done(dev);
+break;
+case PRECOPY_NOTIFY_COMPLETE:
+break;
 default:
 virtio_error(vdev, "%s: %d reason unknown", __func__, pnd->reason);
 }
-- 
2.26.2




QEMU | Pipeline #160380996 has failed for master | 5acc270a

2020-06-26 Thread GitLab via


Your pipeline has failed.

Project: QEMU ( https://gitlab.com/qemu-project/qemu )
Branch: master ( https://gitlab.com/qemu-project/qemu/-/commits/master )

Commit: 5acc270a ( 
https://gitlab.com/qemu-project/qemu/-/commit/5acc270a355120ce967ca1f1eeca0abbdb9303c8
 )
Commit Message: Merge remote-tracking branch 'remotes/xtensa/ta...
Commit Author: Peter Maydell ( https://gitlab.com/pm215 )

Pipeline #160380996 ( 
https://gitlab.com/qemu-project/qemu/-/pipelines/160380996 ) triggered by Alex 
Bennée ( https://gitlab.com/stsquad )
had 2 failed builds.

Job #612737123 ( https://gitlab.com/qemu-project/qemu/-/jobs/612737123/raw )

Stage: test
Name: build-disabled
Trace: qemu-system-i386: falling back to tcg
Could not access KVM kernel module: No such file or directory
qemu-system-i386: -accel kvm: failed to initialize kvm: No such file or 
directory
qemu-system-i386: falling back to tcg
  TESTcheck-qtest-i386: tests/qtest/device-introspect-test
  TESTcheck-qtest-i386: tests/qtest/machine-none-test
  TESTcheck-qtest-i386: tests/qtest/qmp-test
  TESTcheck-qtest-i386: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-i386: tests/qtest/qom-test
  TESTcheck-qtest-i386: tests/qtest/test-hmp
  TESTcheck-qtest-i386: tests/qtest/qos-test
  TESTcheck-qtest-mips64: tests/qtest/endianness-test
  TESTcheck-qtest-mips64: tests/qtest/display-vga-test
  TESTcheck-qtest-mips64: tests/qtest/cdrom-test
  TESTcheck-qtest-mips64: tests/qtest/device-introspect-test
  TESTcheck-qtest-mips64: tests/qtest/machine-none-test
  TESTcheck-qtest-mips64: tests/qtest/qmp-test
  TESTcheck-qtest-mips64: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-mips64: tests/qtest/qom-test
  TESTcheck-qtest-mips64: tests/qtest/test-hmp
  TESTcheck-qtest-mips64: tests/qtest/qos-test
qemu-system-ppc64: warning: machine has no BMC device. Use '-device 
ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' to define one
qemu-system-ppc64: warning: machine has no BMC device. Use '-device 
ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' to define one
qemu-system-ppc64: warning: machine has no BMC device. Use '-device 
ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' to define one
  TESTcheck-qtest-ppc64: tests/qtest/machine-none-test
  TESTcheck-qtest-ppc64: tests/qtest/qmp-test
  TESTcheck-qtest-ppc64: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-ppc64: tests/qtest/qom-test
section_end:1593165288:step_script
ERROR: Job failed: execution took longer than 1h0m0s seconds


Job #612737124 ( https://gitlab.com/qemu-project/qemu/-/jobs/612737124/raw )

Stage: test
Name: build-tcg-disabled
Trace: 208  ...[09:16:03] ...  
208  pass   [09:16:03] [09:16:03]   0s   
209  ...[09:16:03] ...  
209  pass   [09:16:03] [09:16:04]   0s   
215  ...[09:16:04] ...  
215  pass   [09:16:04] [09:17:28]  84s   
216  ...[09:17:28] ...  
216  pass   [09:17:28] [09:17:32]   4s   
218  ...[09:17:32] ...  
218  pass   [09:17:32] [09:17:34]   2s   
222  ...[09:17:34] ...  
222  pass   [09:17:34] [09:17:34]   0s   
227  ...[09:17:34] ...  
227  pass   [09:17:34] [09:17:35]   1s   
234  ...[09:17:35] ...  
234  pass   [09:17:35] [09:17:35]   0s   
246  ...[09:17:35] ...  
246  pass   [09:17:35] [09:17:36]   1s   
247  ...[09:17:36] ...  
247  pass   [09:17:36] [09:17:37]   1s   
248  ...[09:17:37] ...  
248  pass   [09:17:37] [09:17:38]   1s   
250  ...[09:17:38] ...  
250  pass   [09:17:38] [09:17:38]   0s   
254  ...[09:17:38] ...  
254  pass   [09:17:38] [09:17:38]   0s   
255  ...[09:17:38] ...  
255  pass   [09:17:38] [09:17:40]   2s   
257  ...[09:17:40] ...  
257  pass   [09:17:40] [09:17:50]  10s   
258  ...[09:17:50] ...  
258  pass   [09:17:50] [09:17:51]   1s   
260  ...[09:17:51] ...  
260  pass   [09:17:51] [09:17:52]   1s   
261  ...[09:17:52] ...  
26

Re: [PATCH v4 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-06-26 Thread Cornelia Huck
On Wed, 24 Jun 2020 16:23:10 -0400
Collin Walling  wrote:

> As more features and facilities are added to the Read SCP Info (RSCPI)
> response, more space is required to store them. The space used to store
> these new features intrudes on the space originally used to store CPU
> entries. This means as more features and facilities are added to the
> RSCPI response, less space can be used to store CPU entries.
> 
> With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
> the RSCPI command and determine if the SCCB is large enough to store a
> complete reponse. If it is not large enough, then the required length
> will be set in the SCCB header.
> 
> The caller of the SCLP command is responsible for creating a
> large-enough SCCB to store a complete response. Proper checking should
> be in place, and the caller should execute the command once-more with
> the large-enough SCCB.
> 
> This facility also enables an extended SCCB for the Read CPU Info
> (RCPUI) command.
> 
> When this facility is enabled, the boundary violation response cannot
> be a result from the RSCPI, RSCPI Forced, or RCPUI commands.
> 
> In order to tolerate kernels that do not yet have full support for this
> feature, a "fixed" offset to the start of the CPU Entries within the
> Read SCP Info struct is set to allow for the original 248 max entries
> when this feature is disabled.
> 
> Additionally, this is introduced as a CPU feature to protect the guest
> from migrating to a machine that does not support storing an extended
> SCCB. This could otherwise hinder the VM from being able to read all
> available CPU entries after migration (such as during re-ipl).
> 
> Signed-off-by: Collin Walling 
> ---
>  hw/s390x/sclp.c | 24 +++-
>  include/hw/s390x/sclp.h |  1 +
>  target/s390x/cpu_features_def.inc.h |  1 +
>  target/s390x/gen-features.c |  1 +
>  target/s390x/kvm.c  |  8 
>  5 files changed, 34 insertions(+), 1 deletion(-)
> 

(...)

> @@ -111,6 +131,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>  CPUEntry *entries_start = (void *)sccb + offset_cpu;
>  
>  if (!sccb_verify_length(sccb, machine->possible_cpus->len, offset_cpu)) {
> +qemu_log_mask(LOG_GUEST_ERROR, "insufficient sccb size to store "
> +  "read scp info response\n");

Not sure if logging needed/provided length would be helpful here.

>  return;
>  }
>  

(...)

Acked-by: Cornelia Huck 




Re: [PATCH v4 8/8] s390: guest support for diagnose 0x318

2020-06-26 Thread Cornelia Huck
On Wed, 24 Jun 2020 16:23:12 -0400
Collin Walling  wrote:

> DIAGNOSE 0x318 (diag318) is an s390 instruction that allows the storage
> of diagnostic information that is collected by the firmware in the case
> of hardware/firmware service events.
> 
> QEMU handles the instruction by storing the info in the CPU state. A
> subsequent register sync will communicate the data to the hypervisor.
> 
> QEMU handles the migration via a VM State Description.
> 
> This feature depends on the Extended-Length SCCB (els) feature. If
> els is not present, then a warning will be printed and the SCLP bit
> that allows the Linux kernel to execute the instruction will not be
> set.
> 
> Availability of this instruction is determined by byte 134 (aka fac134)
> bit 0 of the SCLP Read Info block. This coincidentally expands into the
> space used for CPU entries, which means VMs running with the diag318
> capability may not be able to read information regarding all CPUs
> unless the guest kernel supports an extended-length SCCB.
> 
> This feature is not supported in protected virtualization mode.
> 
> Signed-off-by: Collin Walling 
> Acked-by: Janosch Frank 
> ---
>  hw/s390x/sclp.c |  5 +
>  include/hw/s390x/sclp.h |  3 +++
>  target/s390x/cpu.h  |  2 ++
>  target/s390x/cpu_features.h |  1 +
>  target/s390x/cpu_features_def.inc.h |  3 +++
>  target/s390x/cpu_models.c   |  1 +
>  target/s390x/gen-features.c |  1 +
>  target/s390x/kvm.c  | 31 +
>  target/s390x/machine.c  | 17 
>  9 files changed, 64 insertions(+)

Acked-by: Cornelia Huck 




Re: [PATCH v1 1/2] semihosting: defer connect_chardevs a little more to use serialx

2020-06-26 Thread Fred Konrad




Le 6/16/20 à 4:52 PM, Alex Bennée a écrit :


kon...@adacore.com writes:


From: KONRAD Frederic 

With that we can just use chardev=serial0.


I don't quite follow what this means.

./aarch64-softmmu/qemu-system-aarch64 -cpu max -monitor none -chardev=serial0 
-M virt -display none -semihosting -kernel ./tests/tcg/aarch64-softmmu/memory
qemu-system-aarch64: -chardev=serial0: invalid option

./aarch64-softmmu/qemu-system-aarch64 -cpu max -monitor none -chardev 
id=serial0 -M virt -display none -semihosting -kernel 
./tests/tcg/aarch64-softmmu/memory
qemu-system-aarch64: -chardev id=serial0: chardev: "serial0" missing backend

The run:

./aarch64-softmmu/qemu-system-aarch64 -cpu max -serial mon:stdio -M virt 
-display none -semihosting -kernel ./tests/tcg/aarch64-softmmu/memory

works fine without this patch.


Hi Alex, and sorry for the delay,

I meant `-semihosting-config chardev=serial0`.  I suspect your last command-line
will print any string sent to semihosting to stderr by default.





Signed-off-by: KONRAD Frederic 
---
  softmmu/vl.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/softmmu/vl.c b/softmmu/vl.c
index f669c06..9b8b48a 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -4123,8 +4123,6 @@ void qemu_init(int argc, char **argv, char **envp)
  
  qemu_opts_foreach(qemu_find_opts("chardev"),

chardev_init_func, NULL, &error_fatal);
-/* now chardevs have been created we may have semihosting to connect */
-qemu_semihosting_connect_chardevs();
  
  #ifdef CONFIG_VIRTFS

  qemu_opts_foreach(qemu_find_opts("fsdev"),
@@ -4271,6 +4269,9 @@ void qemu_init(int argc, char **argv, char **envp)
  if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
  exit(1);
  
+/* now chardevs have been created we may have semihosting to connect */

+qemu_semihosting_connect_chardevs();
+
  /* If no default VGA is requested, the default is "none".  */
  if (default_vga) {
  vga_model = get_default_vga_model(machine_class);







[PATCH 1/5] haiku build fix

2020-06-26 Thread David CARLIER
>From 4d0933384d2bfcd0fc8c4c06eed2d07f3f1b7f8b Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 10:35:40 +
Subject: [PATCH 1/5] Haiku build fix enabling BSD symbols.

Signed-off-by: David Carlier 
---
 configure | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index ba88fd1824..96ba4cf3ce 100755
--- a/configure
+++ b/configure
@@ -901,8 +901,8 @@ SunOS)
 ;;
 Haiku)
   haiku="yes"
-  QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS $QEMU_CFLAGS"
-  LIBS="-lposix_error_mapper -lnetwork $LIBS"
+  QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -DBSD_SOURCE $QEMU_CFLAGS"
+  LIBS="-lposix_error_mapper -lnetwork -lbsd $LIBS"
 ;;
 Linux)
   audio_drv_list="try-pa oss"
--
2.26.0



[PATCH 4/5] haiku build fix

2020-06-26 Thread David CARLIER
>From 775173ded5657de4d4b467f2f68e747f6a9c0750 Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 10:44:36 +
Subject: [PATCH 4/5] Platform specific changes qemu_exec_dir implementation

Signed-off-by: David Carlier 
---
 include/qemu/osdep.h |  4 
 util/oslib-posix.c   | 20 
 2 files changed, 24 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ff7c17b857..da970cf654 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -388,6 +388,10 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #define HAVE_CHARDEV_PARPORT 1
 #endif

+#if defined(__HAIKU__)
+#define SIGIO SIGPOLL
+#endif
+
 #if defined(CONFIG_LINUX)
 #ifndef BUS_MCEERR_AR
 #define BUS_MCEERR_AR 4
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 39ddc77c85..ff36fa41ff 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -38,7 +38,12 @@
 #include "qemu/sockets.h"
 #include "qemu/thread.h"
 #include 
+#if !defined __HAIKU__
 #include 
+#else
+#include 
+#include 
+#endif
 #include "qemu/cutils.h"

 #ifdef CONFIG_LINUX
@@ -390,6 +395,21 @@ void qemu_init_exec_dir(const char *argv0)
 }
 }
 }
+#elif defined(__HAIKU__)
+{
+image_info ii;
+int32_t c = 0;
+
+*buf = '\0';
+while (get_next_image_info(0, &c, &ii) == B_OK) {
+if (ii.type == B_APP_IMAGE) {
+strncpy(buf, ii.name, sizeof(buf));
+buf[sizeof(buf) - 1] = '\0';
+p = buf;
+break;
+}
+}
+}
 #endif
 /* If we don't have any way of figuring out the actual executable
location then try argv[0].  */
--
2.26.0



[ PATCH 2/5] haiku build fix

2020-06-26 Thread David CARLIER
>From 19a41d406eda976001827d248398d7fb172d140b Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 10:38:17 +
Subject: [PATCH 2/5] Enable *pty API.

Signed-off-by: David Carlier 
---
 configure   | 9 +
 util/qemu-openpty.c | 2 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 96ba4cf3ce..f040b07463 100755
--- a/configure
+++ b/configure
@@ -2373,6 +2373,12 @@ else
   l2tpv3=no
 fi

+if check_include "pty.h" ; then
+  pty_h=yes
+else
+  pty_h=no
+fi
+
 #
 # vhost interdependencies and host support

@@ -7758,6 +7764,9 @@ fi
 if test "$sheepdog" = "yes" ; then
   echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
 fi
+if test "$pty_h" = "yes" ; then
+  echo "CONFIG_PTY=y" >> $config_host_mak
+fi
 if test "$fuzzing" = "yes" ; then
   if test "$have_fuzzer" = "yes"; then
 FUZZ_LDFLAGS=" -fsanitize=address,fuzzer"
diff --git a/util/qemu-openpty.c b/util/qemu-openpty.c
index 2e8b43bdf5..9d8ad6905e 100644
--- a/util/qemu-openpty.c
+++ b/util/qemu-openpty.c
@@ -35,7 +35,7 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"

-#if defined(__GLIBC__)
+#if defined CONFIG_PTY
 # include 
 #elif defined CONFIG_BSD
 # include 
--
2.26.0



[PATCH 5/5] haiku build fix

2020-06-26 Thread David CARLIER
>From 68d4d4312eccd212b4d2484e09425816ebd2346a Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 11:01:54 +
Subject: [PATCH 5/5] Last chunk of build fix

Signed-off-by: David Carlier 
---
 include/qemu/bswap.h | 2 ++
 util/Makefile.objs   | 2 +-
 util/compatfd.c  | 2 ++
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 2a9f3fe783..1d3e4c24e4 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -8,6 +8,8 @@
 # include 
 #elif defined(__FreeBSD__)
 # include 
+#elif defined(__HAIKU__)
+# include 
 #elif defined(CONFIG_BYTESWAP_H)
 # include 

diff --git a/util/Makefile.objs b/util/Makefile.objs
index cc5e37177a..faebc13fac 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -39,7 +39,7 @@ util-obj-y += qsp.o
 util-obj-y += range.o
 util-obj-y += stats64.o
 util-obj-y += systemd.o
-util-obj-$(CONFIG_POSIX) += drm.o
+util-obj-$(CONFIG_LINUX) += drm.o
 util-obj-y += guest-random.o
 util-obj-$(CONFIG_GIO) += dbus.o
 dbus.o-cflags = $(GIO_CFLAGS)
diff --git a/util/compatfd.c b/util/compatfd.c
index c296f55d14..ee47dd8089 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -16,7 +16,9 @@
 #include "qemu/osdep.h"
 #include "qemu/thread.h"

+#if defined(CONFIG_SIGNALFD)
 #include 
+#endif

 struct sigfd_compat_info
 {
--
2.26.0



[PATCH 3/5] haiku build fix

2020-06-26 Thread David CARLIER
>From 56890fa5728d11c72232348b3f3273e2df31c197 Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 10:40:58 +
Subject: [PATCH 3/5] Checking mlockall symbol presence

Signed-off-by: David Carlier 
---
 configure  | 15 +++
 os-posix.c |  4 
 2 files changed, 19 insertions(+)

diff --git a/configure b/configure
index f040b07463..34b0f0f036 100755
--- a/configure
+++ b/configure
@@ -2379,6 +2379,18 @@ else
   pty_h=no
 fi

+cat > $TMPC <
+int main(int argc, char *argv[]) {
+return mlockall(MCL_FUTURE);
+}
+EOF
+if compile_prog "" "" ; then
+  have_mlockall=yes
+else
+  have_mlockall=no
+fi
+
 #
 # vhost interdependencies and host support

@@ -7767,6 +7779,9 @@ fi
 if test "$pty_h" = "yes" ; then
   echo "CONFIG_PTY=y" >> $config_host_mak
 fi
+if test "$have_mlockall" = "yes" ; then
+  echo "CONFIG_MLOCKALL=y" >> $config_host_mak
+fi
 if test "$fuzzing" = "yes" ; then
   if test "$have_fuzzer" = "yes"; then
 FUZZ_LDFLAGS=" -fsanitize=address,fuzzer"
diff --git a/os-posix.c b/os-posix.c
index 3cd52e1e70..e02b566940 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -337,6 +337,7 @@ bool is_daemonized(void)

 int os_mlock(void)
 {
+#if defined CONFIG_MLOCKALL
 int ret = 0;

 ret = mlockall(MCL_CURRENT | MCL_FUTURE);
@@ -345,4 +346,7 @@ int os_mlock(void)
 }

 return ret;
+#else
+return -ENOSYS;
+#endif
 }
--
2.26.0



RE: [PATCH v2 3/3] usb/hcd-xhci: Split pci wrapper for xhci base model

2020-06-26 Thread Sai Pavan Boddu
HI Markus,

> -Original Message-
> From: Markus Armbruster 
> Sent: Friday, June 26, 2020 11:42 AM
> To: Sai Pavan Boddu 
> Cc: Peter Maydell ; Thomas Huth
> ; Eduardo Habkost ; qemu-
> de...@nongnu.org; Alistair Francis ; Gerd
> Hoffmann ; Paolo Bonzini ;
> Ying Fang ; 'Marc-André Lureau'
> ; 'Philippe Mathieu-Daudé'
> 
> Subject: Re: [PATCH v2 3/3] usb/hcd-xhci: Split pci wrapper for xhci base
> model
> 
> Sai Pavan Boddu  writes:
> 
> > Hi Markus,
> >
> >> -Original Message-
> >> From: Markus Armbruster 
> >> Sent: Thursday, June 25, 2020 1:42 PM
> >> To: Sai Pavan Boddu 
> >> Cc: Gerd Hoffmann ; Peter Maydell
> >> ; Thomas Huth ;
> Eduardo
> >> Habkost ; qemu-devel@nongnu.org; Alistair
> >> Francis ; 'Marc-André Lureau'
> >> ; Ying Fang ;
> >> Paolo Bonzini ; 'Philippe Mathieu-Daudé'
> >> 
> >> Subject: Re: [PATCH v2 3/3] usb/hcd-xhci: Split pci wrapper for xhci
> >> base model
> >>
> >> Sai Pavan Boddu  writes:
> >>
> >> > This patch sets the base to use xhci as sysbus model, for which pci
> >> > specific hooks are moved to hcd-xhci-pci.c. As a part of this
> >> > requirment msi/msix interrupts handling is moved under
> >> > XHCIPCIState, and XHCIState is  non qom object, make use of
> >> > 'container_of' calls to retrive XHCIPciState. Made required changes for
> qemu-xhci-nec.
> >> >
> >> > Signed-off-by: Sai Pavan Boddu 
> >>
> >> I can't see a "sysbus model".  What I can see is
> >>
> >>  TYPE_DEVICE
> >>   |
> >>TYPE_PCI_DEVICE
> >>   |
> >> TYPE_XHCI_PCI (renamed from TYPE_XHCI)
> >>   /   \
> >> TYPE_QEMU_XHCI TYPE_NEC_XHCI
> >>
> >> All but the two leaves are abstract.
> >>
> >> Do you intend to add a "sysbus model" in a future patch?
> > [Sai Pavan Boddu]  Yes. I would be sending it along with that a device
> > which would be using it. (i.e for zynqmp soc ) Let me know, if its good to
> include hcd-xhci-sysbus.c here ?
> 
> I'm not sure this series is worthwhile this future patch.  Up to the 
> maintainer.
> 
> Here's a clean way to provide different bus connectors (say PCI and
> sysbus) for the same core device:
> 
> Make the core device a TYPE_DEVICE.
> 
> For each desired bus, have a bus-specific device that contains a core device.
> Use object_initialize_child() for the component.
[Sai Pavan Boddu] This was my V1 implementation.
Changed it to non-qom structure after some feedback from @Gred. Felt like 
XHCIState will not be used standalone.

Thanks,
sai Pavan
> 
> Example: core device TYPE_SERIAL, PCI device TYPE_PCI_SERIAL, ISA device
> TYPE_ISA_SERIAL, sysbus devices TYPE_SERIAL_IO. TYPE_SERIAL_MM.



Re: [PATCH] i2c: Match parameters of i2c_start_transfer and i2c_send_recv

2020-06-26 Thread Fred Konrad



Hi Corey,

Le 6/22/20 à 11:32 PM, Corey Minyard a écrit :

On Sun, Jun 21, 2020 at 04:43:38PM +0200, BALATON Zoltan wrote:

These functions have a parameter that decides the direction of
transfer but totally confusingly they don't match but inverted sense.
To avoid frequent mistakes when using these functions change
i2c_send_recv to match i2c_start_transfer. Also use bool in
i2c_start_transfer instead of int to match i2c_send_recv.


Hmm, I have to admit that this is a little better.  Indeed the
hw/misc/auxbus.c looks suspicious.  I can't imagine that code has ever
been tested.


Sorry to hear that..., this auxbus stuff is related to the Xilinx Display Port
device, so you may want to CC the MAINTAINERS of the Xilinx Display Port.

Now about the testing, in theory this code is executed when the driver try to 
fetch the EDID from the i2c-ddc device which is connected to it, and you won't

get any framebuffer with an empty EDID.

But this was long ago and I don't have any image anymore to test that today.
CC'ed Edgar, he can probably help with that.

Regards,
Fred



I don't know the policy on changing an API like this with silent
semantic changes.  You've gotten all the internal ones; I'm wondering if
we worry about silently breaking out of tree things.

I'll pull this into my tree, but hopefully others will comment on this.

-corey



Signed-off-by: BALATON Zoltan 
---
Looks like hw/misc/auxbus.c already got this wrong and calls both
i2c_start_transfer and i2c_send_recv with same is_write parameter.
Although the name of the is_write variable suggest this may need to be
inverted I'm not sure what that value actially means and which usage
was correct so I did not touch it. Someone knowing this device might
want to review and fix it.

  hw/display/sm501.c   |  2 +-
  hw/i2c/core.c| 34 +-
  hw/i2c/ppc4xx_i2c.c  |  2 +-
  include/hw/i2c/i2c.h |  4 ++--
  4 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 2db347dcbc..ccd0a6e376 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -1034,7 +1034,7 @@ static void sm501_i2c_write(void *opaque, hwaddr addr, 
uint64_t value,
  int i;
  for (i = 0; i <= s->i2c_byte_count; i++) {
  res = i2c_send_recv(s->i2c_bus, &s->i2c_data[i],
-!(s->i2c_addr & 1));
+s->i2c_addr & 1);
  if (res) {
  s->i2c_status |= SM501_I2C_STATUS_ERROR;
  return;
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 1aac457a2a..c9d01df427 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -91,7 +91,7 @@ int i2c_bus_busy(I2CBus *bus)
   * without releasing the bus.  If that fails, the bus is still
   * in a transaction.
   */
-int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
+int i2c_start_transfer(I2CBus *bus, uint8_t address, bool recv)
  {
  BusChild *kid;
  I2CSlaveClass *sc;
@@ -175,26 +175,14 @@ void i2c_end_transfer(I2CBus *bus)
  bus->broadcast = false;
  }
  
-int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send)

+int i2c_send_recv(I2CBus *bus, uint8_t *data, bool recv)
  {
  I2CSlaveClass *sc;
  I2CSlave *s;
  I2CNode *node;
  int ret = 0;
  
-if (send) {

-QLIST_FOREACH(node, &bus->current_devs, next) {
-s = node->elt;
-sc = I2C_SLAVE_GET_CLASS(s);
-if (sc->send) {
-trace_i2c_send(s->address, *data);
-ret = ret || sc->send(s, *data);
-} else {
-ret = -1;
-}
-}
-return ret ? -1 : 0;
-} else {
+if (recv) {
  ret = 0xff;
  if (!QLIST_EMPTY(&bus->current_devs) && !bus->broadcast) {
  sc = I2C_SLAVE_GET_CLASS(QLIST_FIRST(&bus->current_devs)->elt);
@@ -206,19 +194,31 @@ int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send)
  }
  *data = ret;
  return 0;
+} else {
+QLIST_FOREACH(node, &bus->current_devs, next) {
+s = node->elt;
+sc = I2C_SLAVE_GET_CLASS(s);
+if (sc->send) {
+trace_i2c_send(s->address, *data);
+ret = ret || sc->send(s, *data);
+} else {
+ret = -1;
+}
+}
+return ret ? -1 : 0;
  }
  }
  
  int i2c_send(I2CBus *bus, uint8_t data)

  {
-return i2c_send_recv(bus, &data, true);
+return i2c_send_recv(bus, &data, false);
  }
  
  uint8_t i2c_recv(I2CBus *bus)

  {
  uint8_t data = 0xff;
  
-i2c_send_recv(bus, &data, false);

+i2c_send_recv(bus, &data, true);
  return data;
  }
  
diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c

index c0a8e04567..d3899203a4 100644
--- a/hw/i2c/ppc4xx_i2c.c
+++ b/hw/i2c/ppc4xx_i2c.c
@@ -239,7 +239,7 @@ static void ppc4x

Re: [PATCH v5 00/11] Mac Old World ROM experiment

2020-06-26 Thread BALATON Zoltan

Hello Mark,

On Tue, 16 Jun 2020, BALATON Zoltan wrote:

v5: Rebased on master, added some more clean ups, CUDA i2c is still to
be sorted out, help with that is welcome.


What about these patches? At least those that are finished (up to patch 9) 
could be merged. I've seen you sent a pull request but not including any 
of these. Will this need another rebase after your patches? If I rebase 
them will you consider merging them? (Otherwise I won't spend time with 
it.)


Thanks,
BALATON Zoltan


BALATON Zoltan (11):
 mac_oldworld: Allow loading binary ROM image
 mac_newworld: Allow loading binary ROM image
 mac_oldworld: Drop a variable, use get_system_memory() directly
 mac_oldworld: Drop some variables
 grackle: Set revision in PCI config to match hardware
 mac_oldworld: Rename ppc_heathrow_reset to ppc_heathrow_cpu_reset
 mac_oldworld: Map macio to expected address at reset
 mac_oldworld: Add machine ID register
 macio: Add dummy screamer register area
 WIP macio/cuda: Attempt to add i2c support
 mac_oldworld: Add SPD data to cover RAM

hw/misc/macio/cuda.c |  62 -
hw/misc/macio/macio.c|  34 ++
hw/pci-host/grackle.c|   2 +-
hw/ppc/mac.h |  15 -
hw/ppc/mac_newworld.c|  22 +++---
hw/ppc/mac_oldworld.c| 127 ++-
include/hw/misc/macio/cuda.h |   1 +
7 files changed, 219 insertions(+), 44 deletions(-)






Re: [PULL 00/12] Block patches

2020-06-26 Thread Stefan Hajnoczi
On Thu, Jun 25, 2020 at 02:31:14PM +0100, Peter Maydell wrote:
> On Wed, 24 Jun 2020 at 11:02, Stefan Hajnoczi  wrote:
> >
> > The following changes since commit 171199f56f5f9bdf1e5d670d09ef1351d8f01bae:
> >
> >   Merge remote-tracking branch 
> > 'remotes/alistair/tags/pull-riscv-to-apply-20200619-3' into staging 
> > (2020-06-22 14:45:25 +0100)
> >
> > are available in the Git repository at:
> >
> >   https://github.com/stefanha/qemu.git tags/block-pull-request
> >
> > for you to fetch changes up to 7838c67f22a81fcf669785cd6c0876438422071a:
> >
> >   block/nvme: support nested aio_poll() (2020-06-23 15:46:08 +0100)
> >
> > 
> > Pull request
> >
> > 
> 
> Failure on iotest 030, x86-64 Linux:
> 
>   TESTiotest-qcow2: 030 [fail]
> QEMU  --
> "/home/petmay01/linaro/qemu-for-merges/build/alldbg/tests/qemu-iotests/../../x86_64-softmmu/qemu-system-x86_64"
> -nodefaults -display none -accel qtest
> QEMU_IMG  --
> "/home/petmay01/linaro/qemu-for-merges/build/alldbg/tests/qemu-iotests/../../qemu-img"
> QEMU_IO   --
> "/home/petmay01/linaro/qemu-for-merges/build/alldbg/tests/qemu-iotests/../../qemu-io"
>  --cache writeback --aio threads -f qcow2
> QEMU_NBD  --
> "/home/petmay01/linaro/qemu-for-merges/build/alldbg/tests/qemu-iotests/../../qemu-nbd"
> IMGFMT-- qcow2 (compat=1.1)
> IMGPROTO  -- file
> PLATFORM  -- Linux/x86_64 e104462 4.15.0-76-generic
> TEST_DIR  --
> /home/petmay01/linaro/qemu-for-merges/build/alldbg/tests/qemu-iotests/scratch
> SOCK_DIR  -- /tmp/tmp.8tgdDjoZcO
> SOCKET_SCM_HELPER --
> /home/petmay01/linaro/qemu-for-merges/build/alldbg/tests/qemu-iotest/socket_scm_helper
> 
> --- /home/petmay01/linaro/qemu-for-merges/tests/qemu-iotests/030.out
>  2019-07-15 17:18:35.251364738 +0100
> +++ 
> /home/petmay01/linaro/qemu-for-merges/build/alldbg/tests/qemu-iotests/030.out.bad
>   2020-06-25 14:04:28.500534007 +0100
> @@ -1,5 +1,17 @@
> -...
> +.F.
> +==
> +FAIL: test_stream_parallel (__main__.TestParallelOps)
> +--
> +Traceback (most recent call last):
> +  File "030", line 246, in test_stream_parallel
> +self.assert_qmp(result, 'return', {})
> +  File "/home/petmay01/linaro/qemu-for-merges/tests/qemu-iotests/iotests.py",
> line 848, in assert_qmp
> +result = self.dictpath(d, path)
> +  File "/home/petmay01/linaro/qemu-for-merges/tests/qemu-iotests/iotests.py",
> line 822, in dictpath
> +self.fail(f'failed path traversal for "{path}" in "{d}"')
> +AssertionError: failed path traversal for "return" in "{'error':
> {'class': 'DeviceNotActive', 'desc': "Block job 'stream-node8' not
> found"}}"
> +
>  --
>  Ran 27 tests
> 
> -OK
> +FAILED (failures=1)

Strange, I can't reproduce this failure on my pull request branch or on
qemu.git/master.

Is this failure deterministic? Are you sure it is introduced by this
pull request?

Stefan


signature.asc
Description: PGP signature


Re: [PATCH v3 1/3] riscv: Unify Qemu's reset vector code path

2020-06-26 Thread Bin Meng
On Fri, Jun 26, 2020 at 8:33 AM Atish Patra  wrote:
>
> Currently, all riscv machines except sifive_u have identical reset vector
> code implementations with memory addresses being different for all machines.
> They can be easily combined into a single function in common code.
>
> Move it to common function and let all the machines use the common function.
>
> Signed-off-by: Atish Patra 
> Reviewed-by: Alistair Francis 
> ---
>  hw/riscv/boot.c | 45 +
>  hw/riscv/sifive_u.c |  1 -
>  hw/riscv/spike.c| 41 +++--
>  hw/riscv/virt.c | 40 +++-
>  include/hw/riscv/boot.h |  2 ++
>  5 files changed, 53 insertions(+), 76 deletions(-)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



[RFC PATCH 3/3] hw/i2c/smbus_eeprom: Trace reset() event

2020-06-26 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i2c/smbus_eeprom.c | 2 ++
 hw/i2c/trace-events   | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index 22ba7b20d4..7a0e1e7455 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -31,6 +31,7 @@
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "hw/i2c/smbus_eeprom.h"
+#include "trace.h"
 
 //#define DEBUG
 
@@ -124,6 +125,7 @@ static void smbus_eeprom_reset(DeviceState *dev)
 {
 SMBusEEPROMDevice *eeprom = SMBUS_EEPROM(dev);
 
+trace_smbus_eeprom_reset(eeprom->description);
 memcpy(eeprom->data, eeprom->init_data, SMBUS_EEPROM_SIZE);
 eeprom->offset = 0;
 }
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
index 08db8fa689..0539c9e111 100644
--- a/hw/i2c/trace-events
+++ b/hw/i2c/trace-events
@@ -14,3 +14,6 @@ aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned 
size, uint64_t val
 aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t 
value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
 aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send 
%d/%d 0x%02x"
 aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv 
%d/%d 0x%02x"
+
+# smbus_eeprom.c
+smbus_eeprom_reset(const char *description) "'%s': reset"
-- 
2.21.3




[RFC PATCH 2/3] hw/i2c/smbus_eeprom: Add description based on child name

2020-06-26 Thread Philippe Mathieu-Daudé
Suggested-by: Markus Armbruster 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i2c/smbus_eeprom.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index 879fd7c416..22ba7b20d4 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -47,6 +47,7 @@ typedef struct SMBusEEPROMDevice {
 uint8_t *init_data;
 uint8_t offset;
 bool accessed;
+char *description;
 } SMBusEEPROMDevice;
 
 static uint8_t eeprom_receive_byte(SMBusDevice *dev)
@@ -134,7 +135,9 @@ static void smbus_eeprom_realize(DeviceState *dev, Error 
**errp)
 smbus_eeprom_reset(dev);
 if (eeprom->init_data == NULL) {
 error_setg(errp, "init_data cannot be NULL");
+return;
 }
+eeprom->description = object_get_canonical_path_component(OBJECT(dev));
 }
 
 static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
-- 
2.21.3




[RFC PATCH 0/3] Use object_get_canonical_path_component to get child description

2020-06-26 Thread Philippe Mathieu-Daudé
This RFC is simply a proof-of-concept to see if I correctly
understood Markus' suggestion, see the thread around:
https://lists.gnu.org/archive/html/qemu-devel/2020-06/msg08652.html

Philippe Mathieu-Daudé (3):
  hw/i2c/smbus_eeprom: Set QOM parent
  hw/i2c/smbus_eeprom: Add description based on child name
  hw/i2c/smbus_eeprom: Trace reset() event

 include/hw/i2c/smbus_eeprom.h |  9 ++---
 hw/i2c/smbus_eeprom.c | 18 +++---
 hw/mips/fuloong2e.c   |  2 +-
 hw/ppc/sam460ex.c |  2 +-
 hw/i2c/trace-events   |  3 +++
 5 files changed, 26 insertions(+), 8 deletions(-)

-- 
2.21.3




[RFC PATCH 1/3] hw/i2c/smbus_eeprom: Set QOM parent

2020-06-26 Thread Philippe Mathieu-Daudé
Suggested-by: Markus Armbruster 
Signed-off-by: Philippe Mathieu-Daudé 
---
Aspeed change pending latest ARM pull-request, so meanwhile sending
as RFC.
---
 include/hw/i2c/smbus_eeprom.h |  9 ++---
 hw/i2c/smbus_eeprom.c | 13 ++---
 hw/mips/fuloong2e.c   |  2 +-
 hw/ppc/sam460ex.c |  2 +-
 4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/include/hw/i2c/smbus_eeprom.h b/include/hw/i2c/smbus_eeprom.h
index 68b0063ab6..037612 100644
--- a/include/hw/i2c/smbus_eeprom.h
+++ b/include/hw/i2c/smbus_eeprom.h
@@ -26,9 +26,12 @@
 #include "exec/cpu-common.h"
 #include "hw/i2c/i2c.h"
 
-void smbus_eeprom_init_one(I2CBus *bus, uint8_t address, uint8_t *eeprom_buf);
-void smbus_eeprom_init(I2CBus *bus, int nb_eeprom,
-   const uint8_t *eeprom_spd, int size);
+void smbus_eeprom_init_one(Object *parent_obj, const char *child_name,
+   I2CBus *smbus, uint8_t address,
+   uint8_t *eeprom_buf);
+void smbus_eeprom_init(Object *parent_obj, const char *child_name_prefix,
+   I2CBus *smbus, int nb_eeprom,
+   const uint8_t *eeprom_spd, int eeprom_spd_size);
 
 enum sdram_type { SDR = 0x4, DDR = 0x7, DDR2 = 0x8 };
 uint8_t *spd_data_generate(enum sdram_type type, ram_addr_t size);
diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index b7def9eeb8..879fd7c416 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -165,7 +165,9 @@ static void smbus_eeprom_register_types(void)
 
 type_init(smbus_eeprom_register_types)
 
-void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf)
+void smbus_eeprom_init_one(Object *parent_obj, const char *child_name,
+   I2CBus *smbus, uint8_t address,
+   uint8_t *eeprom_buf)
 {
 DeviceState *dev;
 
@@ -173,10 +175,12 @@ void smbus_eeprom_init_one(I2CBus *smbus, uint8_t 
address, uint8_t *eeprom_buf)
 qdev_prop_set_uint8(dev, "address", address);
 /* FIXME: use an array of byte or block backend property? */
 SMBUS_EEPROM(dev)->init_data = eeprom_buf;
+object_property_add_child(parent_obj, child_name, OBJECT(dev));
 qdev_realize_and_unref(dev, (BusState *)smbus, &error_fatal);
 }
 
-void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
+void smbus_eeprom_init(Object *parent_obj, const char *child_name_prefix,
+   I2CBus *smbus, int nb_eeprom,
const uint8_t *eeprom_spd, int eeprom_spd_size)
 {
 int i;
@@ -189,8 +193,11 @@ void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
 }
 
 for (i = 0; i < nb_eeprom; i++) {
-smbus_eeprom_init_one(smbus, 0x50 + i,
+char *name = g_strdup_printf("%s-%d", child_name_prefix, i);
+
+smbus_eeprom_init_one(parent_obj, name, smbus, 0x50 + i,
   eeprom_buf + (i * SMBUS_EEPROM_SIZE));
+g_free(name);
 }
 }
 
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 8ca31e5162..304a096c6a 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -377,7 +377,7 @@ static void mips_fuloong2e_init(MachineState *machine)
 
 /* Populate SPD eeprom data */
 spd_data = spd_data_generate(DDR, machine->ram_size);
-smbus_eeprom_init_one(smbus, 0x50, spd_data);
+smbus_eeprom_init_one(OBJECT(machine->ram), "spd", smbus, 0x50, spd_data);
 
 mc146818_rtc_init(isa_bus, 2000, NULL);
 
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 1a106a68de..064d07f4e2 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -337,7 +337,7 @@ static void sam460ex_init(MachineState *machine)
 spd_data = spd_data_generate(ram_sizes[0] < 128 * MiB ? DDR : DDR2,
  ram_sizes[0]);
 spd_data[20] = 4; /* SO-DIMM module */
-smbus_eeprom_init_one(i2c, 0x50, spd_data);
+smbus_eeprom_init_one(OBJECT(machine->ram), "spd", i2c, 0x50, spd_data);
 /* RTC */
 i2c_create_slave(i2c, "m41t80", 0x68);
 
-- 
2.21.3




Re: [PATCH for-5.1 V5 3/4] hw/mips: Add Loongson-3 machine support (with KVM)

2020-06-26 Thread Huacai Chen
Hi, Alexandar,

On Wed, Jun 24, 2020 at 7:27 PM Aleksandar Markovic
 wrote:
>
> >
> > What exactly is missing in tcg support? Would it work if Loongson EXT is 
> > supported in QEMU?
> >
>
> Huacai, hi.
>
> I couldn't find the answer to this question in v6.
>
> Could you please clarify this aspect?
Jiaxun said that Loongson EXT is the only thing missing.

Huacai
>
> Thank you,
> Aleksandar



[PATCH v6 2/5] virtio-iommu: Implement RESV_MEM probe request

2020-06-26 Thread Eric Auger
This patch implements the PROBE request. At the moment,
only THE RESV_MEM property is handled. The first goal is
to report iommu wide reserved regions such as the MSI regions
set by the machine code. On x86 this will be the IOAPIC MSI
region, [0xFEE0 - 0xFEEF], on ARM this may be the ITS
doorbell.

In the future we may introduce per device reserved regions.
This will be useful when protecting host assigned devices
which may expose their own reserved regions

Signed-off-by: Eric Auger 
Reviewed-by: Jean-Philippe Brucker 

---

v5 -> v6:
- removed validation of s->reserved_regions[i].type in the
  probe request as it should rather happen in the realize()

v4 -> v5:
- assert if reserved region type is different from RESERVED or
  MSI

v3 -> v4:
- removed any reference to the NONE property that does not
  exist anymore.

v2 -> v3:
- on probe, do not fill the reminder of the buffer with zeroes
  as the buffer was already zero initialized (Bharat)

v1 -> v2:
- move the unlock back to the same place
- remove the push label and factorize the code after the out label
- fix a bunch of cpu_to_leX according to the latest spec revision
- do not remove sizeof(last) from free space
- check the ep exists
---
 include/hw/virtio/virtio-iommu.h |  2 +
 hw/virtio/virtio-iommu.c | 90 ++--
 hw/virtio/trace-events   |  1 +
 3 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
index e653004d7c..49eb105cd8 100644
--- a/include/hw/virtio/virtio-iommu.h
+++ b/include/hw/virtio/virtio-iommu.h
@@ -53,6 +53,8 @@ typedef struct VirtIOIOMMU {
 GHashTable *as_by_busptr;
 IOMMUPciBus *iommu_pcibus_by_bus_num[PCI_BUS_MAX];
 PCIBus *primary_bus;
+ReservedRegion *reserved_regions;
+uint32_t nb_reserved_regions;
 GTree *domains;
 QemuMutex mutex;
 GTree *endpoints;
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 483883ec1d..5e72fd53a1 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -38,6 +38,7 @@
 
 /* Max size */
 #define VIOMMU_DEFAULT_QUEUE_SIZE 256
+#define VIOMMU_PROBE_SIZE 512
 
 typedef struct VirtIOIOMMUDomain {
 uint32_t id;
@@ -378,6 +379,61 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
 return ret;
 }
 
+static ssize_t virtio_iommu_fill_resv_mem_prop(VirtIOIOMMU *s, uint32_t ep,
+   uint8_t *buf, size_t free)
+{
+struct virtio_iommu_probe_resv_mem prop = {};
+size_t size = sizeof(prop), length = size - sizeof(prop.head), total;
+int i;
+
+total = size * s->nb_reserved_regions;
+
+if (total > free) {
+return -ENOSPC;
+}
+
+for (i = 0; i < s->nb_reserved_regions; i++) {
+prop.head.type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM);
+prop.head.length = cpu_to_le16(length);
+prop.subtype = s->reserved_regions[i].type;
+prop.start = cpu_to_le64(s->reserved_regions[i].low);
+prop.end = cpu_to_le64(s->reserved_regions[i].high);
+
+memcpy(buf, &prop, size);
+
+trace_virtio_iommu_fill_resv_property(ep, prop.subtype,
+  prop.start, prop.end);
+buf += size;
+}
+return total;
+}
+
+/**
+ * virtio_iommu_probe - Fill the probe request buffer with
+ * the properties the device is able to return
+ */
+static int virtio_iommu_probe(VirtIOIOMMU *s,
+  struct virtio_iommu_req_probe *req,
+  uint8_t *buf)
+{
+uint32_t ep_id = le32_to_cpu(req->endpoint);
+size_t free = VIOMMU_PROBE_SIZE;
+ssize_t count;
+
+if (!virtio_iommu_mr(s, ep_id)) {
+return VIRTIO_IOMMU_S_NOENT;
+}
+
+count = virtio_iommu_fill_resv_mem_prop(s, ep_id, buf, free);
+if (count < 0) {
+return VIRTIO_IOMMU_S_INVAL;
+}
+buf += count;
+free -= count;
+
+return VIRTIO_IOMMU_S_OK;
+}
+
 static int virtio_iommu_iov_to_req(struct iovec *iov,
unsigned int iov_cnt,
void *req, size_t req_sz)
@@ -407,15 +463,27 @@ virtio_iommu_handle_req(detach)
 virtio_iommu_handle_req(map)
 virtio_iommu_handle_req(unmap)
 
+static int virtio_iommu_handle_probe(VirtIOIOMMU *s,
+ struct iovec *iov,
+ unsigned int iov_cnt,
+ uint8_t *buf)
+{
+struct virtio_iommu_req_probe req;
+int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req));
+
+return ret ? ret : virtio_iommu_probe(s, &req, buf);
+}
+
 static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
 {
 VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
 struct virtio_iommu_req_head head;
 struct virtio_iommu_req_tail tail = {};
+size_t output_size = sizeof(tail), sz;
 VirtQueueElement *elem;
 unsigned int iov_cnt

Re: [PATCH v3 0/9] Generalize memory encryption models

2020-06-26 Thread Dr. David Alan Gilbert
* Janosch Frank (fran...@linux.ibm.com) wrote:
> On 6/26/20 11:32 AM, Daniel P. Berrangé wrote:
> > On Fri, Jun 26, 2020 at 11:01:58AM +0200, Janosch Frank wrote:
> >> On 6/26/20 8:53 AM, David Hildenbrand wrote:
> >>> Does this have any implications when probing with the 'none' machine?
> >>
> >> I'm not sure.  In your case, I guess the cpu bit would still show up
> >> as before, so it would tell you base feature availability, but not
> >> whether you can use the new configuration option.
> >>
> >> Since the HTL option is generic, you could still set it on the "none"
> >> machine, though it wouldn't really have any effect.  That is, if you
> >> could create a suitable object to point it at, which would depend on
> >> ... details.
> >>
> >
> > The important point is that we never want the (expanded) host cpu model
> > look different when either specifying or not specifying the HTL
> > property.
> 
>  Ah, yes, I see your point.  So my current suggestion will satisfy
>  that, basically it is:
> 
>  cpu has unpack (inc. by default) && htl specified
>   => works (allowing secure), as expected
> >>>
> >>> ack
> >>>
> 
>  !cpu has unpack && htl specified
>   => bails out with an error
> >>>
> >>> ack
> >>>
> 
>  !cpu has unpack && !htl specified
>   => works for a non-secure guest, as expected
>   => guest will fail if it attempts to go secure
> >>>
> >>> ack, behavior just like running on older hw without unpack
> >>>
> 
>  cpu has unpack && !htl specified
>   => works as expected for a non-secure guest (unpack feature is
>  present, but unused)
>   => secure guest may work "by accident", but only if all virtio
>  properties have the right values, which is the user's
>  problem
> 
>  That last case is kinda ugly, but I think it's tolerable.
> >>>
> >>> Right, we must not affect non-secure guests, and existing secure setups
> >>> (e.g., older qemu machines). Will have to think about this some more,
> >>> but does not sound too crazy.
> >>
> >> I severely dislike having to specify things to make PV work.
> >> The IOMMU is already a thorn in our side and we're working on making the
> >> whole ordeal completely transparent so the only requirement to make this
> >> work is the right machine, kernel, qemu and kernel cmd line option
> >> "prot_virt=1". That's why we do the reboot into PV mode in the first place.
> >>
> >> I.e. the goal is that if customers convert compatible guests into
> >> protected ones and start them up on a z15 on a distro with PV support
> >> they can just use the guest without having to change XML or command line
> >> parameters.
> > 
> > If you're exposing new features to the guest machine, then it is usually
> > to be expected that XML and QEMU command line will change. Some simple
> > things might be hidable behind a new QEMU machine type or CPU model, but
> > there's a limit to how much should be hidden that way while staying sane.
> > 
> > I'd really expect the configuration to change when switching a guest to
> > a new hardware platform and wanting major new functionality to be enabled.
> > The XML / QEMU config is a low level instantiation of a particular feature
> > set, optimized for a specific machine, rather than a high level description
> > of ideal "best" config independent of host machine.
> 
> You still have to set the host command line and make sure that unpack is
> available. Currently you also have to specify the IOMMU which we like to
> drop as a requirement. Everything else is dependent on runtime
> information which tells us if we need to take a PV or non-PV branch.
> Having the unpack facility should be enough to use the unpack facility.
> 
> Keep in mind that we have no real concept of a special protected VM to
> begin with. If the VM never boots into a protected kernel it will never
> be protected. On a reboot it drops from protected into unprotected mode
> to execute the bios and boot loader and then may or may not move back
> into a protected state.

My worry isn't actually how painful adding all the iommu glue is, but
what happens when users forget; especially if they forget for one
device.

I could appreciate having a machine option to cause iommu to then get
turned on with all other devices; but I think also we could do with
something that failed with a nice error if an iommu flag was missing.
For SEV this could be done pretty early, but for power/s390 I guess
you'd have to do this when someone tried to enable secure mode, but
I'm not sure you can tell.

Dave


> > 
> > Regards,
> > Daniel
> > 
> 
> 



--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH 3/3] virtiofsd: Allow addition or removal of capabilities

2020-06-26 Thread Stefan Hajnoczi
On Thu, Jun 25, 2020 at 05:29:29PM +0100, Dr. David Alan Gilbert (git) wrote:
> +/*
> + * The modcaps option is a colon separated list of caps,
> + * each preceded by either + or -.
> + */
> +while (lo->modcaps) {
> +capng_act_t action;
> +int cap;
> +
> +char *next = strchr(lo->modcaps, ':');
> +if (next) {
> +*next = '\0';
> +next++;
> +}
> +
> +switch (lo->modcaps[0]) {
> +case '+':
> +action = CAPNG_ADD;
> +break;
> +
> +case '-':
> +action = CAPNG_DROP;
> +break;
> +
> +default:
> +fuse_log(FUSE_LOG_ERR,
> + "%s: Expecting '+'/'-' in modcaps but found '%c'\n",
> + __func__, lo->modcaps[0]);
> +exit(1);
> +}
> +cap = capng_name_to_capability(lo->modcaps + 1);
> +if (cap < 0) {
> +fuse_log(FUSE_LOG_ERR, "%s: Unknown capability '%s'\n", __func__,
> + lo->modcaps);
> +exit(1);
> +}
> +if (capng_update(action, CAPNG_PERMITTED | CAPNG_EFFECTIVE, cap)) {
> +fuse_log(FUSE_LOG_ERR, "%s: capng_update failed for '%s'\n",
> + __func__, lo->modcaps);
> +exit(1);
> +}
> +
> +lo->modcaps = next;

How about passing char *modcaps into this function so that lo->modcaps
isn't modified by the parsing loop? That seems a bit cleaner and if we
ever decide to free lo->modcaps it will work as expected.

Stefan


signature.asc
Description: PGP signature


[PATCH v6 0/5] VIRTIO-IOMMU probe request support and MSI bypass on ARM

2020-06-26 Thread Eric Auger
By default the virtio-iommu translates MSI transactions. This
behavior is inherited from ARM SMMU. However the virt machine
code knows where the MSI doorbells are, so we can easily
declare those regions as VIRTIO_IOMMU_RESV_MEM_T_MSI. With that
setting the guest iommu subsystem will not need to map MSIs.
This setup will simplify the VFIO integration.

In this series, the ITS or GICV2M doorbells are declared as
HW MSI regions to be bypassed by the VIRTIO-IOMMU.

This also paves the way to the x86 integration where the MSI
region, [0xFEE0,0xFEEF], will be exposed by the q35
machine.  However this will be handled in a separate series
when not-DT support gets resolved.

Best Regards

Eric

This series can be found at:
https://github.com/eauger/qemu/tree/v5.0.0-virtio-iommu-msi-bypass-v6

History:

v5 -> v6:
- do not hardcode start/end addresses of doorbells
- check reserved region type on realize()

v4 -> v5:
- Take into account some additional comments from Markus:
  - reserved region type becomes an unsigned + some comment/desc
rewording
  - assert if the type is not RESERVED or MSI

v3 -> v4:
- collected Jean and markus's R-bs
- tool into account all Markus' comments in [1/5] (except removal of
  goto)
- use ':' as delimitor instead of commas
- add example in 4/5 commit message as suggested by Markus

v2 -> v3:
- Introduce VIRT_MSI_CTRL_NONE in VirtMSIControllerType
- do not fill the remainder of the probe buffer

v1 -> v2:
- check which MSI controller is in use and advertise the
  corresponding MSI doorbell
- managed for both ITS and GICv2M
- various fixes spotted by Peter and Jean-Philippe, see
  individual logs

v1: Most of those patches were respinned from
  [PATCH for-5.0 v11 00/20] VIRTIO-IOMMU device
  except the last one which is new

Eric Auger (5):
  qdev: Introduce DEFINE_PROP_RESERVED_REGION
  virtio-iommu: Implement RESV_MEM probe request
  virtio-iommu: Handle reserved regions in the translation process
  virtio-iommu-pci: Add array of Interval properties
  hw/arm/virt: Let the virtio-iommu bypass MSIs

 include/exec/memory.h|   6 ++
 include/hw/arm/virt.h|   7 ++
 include/hw/qdev-properties.h |   3 +
 include/hw/virtio/virtio-iommu.h |   2 +
 include/qemu/typedefs.h  |   1 +
 hw/arm/virt.c|  30 +
 hw/core/qdev-properties.c|  89 +
 hw/virtio/virtio-iommu-pci.c |  13 
 hw/virtio/virtio-iommu.c | 110 +--
 hw/virtio/trace-events   |   1 +
 10 files changed, 258 insertions(+), 4 deletions(-)

-- 
2.20.1




[PATCH v6 3/5] virtio-iommu: Handle reserved regions in the translation process

2020-06-26 Thread Eric Auger
When translating an address we need to check if it belongs to
a reserved virtual address range. If it does, there are 2 cases:

- it belongs to a RESERVED region: the guest should neither use
  this address in a MAP not instruct the end-point to DMA on
  them. We report an error

- It belongs to an MSI region: we bypass the translation.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Xu 
Reviewed-by: Jean-Philippe Brucker 
Reviewed-by: Michael S. Tsirkin 

---

v1 -> v2:
- use addr when testing addr belongs to the reserved region
  and use a block local variable
---
 hw/virtio/virtio-iommu.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 5e72fd53a1..4a50e24d21 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -603,6 +603,7 @@ static IOMMUTLBEntry 
virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
 uint32_t sid, flags;
 bool bypass_allowed;
 bool found;
+int i;
 
 interval.low = addr;
 interval.high = addr + 1;
@@ -636,6 +637,25 @@ static IOMMUTLBEntry 
virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
 goto unlock;
 }
 
+for (i = 0; i < s->nb_reserved_regions; i++) {
+ReservedRegion *reg = &s->reserved_regions[i];
+
+if (addr >= reg->low && addr <= reg->high) {
+switch (reg->type) {
+case VIRTIO_IOMMU_RESV_MEM_T_MSI:
+entry.perm = flag;
+break;
+case VIRTIO_IOMMU_RESV_MEM_T_RESERVED:
+default:
+virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING,
+  VIRTIO_IOMMU_FAULT_F_ADDRESS,
+  sid, addr);
+break;
+}
+goto unlock;
+}
+}
+
 if (!ep->domain) {
 if (!bypass_allowed) {
 error_report_once("%s %02x:%02x.%01x not attached to any domain",
-- 
2.20.1




[PATCH v6 5/5] hw/arm/virt: Let the virtio-iommu bypass MSIs

2020-06-26 Thread Eric Auger
At the moment the virtio-iommu translates MSI transactions.
This behavior is inherited from ARM SMMU. The virt machine
code knows where the guest MSI doorbells are so we can easily
declare those regions as VIRTIO_IOMMU_RESV_MEM_T_MSI. With that
setting the guest will not map MSIs through the IOMMU and those
transactions will be simply bypassed.

Depending on which MSI controller is in use (ITS or GICV2M),
we declare either:
- the ITS interrupt translation space (ITS_base + 0x1),
  containing the GITS_TRANSLATOR or
- The GICV2M single frame, containing the MSI_SETSP_NS register.

Signed-off-by: Eric Auger 

---
v5 -> v6:
- do not hardcode doorbell base and size
- removed Jean's R-b

v3 -> v4:
- use ':' as separators

v2 -> v3:
- Add a new value to VirtMSIControllerType

v1 -> v2:
- Test which MSI controller is instantiated
- If GICV2M is in use, declare its doorbell as an MSI doorbell too
---
 include/hw/arm/virt.h |  7 +++
 hw/arm/virt.c | 30 ++
 2 files changed, 37 insertions(+)

diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 31878ddc72..a18b6b397b 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -96,6 +96,12 @@ typedef enum VirtIOMMUType {
 VIRT_IOMMU_VIRTIO,
 } VirtIOMMUType;
 
+typedef enum VirtMSIControllerType {
+VIRT_MSI_CTRL_NONE,
+VIRT_MSI_CTRL_GICV2M,
+VIRT_MSI_CTRL_ITS,
+} VirtMSIControllerType;
+
 typedef enum VirtGICType {
 VIRT_GIC_VERSION_MAX,
 VIRT_GIC_VERSION_HOST,
@@ -136,6 +142,7 @@ typedef struct {
 OnOffAuto acpi;
 VirtGICType gic_version;
 VirtIOMMUType iommu;
+VirtMSIControllerType msi_controller;
 uint16_t virtio_iommu_bdf;
 struct arm_boot_info bootinfo;
 MemMapEntry *memmap;
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 402c362c14..5ba62d6568 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -602,6 +602,7 @@ static void create_its(VirtMachineState *vms)
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
 
 fdt_add_its_gic_node(vms);
+vms->msi_controller = VIRT_MSI_CTRL_ITS;
 }
 
 static void create_v2m(VirtMachineState *vms)
@@ -622,6 +623,7 @@ static void create_v2m(VirtMachineState *vms)
 }
 
 fdt_add_v2m_gic_node(vms);
+vms->msi_controller = VIRT_MSI_CTRL_GICV2M;
 }
 
 static void create_gic(VirtMachineState *vms)
@@ -2149,8 +2151,36 @@ out:
 static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
 DeviceState *dev, Error **errp)
 {
+VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 virt_memory_pre_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
+hwaddr db_start = 0, db_end = 0;
+char *resv_prop_str;
+
+switch (vms->msi_controller) {
+case VIRT_MSI_CTRL_NONE:
+return;
+case VIRT_MSI_CTRL_ITS:
+/* GITS_TRANSLATER page */
+db_start = base_memmap[VIRT_GIC_ITS].base + 0x1;
+db_end = base_memmap[VIRT_GIC_ITS].base +
+ base_memmap[VIRT_GIC_ITS].size - 1;
+break;
+case VIRT_MSI_CTRL_GICV2M:
+/* MSI_SETSPI_NS page */
+db_start = base_memmap[VIRT_GIC_V2M].base;
+db_end = db_start + base_memmap[VIRT_GIC_V2M].size - 1;
+break;
+}
+resv_prop_str = g_strdup_printf("0x%"PRIx64":0x%"PRIx64":%u",
+db_start, db_end,
+VIRTIO_IOMMU_RESV_MEM_T_MSI);
+
+qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
+qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
+g_free(resv_prop_str);
 }
 }
 
-- 
2.20.1




[PATCH v6 1/5] qdev: Introduce DEFINE_PROP_RESERVED_REGION

2020-06-26 Thread Eric Auger
Introduce a new property defining a reserved region:
::.

This will be used to encode reserved IOVA regions.

For instance, in virtio-iommu use case, reserved IOVA regions
will be passed by the machine code to the virtio-iommu-pci
device (an array of those). The type of the reserved region
will match the virtio_iommu_probe_resv_mem subtype value:
- VIRTIO_IOMMU_RESV_MEM_T_RESERVED (0)
- VIRTIO_IOMMU_RESV_MEM_T_MSI (1)

on PC/Q35 machine, this will be used to inform the
virtio-iommu-pci device it should bypass the MSI region.
The reserved region will be: 0xfee0:0xfeef:1.

On ARM, we can declare the ITS MSI doorbell as an MSI
region to prevent MSIs from being mapped on guest side.

Signed-off-by: Eric Auger 
Reviewed-by: Markus Armbruster 
Reviewed-by: Michael S. Tsirkin 

---

v4 -> v5:
- type becomes an unsigned + comment/error rewording

v3 -> v4:
- use ':' instead of commas as separators.
- rearrange error messages
- check snprintf returned value
- dared to keep Markus' R-b despite those changes
---
 include/exec/memory.h|  6 +++
 include/hw/qdev-properties.h |  3 ++
 include/qemu/typedefs.h  |  1 +
 hw/core/qdev-properties.c| 89 
 4 files changed, 99 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 7207025bd4..84ee5b7a01 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -51,6 +51,12 @@ extern bool global_dirty_log;
 
 typedef struct MemoryRegionOps MemoryRegionOps;
 
+struct ReservedRegion {
+hwaddr low;
+hwaddr high;
+unsigned type;
+};
+
 typedef struct IOMMUTLBEntry IOMMUTLBEntry;
 
 /* See address_space_translate: bit 0 is read, bit 1 is write.  */
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 49c6cd2460..944e3f2e0c 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -19,6 +19,7 @@ extern const PropertyInfo qdev_prop_string;
 extern const PropertyInfo qdev_prop_chr;
 extern const PropertyInfo qdev_prop_tpm;
 extern const PropertyInfo qdev_prop_macaddr;
+extern const PropertyInfo qdev_prop_reserved_region;
 extern const PropertyInfo qdev_prop_on_off_auto;
 extern const PropertyInfo qdev_prop_multifd_compression;
 extern const PropertyInfo qdev_prop_losttickpolicy;
@@ -184,6 +185,8 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive_iothread, BlockBackend *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
+#define DEFINE_PROP_RESERVED_REGION(_n, _s, _f) \
+DEFINE_PROP(_n, _s, _f, qdev_prop_reserved_region, ReservedRegion)
 #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
 DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto)
 #define DEFINE_PROP_MULTIFD_COMPRESSION(_n, _s, _f, _d) \
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index ce4a78b687..15f5047bf1 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -58,6 +58,7 @@ typedef struct ISABus ISABus;
 typedef struct ISADevice ISADevice;
 typedef struct IsaDma IsaDma;
 typedef struct MACAddr MACAddr;
+typedef struct ReservedRegion ReservedRegion;
 typedef struct MachineClass MachineClass;
 typedef struct MachineState MachineState;
 typedef struct MemoryListener MemoryListener;
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 71f8aca7c6..ca7771f307 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -15,6 +15,7 @@
 #include "chardev/char.h"
 #include "qemu/uuid.h"
 #include "qemu/units.h"
+#include "qemu/cutils.h"
 
 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
   Error **errp)
@@ -578,6 +579,94 @@ const PropertyInfo qdev_prop_macaddr = {
 .set   = set_mac,
 };
 
+/* --- Reserved Region --- */
+
+/*
+ * Accepted syntax:
+ *   ::
+ *   where low/high addresses are uint64_t in hexadecimal
+ *   and type is a non-negative decimal integer
+ */
+static void get_reserved_region(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+char buffer[64];
+char *p = buffer;
+int rc;
+
+rc = snprintf(buffer, sizeof(buffer), "0x%"PRIx64":0x%"PRIx64":%u",
+  rr->low, rr->high, rr->type);
+assert(rc < sizeof(buffer));
+
+visit_type_str(v, name, &p, errp);
+}
+
+static void set_reserved_region(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+Error *local_err = NULL;
+const char *endptr;
+char *str;
+int ret;
+
+if (dev->realized) {
+qdev_prop_set_after_realize(dev, name, errp);
+return;
+   

  1   2   3   4   5   6   >