Re: [PATCH 1/2] tests/acceptance: Test ast2400 and ast2500 machines

2021-03-02 Thread Cédric Le Goater
On 3/3/21 2:22 AM, Joel Stanley wrote:
> Test MTD images from the OpenBMC project on AST2400 and AST2500 SoCs
> from ASPEED, by booting Palmetto and Romulus BMC machines.
> 
> The images are fetched from OpenBMC's release directory on github.
> 
> Co-developed-by: Cédric Le Goater 
> Signed-off-by: Joel Stanley 


Reviewed-by: Cédric Le Goater 
Tested-by: Cédric Le Goater 

Thanks,

C. 


> ---
>  tests/acceptance/boot_linux_console.py | 46 ++
>  1 file changed, 46 insertions(+)
> 
> diff --git a/tests/acceptance/boot_linux_console.py 
> b/tests/acceptance/boot_linux_console.py
> index eb012867997f..2f46a08fdc10 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -1048,6 +1048,52 @@ def test_arm_vexpressa9(self):
>  self.vm.add_args('-dtb', self.workdir + 
> '/day16/vexpress-v2p-ca9.dtb')
>  self.do_test_advcal_2018('16', tar_hash, 'winter.zImage')
>  
> +def test_arm_ast2400_palmetto_openbmc_v2_9_0(self):
> +"""
> +:avocado: tags=arch:arm
> +:avocado: tags=machine:palmetto-bmc
> +"""
> +
> +image_url = 
> ('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
> + 'obmc-phosphor-image-palmetto.static.mtd')
> +image_hash = 
> ('3e13bbbc28e424865dc42f35ad672b10f2e82cdb11846bb28fa625b48beafd0d')
> +image_path = self.fetch_asset(image_url, asset_hash=image_hash,
> +  algorithm='sha256')
> +
> +self.do_test_arm_aspeed(image_path)
> +
> +def test_arm_ast2500_romulus_openbmc_v2_9_0(self):
> +"""
> +:avocado: tags=arch:arm
> +:avocado: tags=machine:romulus-bmc
> +"""
> +
> +image_url = 
> ('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
> + 'obmc-phosphor-image-romulus.static.mtd')
> +image_hash = 
> ('820341076803f1955bc31e647a512c79f9add4f5233d0697678bab4604c7bb25')
> +image_path = self.fetch_asset(image_url, asset_hash=image_hash,
> +  algorithm='sha256')
> +
> +self.do_test_arm_aspeed(image_path)
> +
> +def do_test_arm_aspeed(self, image):
> +self.vm.set_console()
> +self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
> + '-net', 'nic')
> +self.vm.launch()
> +
> +self.wait_for_console_pattern("U-Boot 2016.07")
> +self.wait_for_console_pattern("## Loading kernel from FIT Image at 
> 2008")
> +self.wait_for_console_pattern("Starting kernel ...")
> +self.wait_for_console_pattern("Booting Linux on physical CPU 0x0")
> +self.wait_for_console_pattern(
> +"aspeed-smc 1e62.spi: read control register: 203b0641")
> +self.wait_for_console_pattern("ftgmac100 1e66.ethernet eth0: irq 
> ")
> +self.wait_for_console_pattern("systemd[1]: Set hostname to")
> +# This often takes longer than the 90s timeout
> +# self.wait_for_console_pattern("login:")
> +self.vm.shutdown()
> +
>  def test_m68k_mcf5208evb(self):
>  """
>  :avocado: tags=arch:m68k
> 




Re: [PATCH 2/2] tests/acceptance: Test ast2600 machine

2021-03-02 Thread Cédric Le Goater
On 3/3/21 2:22 AM, Joel Stanley wrote:
> This tests a Debian multi-soc arm32 Linux kernel on the AST2600 based
> Tacoma BMC machine.
> 
> There is no root file system so the test terminates when boot reaches
> the stage where it attempts and fails to mount something.

because of that, the test always fails  :

console: [3.615193] No filesystem could mount root, tried:
console: [3.615269]
console: [3.615688] Kernel panic - not syncing: VFS: Unable to mount root 
fs on unknown-block(0,0)
FAIL: Failure message found in console: Kernel panic - not syncing (22.45 s)
RESULTS: PASS 0 | ERROR 0 | FAIL 1 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0


Is there a way around this problem ? 

C. 

> 
> Signed-off-by: Joel Stanley 
> ---
>  tests/acceptance/boot_linux_console.py | 26 ++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/tests/acceptance/boot_linux_console.py 
> b/tests/acceptance/boot_linux_console.py
> index 2f46a08fdc10..6b7d7f5df984 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -1094,6 +1094,32 @@ def do_test_arm_aspeed(self, image):
>  # self.wait_for_console_pattern("login:")
>  self.vm.shutdown()
>  
> +def test_arm_ast2600_debian(self):
> +"""
> +:avocado: tags=arch:arm
> +:avocado: tags=machine:tacoma-bmc
> +"""
> +deb_url = ('http://snapshot.debian.org/archive/debian/'
> +   '20210302T203551Z/'
> +   'pool/main/l/linux/'
> +   'linux-image-5.10.0-3-armmp_5.10.13-1_armhf.deb')
> +deb_hash = 
> 'db40d32fe39255d05482bea48d72467b67d6225bb2a2a4d6f618cb8976f1e09e'
> +deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash,
> +algorithm='sha256')
> +kernel_path = self.extract_from_deb(deb_path, 
> '/boot/vmlinuz-5.10.0-3-armmp')
> +dtb_path = self.extract_from_deb(deb_path,
> +
> '/usr/lib/linux-image-5.10.0-3-armmp/aspeed-bmc-opp-tacoma.dtb')
> +
> +self.vm.set_console()
> +self.vm.add_args('-kernel', kernel_path,
> + '-dtb', dtb_path)
> +self.vm.launch()
> +self.wait_for_console_pattern("Booting Linux on physical CPU 0xf00")
> +self.wait_for_console_pattern("SMP: Total of 2 processors activated")
> +self.wait_for_console_pattern("ftgmac100 1e67.ftgmac eth0: irq")
> +self.wait_for_console_pattern("VFS: Cannot open root device")
> +self.vm.shutdown()
> +
>  def test_m68k_mcf5208evb(self):
>  """
>  :avocado: tags=arch:m68k
> 




Re: [PATCH V2 1/1] hw/block/nvme: support command retry delay

2021-03-02 Thread Klaus Jensen
On Feb 14 23:28, Minwoo Im wrote:
> Set CRDT1(Command Retry Delay Time 1) in the Identify controller data
> structure to milliseconds units of 100ms by the given value of
> 'cmd-retry-delay' parameter which is newly added.  If
> cmd-retry-delay=1000, it will be set CRDT1 to 10.  This patch only
> considers the CRDT1 without CRDT2 and 3 for the simplicity.
> 
> This patch also introduced set/get feature command handler for Host
> Behavior feature (16h).  In this feature, ACRE(Advanced Command Retry
> Enable) will be set by the host based on the Identify controller data
> structure, especially by CRDTs.
> 
> Signed-off-by: Minwoo Im 
> ---

LGTM.

Reviewed-by: Klaus Jensen 


signature.asc
Description: PGP signature


Re: [PATCH] hw/arm/aspeed: Fix location of firmware images in documentation

2021-03-02 Thread Joel Stanley
On Wed, 3 Mar 2021 at 07:28, Cédric Le Goater  wrote:
>
> Firmware images can be found on the OpenBMC jenkins site and on the
> OpenBMC GitHub release page.
>
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Joel Stanley 



[PATCH] hw/arm/aspeed: Fix location of firmware images in documentation

2021-03-02 Thread Cédric Le Goater
Firmware images can be found on the OpenBMC jenkins site and on the
OpenBMC GitHub release page.

Signed-off-by: Cédric Le Goater 
---
 docs/system/arm/aspeed.rst | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index 690bada7842b..8972aa3f7bbe 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -72,18 +72,22 @@ Missing devices
 Boot options
 
 
-The Aspeed machines can be started using the -kernel option to load a
-Linux kernel or from a firmware image which can be downloaded from the
-OpenPOWER jenkins :
+The Aspeed machines can be started using the ``-kernel`` option to
+load a Linux kernel or from a firmware. Images can be downloaded from
+the OpenBMC jenkins :
 
-   https://openpower.xyz/
+   
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
+
+or directly from the OpenBMC GitHub release repository :
+
+   https://github.com/openbmc/openbmc/releases
 
 The image should be attached as an MTD drive. Run :
 
 .. code-block:: bash
 
   $ qemu-system-arm -M romulus-bmc -nic user \
-   -drive file=flash-romulus,format=raw,if=mtd -nographic
+   -drive file=obmc-phosphor-image-romulus.static.mtd,format=raw,if=mtd 
-nographic
 
 Options specific to Aspeed machines are :
 
-- 
2.26.2




Re: [PATCH v3] vl: deprecate -writeconfig

2021-03-02 Thread Gerd Hoffmann
On Tue, Mar 02, 2021 at 07:00:23PM +0100, Paolo Bonzini wrote:
> The functionality of -writeconfig is limited and the code
> does not even try to detect cases where it prints incorrect
> syntax (for example if values have a quote in them, since
> qemu_config_parse does not support any kind of escaping)
> so remove it.
> 
> Signed-off-by: Paolo Bonzini 

Acked-by: Gerd Hoffmann 




Re: [PATCH v2] Autoconnect jack ports by default

2021-03-02 Thread Gerd Hoffmann
  Hi,

> JACK clients with consumer purpose often auto connect to system ports by 
> default because their users mostly use JACK just as a consumer desktop sound 
> server. And I assume this applies to José as well.

Hmm, ok.  I'd suggest to simply change the default for connect-ports
then, that'll allow the user to easily change the behavior by setting
connect-ports to something else (including the empty string to disable
autoconnect).

take care,
  Gerd




[PATCH] multi-process: Initialize variables declared with g_auto*

2021-03-02 Thread Zenghui Yu
Quote docs/devel/style.rst (section "Automatic memory deallocation"):

* Variables declared with g_auto* MUST always be initialized,
  otherwise the cleanup function will use uninitialized stack memory

Initialize @name properly to get rid of the compilation error:

../hw/remote/proxy.c: In function 'pci_proxy_dev_realize':
/usr/include/glib-2.0/glib/glib-autocleanups.h:28:3: error: 'name' may be used 
uninitialized in this function [-Werror=maybe-uninitialized]
   g_free (*pp);
   ^~~~
../hw/remote/proxy.c:350:30: note: 'name' was declared here
 g_autofree char *name;
  ^~~~

Signed-off-by: Zenghui Yu 
---
 hw/remote/memory.c | 3 +--
 hw/remote/proxy.c  | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/remote/memory.c b/hw/remote/memory.c
index 32085b1e05..f5f735c15a 100644
--- a/hw/remote/memory.c
+++ b/hw/remote/memory.c
@@ -43,9 +43,8 @@ void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp)
 remote_sysmem_reset();
 
 for (region = 0; region < msg->num_fds; region++) {
-g_autofree char *name;
+g_autofree char *name = g_strdup_printf("remote-mem-%u", suffix++);
 subregion = g_new(MemoryRegion, 1);
-name = g_strdup_printf("remote-mem-%u", suffix++);
 memory_region_init_ram_from_fd(subregion, NULL,
name, sysmem_info->sizes[region],
true, msg->fds[region],
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
index 4fa4be079d..6dda705fc2 100644
--- a/hw/remote/proxy.c
+++ b/hw/remote/proxy.c
@@ -347,13 +347,12 @@ static void probe_pci_info(PCIDevice *dev, Error **errp)
PCI_BASE_ADDRESS_SPACE_IO : PCI_BASE_ADDRESS_SPACE_MEMORY;
 
 if (size) {
-g_autofree char *name;
+g_autofree char *name = g_strdup_printf("bar-region-%d", i);
 pdev->region[i].dev = pdev;
 pdev->region[i].present = true;
 if (type == PCI_BASE_ADDRESS_SPACE_MEMORY) {
 pdev->region[i].memory = true;
 }
-name = g_strdup_printf("bar-region-%d", i);
 memory_region_init_io(>region[i].mr, OBJECT(pdev),
   _mr_ops, >region[i],
   name, size);
-- 
2.19.1




[PATCH 2/2] aspeed: Integrate HACE

2021-03-02 Thread Joel Stanley
Add the hash and crypto engine model to the aspeed socs.

Signed-off-by: Joel Stanley 
[ clg: documentation update ]
Signed-off-by: Cédric Le Goater 
---
 docs/system/arm/aspeed.rst  |  2 +-
 include/hw/arm/aspeed_soc.h |  3 +++
 hw/arm/aspeed_ast2600.c | 14 ++
 hw/arm/aspeed_soc.c | 15 +++
 4 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index 690bada7842b..ec30cad88a58 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -48,6 +48,7 @@ Supported devices
  * UART
  * Ethernet controllers
  * Front LEDs (PCA9552 on I2C bus)
+ * Hash/Crypto Engine (HACE) - SHA support only, no scatter-gather
 
 
 Missing devices
@@ -59,7 +60,6 @@ Missing devices
  * LPC Bus Controller
  * Slave GPIO Controller
  * Super I/O Controller
- * Hash/Crypto Engine
  * PCI-Express 1 Controller
  * Graphic Display Controller
  * PECI Controller
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 11cfe6e3585b..a8c9a22e5882 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -21,6 +21,7 @@
 #include "hw/rtc/aspeed_rtc.h"
 #include "hw/i2c/aspeed_i2c.h"
 #include "hw/ssi/aspeed_smc.h"
+#include "hw/misc/aspeed_hace.h"
 #include "hw/watchdog/wdt_aspeed.h"
 #include "hw/net/ftgmac100.h"
 #include "target/arm/cpu.h"
@@ -49,6 +50,7 @@ struct AspeedSoCState {
 AspeedTimerCtrlState timerctrl;
 AspeedI2CState i2c;
 AspeedSCUState scu;
+AspeedHACEState hace;
 AspeedXDMAState xdma;
 AspeedSMCState fmc;
 AspeedSMCState spi[ASPEED_SPIS_NUM];
@@ -130,6 +132,7 @@ enum {
 ASPEED_DEV_SDRAM,
 ASPEED_DEV_XDMA,
 ASPEED_DEV_EMMC,
+ASPEED_DEV_HACE,
 };
 
 #endif /* ASPEED_SOC_H */
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bf31ca351feb..7aba3effd7bc 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -42,6 +42,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 [ASPEED_DEV_ETH2]  = 0x1E68,
 [ASPEED_DEV_ETH4]  = 0x1E69,
 [ASPEED_DEV_VIC]   = 0x1E6C,
+[ASPEED_DEV_HACE]  = 0x1E6D,
 [ASPEED_DEV_SDMC]  = 0x1E6E,
 [ASPEED_DEV_SCU]   = 0x1E6E2000,
 [ASPEED_DEV_XDMA]  = 0x1E6E7000,
@@ -102,6 +103,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_I2C]   = 110,   /* 110 -> 125 */
 [ASPEED_DEV_ETH1]  = 2,
 [ASPEED_DEV_ETH2]  = 3,
+[ASPEED_DEV_HACE]  = 4,
 [ASPEED_DEV_ETH3]  = 32,
 [ASPEED_DEV_ETH4]  = 33,
 
@@ -211,6 +213,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
 
 object_initialize_child(obj, "emmc-controller.sdhci", >emmc.slots[0],
 TYPE_SYSBUS_SDHCI);
+
+object_initialize_child(obj, "hace", >hace, TYPE_ASPEED_HACE);
 }
 
 /*
@@ -469,6 +473,16 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>emmc), 0, sc->memmap[ASPEED_DEV_EMMC]);
 sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_EMMC));
+
+/* HACE */
+object_property_set_link(OBJECT(>hace), "dram", OBJECT(s->dram_mr),
+ _abort);
+if (!sysbus_realize(SYS_BUS_DEVICE(>hace), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>hace), 0, sc->memmap[ASPEED_DEV_HACE]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>hace), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 7eefd54ac07a..ce9b8f8c5d6f 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -34,6 +34,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
 [ASPEED_DEV_VIC]= 0x1E6C,
 [ASPEED_DEV_SDMC]   = 0x1E6E,
 [ASPEED_DEV_SCU]= 0x1E6E2000,
+[ASPEED_DEV_HACE]   = 0x1E6E3000,
 [ASPEED_DEV_XDMA]   = 0x1E6E7000,
 [ASPEED_DEV_VIDEO]  = 0x1E70,
 [ASPEED_DEV_ADC]= 0x1E6E9000,
@@ -65,6 +66,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
 [ASPEED_DEV_VIC]= 0x1E6C,
 [ASPEED_DEV_SDMC]   = 0x1E6E,
 [ASPEED_DEV_SCU]= 0x1E6E2000,
+[ASPEED_DEV_HACE]   = 0x1E6E3000,
 [ASPEED_DEV_XDMA]   = 0x1E6E7000,
 [ASPEED_DEV_ADC]= 0x1E6E9000,
 [ASPEED_DEV_VIDEO]  = 0x1E70,
@@ -118,6 +120,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_DEV_ETH2]   = 3,
 [ASPEED_DEV_XDMA]   = 6,
 [ASPEED_DEV_SDHCI]  = 26,
+[ASPEED_DEV_HACE]   = 4,
 };
 
 #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
@@ -211,6 +214,8 @@ static void aspeed_soc_init(Object *obj)
 object_initialize_child(obj, "sdhci[*]", >sdhci.slots[i],
 TYPE_SYSBUS_SDHCI);
 }
+
+object_initialize_child(obj, "hace", >hace, TYPE_ASPEED_HACE);
 }
 
 

Re: [PATCH v2 1/1] hw/s390x: modularize virtio-gpu-ccw

2021-03-02 Thread Gerd Hoffmann
  Hi,

> The only approaches I can think of to make type_register_mayfail()
> "work" involve adding a dependency check in type_register_internal()
> before the call to type_table_add() is made. This can "work" for modules,
> because for types loaded from we can hope, that all dependencies are
> already, as modules are loaded relatively late.

Yes, for modules the lazy binding should not be needed and we should be
able to check for the parent at registration time.  module.c keeps track
of whenever phase1 init for builtin qom objects did happen already, so
we can use that instead of passing mayfail through a bunch of function
calls.  Quick & dirty test hack below.

BTW: "qemu-system-x86_64 -device help" tries to load all modules and is
a nice test case ;)

HTH,
  Gerd

commit 75ca3012e626318b562bcb51ecdc34400e25f2d0
Author: Gerd Hoffmann 
Date:   Tue Mar 2 16:26:39 2021 +0100

[hack] modular type init check

diff --git a/qom/object.c b/qom/object.c
index 491823db4a2d..01785e73f495 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -135,11 +135,22 @@ static TypeImpl *type_new(const TypeInfo *info)
 return ti;
 }
 
+/* HACK: util/module.c */
+extern bool modules_init_done[MODULE_INIT_MAX];
+static TypeImpl *type_get_by_name(const char *name);
+
 static TypeImpl *type_register_internal(const TypeInfo *info)
 {
 TypeImpl *ti;
 ti = type_new(info);
 
+if (modules_init_done[MODULE_INIT_QOM]) {
+if (ti->parent && !type_get_by_name(ti->parent)) {
+g_free(ti);
+return NULL;
+}
+}
+
 type_table_add(ti);
 return ti;
 }
diff --git a/util/module.c b/util/module.c
index cbe89fede628..b7b519eed62c 100644
--- a/util/module.c
+++ b/util/module.c
@@ -34,7 +34,7 @@ typedef struct ModuleEntry
 typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList;
 
 static ModuleTypeList init_type_list[MODULE_INIT_MAX];
-static bool modules_init_done[MODULE_INIT_MAX];
+bool modules_init_done[MODULE_INIT_MAX];
 
 static ModuleTypeList dso_init_list;
 




[PATCH 1/2] hw: Model ASPEED's Hash and Crypto Engine

2021-03-02 Thread Joel Stanley
The HACE (Hash and Crpyto Engine) is a device that offloads MD5, SHA1,
SHA2, RSA and other cryptographic algorithms.

This initial model implements a subset of the device's functionality;
currently only direct access (non-scatter gather) hashing.

Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
---
 include/hw/misc/aspeed_hace.h |  33 
 hw/misc/aspeed_hace.c | 302 ++
 hw/misc/meson.build   |   2 +-
 3 files changed, 336 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/misc/aspeed_hace.h
 create mode 100644 hw/misc/aspeed_hace.c

diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
new file mode 100644
index ..e1fce670ef9e
--- /dev/null
+++ b/include/hw/misc/aspeed_hace.h
@@ -0,0 +1,33 @@
+/*
+ * ASPEED Hash and Crypto Engine
+ *
+ * Copyright (C) 2021 IBM Corp.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_HACE_H
+#define ASPEED_HACE_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ASPEED_HACE "aspeed.hace"
+#define ASPEED_HACE(obj) OBJECT_CHECK(AspeedHACEState, (obj), TYPE_ASPEED_HACE)
+
+#define ASPEED_HACE_NR_REGS (0x64 >> 2)
+
+typedef struct AspeedHACEState {
+/*  */
+SysBusDevice parent;
+
+/*< public >*/
+MemoryRegion iomem;
+qemu_irq irq;
+
+uint32_t regs[ASPEED_HACE_NR_REGS];
+
+MemoryRegion *dram_mr;
+AddressSpace dram_as;
+} AspeedHACEState;
+
+#endif /* _ASPEED_HACE_H_ */
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
new file mode 100644
index ..0e402a0adea9
--- /dev/null
+++ b/hw/misc/aspeed_hace.c
@@ -0,0 +1,302 @@
+/*
+ * ASPEED Hash and Crypto Engine
+ *
+ * Copyright (C) 2021 IBM Corp.
+ *
+ * Joel Stanley 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_hace.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+#include "crypto/hash.h"
+#include "hw/qdev-properties.h"
+#include "hw/irq.h"
+
+#define R_STATUS(0x1c / 4)
+#define HASH_IRQBIT(9)
+#define CRYPT_IRQ   BIT(12)
+#define TAG_IRQ BIT(15)
+
+#define R_HASH_CMD  (0x30 / 4)
+/* Hash algorithim selection */
+#define  HASH_ALGO_MASK (BIT(4) | BIT(5) | BIT(6))
+#define  HASH_ALGO_MD5  0
+#define  HASH_ALGO_SHA1 BIT(5)
+#define  HASH_ALGO_SHA224   BIT(6)
+#define  HASH_ALGO_SHA256   (BIT(4) | BIT(6))
+#define  HASH_ALGO_SHA512_SERIES(BIT(5) | BIT(6))
+/* SHA512 algorithim selection */
+#define  SHA512_HASH_ALGO_MASK  (BIT(10) | BIT(11) | BIT(12))
+#define  HASH_ALGO_SHA512_SHA5120
+#define  HASH_ALGO_SHA512_SHA384BIT(10)
+#define  HASH_ALGO_SHA512_SHA256BIT(11)
+#define  HASH_ALGO_SHA512_SHA224(BIT(10) | BIT(11))
+/* HMAC modes */
+#define  HASH_HMAC_MASK (BIT(7) | BIT(8))
+#define  HASH_DIGEST0
+#define  HASH_DIGEST_HMAC   BIT(7)
+#define  HASH_DIGEST_ACCUM  BIT(8)
+#define  HASH_HMAC_KEY  (BIT(7) | BIT(8))
+/* Cascscaed operation modes */
+#define  HASH_ONLY  0
+#define  HASH_ONLY2 BIT(0)
+#define  HASH_CRYPT_THEN_HASH   BIT(1)
+#define  HASH_HASH_THEN_CRYPT   (BIT(0) | BIT(1))
+/* Other cmd bits */
+#define  HASH_IRQ_ENBIT(9)
+#define  HASH_SG_EN BIT(18)
+
+#define R_CRYPT_CMD (0x10 / 4)
+
+#define R_HASH_SRC  (0x20 / 4)
+#define R_HASH_DEST (0x24 / 4)
+#define R_HASH_SRC_LEN  (0x2c / 4)
+
+static int do_hash_operation(AspeedHACEState *s, int algo)
+{
+hwaddr src, len, dest;
+uint8_t *digest_buf = NULL;
+size_t digest_len = 0;
+char *src_buf;
+int rc;
+
+src = s->regs[R_HASH_SRC];
+len = s->regs[R_HASH_SRC_LEN];
+dest = s->regs[R_HASH_DEST];
+
+src_buf = address_space_map(>dram_as, src, , false,
+MEMTXATTRS_UNSPECIFIED);
+if (!src_buf) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map dram\n", __func__);
+return -EACCES;
+}
+
+rc = qcrypto_hash_bytes(algo, src_buf, len, _buf, _len,
+_fatal);
+if (rc < 0) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
+return rc;
+}
+
+rc = address_space_write(>dram_as, dest, MEMTXATTRS_UNSPECIFIED,
+ digest_buf, digest_len);
+if (rc) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: address space write failed\n", __func__);
+}
+g_free(digest_buf);
+
+address_space_unmap(>dram_as, src_buf, len, false, len);
+
+/*
+ * Set status bits to indicate completion. Testing shows hardware sets
+ * these irrespective of HASH_IRQ_EN.
+ */
+s->regs[R_STATUS] |= HASH_IRQ;
+
+return 0;
+}
+

[PATCH 0/2] hw/misc: Model ASPEED hash and crpyto engine

2021-03-02 Thread Joel Stanley
This adds a model for the ASPEED hash and crypto engine (HACE) found on
all supported ASPEED SoCs.

The model uses Qemu's gcrypto API to perform the SHA and MD5 hashing
directly in the machine's emulated memory space, which I found a neat
use of Qemu's features.

It has been tested using u-boot and from Linux userspace.

Joel Stanley (2):
  hw: Model ASPEED's Hash and Crypto Engine
  aspeed: Integrate HACE

 docs/system/arm/aspeed.rst|   2 +-
 include/hw/arm/aspeed_soc.h   |   3 +
 include/hw/misc/aspeed_hace.h |  33 
 hw/arm/aspeed_ast2600.c   |  14 ++
 hw/arm/aspeed_soc.c   |  15 ++
 hw/misc/aspeed_hace.c | 302 ++
 hw/misc/meson.build   |   2 +-
 7 files changed, 369 insertions(+), 2 deletions(-)
 create mode 100644 include/hw/misc/aspeed_hace.h
 create mode 100644 hw/misc/aspeed_hace.c

-- 
2.30.1




Re: [PATCH 2/3] qapi, audio: respect build time conditions in audio schema

2021-03-02 Thread Gerd Hoffmann
On Tue, Mar 02, 2021 at 05:55:23PM +, Daniel P. Berrangé wrote:
> Currently the -audiodev accepts any audiodev type regardless of what is
> built in to QEMU. An error only occurs later at runtime when a sound
> device tries to use the audio backend.
> 
> With this change QEMU will immediately reject -audiodev args that are
> not compiled into the binary. The QMP schema will also be introspectable
> to identify what is compiled in.

Note that audio backends are modularized, so "compiled with
CONFIG_AUDIO_ALSA" doesn't imply "alsa support is available".

take care,
  Gerd




Re: [PATCH v3] vl: deprecate -writeconfig

2021-03-02 Thread Markus Armbruster
Paolo Bonzini  writes:

> The functionality of -writeconfig is limited and the code
> does not even try to detect cases where it prints incorrect
> syntax (for example if values have a quote in them, since
> qemu_config_parse does not support any kind of escaping)
> so remove it.
>
> Signed-off-by: Paolo Bonzini 

Acked-by: Markus Armbruster 




Re: [PATCH v3] target/s390x: Implement the MVPG condition-code-option bit

2021-03-02 Thread Thomas Huth

On 03/03/2021 03.44, Richard Henderson wrote:

If the CCO bit is set, MVPG should not generate an exception but
report page translation faults via a CC code.

Create a new helper, access_prepare_nf, which can use probe_access_flags
in non-faulting mode, and then handle watchpoints.

Cc: David Hildenbrand 
Reported-by: Thomas Huth 
Signed-off-by: Richard Henderson 
---
  target/s390x/mem_helper.c | 87 ---
  1 file changed, 64 insertions(+), 23 deletions(-)

diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 25cfede806..b397333c0b 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -130,28 +130,62 @@ typedef struct S390Access {
  int mmu_idx;
  } S390Access;
  
+static bool access_prepare_nf(S390Access *access, CPUS390XState *env,

+  bool nofault, vaddr vaddr1, int size,
+  MMUAccessType access_type,
+  int mmu_idx, uintptr_t ra)
+{
+void *haddr1, *haddr2 = NULL;
+int size1, size2;
+vaddr vaddr2 = 0;
+int flags;
+
+assert(size > 0 && size <= 4096);
+
+size1 = MIN(size, -(vaddr1 | TARGET_PAGE_MASK)),
+size2 = size - size1;
+
+flags = probe_access_flags(env, vaddr1, access_type, mmu_idx,
+   nofault, , ra);
+if (unlikely(size2)) {
+/* The access crosses page boundaries. */
+vaddr2 = wrap_address(env, vaddr1 + size1);
+flags |= probe_access_flags(env, vaddr2, access_type, mmu_idx,
+nofault, , ra);
+}
+
+if (unlikely(flags & TLB_INVALID_MASK)) {
+return false;
+}
+if (unlikely(flags & TLB_WATCHPOINT)) {
+/* S390 does not presently use transaction attributes. */
+cpu_check_watchpoint(env_cpu(env), vaddr1, size,
+ MEMTXATTRS_UNSPECIFIED,
+ (access_type == MMU_DATA_STORE
+  ? BP_MEM_WRITE : BP_MEM_READ), ra);
+}
+
+*access = (S390Access) {
+.vaddr1 = vaddr1,
+.vaddr2 = vaddr2,
+.haddr1 = haddr1,
+.haddr2 = haddr2,
+.size1 = size1,
+.size2 = size2,
+.mmu_idx = mmu_idx
+};
+return true;
+}
+
  static S390Access access_prepare(CPUS390XState *env, vaddr vaddr, int size,
   MMUAccessType access_type, int mmu_idx,
   uintptr_t ra)
  {
-S390Access access = {
-.vaddr1 = vaddr,
-.size1 = MIN(size, -(vaddr | TARGET_PAGE_MASK)),
-.mmu_idx = mmu_idx,
-};
-
-g_assert(size > 0 && size <= 4096);
-access.haddr1 = probe_access(env, access.vaddr1, access.size1, access_type,
- mmu_idx, ra);
-
-if (unlikely(access.size1 != size)) {
-/* The access crosses page boundaries. */
-access.vaddr2 = wrap_address(env, vaddr + access.size1);
-access.size2 = size - access.size1;
-access.haddr2 = probe_access(env, access.vaddr2, access.size2,
- access_type, mmu_idx, ra);
-}
-return access;
+S390Access ret;
+bool ok = access_prepare_nf(, env, false, vaddr, size,
+access_type, mmu_idx, ra);
+assert(ok);
+return ret;
  }
  
  /* Helper to handle memset on a single page. */

@@ -845,8 +879,10 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, 
uint64_t r1, uint64_t r2)
  const int mmu_idx = cpu_mmu_index(env, false);
  const bool f = extract64(r0, 11, 1);
  const bool s = extract64(r0, 10, 1);
+const bool cco = extract64(r0, 8, 1);
  uintptr_t ra = GETPC();
  S390Access srca, desta;
+bool ok;
  
  if ((f && s) || extract64(r0, 12, 4)) {

  tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
@@ -858,13 +894,18 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, 
uint64_t r1, uint64_t r2)
  /*
   * TODO:
   * - Access key handling
- * - CC-option with surpression of page-translation exceptions
   * - Store r1/r2 register identifiers at real location 162
   */
-srca = access_prepare(env, r2, TARGET_PAGE_SIZE, MMU_DATA_LOAD, mmu_idx,
-  ra);
-desta = access_prepare(env, r1, TARGET_PAGE_SIZE, MMU_DATA_STORE, mmu_idx,
-   ra);
+ok = access_prepare_nf(, env, cco, r2, TARGET_PAGE_SIZE,
+   MMU_DATA_LOAD, mmu_idx, ra);
+if (!ok) {
+return 2;
+}
+ok = access_prepare_nf(, env, cco, r1, TARGET_PAGE_SIZE,
+   MMU_DATA_STORE, mmu_idx, ra);
+if (!ok) {
+return 1;
+}


Thanks, this looks promising, but one of the MVPG kvm-unit-tests is still 
failing with this patch - the one that checks for an exception if the 
destination page is marked as read-only. MVPG only returns CC1 for invalid 
page table 

[Bug 1917565] Re: Windows 10 fails with "Boot device inaccessible"

2021-03-02 Thread Nick
** Description changed:

  The issue is happening on all versions I tried after the following
  commit. I can also remove this individual change from master and it
  starts to work.
+ 
+ OVMF_CODE.fd is what comes with Ubuntu 20.04 through package manager.
+ 
  
  git diff af1b80ae56c9495999e8ccf7b70ef894378de642~ 
af1b80ae56c9495999e8ccf7b70ef894378de642
  diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
  index b7bc2a..7a5a8b3521 100644
  --- a/hw/i386/acpi-build.c
  +++ b/hw/i386/acpi-build.c
  @@ -1497,7 +1497,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
   dev = aml_device("PCI0");
   aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
   aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
  -aml_append(dev, aml_name_decl("_UID", aml_int(1)));
  +aml_append(dev, aml_name_decl("_UID", aml_int(0)));
   aml_append(sb_scope, dev);
   aml_append(dsdt, sb_scope);
  
  @@ -1512,7 +1512,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
   aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
   aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
   aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
  -aml_append(dev, aml_name_decl("_UID", aml_int(1)));
  +aml_append(dev, aml_name_decl("_UID", aml_int(0)));
   aml_append(dev, build_q35_osc_method());
   aml_append(sb_scope, dev);
   aml_append(dsdt, sb_scope);
  
  The virtual machine start command:
  x86_64-softmmu/qemu-system-x86_64 -name guest=win10-dev,debug-threads=on 
-blockdev 
'{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}'
 -blockdev 
'{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/win10-dev_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}'
 -machine 
pc-q35-4.2,accel=kvm,usb=off,vmport=off,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format
 -cpu 
Skylake-Client-IBRS,ss=on,vmx=on,pdcm=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,ibpb=on,amd-ssbd=on,skip-l1dfl-vmentry=on,pschange-mc-no=on,hv-time,hv-relaxed,hv-vapic,hv-spinlocks=0x1fff
 -m 6144 -overcommit mem-lock=off -smp 4,sockets=4,cores=1,threads=1 -uuid 
5646e540-5022-4ace-8d6a-d7c4b61a6d3d -no-user-config -nodefaults -rtc 
base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet 
-global ICH9-LPC.disable_s3=1 -global ICH9-LPC.disable_s4=1 -boot strict=on 
-device 
pcie-root-port,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x2
 -device pcie-root-port,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 
-device pcie-root-port,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 
-device pcie-root-port,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 
-device pcie-root-port,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 
-device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 -device 
virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 -blockdev 
'{"driver":"host_device","filename":"/dev/disk/by-id/scsi-1SanDisk_Extreme_SSD_20072F404043","aio":"native","node-name":"libvirt-2-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-2-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"raw","file":"libvirt-2-storage"}'
 -device 
ide-hd,bus=ide.0,drive=libvirt-2-format,id=sata0-0-0,bootindex=1,write-cache=on 
-device ide-cd,bus=ide.1,id=sata0-0-1 -netdev user,id=hostnet0 -device 
e1000e,netdev=hostnet0,id=net0,mac=52:54:00:10:5b:55,bus=pci.1,addr=0x0 
-chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 
-chardev spicevmc,id=charchannel0,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
 -device usb-tablet,id=input0,bus=usb.0,port=1 -spice 
port=5900,addr=127.0.0.1,disable-ticketing=on,image-compression=off,seamless-migration=on
 -device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pcie.0,addr=0x1
 -device ich9-intel-hda,id=sound0,bus=pcie.0,addr=0x1b -device 
hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -chardev 
spicevmc,id=charredir0,name=usbredir -device 
usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev 
spicevmc,id=charredir1,name=usbredir -device 
usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device 
virtio-balloon-pci,id=balloon0,bus=pci.4,addr=0x0 -msg timestamp=on -D 
./log.txt -monitor stdio -d

-- 
You 

[Bug 1917565] Re: Windows 10 fails with "Boot device inaccessible"

2021-03-02 Thread Nick
** Description changed:

  The issue is happening on all versions I tried after the following
- commit.
+ commit. I can also remove this individual from master and it starts to
+ work.
  
  git diff af1b80ae56c9495999e8ccf7b70ef894378de642~ 
af1b80ae56c9495999e8ccf7b70ef894378de642
  diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
  index b7bc2a..7a5a8b3521 100644
  --- a/hw/i386/acpi-build.c
  +++ b/hw/i386/acpi-build.c
  @@ -1497,7 +1497,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
-  dev = aml_device("PCI0");
-  aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
-  aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
+  dev = aml_device("PCI0");
+  aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
+  aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
  -aml_append(dev, aml_name_decl("_UID", aml_int(1)));
  +aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-  aml_append(sb_scope, dev);
-  aml_append(dsdt, sb_scope);
-  
+  aml_append(sb_scope, dev);
+  aml_append(dsdt, sb_scope);
+ 
  @@ -1512,7 +1512,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
-  aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
-  aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
-  aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
+  aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
+  aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
+  aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
  -aml_append(dev, aml_name_decl("_UID", aml_int(1)));
  +aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-  aml_append(dev, build_q35_osc_method());
-  aml_append(sb_scope, dev);
-  aml_append(dsdt, sb_scope);
+  aml_append(dev, build_q35_osc_method());
+  aml_append(sb_scope, dev);
+  aml_append(dsdt, sb_scope);
  
  The virtual machine start command:
  x86_64-softmmu/qemu-system-x86_64 -name guest=win10-dev,debug-threads=on 
-blockdev 
'{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}'
 -blockdev 
'{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/win10-dev_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}'
 -machine 
pc-q35-4.2,accel=kvm,usb=off,vmport=off,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format
 -cpu 
Skylake-Client-IBRS,ss=on,vmx=on,pdcm=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,ibpb=on,amd-ssbd=on,skip-l1dfl-vmentry=on,pschange-mc-no=on,hv-time,hv-relaxed,hv-vapic,hv-spinlocks=0x1fff
 -m 6144 -overcommit mem-lock=off -smp 4,sockets=4,cores=1,threads=1 -uuid 
5646e540-5022-4ace-8d6a-d7c4b61a6d3d -no-user-config -nodefaults -rtc 
base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet 
-global ICH9-LPC.disable_s3=1 -global ICH9-LPC.disable_s4=1 -boot strict=on 
-device 
pcie-root-port,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x2
 -device pcie-root-port,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 
-device pcie-root-port,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 
-device pcie-root-port,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 
-device pcie-root-port,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 
-device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 -device 
virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 -blockdev 
'{"driver":"host_device","filename":"/dev/disk/by-id/scsi-1SanDisk_Extreme_SSD_20072F404043","aio":"native","node-name":"libvirt-2-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-2-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"raw","file":"libvirt-2-storage"}'
 -device 
ide-hd,bus=ide.0,drive=libvirt-2-format,id=sata0-0-0,bootindex=1,write-cache=on 
-device ide-cd,bus=ide.1,id=sata0-0-1 -netdev user,id=hostnet0 -device 
e1000e,netdev=hostnet0,id=net0,mac=52:54:00:10:5b:55,bus=pci.1,addr=0x0 
-chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 
-chardev spicevmc,id=charchannel0,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
 -device usb-tablet,id=input0,bus=usb.0,port=1 -spice 
port=5900,addr=127.0.0.1,disable-ticketing=on,image-compression=off,seamless-migration=on
 -device 

Re: [PATCH v3 07/27] cpu: Introduce SysemuCPUOps structure

2021-03-02 Thread Richard Henderson

On 3/2/21 6:57 AM, Philippe Mathieu-Daudé wrote:

+static struct SysemuCPUOps alpha_sysemu_ops = {


const, for all of them.


r~



Re: [Bug 1917565] [NEW] Windows 10 fails with "Boot device inaccessible"

2021-03-02 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/161474788220.8516.15014999465847517073.malone...@gac.canonical.com/



Hi,

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

Type: series
Message-id: 161474788220.8516.15014999465847517073.malone...@gac.canonical.com
Subject: [Bug 1917565] [NEW] Windows 10 fails with "Boot device inaccessible"

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/161474788220.8516.15014999465847517073.malone...@gac.canonical.com -> 
patchew/161474788220.8516.15014999465847517073.malone...@gac.canonical.com
Switched to a new branch 'test'

=== OUTPUT BEGIN ===
checkpatch.pl: no revisions returned for revlist 'base..'
=== OUTPUT END ===

Test command exited with code: 255


The full log is available at
http://patchew.org/logs/161474788220.8516.15014999465847517073.malone...@gac.canonical.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[Bug 1917565] [NEW] Windows 10 fails with "Boot device inaccessible"

2021-03-02 Thread Nick
Public bug reported:

The issue is happening on all versions I tried after the following
commit.

git diff af1b80ae56c9495999e8ccf7b70ef894378de642~ 
af1b80ae56c9495999e8ccf7b70ef894378de642
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b7bc2a..7a5a8b3521 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1497,7 +1497,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 dev = aml_device("PCI0");
 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
 aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
-aml_append(dev, aml_name_decl("_UID", aml_int(1)));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
 aml_append(sb_scope, dev);
 aml_append(dsdt, sb_scope);
 
@@ -1512,7 +1512,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
 aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
 aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
-aml_append(dev, aml_name_decl("_UID", aml_int(1)));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
 aml_append(dev, build_q35_osc_method());
 aml_append(sb_scope, dev);
 aml_append(dsdt, sb_scope);

The virtual machine start command:
x86_64-softmmu/qemu-system-x86_64 -name guest=win10-dev,debug-threads=on 
-blockdev 
'{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}'
 -blockdev 
'{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/win10-dev_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}'
 -machine 
pc-q35-4.2,accel=kvm,usb=off,vmport=off,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format
 -cpu 
Skylake-Client-IBRS,ss=on,vmx=on,pdcm=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,ibpb=on,amd-ssbd=on,skip-l1dfl-vmentry=on,pschange-mc-no=on,hv-time,hv-relaxed,hv-vapic,hv-spinlocks=0x1fff
 -m 6144 -overcommit mem-lock=off -smp 4,sockets=4,cores=1,threads=1 -uuid 
5646e540-5022-4ace-8d6a-d7c4b61a6d3d -no-user-config -nodefaults -rtc 
base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet 
-global ICH9-LPC.disable_s3=1 -global ICH9-LPC.disable_s4=1 -boot strict=on 
-device 
pcie-root-port,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x2
 -device pcie-root-port,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 
-device pcie-root-port,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 
-device pcie-root-port,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 
-device pcie-root-port,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 
-device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 -device 
virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 -blockdev 
'{"driver":"host_device","filename":"/dev/disk/by-id/scsi-1SanDisk_Extreme_SSD_20072F404043","aio":"native","node-name":"libvirt-2-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}'
 -blockdev 
'{"node-name":"libvirt-2-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"raw","file":"libvirt-2-storage"}'
 -device 
ide-hd,bus=ide.0,drive=libvirt-2-format,id=sata0-0-0,bootindex=1,write-cache=on 
-device ide-cd,bus=ide.1,id=sata0-0-1 -netdev user,id=hostnet0 -device 
e1000e,netdev=hostnet0,id=net0,mac=52:54:00:10:5b:55,bus=pci.1,addr=0x0 
-chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 
-chardev spicevmc,id=charchannel0,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
 -device usb-tablet,id=input0,bus=usb.0,port=1 -spice 
port=5900,addr=127.0.0.1,disable-ticketing=on,image-compression=off,seamless-migration=on
 -device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pcie.0,addr=0x1
 -device ich9-intel-hda,id=sound0,bus=pcie.0,addr=0x1b -device 
hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -chardev 
spicevmc,id=charredir0,name=usbredir -device 
usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev 
spicevmc,id=charredir1,name=usbredir -device 
usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device 
virtio-balloon-pci,id=balloon0,bus=pci.4,addr=0x0 -msg timestamp=on -D 
./log.txt -monitor stdio -d

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: 10 boot device inaccessible windows

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

[PATCH V2 7/7] net/net.c: Add handler for COLO passthrough connection

2021-03-02 Thread Zhang Chen
From: Zhang Chen 

Use connection protocol,src port,dst port,src ip,dst ip as the key
to bypass certain network traffic in COLO compare.

Signed-off-by: Zhang Chen 
---
 net/net.c | 147 ++
 1 file changed, 147 insertions(+)

diff --git a/net/net.c b/net/net.c
index 037dcc5973..bb2fb1d8b5 100644
--- a/net/net.c
+++ b/net/net.c
@@ -55,6 +55,8 @@
 #include "sysemu/sysemu.h"
 #include "net/filter.h"
 #include "qapi/string-output-visitor.h"
+#include "net/colo-compare.h"
+#include "qom/object_interfaces.h"
 
 /* Net bridge is currently not supported for W32. */
 #if !defined(_WIN32)
@@ -1151,14 +1153,159 @@ void qmp_netdev_del(const char *id, Error **errp)
 qemu_del_net_client(nc);
 }
 
+static CompareState *colo_passthrough_check(L4_Connection *conn, Error **errp)
+{
+Object *container;
+Object *obj;
+CompareState *s;
+
+if (!conn->id) {
+error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id",
+   "Need input colo-compare object id");
+return NULL;
+}
+
+container = object_get_objects_root();
+obj = object_resolve_path_component(container, conn->id);
+if (!obj) {
+error_setg(errp, "colo-compare '%s' not found", conn->id);
+return NULL;
+}
+
+s = COLO_COMPARE(obj);
+
+if (conn->protocol == -1) {
+error_setg(errp, "COLO pass through get wrong protocol");
+return NULL;
+}
+
+if ((conn->src_ip && !qemu_isdigit(conn->src_ip[0])) ||
+(conn->dst_ip && !qemu_isdigit(conn->dst_ip[0]))) {
+error_setg(errp, "COLO pass through get wrong IP");
+return NULL;
+}
+
+if (conn->src_port > 65536 || conn->src_port < 0 ||
+conn->dst_port > 65536 || conn->dst_port < 0) {
+error_setg(errp, "COLO pass through get wrong port");
+return NULL;
+}
+
+return s;
+}
+
+static void compare_passthrough_add(CompareState *s,
+L4_Connection *conn,
+Error **errp)
+{
+PassthroughEntry *bypass = NULL, *next = NULL, *origin = NULL;
+
+bypass = g_new0(PassthroughEntry, 1);
+
+bypass->l4_protocol = conn->protocol;
+bypass->src_port = conn->src_port;
+bypass->dst_port = conn->dst_port;
+
+if (!inet_aton(conn->src_ip, >src_ip)) {
+bypass->src_ip.s_addr = 0;
+}
+
+if (!inet_aton(conn->dst_ip, >dst_ip)) {
+bypass->dst_ip.s_addr = 0;
+}
+
+if (!QLIST_EMPTY(>passthroughlist)) {
+QLIST_FOREACH_SAFE(origin, >passthroughlist, node, next) {
+if ((bypass->l4_protocol == origin->l4_protocol) &&
+(bypass->src_port == origin->src_port) &&
+(bypass->src_ip.s_addr == origin->src_ip.s_addr) &&
+(bypass->dst_ip.s_addr == origin->dst_ip.s_addr)) {
+error_setg(errp, "The pass through connection already exists");
+g_free(bypass);
+return;
+}
+}
+}
+
+QLIST_INSERT_HEAD(>passthroughlist, bypass, node);
+}
+
+static void compare_passthrough_del(CompareState *s,
+L4_Connection *conn,
+Error **errp)
+{
+PassthroughEntry *bypass = NULL, *next = NULL, *origin = NULL;
+
+bypass = g_new0(PassthroughEntry, 1);
+
+bypass->l4_protocol = conn->protocol;
+bypass->src_port = conn->src_port;
+bypass->dst_port = conn->dst_port;
+
+if (!inet_aton(conn->src_ip, >src_ip)) {
+bypass->src_ip.s_addr = 0;
+}
+
+if (!inet_aton(conn->dst_ip, >dst_ip)) {
+bypass->dst_ip.s_addr = 0;
+}
+
+if (!QLIST_EMPTY(>passthroughlist)) {
+QLIST_FOREACH_SAFE(origin, >passthroughlist, node, next) {
+if ((bypass->l4_protocol == origin->l4_protocol) &&
+(bypass->src_port == origin->src_port) &&
+(bypass->src_ip.s_addr == origin->src_ip.s_addr) &&
+(bypass->dst_ip.s_addr == origin->dst_ip.s_addr)) {
+QLIST_REMOVE(origin, node);
+g_free(origin);
+g_free(bypass);
+return;
+}
+}
+error_setg(errp, "The pass through list can't find the connection");
+} else {
+error_setg(errp, "The pass through connection list is empty");
+}
+
+g_free(bypass);
+}
+
 void qmp_colo_passthrough_add(L4_Connection *conn, Error **errp)
 {
 /* Setup passthrough connection */
+CompareState *s;
+Error *err = NULL;
+
+s = colo_passthrough_check(conn, );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+compare_passthrough_add(s, conn, );
+if (err) {
+error_propagate(errp, err);
+return;
+}
 }
 
 void qmp_colo_passthrough_del(L4_Connection *conn, Error **errp)
 {
 /* Delete passthrough connection */
+CompareState *s;
+Error *err = NULL;
+
+s = 

[PATCH V2 6/7] net/colo-compare: Add passthrough list to CompareState

2021-03-02 Thread Zhang Chen
From: Zhang Chen 

Add passthrough list for each CompareState.

Signed-off-by: Zhang Chen 
---
 net/colo-compare.c | 25 +
 net/colo-compare.h | 10 ++
 2 files changed, 35 insertions(+)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index a803f8b888..80cea32c20 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -141,6 +141,7 @@ static int packet_enqueue(CompareState *s, int mode, 
Connection **con)
 ConnectionKey key;
 Packet *pkt = NULL;
 Connection *conn;
+PassthroughEntry *bypass, *next;
 int ret;
 
 if (mode == PRIMARY_IN) {
@@ -160,6 +161,29 @@ static int packet_enqueue(CompareState *s, int mode, 
Connection **con)
 }
 fill_connection_key(pkt, );
 
+/* Check COLO passthrough connenction */
+if (!QLIST_EMPTY(>passthroughlist)) {
+QLIST_FOREACH_SAFE(bypass, >passthroughlist, node, next) {
+if (((key.ip_proto == IPPROTO_TCP) && (bypass->l4_protocol == 0)) 
||
+((key.ip_proto == IPPROTO_UDP) && (bypass->l4_protocol == 1))) 
{
+if (bypass->src_port == 0 || bypass->src_port == key.dst_port) 
{
+if (bypass->src_ip.s_addr == 0 ||
+bypass->src_ip.s_addr == key.src.s_addr) {
+if (bypass->dst_port == 0 ||
+bypass->dst_port == key.src_port) {
+if (bypass->dst_ip.s_addr == 0 ||
+bypass->dst_ip.s_addr == key.dst.s_addr) {
+packet_destroy(pkt, NULL);
+pkt = NULL;
+return -1;
+}
+}
+}
+}
+}
+}
+}
+
 conn = connection_get(s->connection_track_table,
   ,
   >conn_list);
@@ -1224,6 +1248,7 @@ static void colo_compare_complete(UserCreatable *uc, 
Error **errp)
 }
 
 g_queue_init(>conn_list);
+QLIST_INIT(>passthroughlist);
 
 s->connection_track_table = g_hash_table_new_full(connection_key_hash,
   connection_key_equal,
diff --git a/net/colo-compare.h b/net/colo-compare.h
index 2a9dcac0a7..31644f145b 100644
--- a/net/colo-compare.h
+++ b/net/colo-compare.h
@@ -54,6 +54,15 @@ typedef struct SendEntry {
 uint8_t *buf;
 } SendEntry;
 
+typedef struct PassthroughEntry {
+int l4_protocol;
+int src_port;
+int dst_port;
+struct in_addr src_ip;
+struct in_addr dst_ip;
+QLIST_ENTRY(PassthroughEntry) node;
+} PassthroughEntry;
+
 /*
  *  + CompareState ++
  *  |   |
@@ -110,6 +119,7 @@ struct CompareState {
 
 QEMUBH *event_bh;
 enum colo_event event;
+QLIST_HEAD(, PassthroughEntry) passthroughlist;
 
 QTAILQ_ENTRY(CompareState) next;
 };
-- 
2.25.1




[PATCH V2 0/7] Bypass specific network traffic in COLO

2021-03-02 Thread Zhang Chen
From: Zhang Chen 

Since the real user scenario does not need to monitor all traffic.
This series give user ability to bypass kinds of network stream.

  V2:
- Add some qapi definitions.
- Support multi colo-compare objects.
- Support setup each rules for each objects individually.
- Clean up COLO compare definition to .h file.
- Rebase HMP command for stable tree.
- Add redundant rules check.

Zhang Chen (7):
  qapi/net.json: Add IP_PROTOCOL definition
  qapi/net.json: Add L4_Connection definition
  qapi/net: Add new QMP command for COLO passthrough
  hmp-commands: Add new HMP command for COLO passthrough
  net/colo-compare: Move data structure and define to .h file.
  net/colo-compare: Add passthrough list to CompareState
  net/net.c: Add handler for COLO passthrough connection

 hmp-commands.hx   |  26 +++
 include/monitor/hmp.h |   2 +
 monitor/hmp-cmds.c|  34 +
 net/colo-compare.c| 131 +++
 net/colo-compare.h| 116 +++
 net/net.c | 157 ++
 qapi/net.json |  96 ++
 7 files changed, 456 insertions(+), 106 deletions(-)

-- 
2.25.1




[PATCH V2 5/7] net/colo-compare: Move data structure and define to .h file.

2021-03-02 Thread Zhang Chen
From: Zhang Chen 

Make other modules can reuse COLO code.

Signed-off-by: Zhang Chen 
---
 net/colo-compare.c | 106 -
 net/colo-compare.h | 106 +
 2 files changed, 106 insertions(+), 106 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 84db4978ac..a803f8b888 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -17,44 +17,24 @@
 #include "qemu/error-report.h"
 #include "trace.h"
 #include "qapi/error.h"
-#include "net/net.h"
 #include "net/eth.h"
 #include "qom/object_interfaces.h"
 #include "qemu/iov.h"
 #include "qom/object.h"
 #include "net/queue.h"
-#include "chardev/char-fe.h"
 #include "qemu/sockets.h"
-#include "colo.h"
-#include "sysemu/iothread.h"
 #include "net/colo-compare.h"
-#include "migration/colo.h"
-#include "migration/migration.h"
 #include "util.h"
 
 #include "block/aio-wait.h"
 #include "qemu/coroutine.h"
 
-#define TYPE_COLO_COMPARE "colo-compare"
-typedef struct CompareState CompareState;
-DECLARE_INSTANCE_CHECKER(CompareState, COLO_COMPARE,
- TYPE_COLO_COMPARE)
-
 static QTAILQ_HEAD(, CompareState) net_compares =
QTAILQ_HEAD_INITIALIZER(net_compares);
 
 static NotifierList colo_compare_notifiers =
 NOTIFIER_LIST_INITIALIZER(colo_compare_notifiers);
 
-#define COMPARE_READ_LEN_MAX NET_BUFSIZE
-#define MAX_QUEUE_SIZE 1024
-
-#define COLO_COMPARE_FREE_PRIMARY 0x01
-#define COLO_COMPARE_FREE_SECONDARY   0x02
-
-#define REGULAR_PACKET_CHECK_MS 1000
-#define DEFAULT_TIME_OUT_MS 3000
-
 /* #define DEBUG_COLO_PACKETS */
 
 static QemuMutex colo_compare_mutex;
@@ -64,92 +44,6 @@ static QemuCond event_complete_cond;
 static int event_unhandled_count;
 static uint32_t max_queue_size;
 
-/*
- *  + CompareState ++
- *  |   |
- *  +---+   +---+ +---+
- *  |   conn list   + - >  conn + --- >  conn + -- > ..
- *  +---+   +---+ +---+
- *  |   | |   | |  |
- *  +---+ +---v+  +---v++---v+ +---v+
- *|primary |  |secondary|primary | |secondary
- *|packet  |  |packet  +|packet  | |packet  +
- *++  ++++ ++
- *|   | |  |
- *+---v+  +---v++---v+ +---v+
- *|primary |  |secondary|primary | |secondary
- *|packet  |  |packet  +|packet  | |packet  +
- *++  ++++ ++
- *|   | |  |
- *+---v+  +---v++---v+ +---v+
- *|primary |  |secondary|primary | |secondary
- *|packet  |  |packet  +|packet  | |packet  +
- *++  ++++ ++
- */
-
-typedef struct SendCo {
-Coroutine *co;
-struct CompareState *s;
-CharBackend *chr;
-GQueue send_list;
-bool notify_remote_frame;
-bool done;
-int ret;
-} SendCo;
-
-typedef struct SendEntry {
-uint32_t size;
-uint32_t vnet_hdr_len;
-uint8_t *buf;
-} SendEntry;
-
-struct CompareState {
-Object parent;
-
-char *pri_indev;
-char *sec_indev;
-char *outdev;
-char *notify_dev;
-CharBackend chr_pri_in;
-CharBackend chr_sec_in;
-CharBackend chr_out;
-CharBackend chr_notify_dev;
-SocketReadState pri_rs;
-SocketReadState sec_rs;
-SocketReadState notify_rs;
-SendCo out_sendco;
-SendCo notify_sendco;
-bool vnet_hdr;
-uint64_t compare_timeout;
-uint32_t expired_scan_cycle;
-
-/*
- * Record the connection that through the NIC
- * Element type: Connection
- */
-GQueue conn_list;
-/* Record the connection without repetition */
-GHashTable *connection_track_table;
-
-IOThread *iothread;
-GMainContext *worker_context;
-QEMUTimer *packet_check_timer;
-
-QEMUBH *event_bh;
-enum colo_event event;
-
-QTAILQ_ENTRY(CompareState) next;
-};
-
-typedef struct CompareClass {
-ObjectClass parent_class;
-} CompareClass;
-
-enum {
-PRIMARY_IN = 0,
-SECONDARY_IN,
-};
-
 static const char *colo_mode[] = {
 [PRIMARY_IN] = "primary",
 [SECONDARY_IN] = "secondary",
diff --git a/net/colo-compare.h b/net/colo-compare.h
index 22ddd512e2..2a9dcac0a7 100644
--- a/net/colo-compare.h
+++ b/net/colo-compare.h
@@ -17,6 +17,112 @@
 #ifndef QEMU_COLO_COMPARE_H
 #define QEMU_COLO_COMPARE_H
 
+#include "net/net.h"
+#include "chardev/char-fe.h"
+#include "migration/colo.h"
+#include "migration/migration.h"
+#include "sysemu/iothread.h"
+#include "colo.h"
+
+#define TYPE_COLO_COMPARE "colo-compare"
+typedef struct 

[PATCH V2 4/7] hmp-commands: Add new HMP command for COLO passthrough

2021-03-02 Thread Zhang Chen
From: Zhang Chen 

Add hmp_colo_passthrough_add and hmp_colo_passthrough_del make user
can maintain COLO network passthrough list in human monitor.

Signed-off-by: Zhang Chen 
---
 hmp-commands.hx   | 26 ++
 include/monitor/hmp.h |  2 ++
 monitor/hmp-cmds.c| 34 ++
 3 files changed, 62 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 73e0832ea1..c71521303c 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1341,6 +1341,32 @@ SRST
   Remove host network device.
 ERST
 
+{
+.name   = "colo_passthrough_add",
+.args_type  = 
"protocol:s,id:s?,src_ip:s?,dst_ip:s?,src_port:i?,dst_port:i?",
+.params = "protocol [id] [src_ip] [dst_ip] [src_port] [dst_port]",
+.help   = "Add network stream to colo passthrough list",
+.cmd= hmp_colo_passthrough_add,
+},
+
+SRST
+``colo_passthrough_add``
+  Add network stream to colo passthrough list.
+ERST
+
+{
+.name   = "colo_passthrough_del",
+.args_type  = 
"protocol:s,id:s?,src_ip:s?,dst_ip:s?,src_port:i?,dst_port:i?",
+.params = "protocol [id] [src_ip] [dst_ip] [src_port] [dst_port]",
+.help   = "Delete network stream from colo passthrough list",
+.cmd= hmp_colo_passthrough_del,
+},
+
+SRST
+``colo_passthrough_del``
+  Delete network stream from colo passthrough list.
+ERST
+
 {
 .name   = "object_add",
 .args_type  = "object:O",
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index ed2913fd18..3c4943b09f 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -81,6 +81,8 @@ void hmp_device_del(Monitor *mon, const QDict *qdict);
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
 void hmp_netdev_add(Monitor *mon, const QDict *qdict);
 void hmp_netdev_del(Monitor *mon, const QDict *qdict);
+void hmp_colo_passthrough_add(Monitor *mon, const QDict *qdict);
+void hmp_colo_passthrough_del(Monitor *mon, const QDict *qdict);
 void hmp_getfd(Monitor *mon, const QDict *qdict);
 void hmp_closefd(Monitor *mon, const QDict *qdict);
 void hmp_sendkey(Monitor *mon, const QDict *qdict);
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index fd4d77e246..de675d16e7 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1660,6 +1660,40 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
 hmp_handle_error(mon, err);
 }
 
+void hmp_colo_passthrough_add(Monitor *mon, const QDict *qdict)
+{
+const char *prot = qdict_get_str(qdict, "protocol");
+L4_Connection *l4_conn = g_new0(L4_Connection, 1);
+Error *err = NULL;
+
+l4_conn->id = g_strdup(qdict_get_try_str(qdict, "id"));
+l4_conn->protocol = qapi_enum_parse(_PROTOCOL_lookup, prot, -1, );
+l4_conn->src_ip = g_strdup(qdict_get_try_str(qdict, "src_ip"));
+l4_conn->dst_ip = g_strdup(qdict_get_try_str(qdict, "dst_ip"));
+l4_conn->src_port = qdict_get_try_int(qdict, "src_port", 0);
+l4_conn->dst_port = qdict_get_try_int(qdict, "dst_port", 0);
+
+qmp_colo_passthrough_add(l4_conn, );
+hmp_handle_error(mon, err);
+}
+
+void hmp_colo_passthrough_del(Monitor *mon, const QDict *qdict)
+{
+const char *prot = qdict_get_str(qdict, "protocol");
+L4_Connection *l4_conn = g_new0(L4_Connection, 1);
+Error *err = NULL;
+
+l4_conn->id = g_strdup(qdict_get_try_str(qdict, "id"));
+l4_conn->protocol = qapi_enum_parse(_PROTOCOL_lookup, prot, -1, );
+l4_conn->src_ip = g_strdup(qdict_get_try_str(qdict, "src_ip"));
+l4_conn->dst_ip = g_strdup(qdict_get_try_str(qdict, "dst_ip"));
+l4_conn->src_port = qdict_get_try_int(qdict, "src_port", 0);
+l4_conn->dst_port = qdict_get_try_int(qdict, "dst_port", 0);
+
+qmp_colo_passthrough_del(l4_conn, );
+hmp_handle_error(mon, err);
+}
+
 void hmp_object_add(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
-- 
2.25.1




[PATCH V2 2/7] qapi/net.json: Add L4_Connection definition

2021-03-02 Thread Zhang Chen
From: Zhang Chen 

Add L4_Connection struct for other QMP commands.
Except protocol field is necessary, other fields are optional.

Signed-off-by: Zhang Chen 
---
 qapi/net.json | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/qapi/net.json b/qapi/net.json
index dc4c87dc7b..b4958447f2 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -744,3 +744,29 @@
 ##
 { 'enum': 'IP_PROTOCOL', 'data': [ 'tcp', 'udp', 'dccp', 'sctp', 'udplite',
 'icmp', 'igmp', 'ipv6' ] }
+
+##
+# @L4_Connection:
+#
+# Layer 4 network connection.
+#
+# Just for IPv4.
+#
+# @protocol: Transport layer protocol like TCP/UDP...
+#
+# @id: For specific module with Qemu object ID, If there is no such part,
+#  it means global rules.
+#
+# @src_ip: Source IP.
+#
+# @dst_ip: Destination IP.
+#
+# @src_port: Source port.
+#
+# @dst_port: Destination port.
+#
+# Since: 6.0
+##
+{ 'struct': 'L4_Connection',
+  'data': { 'protocol': 'IP_PROTOCOL', '*id': 'str', '*src_ip': 'str', 
'*dst_ip': 'str',
+'*src_port': 'int', '*dst_port': 'int' } }
-- 
2.25.1




[PATCH V2 1/7] qapi/net.json: Add IP_PROTOCOL definition

2021-03-02 Thread Zhang Chen
From: Zhang Chen 

Add IP_PROTOCOL as enum include TCP,UDP, ICMP... for other QMP commands.

Signed-off-by: Zhang Chen 
---
 qapi/net.json | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/qapi/net.json b/qapi/net.json
index c31748c87f..dc4c87dc7b 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -714,3 +714,33 @@
 ##
 { 'event': 'FAILOVER_NEGOTIATED',
   'data': {'device-id': 'str'} }
+
+##
+# @IP_PROTOCOL:
+#
+# Transport layer protocol.
+#
+# Just for IPv4.
+#
+# @tcp: Transmission Control Protocol.
+#
+# @udp: User Datagram Protocol.
+#
+# @dccp: Datagram Congestion Control Protocol.
+#
+# @sctp: Stream Control Transmission Protocol.
+#
+# @udplite: Lightweight User Datagram Protocol.
+#
+# @icmp: Internet Control Message Protocol.
+#
+# @igmp: Internet Group Management Protocol.
+#
+# @ipv6: IPv6 Encapsulation.
+#
+# TODO: Need to add more transport layer protocol.
+#
+# Since: 6.0
+##
+{ 'enum': 'IP_PROTOCOL', 'data': [ 'tcp', 'udp', 'dccp', 'sctp', 'udplite',
+'icmp', 'igmp', 'ipv6' ] }
-- 
2.25.1




[PATCH V2 3/7] qapi/net: Add new QMP command for COLO passthrough

2021-03-02 Thread Zhang Chen
From: Zhang Chen 

Since the real user scenario does not need COLO to monitor all traffic.
Add colo-passthrough-add and colo-passthrough-del to maintain
a COLO network passthrough list.

Signed-off-by: Zhang Chen 
---
 net/net.c | 10 ++
 qapi/net.json | 40 
 2 files changed, 50 insertions(+)

diff --git a/net/net.c b/net/net.c
index e1035f21d1..037dcc5973 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1151,6 +1151,16 @@ void qmp_netdev_del(const char *id, Error **errp)
 qemu_del_net_client(nc);
 }
 
+void qmp_colo_passthrough_add(L4_Connection *conn, Error **errp)
+{
+/* Setup passthrough connection */
+}
+
+void qmp_colo_passthrough_del(L4_Connection *conn, Error **errp)
+{
+/* Delete passthrough connection */
+}
+
 static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
 {
 char *str;
diff --git a/qapi/net.json b/qapi/net.json
index b4958447f2..e0c6e1d8f3 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -770,3 +770,43 @@
 { 'struct': 'L4_Connection',
   'data': { 'protocol': 'IP_PROTOCOL', '*id': 'str', '*src_ip': 'str', 
'*dst_ip': 'str',
 '*src_port': 'int', '*dst_port': 'int' } }
+
+##
+# @colo-passthrough-add:
+#
+# Add passthrough entry according to customer's needs in COLO-compare.
+#
+# Returns: Nothing on success
+#
+# Since: 6.0
+#
+# Example:
+#
+# -> { "execute": "colo-passthrough-add",
+#  "arguments": { "protocol": "tcp", "id": "object0", "src_ip": 
"192.168.1.1",
+#  "dst_ip": "192.168.1.2", "src_port": 1234, "dst_port": 4321 } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'colo-passthrough-add', 'boxed': true,
+ 'data': 'L4_Connection' }
+
+##
+# @colo-passthrough-del:
+#
+# Delete passthrough entry according to customer's needs in COLO-compare.
+#
+# Returns: Nothing on success
+#
+# Since: 6.0
+#
+# Example:
+#
+# -> { "execute": "colo-passthrough-del",
+#  "arguments": { "protocol": "tcp", "id": "object0", "src_ip": 
"192.168.1.1",
+#  "dst_ip": "192.168.1.2", "src_port": 1234, "dst_port": 4321 } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'colo-passthrough-del', 'boxed': true,
+ 'data': 'L4_Connection' }
-- 
2.25.1




RE: [PATCH v3 02/21] sd: emmc: Add support for eMMC cards

2021-03-02 Thread Sai Pavan Boddu
Hi Cedric,
> -Original Message-
> From: Cédric Le Goater 
> Sent: Monday, March 1, 2021 4:32 PM
> To: Sai Pavan Boddu ; Markus Armbruster
> ; Kevin Wolf ; Max Reitz
> ; Vladimir Sementsov-Ogievskiy
> ; Eric Blake ; Joel Stanley
> ; Vincent Palatin ; Dr. David Alan
> Gilbert ; Thomas Huth ; Stefan
> Hajnoczi ; Peter Maydell ;
> Alistair Francis ; Edgar Iglesias 
> ;
> Luc Michel ; Paolo Bonzini
> 
> Cc: qemu-bl...@nongnu.org; qemu-devel@nongnu.org; Sai Pavan Boddu
> 
> Subject: Re: [PATCH v3 02/21] sd: emmc: Add support for eMMC cards
> 
> On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> > Add eMMC device built on top of SD card.
> >
> > Signed-off-by: Sai Pavan Boddu 
> > ---
> >  include/hw/sd/sd.h |  2 ++
> >  hw/sd/sd.c | 20 
> >  2 files changed, 22 insertions(+)
> >
> > diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index
> > 05ef9b7..b402dad 100644
> > --- a/include/hw/sd/sd.h
> > +++ b/include/hw/sd/sd.h
> > @@ -90,6 +90,8 @@ typedef struct {
> >  } SDRequest;
> >
> >
> > +#define TYPE_EMMC "emmc"
> > +OBJECT_DECLARE_SIMPLE_TYPE(EMMCState, EMMC)
> >  #define TYPE_SD_CARD "sd-card"
> >  OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index 74b9162..a23af6d 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -108,6 +108,7 @@ struct SDState {
> >  uint8_t spec_version;
> >  BlockBackend *blk;
> >  bool spi;
> > +bool emmc;
> >
> >  /* Runtime changeables */
> >
> > @@ -143,6 +144,10 @@ struct SDState {
> >  bool cmd_line;
> >  };
> >
> > +struct EMMCState {
> > +SDState parent;
> > +};
> > +
> >  static void sd_realize(DeviceState *dev, Error **errp);
> >
> >  static const char *sd_state_name(enum SDCardStates state) @@ -2105,6
> > +2110,13 @@ static void sd_instance_init(Object *obj)
> >  sd->ocr_power_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > sd_ocr_powerup, sd);  }
> >
> > +static void emmc_instance_init(Object *obj) {
> > +SDState *sd = SD_CARD(obj);
> > +
> > +sd->emmc = true;
> > +}
> I think field 'emmc' would fit better in SDCardClass since it is a device 
> constant.
> You should not need 'struct EMMCState'. So something like below.
> Then you can add handlers for specific emmc commands.
> 
> Thanks,
> 
> C.
> 
> 
> diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index
> 47360ba4ee98..80e7cd526a57 100644
> --- a/include/hw/sd/sd.h
> +++ b/include/hw/sd/sd.h
> @@ -93,6 +93,8 @@ typedef struct {
>  #define TYPE_SD_CARD "sd-card"
>  OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
> 
> +#define TYPE_EMMC "emmc"
> +
>  struct SDCardClass {
>  /*< private >*/
>  DeviceClass parent_class;
> @@ -124,6 +126,8 @@ struct SDCardClass {
>  void (*enable)(SDState *sd, bool enable);
>  bool (*get_inserted)(SDState *sd);
>  bool (*get_readonly)(SDState *sd);
> +
> +bool emmc;
>  };
> 
>  #define TYPE_SD_BUS "sd-bus"
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 660026f2a667..95608f11b36e 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -2447,9 +2447,24 @@ static const TypeInfo sd_info = {
>  .instance_finalize = sd_instance_finalize,  };
> 
> +static void emmc_class_init(ObjectClass *klass, void *data) {
> +SDCardClass *sc = SD_CARD_CLASS(klass);
> +
> +sc->emmc = true;
> +}
> +
> +static const TypeInfo emmc_info = {
> +.name = TYPE_EMMC,
> +.parent = TYPE_SD_CARD,
> +.instance_size = sizeof(SDState),
> +.class_init = emmc_class_init,
> +};
> +
[Sai Pavan Boddu] Yes, I see your point. Let me try, I was preferring a simpler 
approach just to not disturb the code much but lets see how this workout.

Thanks,
Sai Pavan
>  static void sd_register_types(void)
>  {
>  type_register_static(_info);
> +type_register_static(_info);
>  }
> 
>  type_init(sd_register_types)



RE: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence

2021-03-02 Thread Sai Pavan Boddu
Hi David,

> -Original Message-
> From: Dr. David Alan Gilbert 
> Sent: Monday, March 1, 2021 4:12 PM
> To: Sai Pavan Boddu 
> Cc: Markus Armbruster ; Kevin Wolf
> ; Max Reitz ; Vladimir Sementsov-
> Ogievskiy ; Eric Blake ;
> Joel Stanley ; Cédric Le Goater ; Vincent
> Palatin ; Thomas Huth ; Stefan
> Hajnoczi ; Peter Maydell ;
> Alistair Francis ; Edgar Iglesias 
> ;
> Luc Michel ; Paolo Bonzini
> ; qemu-bl...@nongnu.org; qemu-devel@nongnu.org;
> Sai Pavan Boddu 
> Subject: Re: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence
> 
> * Sai Pavan Boddu (sai.pavan.bo...@xilinx.com) wrote:
> > eMMC cards support tuning sequence for entering HS200 mode.
> >
> > Signed-off-by: Sai Pavan Boddu 
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  hw/sd/sd.c | 47 +++
> >  1 file changed, 47 insertions(+)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index bf963ec..174c28e 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -1386,6 +1386,14 @@ static sd_rsp_type_t
> sd_normal_command(SDState *sd, SDRequest req)
> >  }
> >  break;
> >
> > +case 21:/* CMD21: mmc SEND TUNING_BLOCK */
> > +if (sd->emmc && (sd->state == sd_transfer_state)) {
> > +sd->state = sd_sendingdata_state;
> > +sd->data_offset = 0;
> > +return sd_r1;
> > +}
> > +break;
> > +
> >  case 23:/* CMD23: SET_BLOCK_COUNT */
> >  if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
> >  break;
> > @@ -2120,6 +2128,30 @@ static const uint8_t
> sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
> >  0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
> >  };
> >
> > +#define EXCSD_BUS_WIDTH_OFFSET 183
> > +#define BUS_WIDTH_8_MASK0x4
> > +#define BUS_WIDTH_4_MASK0x2
> > +#define MMC_TUNING_BLOCK_SIZE   128
> > +
> > +static const uint8_t mmc_tunning_block_pattern[128] = {
> > +   0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
> > +   0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
> > +   0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
> > +   0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
> > +   0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
> > +   0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
> > +   0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
> > +   0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
> > +   0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
> > +   0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
> > +   0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
> > +   0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
> > +   0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
> > +   0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
> > +   0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
> > +   0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
> 
> Where does this magic pattern come from?  Is it part of some spec?
[Sai Pavan Boddu] Yes its part of JEDEC eMMC spec. It's the tuning sequence for 
HS200 mode.

Regards,
Sai Pavan
> 
> Dave
> 
> > +};
> > +
> >  uint8_t sd_read_byte(SDState *sd)
> >  {
> >  /* TODO: Append CRCs */
> > @@ -2213,6 +2245,21 @@ uint8_t sd_read_byte(SDState *sd)
> >  ret = sd_tuning_block_pattern[sd->data_offset++];
> >  break;
> >
> > +case 21:/* CMD21: SEND_TUNNING_BLOCK (MMC) */
> > +if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
> > +sd->state = sd_transfer_state;
> > +}
> > +if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
> > +ret = mmc_tunning_block_pattern[sd->data_offset++];
> > +} else {
> > +/* Return LSB Nibbles of two byte from the 8bit tuning block
> > + * for 4bit mode
> > + */
> > +ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
> > +ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) 
> > << 4;
> > +}
> > +break;
> > +
> >  case 22:/* ACMD22: SEND_NUM_WR_BLOCKS */
> >  ret = sd->data[sd->data_offset ++];
> >
> > --
> > 2.7.4
> >
> --
> Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




[Bug 1916501] Re: qemu-img convert segfaults with specific URL

2021-03-02 Thread Julio Faracco
Guys, when I run with valgrind, I always get this when segfault occurs:

==74885== Invalid read of size 8
==74885==at 0x1DC87D: curl_multi_do (curl.c:410)
==74885==by 0x23B949: aio_dispatch_handler (aio-posix.c:329)
==74885==by 0x23C0A1: aio_dispatch_handlers (aio-posix.c:372)
==74885==by 0x23C0A1: aio_dispatch (aio-posix.c:382)
==74885==by 0x22DEE1: aio_ctx_dispatch (async.c:306)
==74885==by 0x4A854DA: g_main_context_dispatch (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6600.1)
==74885==by 0x236097: glib_pollfds_poll (main-loop.c:232)
==74885==by 0x236097: os_host_main_loop_wait (main-loop.c:255)
==74885==by 0x236097: main_loop_wait (main-loop.c:531)
==74885==by 0x13E30C: convert_do_copy (qemu-img.c:2139)
==74885==by 0x13E30C: img_convert (qemu-img.c:2738)
==74885==by 0x134660: main (qemu-img.c:5536)
==74885==  Address 0xf9779b8 is 8 bytes inside a block of size 32 free'd
==74885==at 0x483DA3F: free (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==74885==by 0x1DC5BC: curl_clean_state (curl.c:529)
==74885==by 0x1DC5BC: curl_clean_state (curl.c:515)
==74885==by 0x1DC7E4: curl_multi_check_completion (curl.c:385)
==74885==by 0x1DC8D4: curl_multi_do (curl.c:414)
==74885==by 0x23B949: aio_dispatch_handler (aio-posix.c:329)
==74885==by 0x23C0A1: aio_dispatch_handlers (aio-posix.c:372)
==74885==by 0x23C0A1: aio_dispatch (aio-posix.c:382)
==74885==by 0x22DEE1: aio_ctx_dispatch (async.c:306)
==74885==by 0x4A854DA: g_main_context_dispatch (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6600.1)
==74885==by 0x236097: glib_pollfds_poll (main-loop.c:232)
==74885==by 0x236097: os_host_main_loop_wait (main-loop.c:255)
==74885==by 0x236097: main_loop_wait (main-loop.c:531)
==74885==by 0x13E30C: convert_do_copy (qemu-img.c:2139)
==74885==by 0x13E30C: img_convert (qemu-img.c:2738)
==74885==by 0x134660: main (qemu-img.c:5536)
==74885==  Block was alloc'd at
==74885==at 0x483ED99: calloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==74885==by 0x4A8B5A0: g_malloc0 (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6600.1)
==74885==by 0x1DBDC9: curl_sock_cb (curl.c:156)
==74885==by 0x55402C1: ??? (in 
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.6.0)
==74885==by 0x5543D33: ??? (in 
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.6.0)
==74885==by 0x5543E77: curl_multi_socket_action (in 
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.6.0)
==74885==by 0x1DC8C7: curl_multi_do_locked (curl.c:403)
==74885==by 0x1DC8C7: curl_multi_do (curl.c:413)
==74885==by 0x23B949: aio_dispatch_handler (aio-posix.c:329)
==74885==by 0x23C0A1: aio_dispatch_handlers (aio-posix.c:372)
==74885==by 0x23C0A1: aio_dispatch (aio-posix.c:382)
==74885==by 0x22DEE1: aio_ctx_dispatch (async.c:306)
==74885==by 0x4A854DA: g_main_context_dispatch (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6600.1)
==74885==by 0x236097: glib_pollfds_poll (main-loop.c:232)
==74885==by 0x236097: os_host_main_loop_wait (main-loop.c:255)
==74885==by 0x236097: main_loop_wait (main-loop.c:531)

It seems that sockets are being free'd in a non-expecting situation.

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

Title:
  qemu-img convert segfaults with specific URL

Status in QEMU:
  New

Bug description:
  Using what is currently the latest git: (commit
  00d8ba9e0d62ea1c7459c25aeabf9c8bb7659462, Date:   Sun Feb 21 19:52:58
  2021 +)

  $ ./build/qemu-img convert -f qcow2 -O raw 
https://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img out.img
  Segmentation fault (core dumped)

  
  Backtrace for convenience:
  qemu: qemu_mutex_lock_impl: Invalid argument

  Thread 1 "qemu-img" received signal SIGABRT, Aborted.
  0x777c59d5 in raise () from /lib64/libc.so.6
  (gdb) bt
  #0  0x777c59d5 in raise () from /lib64/libc.so.6
  #1  0x777ae8a4 in abort () from /lib64/libc.so.6
  #2  0x556705b2 in error_exit (err=, 
msg=msg@entry=0x556b69a0 <__func__.31> "qemu_mutex_lock_impl") at 
../util/qemu-thread-posix.c:37
  #3  0x55670945 in qemu_mutex_lock_impl (mutex=0x55ae3758, 
file=0x556827a2 "../block/curl.c", line=406) at 
../util/qemu-thread-posix.c:81
  #4  0x5559a05b in curl_multi_do (arg=0x55aad2a0) at 
../block/curl.c:406
  #5  0x5566193a in aio_dispatch_handler (ctx=ctx@entry=0x55737790, 
node=0x55b14150) at ../util/aio-posix.c:329
  #6  0x55662072 in aio_dispatch_handlers (ctx=0x55737790) at 
../util/aio-posix.c:372
  #7  aio_dispatch (ctx=0x55737790) at ../util/aio-posix.c:382
  #8  0x5564442e in aio_ctx_dispatch (source=, 
callback=, user_data=) at ../util/async.c:306
  #9  0x77cfda9f in g_main_context_dispatch () from 

[PATCH V2] file-posix: allow -EBUSY -EINVAL errors during write zeros on block

2021-03-02 Thread ChangLimin
Since Linux 5.10, write zeros to a multipath device using
ioctl(fd, BLKZEROOUT, range) with cache none or directsync return -EBUSY
permanently.

Similar to handle_aiocb_write_zeroes_unmap, handle_aiocb_write_zeroes_block
allow -EBUSY and -EINVAL errors during ioctl(fd, BLKZEROOUT, range).

Reference commit in Linux 5.10:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=384d87ef2c954fc58e6c5fd8253e4a1984f5fe02

Signed-off-by: ChangLimin 
---
 block/file-posix.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 05079b40ca..4e132db929 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1629,8 +1629,13 @@ static ssize_t 
handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
 } while (errno == EINTR);

 ret = translate_err(-errno);
-if (ret == -ENOTSUP) {
-s->has_write_zeroes = false;
+switch (ret) {
+case -ENOTSUP:
+s->has_write_zeroes = false; /* fall through */
+case -EINVAL:
+case -EBUSY:
+return -ENOTSUP;
+break;
 }
 }
 #endif
--
2.27.0



Re: [PATCH v1] vhost-vdpa: Set discarding of RAM broken when initializing the backend

2021-03-02 Thread Jason Wang



On 2021/3/3 12:21 上午, David Hildenbrand wrote:

Similar to VFIO, vDPA will go ahead an map+pin all guest memory. Memory
that used to be discarded will get re-populated and if we
discard+re-access memory after mapping+pinning, the pages mapped into the
vDPA IOMMU will go out of sync with the actual pages mapped into the user
space page tables.

Set discarding of RAM broken such that:
- virtio-mem and vhost-vdpa run mutually exclusive
- virtio-balloon is inhibited and no memory discards will get issued

In the future, we might be able to support coordinated discarding of RAM
as used by virtio-mem and as planned for VFIO.

Cc: Jason Wang 
Cc: Michael S. Tsirkin 
Cc: Cindy Lu 
Signed-off-by: David Hildenbrand 



Acked-by: Jason Wang 



---

Note: I was not actually able to reproduce/test as I fail to get the
vdpa_sim/vdpa_sim_net running on upstream Linux (whetever vdpa, vhost_vdpa,
vdpa_sim, vdpa_sim_net modules I probe, and in which order, no vdpa devices
appear under /sys/bus/vdpa/devices/ or /dev/).



The device creation was switched to use vdpa tool that is integrated 
with iproue2[1].


[1] 
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=143610383da51e1f868c6d5a2a5e2fb552293d18





---
  hw/virtio/vhost-vdpa.c | 13 +
  1 file changed, 13 insertions(+)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 01d2101d09..86058d4041 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -278,6 +278,17 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void 
*opaque)
  uint64_t features;
  assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
  trace_vhost_vdpa_init(dev, opaque);
+int ret;
+
+/*
+ * Similar to VFIO, we end up pinning all guest memory and have to
+ * disable discarding of RAM.
+ */
+ret = ram_block_discard_disable(true);
+if (ret) {
+error_report("Cannot set discarding of RAM broken");
+return ret;
+}



vDPA will support non pinning (shared VM) backend soon[2]. So I guess we 
need a flag to be advertised to usersapce then we can conditionly enable 
the discard here.


[2] https://www.spinics.net/lists/netdev/msg723944.html

Thanks


  
  v = opaque;

  v->dev = dev;
@@ -302,6 +313,8 @@ static int vhost_vdpa_cleanup(struct vhost_dev *dev)
  memory_listener_unregister(>listener);
  
  dev->opaque = NULL;

+ram_block_discard_disable(false);
+
  return 0;
  }
  





[PATCH v3] target/s390x: Implement the MVPG condition-code-option bit

2021-03-02 Thread Richard Henderson
If the CCO bit is set, MVPG should not generate an exception but
report page translation faults via a CC code.

Create a new helper, access_prepare_nf, which can use probe_access_flags
in non-faulting mode, and then handle watchpoints.

Cc: David Hildenbrand 
Reported-by: Thomas Huth 
Signed-off-by: Richard Henderson 
---
 target/s390x/mem_helper.c | 87 ---
 1 file changed, 64 insertions(+), 23 deletions(-)

diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 25cfede806..b397333c0b 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -130,28 +130,62 @@ typedef struct S390Access {
 int mmu_idx;
 } S390Access;
 
+static bool access_prepare_nf(S390Access *access, CPUS390XState *env,
+  bool nofault, vaddr vaddr1, int size,
+  MMUAccessType access_type,
+  int mmu_idx, uintptr_t ra)
+{
+void *haddr1, *haddr2 = NULL;
+int size1, size2;
+vaddr vaddr2 = 0;
+int flags;
+
+assert(size > 0 && size <= 4096);
+
+size1 = MIN(size, -(vaddr1 | TARGET_PAGE_MASK)),
+size2 = size - size1;
+
+flags = probe_access_flags(env, vaddr1, access_type, mmu_idx,
+   nofault, , ra);
+if (unlikely(size2)) {
+/* The access crosses page boundaries. */
+vaddr2 = wrap_address(env, vaddr1 + size1);
+flags |= probe_access_flags(env, vaddr2, access_type, mmu_idx,
+nofault, , ra);
+}
+
+if (unlikely(flags & TLB_INVALID_MASK)) {
+return false;
+}
+if (unlikely(flags & TLB_WATCHPOINT)) {
+/* S390 does not presently use transaction attributes. */
+cpu_check_watchpoint(env_cpu(env), vaddr1, size,
+ MEMTXATTRS_UNSPECIFIED,
+ (access_type == MMU_DATA_STORE
+  ? BP_MEM_WRITE : BP_MEM_READ), ra);
+}
+
+*access = (S390Access) {
+.vaddr1 = vaddr1,
+.vaddr2 = vaddr2,
+.haddr1 = haddr1,
+.haddr2 = haddr2,
+.size1 = size1,
+.size2 = size2,
+.mmu_idx = mmu_idx
+};
+return true;
+}
+
 static S390Access access_prepare(CPUS390XState *env, vaddr vaddr, int size,
  MMUAccessType access_type, int mmu_idx,
  uintptr_t ra)
 {
-S390Access access = {
-.vaddr1 = vaddr,
-.size1 = MIN(size, -(vaddr | TARGET_PAGE_MASK)),
-.mmu_idx = mmu_idx,
-};
-
-g_assert(size > 0 && size <= 4096);
-access.haddr1 = probe_access(env, access.vaddr1, access.size1, access_type,
- mmu_idx, ra);
-
-if (unlikely(access.size1 != size)) {
-/* The access crosses page boundaries. */
-access.vaddr2 = wrap_address(env, vaddr + access.size1);
-access.size2 = size - access.size1;
-access.haddr2 = probe_access(env, access.vaddr2, access.size2,
- access_type, mmu_idx, ra);
-}
-return access;
+S390Access ret;
+bool ok = access_prepare_nf(, env, false, vaddr, size,
+access_type, mmu_idx, ra);
+assert(ok);
+return ret;
 }
 
 /* Helper to handle memset on a single page. */
@@ -845,8 +879,10 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, 
uint64_t r1, uint64_t r2)
 const int mmu_idx = cpu_mmu_index(env, false);
 const bool f = extract64(r0, 11, 1);
 const bool s = extract64(r0, 10, 1);
+const bool cco = extract64(r0, 8, 1);
 uintptr_t ra = GETPC();
 S390Access srca, desta;
+bool ok;
 
 if ((f && s) || extract64(r0, 12, 4)) {
 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
@@ -858,13 +894,18 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, 
uint64_t r1, uint64_t r2)
 /*
  * TODO:
  * - Access key handling
- * - CC-option with surpression of page-translation exceptions
  * - Store r1/r2 register identifiers at real location 162
  */
-srca = access_prepare(env, r2, TARGET_PAGE_SIZE, MMU_DATA_LOAD, mmu_idx,
-  ra);
-desta = access_prepare(env, r1, TARGET_PAGE_SIZE, MMU_DATA_STORE, mmu_idx,
-   ra);
+ok = access_prepare_nf(, env, cco, r2, TARGET_PAGE_SIZE,
+   MMU_DATA_LOAD, mmu_idx, ra);
+if (!ok) {
+return 2;
+}
+ok = access_prepare_nf(, env, cco, r1, TARGET_PAGE_SIZE,
+   MMU_DATA_STORE, mmu_idx, ra);
+if (!ok) {
+return 1;
+}
 access_memmove(env, , , ra);
 return 0; /* data moved */
 }
-- 
2.25.1




Re: [PATCH v2] target/s390x: Implement the MVPG condition-code-option bit

2021-03-02 Thread Richard Henderson

On 3/2/21 5:39 PM, Richard Henderson wrote:

+ok = probe_access_flags(env, vaddr1, access_type, mmu_idx,
+nofault, , ra);


Bah, I confused myself and remembered the wrong interface.
Expect a v3.

r~



Re: [PATCH v2] target/s390x: Implement the MVPG condition-code-option bit

2021-03-02 Thread Richard Henderson

On 3/2/21 5:39 PM, Richard Henderson wrote:

If the CCO bit is set, MVPG should not generate an exception
but report page translation faults via a CC code.  Create a new
helper, access_prepare_nf, which can use probe_access_flags in
non-faulting mode.

Cc: David Hildenbrand
Reported-by: Thomas Huth
Signed-off-by: Richard Henderson
---
  target/s390x/mem_helper.c | 76 +++
  1 file changed, 53 insertions(+), 23 deletions(-)


Oh, I meant to say that this is untested, but is what I was
talking about wrt performing only a single lookup per page.


r~



[PATCH v2] target/s390x: Implement the MVPG condition-code-option bit

2021-03-02 Thread Richard Henderson
If the CCO bit is set, MVPG should not generate an exception
but report page translation faults via a CC code.  Create a new
helper, access_prepare_nf, which can use probe_access_flags in
non-faulting mode.

Cc: David Hildenbrand 
Reported-by: Thomas Huth 
Signed-off-by: Richard Henderson 
---
 target/s390x/mem_helper.c | 76 +++
 1 file changed, 53 insertions(+), 23 deletions(-)

diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 25cfede806..9e359b0d19 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -130,28 +130,51 @@ typedef struct S390Access {
 int mmu_idx;
 } S390Access;
 
+static bool access_prepare_nf(S390Access *access, CPUS390XState *env,
+  bool nofault, vaddr vaddr1, int size,
+  MMUAccessType access_type,
+  int mmu_idx, uintptr_t ra)
+{
+void *haddr1, *haddr2 = NULL;
+int size1, size2;
+vaddr vaddr2 = 0;
+bool ok;
+
+g_assert(size > 0 && size <= 4096);
+
+size1 = MIN(size, -(vaddr1 | TARGET_PAGE_MASK)),
+size2 = size - size1;
+
+ok = probe_access_flags(env, vaddr1, access_type, mmu_idx,
+nofault, , ra);
+if (likely(ok) && unlikely(size2)) {
+/* The access crosses page boundaries. */
+vaddr2 = wrap_address(env, vaddr1 + size1);
+ok = probe_access_flags(env, vaddr2, access_type, mmu_idx,
+nofault, , ra);
+}
+
+*access = (S390Access) {
+.vaddr1 = vaddr1,
+.vaddr2 = vaddr2,
+.haddr1 = haddr1,
+.haddr2 = haddr2,
+.size1 = size1,
+.size2 = size2,
+.mmu_idx = mmu_idx
+};
+return ok;
+}
+
 static S390Access access_prepare(CPUS390XState *env, vaddr vaddr, int size,
  MMUAccessType access_type, int mmu_idx,
  uintptr_t ra)
 {
-S390Access access = {
-.vaddr1 = vaddr,
-.size1 = MIN(size, -(vaddr | TARGET_PAGE_MASK)),
-.mmu_idx = mmu_idx,
-};
-
-g_assert(size > 0 && size <= 4096);
-access.haddr1 = probe_access(env, access.vaddr1, access.size1, access_type,
- mmu_idx, ra);
-
-if (unlikely(access.size1 != size)) {
-/* The access crosses page boundaries. */
-access.vaddr2 = wrap_address(env, vaddr + access.size1);
-access.size2 = size - access.size1;
-access.haddr2 = probe_access(env, access.vaddr2, access.size2,
- access_type, mmu_idx, ra);
-}
-return access;
+S390Access ret;
+bool ok = access_prepare_nf(, env, false, vaddr, size,
+access_type, mmu_idx, ra);
+g_assert(ok);
+return ret;
 }
 
 /* Helper to handle memset on a single page. */
@@ -845,8 +868,10 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, 
uint64_t r1, uint64_t r2)
 const int mmu_idx = cpu_mmu_index(env, false);
 const bool f = extract64(r0, 11, 1);
 const bool s = extract64(r0, 10, 1);
+const bool cco = extract64(r0, 8, 1);
 uintptr_t ra = GETPC();
 S390Access srca, desta;
+bool ok;
 
 if ((f && s) || extract64(r0, 12, 4)) {
 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
@@ -858,13 +883,18 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, 
uint64_t r1, uint64_t r2)
 /*
  * TODO:
  * - Access key handling
- * - CC-option with surpression of page-translation exceptions
  * - Store r1/r2 register identifiers at real location 162
  */
-srca = access_prepare(env, r2, TARGET_PAGE_SIZE, MMU_DATA_LOAD, mmu_idx,
-  ra);
-desta = access_prepare(env, r1, TARGET_PAGE_SIZE, MMU_DATA_STORE, mmu_idx,
-   ra);
+ok = access_prepare_nf(, env, cco, r2, TARGET_PAGE_SIZE,
+   MMU_DATA_LOAD, mmu_idx, ra);
+if (!ok) {
+return 2;
+}
+ok = access_prepare_nf(, env, cco, r1, TARGET_PAGE_SIZE,
+   MMU_DATA_STORE, mmu_idx, ra);
+if (!ok) {
+return 1;
+}
 access_memmove(env, , , ra);
 return 0; /* data moved */
 }
-- 
2.25.1




Re: [PATCH v4 6/6] hw/ppc: Add emulation of Genesi/bPlan Pegasos II

2021-03-02 Thread David Gibson
On Tue, Mar 02, 2021 at 10:13:19AM +0100, BALATON Zoltan wrote:
> On Tue, 2 Mar 2021, Philippe Mathieu-Daudé wrote:
> > On 2/25/21 8:47 PM, BALATON Zoltan wrote:
> > > Add new machine called pegasos2 emulating the Genesi/bPlan Pegasos II,
> > > a PowerPC board based on the Marvell MV64361 system controller and the
> > > VIA VT8231 integrated south bridge/superio chips. It can run Linux,
> > > AmigaOS and a wide range of MorphOS versions. Currently a firmware ROM
> > > image is needed to boot and only MorphOS has a video driver to produce
> > > graphics output. Linux could work too but distros that supported this
> > > machine don't include usual video drivers so those only run with
> > > serial console for now.
> > > 
> > > Signed-off-by: BALATON Zoltan 
> > > ---
> > >  MAINTAINERS |  10 ++
> > >  default-configs/devices/ppc-softmmu.mak |   2 +
> > >  hw/ppc/Kconfig  |  10 ++
> > >  hw/ppc/meson.build  |   2 +
> > >  hw/ppc/pegasos2.c   | 144 
> > >  5 files changed, 168 insertions(+)
> > >  create mode 100644 hw/ppc/pegasos2.c
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 9b2aa18e1f..a023217702 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -1345,6 +1345,16 @@ F: pc-bios/canyonlands.dt[sb]
> > >  F: pc-bios/u-boot-sam460ex-20100605.bin
> > >  F: roms/u-boot-sam460ex
> > > 
> > > +pegasos2
> > > +M: BALATON Zoltan 
> > > +R: David Gibson 
> > 
> > :)
> 
> He's also listed as reviewer for the sam460ex and I think as the PPC
> maintainer probably should be notified about changes that's why this is
> here. I guess he can complain or submit a patch later if he wants to be
> removed.

Including me as reviewer is fine for now.

> 
> > > +L: qemu-...@nongnu.org
> > > +S: Maintained
> > > +F: hw/ppc/pegasos2.c
> > > +F: hw/pci-host/mv64361.c
> > > +F: hw/pci-host/mv643xx.h
> > > +F: include/hw/pci-host/mv64361.h
> > > +
> > >  RISC-V Machines
> > >  ---
> > >  OpenTitan
> > > diff --git a/default-configs/devices/ppc-softmmu.mak 
> > > b/default-configs/devices/ppc-softmmu.mak
> > > index 61b78b844d..4535993d8d 100644
> > > --- a/default-configs/devices/ppc-softmmu.mak
> > > +++ b/default-configs/devices/ppc-softmmu.mak
> > > @@ -14,5 +14,7 @@ CONFIG_SAM460EX=y
> > >  CONFIG_MAC_OLDWORLD=y
> > >  CONFIG_MAC_NEWWORLD=y
> > > 
> > > +CONFIG_PEGASOS2=y
> > > +
> > >  # For PReP
> > >  CONFIG_PREP=y
> > > diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
> > > index d11dc30509..98d8dd1a84 100644
> > > --- a/hw/ppc/Kconfig
> > > +++ b/hw/ppc/Kconfig
> > > @@ -68,6 +68,16 @@ config SAM460EX
> > >  select USB_OHCI
> > >  select FDT_PPC
> > > 
> > > +config PEGASOS2
> > > +bool
> > > +select MV64361
> > > +select VT82C686
> > > +select IDE_VIA
> > > +select SMBUS_EEPROM
> > > +# These should come with VT82C686
> > > +select APM
> > > +select ACPI_X86
> > > +
> > >  config PREP
> > >  bool
> > >  imply PCI_DEVICES
> > > diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
> > > index 218631c883..86d6f379d1 100644
> > > --- a/hw/ppc/meson.build
> > > +++ b/hw/ppc/meson.build
> > > @@ -78,5 +78,7 @@ ppc_ss.add(when: 'CONFIG_E500', if_true: files(
> > >  ))
> > >  # PowerPC 440 Xilinx ML507 reference board.
> > >  ppc_ss.add(when: 'CONFIG_VIRTEX', if_true: files('virtex_ml507.c'))
> > > +# Pegasos2
> > > +ppc_ss.add(when: 'CONFIG_PEGASOS2', if_true: files('pegasos2.c'))
> > > 
> > >  hw_arch += {'ppc': ppc_ss}
> > > diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> > > new file mode 100644
> > > index 00..427e884fbf
> > > --- /dev/null
> > > +++ b/hw/ppc/pegasos2.c
> > > @@ -0,0 +1,144 @@
> > > +/*
> > > + * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
> > > + *
> > > + * Copyright (c) 2018-2020 BALATON Zoltan
> > 
> > 2018-2021
> 
> Not really. I've done this between Christmas of 2018 and 2020. This year
> were only changes for upstreaming and review comments so I preserved the
> dates to record when the actual code was written.

Fwiw, Red Hat's internal guidelines have the opinion that the years
don't matter that much and are usually out of date, so they suggest
simply "Copyright Red Hat." for contributions from us. IANAL.

> > > + *
> > > + * This work is licensed under the GNU GPL license version 2 or later.
> > > + *
> > > + */
> > > +
> > > +#include "qemu/osdep.h"
> > > +#include "qemu-common.h"
> > > +#include "qemu/units.h"
> > > +#include "qapi/error.h"
> > > +#include "hw/hw.h"
> > > +#include "hw/ppc/ppc.h"
> > > +#include "hw/sysbus.h"
> > > +#include "hw/pci/pci_host.h"
> > > +#include "hw/irq.h"
> > > +#include "hw/pci-host/mv64361.h"
> > > +#include "hw/isa/vt82c686.h"
> > > +#include "hw/ide/pci.h"
> > > +#include "hw/i2c/smbus_eeprom.h"
> > > +#include "hw/qdev-properties.h"
> > > +#include "sysemu/reset.h"
> > > +#include "hw/boards.h"
> > > +#include "hw/loader.h"
> > > 

[Bug 1917542] [NEW] qemu-img crash on M1 Mac

2021-03-02 Thread Changhee Oh
Public bug reported:

1. Symptom
$ qemu-img create -f qcow2 disk.qcow2 10G
[1] 72373 killed qemu-img create -f qcow2 disk.qcow2 10G

2. System environment
CPU: Apple M1
OS: Big Sur 11.2.2
qemu:  stable 5.2.0 (Binary installed by homebrew)

3. Kernel logs
$ sudo log show --predicate ‘eventMessage LIKE “qemu”’ --debug
ntID Dirty: 1 Event: com.apple.stability.crash 
{“appVersion”:"???",“exceptionType”:1,“logwritten”:1,“process”:“qemu-img”,“responsibleApp”:“iTerm2”,“timestamp”:1614666875993238}
2021-03-02 15:36:52.728210+0900 0xfb308 Default 0x0 0 0 kernel: CODE SIGNING: 
cs_invalid_page(0x10293): p=72373[qemu-img] final status 0x23000200, 
denying page sending SIGKILL
2021-03-02 15:36:52.728222+0900 0xfb308 Default 0x0 0 0 kernel: CODE SIGNING: 
process 72373[qemu-img]: rejecting invalid page at address 0x10293 from 
offset 0x0 in file “/opt/homebrew/Cellar/libssh/0.9.5_1/lib/libssh.4.8.6.dylib” 
(cs_mtime:1614297740.413435328 == mtime:1614297740.413435328) (signed:1 
validated:1 tainted:1 nx:0 wpmapped:0 dirty:0 depth:0)
2021-03-02 15:36:52.728477+0900 0xfab09 Default 0x0 919 0 ReportCrash: Parsing 
corpse data for process qemu-img [pid 72373]
2021-03-02 15:36:52.884736+0900 0xfab09 Default 0x0 919 0 ReportCrash: 
(CrashReporterSupport) Saved crash report for qemu-img[72373] version 0 to 
qemu-img_2021-03-02-153652_.crash

4. Crash logs
$ sudo cat 
/Users//Library/Logs/DiagnosticReports/qemu-img_2021-03-02-153652_.crash
Process: qemu-img [72373]
Path: /opt/homebrew/*/qemu-img
Identifier: qemu-img
Version: 0
Code Type: ARM-64 (Native)
Parent Process: zsh [67484]
Responsible: iTerm2 [556]
User ID: 501

Date/Time: 2021-03-02 15:36:52.710 +0900
OS Version: macOS 11.2.2 (20D80)
Report Version: 12
Anonymous UUID: AF87D5F0-2BED-EB72-1DC8-26F63A24DA7C

Sleep/Wake UUID: 3862EA39-132E-42BD-A4BB-5A36F36607F1

Time Awake Since Boot: 89000 seconds
Time Since Wake: 520 seconds

System Integrity Protection: enabled

Crashed Thread: 0

Exception Type: EXC_BAD_ACCESS (Code Signature Invalid)
Exception Codes: 0x0032, 0x00010293
Exception Note: EXC_CORPSE_NOTIFY

Termination Reason: Namespace CODESIGNING, Code 0x2

kernel messages:

VM Regions Near 0x10293:
__LINKEDIT 102908000-10293 [ 160K] r–/r-- SM=COW /opt/homebrew/*
→ mapped file 10293-102934000 [ 16K] r–/r-x SM=PRV Object_id=fc8cc3db
__TEXT 1029bc000-102a38000 [ 496K] r-x/r-x SM=COW /usr/lib/dyld

Application Specific Information:
dyld: launch, loading dependent libraries
/opt/homebrew/opt/libssh/lib/libssh.4.dylib

Thread 0 Crashed:
0 dyld 0x000102a18780 bcmp + 16
1 dyld 0x0001029d9408 
ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, 
unsigned char const*, unsigned long, long long, ImageLoader::LinkContext 
const&) + 136
2 dyld 0x0001029e03b8 ImageLoaderMachOCompressed::instantiateFromFile(char 
const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned 
long long, stat const&, unsigned int, unsigned int, linkedit_data_command 
const*, encryption_info_command const*, ImageLoader::LinkContext const&) + 268
3 dyld 0x0001029d7ffc ImageLoaderMachO::instantiateFromFile(char const*, 
int, unsigned char const*, unsigned long, unsigned long long, unsigned long 
long, stat const&, ImageLoader::LinkContext const&) + 172
4 dyld 0x0001029c0290 dyld::loadPhase6(int, stat const&, char const*, 
dyld::LoadContext const&) + 668
5 dyld 0x0001029c8dd8 dyld::loadPhase5(char const*, char const*, 
dyld::LoadContext const&, unsigned int&, std::__1::vector >) + 1328
6 dyld 0x0001029c8824 dyld::loadPhase4(char const, char const*, 
dyld::LoadContext const&, unsigned int&, std::__1::vector >) + 208
7 dyld 0x0001029c8530 dyld::loadPhase3(char const, char const*, 
dyld::LoadContext const&, unsigned int&, std::__1::vector >) + 1100
8 dyld 0x0001029c7cf0 dyld::loadPhase1(char const, char const*, 
dyld::LoadContext const&, unsigned int&, std::__1::vector >) + 212
9 dyld 0x0001029bfe0c dyld::loadPhase0(char const, char const*, 
dyld::LoadContext const&, unsigned int&, std::__1::vector >) + 468
10 dyld 0x0001029bf9b0 dyld::load(char const, dyld::LoadContext const&, 
unsigned int&) + 196
11 dyld 0x0001029c977c dyld::libraryLocator(char const*, bool, char const*, 
ImageLoader::RPathChain const*, unsigned int&) + 56
12 dyld 0x0001029d39d4 
ImageLoader::recursiveLoadLibraries(ImageLoader::LinkContext const&, bool, 
ImageLoader::RPathChain const&, char const*) + 344
13 dyld 0x0001029d21ac ImageLoader::link(ImageLoader::LinkContext const&, 
bool, bool, bool, ImageLoader::RPathChain const&, char const*) + 160
14 dyld 0x0001029c25f4 dyld::link(ImageLoader*, bool, bool, 
ImageLoader::RPathChain const&, unsigned int) + 328
15 dyld 0x0001029c4928 dyld::_main(macho_header const*, unsigned long, int, 
char const**, char const**, char const**, unsigned long*) + 6764
16 dyld 0x0001029bd258 dyldbootstrap::start(dyld3::MachOLoaded const*, int, 
char const**, 

[PATCH 2/2] tests/acceptance: Test ast2600 machine

2021-03-02 Thread Joel Stanley
This tests a Debian multi-soc arm32 Linux kernel on the AST2600 based
Tacoma BMC machine.

There is no root file system so the test terminates when boot reaches
the stage where it attempts and fails to mount something.

Signed-off-by: Joel Stanley 
---
 tests/acceptance/boot_linux_console.py | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 2f46a08fdc10..6b7d7f5df984 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -1094,6 +1094,32 @@ def do_test_arm_aspeed(self, image):
 # self.wait_for_console_pattern("login:")
 self.vm.shutdown()
 
+def test_arm_ast2600_debian(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:tacoma-bmc
+"""
+deb_url = ('http://snapshot.debian.org/archive/debian/'
+   '20210302T203551Z/'
+   'pool/main/l/linux/'
+   'linux-image-5.10.0-3-armmp_5.10.13-1_armhf.deb')
+deb_hash = 
'db40d32fe39255d05482bea48d72467b67d6225bb2a2a4d6f618cb8976f1e09e'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash,
+algorithm='sha256')
+kernel_path = self.extract_from_deb(deb_path, 
'/boot/vmlinuz-5.10.0-3-armmp')
+dtb_path = self.extract_from_deb(deb_path,
+
'/usr/lib/linux-image-5.10.0-3-armmp/aspeed-bmc-opp-tacoma.dtb')
+
+self.vm.set_console()
+self.vm.add_args('-kernel', kernel_path,
+ '-dtb', dtb_path)
+self.vm.launch()
+self.wait_for_console_pattern("Booting Linux on physical CPU 0xf00")
+self.wait_for_console_pattern("SMP: Total of 2 processors activated")
+self.wait_for_console_pattern("ftgmac100 1e67.ftgmac eth0: irq")
+self.wait_for_console_pattern("VFS: Cannot open root device")
+self.vm.shutdown()
+
 def test_m68k_mcf5208evb(self):
 """
 :avocado: tags=arch:m68k
-- 
2.30.1




[PATCH 0/2] tests/acceptance: Test Aspeed ARM machines

2021-03-02 Thread Joel Stanley
This adds tests for the Aspeed ARM SoCs. The AST2400 and AST2500 tests
use OpenBMC images from that project, fetched from github releases. The
AST2600 test uses a Debian arm32 kernel.

Note that the ast2600 test will fail if [1] is not applied. I have
tested locally and all seems good.

I note that checkpatch warns about a couple of lines over 80 columns in
this file.  Can we agree to relax this restriction for this file, as it
helps the readability of the constants such as sha hashes and URLs?

[1] 
https://lore.kernel.org/qemu-devel/20210303010505.635621-1-j...@jms.id.au/T/#u

Joel Stanley (2):
  tests/acceptance: Test ast2400 and ast2500 machines
  tests/acceptance: Test ast2600 machine

 tests/acceptance/boot_linux_console.py | 72 ++
 1 file changed, 72 insertions(+)

-- 
2.30.1




[PATCH 1/2] tests/acceptance: Test ast2400 and ast2500 machines

2021-03-02 Thread Joel Stanley
Test MTD images from the OpenBMC project on AST2400 and AST2500 SoCs
from ASPEED, by booting Palmetto and Romulus BMC machines.

The images are fetched from OpenBMC's release directory on github.

Co-developed-by: Cédric Le Goater 
Signed-off-by: Joel Stanley 
---
 tests/acceptance/boot_linux_console.py | 46 ++
 1 file changed, 46 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index eb012867997f..2f46a08fdc10 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -1048,6 +1048,52 @@ def test_arm_vexpressa9(self):
 self.vm.add_args('-dtb', self.workdir + '/day16/vexpress-v2p-ca9.dtb')
 self.do_test_advcal_2018('16', tar_hash, 'winter.zImage')
 
+def test_arm_ast2400_palmetto_openbmc_v2_9_0(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:palmetto-bmc
+"""
+
+image_url = 
('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
+ 'obmc-phosphor-image-palmetto.static.mtd')
+image_hash = 
('3e13bbbc28e424865dc42f35ad672b10f2e82cdb11846bb28fa625b48beafd0d')
+image_path = self.fetch_asset(image_url, asset_hash=image_hash,
+  algorithm='sha256')
+
+self.do_test_arm_aspeed(image_path)
+
+def test_arm_ast2500_romulus_openbmc_v2_9_0(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:romulus-bmc
+"""
+
+image_url = 
('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
+ 'obmc-phosphor-image-romulus.static.mtd')
+image_hash = 
('820341076803f1955bc31e647a512c79f9add4f5233d0697678bab4604c7bb25')
+image_path = self.fetch_asset(image_url, asset_hash=image_hash,
+  algorithm='sha256')
+
+self.do_test_arm_aspeed(image_path)
+
+def do_test_arm_aspeed(self, image):
+self.vm.set_console()
+self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
+ '-net', 'nic')
+self.vm.launch()
+
+self.wait_for_console_pattern("U-Boot 2016.07")
+self.wait_for_console_pattern("## Loading kernel from FIT Image at 
2008")
+self.wait_for_console_pattern("Starting kernel ...")
+self.wait_for_console_pattern("Booting Linux on physical CPU 0x0")
+self.wait_for_console_pattern(
+"aspeed-smc 1e62.spi: read control register: 203b0641")
+self.wait_for_console_pattern("ftgmac100 1e66.ethernet eth0: irq ")
+self.wait_for_console_pattern("systemd[1]: Set hostname to")
+# This often takes longer than the 90s timeout
+# self.wait_for_console_pattern("login:")
+self.vm.shutdown()
+
 def test_m68k_mcf5208evb(self):
 """
 :avocado: tags=arch:m68k
-- 
2.30.1




[PATCH] arm/ast2600: Fix SMP booting with -kernel

2021-03-02 Thread Joel Stanley
The ast2600 machines do not have PSCI firmware, so this property should
have never been set. Removing this node fixes SMP booting Linux kernels
that have PSCI enabled, as Linux fails to find PSCI in the device tree
and falls back to the soc-specific method for enabling secondary CPUs.

The comment is out of date as Qemu has supported -kernel booting since
9bb6d14081ce ("aspeed: Add boot stub for smp booting"), in v5.1.

Fixes: f25c0ae1079d ("aspeed/soc: Add AST2600 support")
Signed-off-by: Joel Stanley 
---
 hw/arm/aspeed_ast2600.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bf31ca351feb..49b00763864c 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -241,8 +241,6 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 
 /* CPU */
 for (i = 0; i < sc->num_cpus; i++) {
-object_property_set_int(OBJECT(>cpu[i]), "psci-conduit",
-QEMU_PSCI_CONDUIT_SMC, _abort);
 if (sc->num_cpus > 1) {
 object_property_set_int(OBJECT(>cpu[i]), "reset-cbar",
 ASPEED_A7MPCORE_ADDR, _abort);
@@ -253,11 +251,6 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 object_property_set_int(OBJECT(>cpu[i]), "cntfrq", 112500,
 _abort);
 
-/*
- * TODO: the secondary CPUs are started and a boot helper
- * is needed when using -kernel
- */
-
 if (!qdev_realize(DEVICE(>cpu[i]), NULL, errp)) {
 return;
 }
-- 
2.30.1




Re: [PATCH v2 8/8] hw/vfio/pci-quirks: Replace the word 'blacklist'

2021-03-02 Thread Philippe Mathieu-Daudé
On 3/2/21 10:55 PM, Alex Williamson wrote:
> On Fri,  5 Feb 2021 18:18:17 +0100
> Philippe Mathieu-Daudé  wrote:
> 
>> Follow the inclusive terminology from the "Conscious Language in your
>> Open Source Projects" guidelines [*] and replace the word "blacklist"
>> appropriately.
>>
>> [*] https://github.com/conscious-lang/conscious-lang-docs/blob/main/faq.md
>>
>> Reviewed-by: Alex Williamson 
>> Acked-by: Alex Williamson 
>> Reviewed-by: Daniel P. Berrangé 
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>  hw/vfio/pci.h|  2 +-
>>  hw/vfio/pci-quirks.c | 14 +++---
>>  hw/vfio/pci.c|  4 ++--
>>  hw/vfio/trace-events |  2 +-
>>  4 files changed, 11 insertions(+), 11 deletions(-)
> 
> I thought someone might grab the whole series, but since that hasn't
> happened yet, I've queued this one.  Thanks,

Thanks :)




Re: [PATCH] vfio: Fix vfio_listener_log_sync function name typo

2021-03-02 Thread Alex Williamson
On Fri, 4 Dec 2020 09:42:40 +0800
Zenghui Yu  wrote:

> There is an obvious typo in the function name of the .log_sync() callback.
> Spell it correctly.
> 
> Signed-off-by: Zenghui Yu 
> ---
>  hw/vfio/common.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index 6ff1daa763..d360d6f2da 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -1118,7 +1118,7 @@ static int vfio_sync_dirty_bitmap(VFIOContainer 
> *container,
> int128_get64(section->size), ram_addr);
>  }
>  
> -static void vfio_listerner_log_sync(MemoryListener *listener,
> +static void vfio_listener_log_sync(MemoryListener *listener,
>  MemoryRegionSection *section)
>  {
>  VFIOContainer *container = container_of(listener, VFIOContainer, 
> listener);
> @@ -1136,7 +1136,7 @@ static void vfio_listerner_log_sync(MemoryListener 
> *listener,
>  static const MemoryListener vfio_memory_listener = {
>  .region_add = vfio_listener_region_add,
>  .region_del = vfio_listener_region_del,
> -.log_sync = vfio_listerner_log_sync,
> +.log_sync = vfio_listener_log_sync,
>  };
>  
>  static void vfio_listener_release(VFIOContainer *container)

Sorry for the delay, queued.  Thanks,

Alex




Re: [PATCH] target/s390x: Implement the MVPG condition-code-option bit

2021-03-02 Thread David Hildenbrand


> Am 02.03.2021 um 22:46 schrieb Richard Henderson 
> :
> 
> On 3/2/21 11:25 AM, David Hildenbrand wrote:
>>> On 02.03.21 20:12, Thomas Huth wrote:
>>> If the CCO bit is set, MVPG should not generate an exception
>>> but report page translation faults via a CC code, so we have
>>> to check the translation in this case before calling the
>>> access_prepare() function.
>>> 
>>> Signed-off-by: Thomas Huth 
>>> ---
>>>   This patch is required to get Claudio's new kvm-unit-tests patches
>>>   working with TCG: https://www.spinics.net/lists/kvm/msg236784.html
>>> 
>>>   target/s390x/cpu.h | 14 ++
>>>   target/s390x/excp_helper.c | 14 --
>>>   target/s390x/mem_helper.c  | 23 ++-
>>>   3 files changed, 36 insertions(+), 15 deletions(-)
>>> 
>>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>>> index 60d434d5ed..731e2c6452 100644
>>> --- a/target/s390x/cpu.h
>>> +++ b/target/s390x/cpu.h
>>> @@ -366,6 +366,20 @@ static inline int cpu_mmu_index(CPUS390XState *env, 
>>> bool ifetch)
>>>   #endif
>>>   }
>>> +static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
>>> +{
>>> +switch (mmu_idx) {
>>> +case MMU_PRIMARY_IDX:
>>> +return PSW_ASC_PRIMARY;
>>> +case MMU_SECONDARY_IDX:
>>> +return PSW_ASC_SECONDARY;
>>> +case MMU_HOME_IDX:
>>> +return PSW_ASC_HOME;
>>> +default:
>>> +abort();
>>> +}
>>> +}
>>> +
>>>   static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong 
>>> *pc,
>>>   target_ulong *cs_base, uint32_t 
>>> *flags)
>>>   {
>>> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
>>> index ce16af394b..44bff27f8f 100644
>>> --- a/target/s390x/excp_helper.c
>>> +++ b/target/s390x/excp_helper.c
>>> @@ -105,20 +105,6 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, 
>>> int size,
>>>   #else /* !CONFIG_USER_ONLY */
>>> -static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
>>> -{
>>> -switch (mmu_idx) {
>>> -case MMU_PRIMARY_IDX:
>>> -return PSW_ASC_PRIMARY;
>>> -case MMU_SECONDARY_IDX:
>>> -return PSW_ASC_SECONDARY;
>>> -case MMU_HOME_IDX:
>>> -return PSW_ASC_HOME;
>>> -default:
>>> -abort();
>>> -}
>>> -}
>>> -
>>>   bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>>>  MMUAccessType access_type, int mmu_idx,
>>>  bool probe, uintptr_t retaddr)
>>> diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
>>> index 25cfede806..c7037adf2c 100644
>>> --- a/target/s390x/mem_helper.c
>>> +++ b/target/s390x/mem_helper.c
>>> @@ -855,10 +855,31 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t 
>>> r0, uint64_t r1, uint64_t r2)
>>>   r1 = wrap_address(env, r1 & TARGET_PAGE_MASK);
>>>   r2 = wrap_address(env, r2 & TARGET_PAGE_MASK);
>>> +/*
>>> + * If the condition-code-option (CCO) bit is set and DAT is enabled,
>>> + * we have to check for page table translation faults first:
>>> + */
>>> +#ifndef CONFIG_USER_ONLY
>>> +if (extract64(r0, 8, 1) && mmu_idx != MMU_REAL_IDX) {
>>> +uint64_t asc = cpu_mmu_idx_to_asc(mmu_idx);
>>> +uint64_t raddr, tec;
>>> +int flags, exc;
>>> +
>>> +exc = mmu_translate(env, r2, MMU_DATA_LOAD, asc, , , 
>>> );
>>> +if (exc) {
>>> +return 2;
>>> +}
>>> +
>>> +exc = mmu_translate(env, r1, MMU_DATA_STORE, asc, , , 
>>> );
>>> +if (exc && exc != PGM_PROTECTION) {
>>> +return 1;
>>> +}
>>> +}
>>> +#endif
>>> +
>> This way you always need two additional translations and don't even check if 
>> we have something in the TLB. While this works, it's quite inefficient.
>> Using probe_access_flags() we can actually lookup the tlb/fill the tlb but 
>> get an error instead of a fault. We could e.g., extent probe_access() to 
>> allow specifying whether we want a fault or not.
> 
> I think probe_access_flags() will do all that you need; no further extension 
> to probe_access() required.  I presume you meant access_prepare() is what you 
> meant to extend?

I was worrying about watchpoint handling etc. as done in probe_access().

But I think what you mean is we can simply do two probe_access_flags() to catch 
these special pgm interrupt, followed by existing access_prepare(). That should 
work I guess.




Re: [PATCH v2 30/42] esp: add 4 byte PDMA read and write transfers

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit :
> The MacOS toolbox ROM performs 4 byte reads/writes when transferring data to
> and from the target. Since the SCSI bus is 16-bits wide, use the memory API
> to split a 4 byte access into 2 x 2 byte accesses.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 7671cc398d..1d56c99527 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -1003,7 +1003,9 @@ static const MemoryRegionOps sysbus_esp_pdma_ops = {
>  .write = sysbus_esp_pdma_write,
>  .endianness = DEVICE_NATIVE_ENDIAN,
>  .valid.min_access_size = 1,
> -.valid.max_access_size = 2,
> +.valid.max_access_size = 4,
> +.impl.min_access_size = 1,
> +.impl.max_access_size = 2,
>  };
>  
>  static const struct SCSIBusInfo esp_scsi_info = {
> @@ -1048,7 +1050,7 @@ static void sysbus_esp_realize(DeviceState *dev, Error 
> **errp)
>sysbus, "esp-regs", ESP_REGS << sysbus->it_shift);
>  sysbus_init_mmio(sbd, >iomem);
>  memory_region_init_io(>pdma, OBJECT(sysbus), 
> _esp_pdma_ops,
> -  sysbus, "esp-pdma", 2);
> +  sysbus, "esp-pdma", 4);
>  sysbus_init_mmio(sbd, >pdma);
>  
>  qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
> 

Reviewed-by: Laurent Vivier 



Re: [PATCH v2 29/42] esp: remove pdma_origin from ESPState

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit :
> Now that all data is transferred via the FIFO (ti_buf) there is no need to 
> track
> the source buffer being used for the data transfer. This also eliminates the
> need for a separate subsection for PDMA state migration.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 74 +--
>  include/hw/scsi/esp.h |  6 
>  2 files changed, 8 insertions(+), 72 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 5dcd4cd651..7671cc398d 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -127,32 +127,14 @@ static uint32_t esp_get_stc(ESPState *s)
>  return dmalen;
>  }
>  
> -static void set_pdma(ESPState *s, enum pdma_origin_id origin)
> -{
> -s->pdma_origin = origin;
> -}
> -
>  static uint8_t esp_pdma_read(ESPState *s)
>  {
>  uint8_t val;
>  
> -switch (s->pdma_origin) {
> -case TI:
> -if (s->do_cmd) {
> -val = s->cmdbuf[s->cmdlen++];
> -} else {
> -val = s->ti_buf[s->ti_rptr++];
> -}
> -break;
> -case ASYNC:
> -val = s->async_buf[0];
> -if (s->async_len > 0) {
> -s->async_len--;
> -s->async_buf++;
> -}
> -break;
> -default:
> -g_assert_not_reached();
> +if (s->do_cmd) {
> +val = s->cmdbuf[s->cmdlen++];
> +} else {
> +val = s->ti_buf[s->ti_rptr++];
>  }
>  
>  return val;
> @@ -166,23 +148,10 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  return;
>  }
>  
> -switch (s->pdma_origin) {
> -case TI:
> -if (s->do_cmd) {
> -s->cmdbuf[s->cmdlen++] = val;
> -} else {
> -s->ti_buf[s->ti_wptr++] = val;
> -}
> -break;
> -case ASYNC:
> -s->async_buf[0] = val;
> -if (s->async_len > 0) {
> -s->async_len--;
> -s->async_buf++;
> -}
> -break;
> -default:
> -g_assert_not_reached();
> +if (s->do_cmd) {
> +s->cmdbuf[s->cmdlen++] = val;
> +} else {
> +s->ti_buf[s->ti_wptr++] = val;
>  }
>  
>  dmalen--;
> @@ -232,7 +201,6 @@ static uint32_t get_cmd(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, buf, dmalen);
>  } else {
> -set_pdma(s, TI);
>  if (esp_select(s) < 0) {
>  return -1;
>  }
> @@ -411,7 +379,6 @@ static void write_response(ESPState *s)
>  s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
>  s->rregs[ESP_RSEQ] = SEQ_CD;
>  } else {
> -set_pdma(s, TI);
>  s->pdma_cb = write_response_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -522,7 +489,6 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, >cmdbuf[s->cmdlen], len);
>  } else {
> -set_pdma(s, TI);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -545,7 +511,6 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, s->async_buf, len);
>  } else {
> -set_pdma(s, TI);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -562,7 +527,6 @@ static void esp_do_dma(ESPState *s)
>  s->async_len -= len;
>  s->ti_size -= len;
>  esp_set_tc(s, esp_get_tc(s) - len);
> -set_pdma(s, TI);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  
> @@ -899,24 +863,6 @@ static bool esp_mem_accepts(void *opaque, hwaddr addr,
>  return (size == 1) || (is_write && size == 4);
>  }
>  
> -static bool esp_pdma_needed(void *opaque)
> -{
> -ESPState *s = opaque;
> -return s->dma_memory_read == NULL && s->dma_memory_write == NULL &&
> -   s->dma_enabled;
> -}
> -
> -static const VMStateDescription vmstate_esp_pdma = {
> -.name = "esp/pdma",
> -.version_id = 2,
> -.minimum_version_id = 2,
> -.needed = esp_pdma_needed,
> -.fields = (VMStateField[]) {
> -VMSTATE_INT32(pdma_origin, ESPState),
> -VMSTATE_END_OF_LIST()
> -}
> -};
> -
>  static bool esp_is_before_version_5(void *opaque, int version_id)
>  {
>  ESPState *s = ESP(opaque);
> @@ -971,10 +917,6 @@ const VMStateDescription vmstate_esp = {
>  VMSTATE_UINT32_TEST(mig_dma_left, ESPState, esp_is_before_version_5),
>  VMSTATE_END_OF_LIST()
>  },
> -.subsections = (const VMStateDescription * []) {
> -_esp_pdma,
> -NULL
> -}
>  };
>  
>  static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
> diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
> index a8d5bf8a63..6618f4e091 100644
> --- 

Re: [PATCH v2 28/42] esp: use FIFO for PDMA transfers between initiator and device

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit :
> PDMA as implemented on the Quadra 800 uses DREQ to load data into the FIFO
> up to a maximum of 16 bytes at a time. The MacOS toolbox ROM requires this
> because it mixes FIFO and PDMA transfers whilst checking the FIFO status
> and counter registers to ensure success.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 109 ++
>  1 file changed, 75 insertions(+), 34 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index b7ab5a5592..5dcd4cd651 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -134,13 +134,8 @@ static void set_pdma(ESPState *s, enum pdma_origin_id 
> origin)
>  
>  static uint8_t esp_pdma_read(ESPState *s)
>  {
> -uint32_t dmalen = esp_get_tc(s);
>  uint8_t val;
>  
> -if (dmalen == 0) {
> -return 0;
> -}
> -
>  switch (s->pdma_origin) {
>  case TI:
>  if (s->do_cmd) {
> @@ -160,10 +155,6 @@ static uint8_t esp_pdma_read(ESPState *s)
>  g_assert_not_reached();
>  }
>  
> -s->ti_size--;
> -dmalen--;
> -esp_set_tc(s, dmalen);
> -
>  return val;
>  }
>  
> @@ -194,7 +185,6 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  g_assert_not_reached();
>  }
>  
> -s->ti_size++;
>  dmalen--;
>  esp_set_tc(s, dmalen);
>  }
> @@ -290,6 +280,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, 
> uint8_t busid)
>  s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
>  s->rregs[ESP_RSEQ] = SEQ_CD;
>  esp_raise_irq(s);
> +esp_lower_drq(s);
>  }
>  
>  static void do_cmd(ESPState *s)
> @@ -447,28 +438,71 @@ static void esp_dma_done(ESPState *s)
>  static void do_dma_pdma_cb(ESPState *s)
>  {
>  int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
> +int len;
>  
>  if (s->do_cmd) {
>  s->ti_size = 0;
>  s->cmdlen = 0;
>  s->do_cmd = 0;
>  do_cmd(s);
> +esp_lower_drq(s);
>  return;
>  }
> -if (s->async_len == 0) {
> -scsi_req_continue(s->current_req);
> -/*
> - * If there is still data to be read from the device then
> - * complete the DMA operation immediately.  Otherwise defer
> - * until the scsi layer has completed.
> - */
> -if (to_device || esp_get_tc(s) != 0 || s->ti_size == 0) {
> +
> +if (to_device) {
> +/* Copy FIFO data to device */
> +len = MIN(s->ti_wptr, TI_BUFSZ);
> +memcpy(s->async_buf, s->ti_buf, len);
> +s->ti_wptr = 0;
> +s->ti_rptr = 0;
> +s->async_buf += len;
> +s->async_len -= len;
> +s->ti_size += len;
> +if (s->async_len == 0) {
> +scsi_req_continue(s->current_req);
>  return;
>  }
> -}
>  
> -/* Partially filled a scsi buffer. Complete immediately.  */
> -esp_dma_done(s);
> +if (esp_get_tc(s) == 0) {
> +esp_lower_drq(s);
> +esp_dma_done(s);
> +}
> +
> +return;
> +} else {
> +if (s->async_len == 0) {
> +if (s->current_req) {
> +scsi_req_continue(s->current_req);
> +}
> +
> +/*
> + * If there is still data to be read from the device then
> + * complete the DMA operation immediately.  Otherwise defer
> + * until the scsi layer has completed.
> + */
> +if (esp_get_tc(s) != 0 || s->ti_size == 0) {
> +return;
> +}
> +}
> +
> +if (esp_get_tc(s) != 0) {
> +/* Copy device data to FIFO */
> +s->ti_wptr = 0;
> +s->ti_rptr = 0;
> +len = MIN(s->async_len, TI_BUFSZ);
> +memcpy(s->ti_buf, s->async_buf, len);
> +s->ti_wptr += len;
> +s->async_buf += len;
> +s->async_len -= len;
> +s->ti_size -= len;
> +esp_set_tc(s, esp_get_tc(s) - len);
> +return;
> +}
> +
> +/* Partially filled a scsi buffer. Complete immediately.  */
> +esp_lower_drq(s);
> +esp_dma_done(s);
> +}
>  }
>  
>  static void esp_do_dma(ESPState *s)
> @@ -511,7 +545,7 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, s->async_buf, len);
>  } else {
> -set_pdma(s, ASYNC);
> +set_pdma(s, TI);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -520,9 +554,20 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_write) {
>  s->dma_memory_write(s->dma_opaque, s->async_buf, len);
>  } else {
> -set_pdma(s, ASYNC);
> +/* Copy device data to FIFO */
> +len = MIN(len, TI_BUFSZ - s->ti_wptr);
> +memcpy(>ti_buf[s->ti_wptr], s->async_buf, len);
> + 

Re: [PATCH v2 27/42] esp: fix PDMA target selection

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit :
> Currently the target selection for PDMA is done after the SCSI command has 
> been
> delivered which is not correct. Perform target selection as part of the 
> initial
> get_cmd() call when the command is submitted: if no target is present, don't
> raise DRQ.
> 
> If the target is present then switch to the command phase since the MacOS 
> toolbox
> ROM checks for this before attempting to submit the SCSI command.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 53 +--
>  1 file changed, 34 insertions(+), 19 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 6736e7142c..b7ab5a5592 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -243,6 +243,9 @@ static uint32_t get_cmd(ESPState *s)
>  s->dma_memory_read(s->dma_opaque, buf, dmalen);
>  } else {
>  set_pdma(s, TI);
> +if (esp_select(s) < 0) {
> +return -1;
> +}
>  esp_raise_drq(s);
>  return 0;
>  }
> @@ -257,7 +260,7 @@ static uint32_t get_cmd(ESPState *s)
>  trace_esp_get_cmd(dmalen, target);
>  
>  if (esp_select(s) < 0) {
> -return 0;
> +return -1;
>  }
>  return dmalen;
>  }
> @@ -299,9 +302,6 @@ static void do_cmd(ESPState *s)
>  
>  static void satn_pdma_cb(ESPState *s)
>  {
> -if (esp_select(s) < 0) {
> -return;
> -}
>  s->do_cmd = 0;
>  if (s->cmdlen) {
>  do_cmd(s);
> @@ -310,24 +310,28 @@ static void satn_pdma_cb(ESPState *s)
>  
>  static void handle_satn(ESPState *s)
>  {
> +int32_t cmdlen;
> +
>  if (s->dma && !s->dma_enabled) {
>  s->dma_cb = handle_satn;
>  return;
>  }
>  s->pdma_cb = satn_pdma_cb;
> -s->cmdlen = get_cmd(s);
> -if (s->cmdlen) {
> +cmdlen = get_cmd(s);
> +if (cmdlen > 0) {
> +s->cmdlen = cmdlen;
>  do_cmd(s);
> -} else {
> +} else if (cmdlen == 0) {
> +s->cmdlen = 0;
>  s->do_cmd = 1;
> +/* Target present, but no cmd yet - switch to command phase */
> +s->rregs[ESP_RSEQ] = SEQ_CD;
> +s->rregs[ESP_RSTAT] = STAT_CD;
>  }
>  }
>  
>  static void s_without_satn_pdma_cb(ESPState *s)
>  {
> -if (esp_select(s) < 0) {
> -return;
> -}
>  s->do_cmd = 0;
>  if (s->cmdlen) {
>  do_busid_cmd(s, s->cmdbuf, 0);
> @@ -336,24 +340,28 @@ static void s_without_satn_pdma_cb(ESPState *s)
>  
>  static void handle_s_without_atn(ESPState *s)
>  {
> +int32_t cmdlen;
> +
>  if (s->dma && !s->dma_enabled) {
>  s->dma_cb = handle_s_without_atn;
>  return;
>  }
>  s->pdma_cb = s_without_satn_pdma_cb;
> -s->cmdlen = get_cmd(s);
> -if (s->cmdlen) {
> +cmdlen = get_cmd(s);
> +if (cmdlen > 0) {
> +s->cmdlen = cmdlen;
>  do_busid_cmd(s, s->cmdbuf, 0);
> -} else {
> +} else if (cmdlen == 0) {
> +s->cmdlen = 0;
>  s->do_cmd = 1;
> +/* Target present, but no cmd yet - switch to command phase */
> +s->rregs[ESP_RSEQ] = SEQ_CD;
> +s->rregs[ESP_RSTAT] = STAT_CD;
>  }
>  }
>  
>  static void satn_stop_pdma_cb(ESPState *s)
>  {
> -if (esp_select(s) < 0) {
> -return;
> -}
>  s->do_cmd = 0;
>  if (s->cmdlen) {
>  trace_esp_handle_satn_stop(s->cmdlen);
> @@ -367,21 +375,28 @@ static void satn_stop_pdma_cb(ESPState *s)
>  
>  static void handle_satn_stop(ESPState *s)
>  {
> +int32_t cmdlen;
> +
>  if (s->dma && !s->dma_enabled) {
>  s->dma_cb = handle_satn_stop;
>  return;
>  }
>  s->pdma_cb = satn_stop_pdma_cb;
> -s->cmdlen = get_cmd(s);
> -if (s->cmdlen) {
> +cmdlen = get_cmd(s);
> +if (cmdlen > 0) {
>  trace_esp_handle_satn_stop(s->cmdlen);
> +s->cmdlen = cmdlen;
>  s->do_cmd = 1;
>  s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
>  s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
>  s->rregs[ESP_RSEQ] = SEQ_CD;
>  esp_raise_irq(s);
> -} else {
> +} else if (cmdlen == 0) {
> +s->cmdlen = 0;
>  s->do_cmd = 1;
> +/* Target present, but no cmd yet - switch to command phase */
> +s->rregs[ESP_RSEQ] = SEQ_CD;
> +s->rregs[ESP_RSTAT] = STAT_CD;
>  }
>  }
>  
> 

Reviewed-by: Laurent Vivier 



Re: [PATCH] MAINTAINERS: Cover docs/igd-assign.txt in VFIO section

2021-03-02 Thread Alex Williamson
On Mon, 22 Feb 2021 09:26:17 +0100
Philippe Mathieu-Daudé  wrote:

> ping?
> 
> On 2/2/21 4:56 PM, Philippe Mathieu-Daudé wrote:
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> >  MAINTAINERS | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index bcd88668bcd..838d0f14a59 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1768,6 +1768,7 @@ M: Alex Williamson 
> >  S: Supported
> >  F: hw/vfio/*
> >  F: include/hw/vfio/
> > +F: docs/igd-assign.txt
> >  
> >  vfio-ccw
> >  M: Cornelia Huck 
> >   
> 

Queued.  Thanks,

Alex




Re: [PATCH v2 8/8] hw/vfio/pci-quirks: Replace the word 'blacklist'

2021-03-02 Thread Alex Williamson
On Fri,  5 Feb 2021 18:18:17 +0100
Philippe Mathieu-Daudé  wrote:

> Follow the inclusive terminology from the "Conscious Language in your
> Open Source Projects" guidelines [*] and replace the word "blacklist"
> appropriately.
> 
> [*] https://github.com/conscious-lang/conscious-lang-docs/blob/main/faq.md
> 
> Reviewed-by: Alex Williamson 
> Acked-by: Alex Williamson 
> Reviewed-by: Daniel P. Berrangé 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/vfio/pci.h|  2 +-
>  hw/vfio/pci-quirks.c | 14 +++---
>  hw/vfio/pci.c|  4 ++--
>  hw/vfio/trace-events |  2 +-
>  4 files changed, 11 insertions(+), 11 deletions(-)

I thought someone might grab the whole series, but since that hasn't
happened yet, I've queued this one.  Thanks,

Alex

> 
> diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
> index 1574ef983f8..64777516d16 100644
> --- a/hw/vfio/pci.h
> +++ b/hw/vfio/pci.h
> @@ -197,7 +197,7 @@ void vfio_pci_write_config(PCIDevice *pdev,
>  uint64_t vfio_vga_read(void *opaque, hwaddr addr, unsigned size);
>  void vfio_vga_write(void *opaque, hwaddr addr, uint64_t data, unsigned size);
>  
> -bool vfio_blacklist_opt_rom(VFIOPCIDevice *vdev);
> +bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev);
>  void vfio_vga_quirk_setup(VFIOPCIDevice *vdev);
>  void vfio_vga_quirk_exit(VFIOPCIDevice *vdev);
>  void vfio_vga_quirk_finalize(VFIOPCIDevice *vdev);
> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
> index fc8d63c8504..81c3e30df77 100644
> --- a/hw/vfio/pci-quirks.c
> +++ b/hw/vfio/pci-quirks.c
> @@ -43,19 +43,19 @@
>  static const struct {
>  uint32_t vendor;
>  uint32_t device;
> -} romblacklist[] = {
> +} rom_denylist[] = {
>  { 0x14e4, 0x168e }, /* Broadcom BCM 57810 */
>  };
>  
> -bool vfio_blacklist_opt_rom(VFIOPCIDevice *vdev)
> +bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev)
>  {
>  int i;
>  
> -for (i = 0 ; i < ARRAY_SIZE(romblacklist); i++) {
> -if (vfio_pci_is(vdev, romblacklist[i].vendor, 
> romblacklist[i].device)) {
> -trace_vfio_quirk_rom_blacklisted(vdev->vbasedev.name,
> - romblacklist[i].vendor,
> - romblacklist[i].device);
> +for (i = 0 ; i < ARRAY_SIZE(rom_denylist); i++) {
> +if (vfio_pci_is(vdev, rom_denylist[i].vendor, 
> rom_denylist[i].device)) {
> +trace_vfio_quirk_rom_in_denylist(vdev->vbasedev.name,
> + rom_denylist[i].vendor,
> + rom_denylist[i].device);
>  return true;
>  }
>  }
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index f74be782091..759a3b1abf4 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -900,7 +900,7 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
>  
>  if (vdev->pdev.romfile || !vdev->pdev.rom_bar) {
>  /* Since pci handles romfile, just print a message and return */
> -if (vfio_blacklist_opt_rom(vdev) && vdev->pdev.romfile) {
> +if (vfio_opt_rom_in_denylist(vdev) && vdev->pdev.romfile) {
>  warn_report("Device at %s is known to cause system instability"
>  " issues during option rom execution",
>  vdev->vbasedev.name);
> @@ -927,7 +927,7 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
>  return;
>  }
>  
> -if (vfio_blacklist_opt_rom(vdev)) {
> +if (vfio_opt_rom_in_denylist(vdev)) {
>  if (dev->opts && qemu_opt_get(dev->opts, "rombar")) {
>  warn_report("Device at %s is known to cause system instability"
>  " issues during option rom execution",
> diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
> index c0e75f24b76..079f53acf28 100644
> --- a/hw/vfio/trace-events
> +++ b/hw/vfio/trace-events
> @@ -49,7 +49,7 @@ vfio_pci_emulated_sub_vendor_id(const char *name, uint16_t 
> val) "%s 0x%04x"
>  vfio_pci_emulated_sub_device_id(const char *name, uint16_t val) "%s 0x%04x"
>  
>  # pci-quirks.c
> -vfio_quirk_rom_blacklisted(const char *name, uint16_t vid, uint16_t did) "%s 
> %04x:%04x"
> +vfio_quirk_rom_in_denylist(const char *name, uint16_t vid, uint16_t did) "%s 
> %04x:%04x"
>  vfio_quirk_generic_window_address_write(const char *name, const char * 
> region_name, uint64_t data) "%s %s 0x%"PRIx64
>  vfio_quirk_generic_window_data_read(const char *name, const char * 
> region_name, uint64_t data) "%s %s 0x%"PRIx64
>  vfio_quirk_generic_window_data_write(const char *name, const char * 
> region_name, uint64_t data) "%s %s 0x%"PRIx64




Re: [PATCH v2 25/42] esp: remove CMD pdma_origin

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit :
> The cmdbuf is really just a copy of FIFO data (including extra message phase
> bytes) so its pdma_origin is effectively TI. Fortunately we already know when
> we are receiving a SCSI command since do_cmd == 1 which enables us to
> distinguish between the two cases in esp_pdma_read()/esp_pdma_write().
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 22 --
>  include/hw/scsi/esp.h |  1 -
>  2 files changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index bff330733f..921f79ae89 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -143,10 +143,11 @@ static uint8_t esp_pdma_read(ESPState *s)
>  
>  switch (s->pdma_origin) {
>  case TI:
> -val = s->ti_buf[s->ti_rptr++];
> -break;
> -case CMD:
> -val = s->cmdbuf[s->cmdlen++];
> +if (s->do_cmd) {
> +val = s->cmdbuf[s->cmdlen++];
> +} else {
> +val = s->ti_buf[s->ti_rptr++];
> +}
>  break;
>  case ASYNC:
>  val = s->async_buf[0];
> @@ -176,10 +177,11 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  
>  switch (s->pdma_origin) {
>  case TI:
> -s->ti_buf[s->ti_wptr++] = val;
> -break;
> -case CMD:
> -s->cmdbuf[s->cmdlen++] = val;
> +if (s->do_cmd) {
> +s->cmdbuf[s->cmdlen++] = val;
> +} else {
> +s->ti_buf[s->ti_wptr++] = val;
> +}
>  break;
>  case ASYNC:
>  s->async_buf[0] = val;
> @@ -240,7 +242,7 @@ static uint32_t get_cmd(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, buf, dmalen);
>  } else {
> -set_pdma(s, CMD);
> +set_pdma(s, TI);
>  esp_raise_drq(s);
>  return 0;
>  }
> @@ -471,7 +473,7 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, >cmdbuf[s->cmdlen], len);
>  } else {
> -set_pdma(s, CMD);
> +set_pdma(s, TI);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
> index 1e84b7bfb0..a8d5bf8a63 100644
> --- a/include/hw/scsi/esp.h
> +++ b/include/hw/scsi/esp.h
> @@ -17,7 +17,6 @@ typedef struct ESPState ESPState;
>  
>  enum pdma_origin_id {
>  TI,
> -CMD,
>  ASYNC,
>  };
>  
> 

Reviewed-by: Laurent Vivier 



Re: [PATCH v2 26/42] esp: rename get_cmd_cb() to esp_select()

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit :
> This better describes the purpose of the function.
> 
> Signed-off-by: Mark Cave-Ayland 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
>  hw/scsi/esp.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 921f79ae89..6736e7142c 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -199,7 +199,7 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  esp_set_tc(s, dmalen);
>  }
>  
> -static int get_cmd_cb(ESPState *s)
> +static int esp_select(ESPState *s)
>  {
>  int target;
>  
> @@ -256,7 +256,7 @@ static uint32_t get_cmd(ESPState *s)
>  }
>  trace_esp_get_cmd(dmalen, target);
>  
> -if (get_cmd_cb(s) < 0) {
> +if (esp_select(s) < 0) {
>  return 0;
>  }
>  return dmalen;
> @@ -299,7 +299,7 @@ static void do_cmd(ESPState *s)
>  
>  static void satn_pdma_cb(ESPState *s)
>  {
> -if (get_cmd_cb(s) < 0) {
> +if (esp_select(s) < 0) {
>  return;
>  }
>  s->do_cmd = 0;
> @@ -325,7 +325,7 @@ static void handle_satn(ESPState *s)
>  
>  static void s_without_satn_pdma_cb(ESPState *s)
>  {
> -if (get_cmd_cb(s) < 0) {
> +if (esp_select(s) < 0) {
>  return;
>  }
>  s->do_cmd = 0;
> @@ -351,7 +351,7 @@ static void handle_s_without_atn(ESPState *s)
>  
>  static void satn_stop_pdma_cb(ESPState *s)
>  {
> -if (get_cmd_cb(s) < 0) {
> +if (esp_select(s) < 0) {
>  return;
>  }
>  s->do_cmd = 0;
> 

Reviewed-by: Laurent Vivier 



Re: [PATCH v2 23/42] esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:29, Mark Cave-Ayland a écrit :
> This eliminates the last user of the PDMA-specific pdma_cur variable which can
> now be removed.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 23 ---
>  include/hw/scsi/esp.h |  1 -
>  2 files changed, 8 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 691a2f4bdc..50503a6f53 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -127,11 +127,9 @@ static uint32_t esp_get_stc(ESPState *s)
>  return dmalen;
>  }
>  
> -static void set_pdma(ESPState *s, enum pdma_origin_id origin,
> - uint32_t index, uint32_t len)
> +static void set_pdma(ESPState *s, enum pdma_origin_id origin, uint32_t len)
>  {
>  s->pdma_origin = origin;
> -s->pdma_cur = index;
>  s->pdma_len = len;
>  }
>  
> @@ -146,11 +144,10 @@ static uint8_t esp_pdma_read(ESPState *s)
>  
>  switch (s->pdma_origin) {
>  case TI:
> -val = s->ti_buf[s->pdma_cur++];
> +val = s->ti_buf[s->ti_rptr++];
>  break;
>  case CMD:
>  val = s->cmdbuf[s->cmdlen++];
> -s->pdma_cur++;
>  break;
>  case ASYNC:
>  val = s->async_buf[0];
> @@ -158,7 +155,6 @@ static uint8_t esp_pdma_read(ESPState *s)
>  s->async_len--;
>  s->async_buf++;
>  }
> -s->pdma_cur++;
>  break;
>  default:
>  g_assert_not_reached();
> @@ -182,11 +178,10 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  
>  switch (s->pdma_origin) {
>  case TI:
> -s->ti_buf[s->pdma_cur++] = val;
> +s->ti_buf[s->ti_wptr++] = val;
>  break;
>  case CMD:
>  s->cmdbuf[s->cmdlen++] = val;
> -s->pdma_cur++;
>  break;
>  case ASYNC:
>  s->async_buf[0] = val;
> @@ -194,7 +189,6 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  s->async_len--;
>  s->async_buf++;
>  }
> -s->pdma_cur++;
>  break;
>  default:
>  g_assert_not_reached();
> @@ -249,7 +243,7 @@ static uint32_t get_cmd(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, buf, dmalen);
>  } else {
> -set_pdma(s, CMD, 0, dmalen);
> +set_pdma(s, CMD, dmalen);
>  esp_raise_drq(s);
>  return 0;
>  }
> @@ -412,7 +406,7 @@ static void write_response(ESPState *s)
>  s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
>  s->rregs[ESP_RSEQ] = SEQ_CD;
>  } else {
> -set_pdma(s, TI, 0, 2);
> +set_pdma(s, TI, 2);
>  s->pdma_cb = write_response_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -480,7 +474,7 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, >cmdbuf[s->cmdlen], len);
>  } else {
> -set_pdma(s, CMD, s->cmdlen, len);
> +set_pdma(s, CMD, len);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -503,7 +497,7 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, s->async_buf, len);
>  } else {
> -set_pdma(s, ASYNC, 0, len);
> +set_pdma(s, ASYNC, len);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -512,7 +506,7 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_write) {
>  s->dma_memory_write(s->dma_opaque, s->async_buf, len);
>  } else {
> -set_pdma(s, ASYNC, 0, len);
> +set_pdma(s, ASYNC, len);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -858,7 +852,6 @@ static const VMStateDescription vmstate_esp_pdma = {
>  .fields = (VMStateField[]) {
>  VMSTATE_INT32(pdma_origin, ESPState),
>  VMSTATE_UINT32(pdma_len, ESPState),
> -VMSTATE_UINT32(pdma_cur, ESPState),
>  VMSTATE_END_OF_LIST()
>  }
>  };
> diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
> index 578d936214..5908d59a0a 100644
> --- a/include/hw/scsi/esp.h
> +++ b/include/hw/scsi/esp.h
> @@ -58,7 +58,6 @@ struct ESPState {
>  void (*dma_cb)(ESPState *s);
>  int pdma_origin;
>  uint32_t pdma_len;
> -uint32_t pdma_cur;
>  void (*pdma_cb)(ESPState *s);
>  
>  uint8_t mig_version_id;
> 

Reviewed-by: Laurent Vivier 



Re: [PATCH v2 24/42] esp: use in-built TC to determine PDMA transfer length

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit :
> Real hardware simply counts down using the in-built TC to determine when the
> the PDMA request is complete. Use the TC to determine the PDMA transfer length
> which then enables us to remove the redundant pdma_len variable.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 28 +---
>  include/hw/scsi/esp.h |  1 -
>  2 files changed, 13 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 50503a6f53..bff330733f 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -127,10 +127,9 @@ static uint32_t esp_get_stc(ESPState *s)
>  return dmalen;
>  }
>  
> -static void set_pdma(ESPState *s, enum pdma_origin_id origin, uint32_t len)
> +static void set_pdma(ESPState *s, enum pdma_origin_id origin)
>  {
>  s->pdma_origin = origin;
> -s->pdma_len = len;
>  }
>  
>  static uint8_t esp_pdma_read(ESPState *s)
> @@ -138,7 +137,7 @@ static uint8_t esp_pdma_read(ESPState *s)
>  uint32_t dmalen = esp_get_tc(s);
>  uint8_t val;
>  
> -if (dmalen == 0 || s->pdma_len == 0) {
> +if (dmalen == 0) {
>  return 0;
>  }
>  
> @@ -161,7 +160,6 @@ static uint8_t esp_pdma_read(ESPState *s)
>  }
>  
>  s->ti_size--;
> -s->pdma_len--;
>  dmalen--;
>  esp_set_tc(s, dmalen);
>  
> @@ -172,7 +170,7 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  {
>  uint32_t dmalen = esp_get_tc(s);
>  
> -if (dmalen == 0 || s->pdma_len == 0) {
> +if (dmalen == 0) {
>  return;
>  }
>  
> @@ -195,7 +193,6 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  }
>  
>  s->ti_size++;
> -s->pdma_len--;
>  dmalen--;
>  esp_set_tc(s, dmalen);
>  }
> @@ -243,7 +240,7 @@ static uint32_t get_cmd(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, buf, dmalen);
>  } else {
> -set_pdma(s, CMD, dmalen);
> +set_pdma(s, CMD);
>  esp_raise_drq(s);
>  return 0;
>  }
> @@ -406,7 +403,7 @@ static void write_response(ESPState *s)
>  s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
>  s->rregs[ESP_RSEQ] = SEQ_CD;
>  } else {
> -set_pdma(s, TI, 2);
> +set_pdma(s, TI);
>  s->pdma_cb = write_response_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -474,7 +471,7 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, >cmdbuf[s->cmdlen], len);
>  } else {
> -set_pdma(s, CMD, len);
> +set_pdma(s, CMD);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -497,7 +494,7 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, s->async_buf, len);
>  } else {
> -set_pdma(s, ASYNC, len);
> +set_pdma(s, ASYNC);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -506,7 +503,7 @@ static void esp_do_dma(ESPState *s)
>  if (s->dma_memory_write) {
>  s->dma_memory_write(s->dma_opaque, s->async_buf, len);
>  } else {
> -set_pdma(s, ASYNC, len);
> +set_pdma(s, ASYNC);
>  s->pdma_cb = do_dma_pdma_cb;
>  esp_raise_drq(s);
>  return;
> @@ -851,7 +848,6 @@ static const VMStateDescription vmstate_esp_pdma = {
>  .needed = esp_pdma_needed,
>  .fields = (VMStateField[]) {
>  VMSTATE_INT32(pdma_origin, ESPState),
> -VMSTATE_UINT32(pdma_len, ESPState),
>  VMSTATE_END_OF_LIST()
>  }
>  };
> @@ -950,6 +946,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr 
> addr,
>  {
>  SysBusESPState *sysbus = opaque;
>  ESPState *s = ESP(>esp);
> +uint32_t dmalen;
>  
>  trace_esp_pdma_write(size);
>  
> @@ -962,7 +959,8 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr 
> addr,
>  esp_pdma_write(s, val);
>  break;
>  }
> -if (s->pdma_len == 0 && s->pdma_cb) {
> +dmalen = esp_get_tc(s);
> +if (dmalen == 0 && s->pdma_cb) {
>  esp_lower_drq(s);
>  s->pdma_cb(s);
>  s->pdma_cb = NULL;
> @@ -979,7 +977,7 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr 
> addr,
>  
>  trace_esp_pdma_read(size);
>  
> -if (dmalen == 0 || s->pdma_len == 0) {
> +if (dmalen == 0) {
>  return 0;
>  }
>  switch (size) {
> @@ -992,7 +990,7 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr 
> addr,
>  break;
>  }
>  dmalen = esp_get_tc(s);
> -if (dmalen == 0 || (s->pdma_len == 0 && s->pdma_cb)) {
> +if (dmalen == 0 && s->pdma_cb) {
>  esp_lower_drq(s);
>  s->pdma_cb(s);
>  s->pdma_cb = NULL;
> diff 

Re: [PATCH] target/s390x: Implement the MVPG condition-code-option bit

2021-03-02 Thread Richard Henderson

On 3/2/21 11:25 AM, David Hildenbrand wrote:

On 02.03.21 20:12, Thomas Huth wrote:

If the CCO bit is set, MVPG should not generate an exception
but report page translation faults via a CC code, so we have
to check the translation in this case before calling the
access_prepare() function.

Signed-off-by: Thomas Huth 
---
  This patch is required to get Claudio's new kvm-unit-tests patches
  working with TCG: https://www.spinics.net/lists/kvm/msg236784.html

  target/s390x/cpu.h | 14 ++
  target/s390x/excp_helper.c | 14 --
  target/s390x/mem_helper.c  | 23 ++-
  3 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 60d434d5ed..731e2c6452 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -366,6 +366,20 @@ static inline int cpu_mmu_index(CPUS390XState *env, bool 
ifetch)

  #endif
  }
+static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
+{
+    switch (mmu_idx) {
+    case MMU_PRIMARY_IDX:
+    return PSW_ASC_PRIMARY;
+    case MMU_SECONDARY_IDX:
+    return PSW_ASC_SECONDARY;
+    case MMU_HOME_IDX:
+    return PSW_ASC_HOME;
+    default:
+    abort();
+    }
+}
+
  static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
  target_ulong *cs_base, uint32_t 
*flags)

  {
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index ce16af394b..44bff27f8f 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -105,20 +105,6 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,

  #else /* !CONFIG_USER_ONLY */
-static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
-{
-    switch (mmu_idx) {
-    case MMU_PRIMARY_IDX:
-    return PSW_ASC_PRIMARY;
-    case MMU_SECONDARY_IDX:
-    return PSW_ASC_SECONDARY;
-    case MMU_HOME_IDX:
-    return PSW_ASC_HOME;
-    default:
-    abort();
-    }
-}
-
  bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 25cfede806..c7037adf2c 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -855,10 +855,31 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, 
uint64_t r1, uint64_t r2)

  r1 = wrap_address(env, r1 & TARGET_PAGE_MASK);
  r2 = wrap_address(env, r2 & TARGET_PAGE_MASK);
+    /*
+ * If the condition-code-option (CCO) bit is set and DAT is enabled,
+ * we have to check for page table translation faults first:
+ */
+#ifndef CONFIG_USER_ONLY
+    if (extract64(r0, 8, 1) && mmu_idx != MMU_REAL_IDX) {
+    uint64_t asc = cpu_mmu_idx_to_asc(mmu_idx);
+    uint64_t raddr, tec;
+    int flags, exc;
+
+    exc = mmu_translate(env, r2, MMU_DATA_LOAD, asc, , , );
+    if (exc) {
+    return 2;
+    }
+
+    exc = mmu_translate(env, r1, MMU_DATA_STORE, asc, , , 
);

+    if (exc && exc != PGM_PROTECTION) {
+    return 1;
+    }
+    }
+#endif
+


This way you always need two additional translations and don't even check if we 
have something in the TLB. While this works, it's quite inefficient.


Using probe_access_flags() we can actually lookup the tlb/fill the tlb but get 
an error instead of a fault. We could e.g., extent probe_access() to allow 
specifying whether we want a fault or not.


I think probe_access_flags() will do all that you need; no further extension to 
probe_access() required.  I presume you meant access_prepare() is what you 
meant to extend?



r~



Re: [PATCH v2 22/42] esp: move PDMA length adjustments into esp_pdma_read()/esp_pdma_write()

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:29, Mark Cave-Ayland a écrit :
> Here the updates to async_len and ti_size are moved into the corresponding
> esp_pdma_read()/esp_pdma_write() function to eliminate the reference to
> pdma_cur in do_dma_pdma_cb().
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 24 ++--
>  1 file changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 91f65a5d9b..691a2f4bdc 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -153,12 +153,18 @@ static uint8_t esp_pdma_read(ESPState *s)
>  s->pdma_cur++;
>  break;
>  case ASYNC:
> -val = s->async_buf[s->pdma_cur++];
> +val = s->async_buf[0];
> +if (s->async_len > 0) {
> +s->async_len--;
> +s->async_buf++;
> +}
> +s->pdma_cur++;
>  break;
>  default:
>  g_assert_not_reached();
>  }
>  
> +s->ti_size--;
>  s->pdma_len--;
>  dmalen--;
>  esp_set_tc(s, dmalen);
> @@ -183,12 +189,18 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  s->pdma_cur++;
>  break;
>  case ASYNC:
> -s->async_buf[s->pdma_cur++] = val;
> +s->async_buf[0] = val;
> +if (s->async_len > 0) {
> +s->async_len--;
> +s->async_buf++;
> +}
> +s->pdma_cur++;
>  break;
>  default:
>  g_assert_not_reached();
>  }
>  
> +s->ti_size++;
>  s->pdma_len--;
>  dmalen--;
>  esp_set_tc(s, dmalen);
> @@ -427,7 +439,6 @@ static void esp_dma_done(ESPState *s)
>  static void do_dma_pdma_cb(ESPState *s)
>  {
>  int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
> -int len = s->pdma_cur;
>  
>  if (s->do_cmd) {
>  s->ti_size = 0;
> @@ -436,13 +447,6 @@ static void do_dma_pdma_cb(ESPState *s)
>  do_cmd(s);
>  return;
>  }
> -s->async_buf += len;
> -s->async_len -= len;
> -if (to_device) {
> -s->ti_size += len;
> -} else {
> -s->ti_size -= len;
> -}
>  if (s->async_len == 0) {
>  scsi_req_continue(s->current_req);
>  /*
> 

Reviewed-by: Laurent Vivier 



[Bug 1917442] Re: [AHCI] crash when running a GNU/Hurd guest

2021-03-02 Thread Samuel thibault
Note: this is using the rump ahci driver.

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

Title:
  [AHCI] crash when running a GNU/Hurd guest

Status in QEMU:
  New

Bug description:
  QEMU git hash = 51db2d7cf2

  Running guest OS using:

  $ gdb --args /extra/qemu/bin/qemu-system-i386 -M q35,accel=kvm -m 4096
  -net user,hostfwd=tcp::-:22 -net nic -drive
  id=udisk,file=/dev/sdd,format=raw,if=none -device ide-
  drive,drive=udisk,bootindex=1 -curses

  ...

  root@zamhurd:~# .ahcisata0 channel 5: setting WDCTL_RST failed for
  drive 0

  
  Thread 1 "qemu-system-i38" received signal SIGSEGV, Segmentation fault.
 
[Switching to Thread 0x74f7bf00 (LWP 590666)]
  ahci_commit_buf (dma=0x57335870, tx_bytes=2048) at ../hw/ide/ahci.c:1462
  1462tx_bytes += le32_to_cpu(ad->cur_cmd->status);
  (gdb) bt full
  #0  ahci_commit_buf (dma=0x57335870, tx_bytes=2048)
  at ../hw/ide/ahci.c:1462
  ad = 0x57335870
  #1  0x55893171 in dma_buf_commit (s=0x57335930, tx_bytes=2048)
  at ../hw/ide/core.c:805
  #2  0x558934f8 in ide_dma_cb (opaque=0x57335930, ret=0)
  at ../hw/ide/core.c:887
  s = 0x57335930
  n = 4
  sector_num = 4491160
  offset = 140732794753312
  stay_active = false
  prep_size = 0
  __PRETTY_FUNCTION__ = "ide_dma_cb"
  #3  0x55830720 in dma_complete (dbs=0x7ffee83d5120, ret=0)
  at ../softmmu/dma-helpers.c:121
  __PRETTY_FUNCTION__ = "dma_complete"
  #4  0x558307cd in dma_blk_cb (opaque=0x7ffee83d5120, ret=0)
  at ../softmmu/dma-helpers.c:139
  dbs = 0x7ffee83d5120
  cur_addr = 140732794753408
  cur_len = 93825013280880
  mem = 0x7ffeeccfef00
  __PRETTY_FUNCTION__ = "dma_blk_cb"
  #5  0x55d92bce in blk_aio_complete (acb=0x7ffee847bbe0)
  at ../block/block-backend.c:1412
  #6  0x55d92df0 in blk_aio_read_entry (opaque=0x7ffee847bbe0)
  at ../block/block-backend.c:1466
  acb = 0x7ffee847bbe0
  rwco = 0x7ffee847bc08
  qiov = 0x7ffee83d5180
  __PRETTY_FUNCTION__ = "blk_aio_read_entry"
  #7  0x55e85580 in coroutine_trampoline (i0=-398117056, i1=32766)
  at ../util/coroutine-ucontext.c:173
  arg = {p = 0x7ffee8453740, i = {-398117056, 32766}}
  self = 0x7ffee8453740
  co = 0x7ffee8453740
  fake_stack_save = 0x0
  #8  0x76544020 in __start_context () at /lib64/libc.so.6
  #9  0x7ffeefdfd680 in  ()
  #10 0x in  ()
  (gdb)
  (gdb) l
  1457   */
  1458  static void ahci_commit_buf(const IDEDMA *dma, uint32_t tx_bytes)
  1459  {
  1460  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
  1461  
  1462  tx_bytes += le32_to_cpu(ad->cur_cmd->status);
  1463  ad->cur_cmd->status = cpu_to_le32(tx_bytes);
  1464  }
  1465  
  1466  static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write)
  (gdb) p ad
  $1 = (AHCIDevice *) 0x57335870
  (gdb) p ad->cur_cmd
  $2 = (AHCICmdHdr *) 0x0
  (gdb)

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



Re: [PATCH v1 8/9] util/mmap-alloc: support RAM_NORESERVE via MAP_NORESERVE

2021-03-02 Thread Peter Xu
On Tue, Mar 02, 2021 at 08:01:11PM +0100, David Hildenbrand wrote:
> On 02.03.21 18:51, Peter Xu wrote:
> > On Tue, Feb 09, 2021 at 02:49:38PM +0100, David Hildenbrand wrote:
> > > +#define OVERCOMMIT_MEMORY_PATH "/proc/sys/vm/overcommit_memory"
> > > +static bool map_noreserve_effective(int fd, bool shared)
> > > +{
> > > +#if defined(__linux__)
> > > +gchar *content = NULL;
> > > +const char *endptr;
> > > +unsigned int tmp;
> > > +
> > > +/* hugetlbfs behaves differently */
> > > +if (qemu_fd_getpagesize(fd) != qemu_real_host_page_size) {
> > > +return true;
> > > +}
> > > +
> > > +/* only private shared mappings are accounted (ignoring /dev/zero) */
> > > +if (fd != -1 && shared) {
> > > +return true;
> > > +}

[1]

> > > +
> > > +if (g_file_get_contents(OVERCOMMIT_MEMORY_PATH, , NULL, 
> > > NULL) &&
> > > +!qemu_strtoui(content, , 0, ) &&
> > > +(!endptr || *endptr == '\n')) {
> > > +if (tmp == 2) {
> > > +error_report("Skipping reservation of swap space is not 
> > > supported: "
> > > + " \"" OVERCOMMIT_MEMORY_PATH "\" is \"2\"");
> > > +return false;
> > > +}
> > > +return true;
> > > +}
> > > +/* this interface has been around since Linux 2.6 */
> > > +error_report("Skipping reservation of swap space is not supported: "
> > > + " Could not read: \"" OVERCOMMIT_MEMORY_PATH "\"");
> > > +return false;
> > > +#else
> > > +return true;
> > > +#endif
> > > +}
> > 
> > I feel like this helper wants to fail gracefully for some conditions.  Could
> > you elaborate one example and attach to the commit log?
> 
> Sure. The case is "/proc/sys/vm/overcommit_memory == 2" (never overcommit)
> 
> MAP_NORESERVE is without effect and sparse memory regions are somewhat
> impossible.
> 
> > 
> > I'm also wondering whether it would worth to check the global value.  Even 
> > if
> > overcommit is globally disabled, do we (as an application process) need to 
> > care
> > about it?  I think the MAP_NORESERVE would simply be silently ignored by the
> > kernel and that seems to be design of it, otherwise would all apps who uses 
> > > MAP_NORESERVE would need to do similar things too?
> 
> Right, I want to catch the "gets silently ignored" part, because someone
> requested "reserved=off" (!default) but does not actually get what he asked
> for.
> 
> As one example, glibc manages heaps via:
> 
> a) Creating a new heap: mmap(PROT_NONE, MAP_NORESERVE) the maximum size,
> then mprotect(PROT_READ|PROT_WRITE) the initial heap size. Even if
> MAP_NORESERVE is ignored, only !PROT_NONE memory ever gets committed
> ("reserve swap space") in Linux.
> 
> b) Growing the heap via mprotect(PROT_READ|PROT_WRITE) within the existing
> mmap. This will commit memory in case MAP_NORESERVE got ignored.
> 
> c) Shrinking the heap ("discard memory") via MADV_DONTNEED *unless*
> "/proc/sys/vm/overcommit_memory == 2" - the only way to undo
> mprotect(PROT_READ|PROT_WRITE) and to un-commit memory is by doing a
> mmap(PROT_NONE, MAP_FIXED) over the problematic region.
> 
> If you're interested, you can take a look at:
> 
> malloc/arena.c
> sysdeps/unix/sysv/linux/malloc-sysdep.h:check_may_shrink_heap()

Thanks for the context.  It's interesting to know libc has such special heap
operations.

Glibc shrinks heap to save memory for the no-over-commit case, however in our
case currently we'd like to fail some users using global_overcommit=2 but
reserve=off - it means even if we don't fail the user, mmap() could also fail
if it's overcommitted. Even if this mmap() didn't fail, it'll fail very easily
later on iiuc, right?

I think it's fine to have that early failure, it just seems less helpful than
what glibc was doing which shrinks active memory for real, meanwhile there
seems to encode some very detailed OS information into this helper, so just
less charming.

Btw above [1] "fd != -1 && shared" looks weird to me.

Firstly it'll bypass overcommit_memory==2 check and return true directly, is
that right?  I thought the global will be meaningful for all memories except
hugetlbfs (in do_mmap() of Linux).

Meanwhile, I don't see why file-backed share memories is so special too..  From
your commit message, I'm not sure whether you wanted to return false instead,
however that's still not the case IIUC, since e.g. /dev/shmem still does
accounting iiuc, while MAP_NORESERVE will skip it.

-- 
Peter Xu




[PATCH] i386: Add missing cpu feature bits in EPYC-Rome model

2021-03-02 Thread Babu Moger
Found the following cpu feature bits missing from EPYC-Rome model.
ibrs: Indirect Branch Restricted Speculation
ssbd: Speculative Store Bypass Disable

These new features will be added in EPYC-Rome-v2. The -cpu help output
after the change.

x86 EPYC-Rome (alias configured by machine type)
x86 EPYC-Rome-v1  AMD EPYC-Rome Processor
x86 EPYC-Rome-v2  AMD EPYC-Rome Processor

Reported-by: Pankaj Gupta 
Signed-off-by: Babu Moger 
Signed-off-by: Pankaj Gupta 
---
 target/i386/cpu.c |   14 ++
 1 file changed, 14 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 6a53446e6a..9b5a31783d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4179,6 +4179,20 @@ static X86CPUDefinition builtin_x86_defs[] = {
 .xlevel = 0x801E,
 .model_id = "AMD EPYC-Rome Processor",
 .cache_info = _rome_cache_info,
+.versions = (X86CPUVersionDefinition[]) {
+{ .version = 1 },
+{
+.version = 2,
+.props = (PropValue[]) {
+{ "ibrs", "on" },
+{ "amd-ssbd", "on" },
+{ "model-id",
+  "AMD EPYC-Rome Processor" },
+{ /* end of list */ }
+}
+},
+{ /* end of list */ }
+}
 },
 {
 .name = "EPYC-Milan",




[PATCH v5 8/8] hw/ppc: Add emulation of Genesi/bPlan Pegasos II

2021-03-02 Thread BALATON Zoltan
Add new machine called pegasos2 emulating the Genesi/bPlan Pegasos II,
a PowerPC board based on the Marvell MV64361 system controller and the
VIA VT8231 integrated south bridge/superio chips. It can run Linux,
AmigaOS and a wide range of MorphOS versions. Currently a firmware ROM
image is needed to boot and only MorphOS has a video driver to produce
graphics output. Linux could work too but distros that supported this
machine don't include usual video drivers so those only run with
serial console for now.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS |  10 ++
 default-configs/devices/ppc-softmmu.mak |   2 +
 hw/ppc/Kconfig  |   9 ++
 hw/ppc/meson.build  |   2 +
 hw/ppc/pegasos2.c   | 144 
 5 files changed, 167 insertions(+)
 create mode 100644 hw/ppc/pegasos2.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9b2aa18e1f..a023217702 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1345,6 +1345,16 @@ F: pc-bios/canyonlands.dt[sb]
 F: pc-bios/u-boot-sam460ex-20100605.bin
 F: roms/u-boot-sam460ex
 
+pegasos2
+M: BALATON Zoltan 
+R: David Gibson 
+L: qemu-...@nongnu.org
+S: Maintained
+F: hw/ppc/pegasos2.c
+F: hw/pci-host/mv64361.c
+F: hw/pci-host/mv643xx.h
+F: include/hw/pci-host/mv64361.h
+
 RISC-V Machines
 ---
 OpenTitan
diff --git a/default-configs/devices/ppc-softmmu.mak 
b/default-configs/devices/ppc-softmmu.mak
index 61b78b844d..4535993d8d 100644
--- a/default-configs/devices/ppc-softmmu.mak
+++ b/default-configs/devices/ppc-softmmu.mak
@@ -14,5 +14,7 @@ CONFIG_SAM460EX=y
 CONFIG_MAC_OLDWORLD=y
 CONFIG_MAC_NEWWORLD=y
 
+CONFIG_PEGASOS2=y
+
 # For PReP
 CONFIG_PREP=y
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index d11dc30509..e51e0e5e5a 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -68,6 +68,15 @@ config SAM460EX
 select USB_OHCI
 select FDT_PPC
 
+config PEGASOS2
+bool
+select MV64361
+select VT82C686
+select IDE_VIA
+select SMBUS_EEPROM
+# This should come with VT82C686
+select ACPI_X86
+
 config PREP
 bool
 imply PCI_DEVICES
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 218631c883..86d6f379d1 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -78,5 +78,7 @@ ppc_ss.add(when: 'CONFIG_E500', if_true: files(
 ))
 # PowerPC 440 Xilinx ML507 reference board.
 ppc_ss.add(when: 'CONFIG_VIRTEX', if_true: files('virtex_ml507.c'))
+# Pegasos2
+ppc_ss.add(when: 'CONFIG_PEGASOS2', if_true: files('pegasos2.c'))
 
 hw_arch += {'ppc': ppc_ss}
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
new file mode 100644
index 00..0bfd0928aa
--- /dev/null
+++ b/hw/ppc/pegasos2.c
@@ -0,0 +1,144 @@
+/*
+ * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
+ *
+ * Copyright (c) 2018-2020 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/ppc/ppc.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/pci-host/mv64361.h"
+#include "hw/isa/vt82c686.h"
+#include "hw/ide/pci.h"
+#include "hw/i2c/smbus_eeprom.h"
+#include "hw/qdev-properties.h"
+#include "sysemu/reset.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "hw/fw-path-provider.h"
+#include "elf.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "sysemu/kvm.h"
+#include "kvm_ppc.h"
+#include "exec/address-spaces.h"
+#include "trace.h"
+#include "qemu/datadir.h"
+#include "sysemu/device_tree.h"
+
+#define PROM_FILENAME "pegasos2.rom"
+#define PROM_ADDR 0xfff0
+#define PROM_SIZE 0x8
+
+#define BUS_FREQ_HZ 1
+
+static void pegasos2_cpu_reset(void *opaque)
+{
+PowerPCCPU *cpu = opaque;
+
+cpu_reset(CPU(cpu));
+cpu->env.spr[SPR_HID1] = 7ULL << 28;
+}
+
+static void pegasos2_init(MachineState *machine)
+{
+PowerPCCPU *cpu = NULL;
+MemoryRegion *rom = g_new(MemoryRegion, 1);
+DeviceState *mv;
+PCIBus *pci_bus;
+PCIDevice *dev;
+I2CBus *i2c_bus;
+const char *fwname = machine->firmware ?: PROM_FILENAME;
+char *filename;
+int sz;
+uint8_t *spd_data;
+
+/* init CPU */
+cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
+if (PPC_INPUT(>env) != PPC_FLAGS_INPUT_6xx) {
+error_report("Incompatible CPU, only 6xx bus supported");
+exit(1);
+}
+
+/* Set time-base frequency */
+cpu_ppc_tb_init(>env, BUS_FREQ_HZ / 4);
+qemu_register_reset(pegasos2_cpu_reset, cpu);
+
+/* RAM */
+memory_region_add_subregion(get_system_memory(), 0, machine->ram);
+
+/* allocate and load firmware */
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, fwname);
+if (!filename) {
+error_report("Could not find firmware '%s'", fwname);
+exit(1);
+}
+

[PATCH v5 4/8] vt82c686: Introduce abstract TYPE_VIA_ISA and base vt82c686b_isa on it

2021-03-02 Thread BALATON Zoltan
To allow reusing ISA bridge emulation for vt8231_isa move the device
state of vt82c686b_isa emulation in an abstract via_isa class.

Signed-off-by: BALATON Zoltan 
---
 hw/isa/vt82c686.c| 70 ++--
 include/hw/pci/pci_ids.h |  2 +-
 2 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 72234bc4d1..5137f97f37 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -609,24 +609,48 @@ static const TypeInfo vt8231_superio_info = {
 };
 
 
-OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA)
+#define TYPE_VIA_ISA "via-isa"
+OBJECT_DECLARE_SIMPLE_TYPE(ViaISAState, VIA_ISA)
 
-struct VT82C686BISAState {
+struct ViaISAState {
 PCIDevice dev;
 qemu_irq cpu_intr;
 ViaSuperIOState *via_sio;
 };
 
+static const VMStateDescription vmstate_via = {
+.name = "via-isa",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, ViaISAState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static const TypeInfo via_isa_info = {
+.name  = TYPE_VIA_ISA,
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(ViaISAState),
+.abstract  = true,
+.interfaces= (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+};
+
 static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
 {
-VT82C686BISAState *s = opaque;
+ViaISAState *s = opaque;
 qemu_set_irq(s->cpu_intr, level);
 }
 
+/* TYPE_VT82C686B_ISA */
+
 static void vt82c686b_write_config(PCIDevice *d, uint32_t addr,
uint32_t val, int len)
 {
-VT82C686BISAState *s = VT82C686B_ISA(d);
+ViaISAState *s = VIA_ISA(d);
 
 trace_via_isa_write(addr, val, len);
 pci_default_write_config(d, addr, val, len);
@@ -636,19 +660,9 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t 
addr,
 }
 }
 
-static const VMStateDescription vmstate_via = {
-.name = "vt82c686b",
-.version_id = 1,
-.minimum_version_id = 1,
-.fields = (VMStateField[]) {
-VMSTATE_PCI_DEVICE(dev, VT82C686BISAState),
-VMSTATE_END_OF_LIST()
-}
-};
-
 static void vt82c686b_isa_reset(DeviceState *dev)
 {
-VT82C686BISAState *s = VT82C686B_ISA(dev);
+ViaISAState *s = VIA_ISA(dev);
 uint8_t *pci_conf = s->dev.config;
 
 pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0);
@@ -668,7 +682,7 @@ static void vt82c686b_isa_reset(DeviceState *dev)
 
 static void vt82c686b_realize(PCIDevice *d, Error **errp)
 {
-VT82C686BISAState *s = VT82C686B_ISA(d);
+ViaISAState *s = VIA_ISA(d);
 DeviceState *dev = DEVICE(d);
 ISABus *isa_bus;
 qemu_irq *isa_irq;
@@ -692,7 +706,7 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp)
 }
 }
 
-static void via_class_init(ObjectClass *klass, void *data)
+static void vt82c686b_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -700,28 +714,21 @@ static void via_class_init(ObjectClass *klass, void *data)
 k->realize = vt82c686b_realize;
 k->config_write = vt82c686b_write_config;
 k->vendor_id = PCI_VENDOR_ID_VIA;
-k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE;
+k->device_id = PCI_DEVICE_ID_VIA_82C686B_ISA;
 k->class_id = PCI_CLASS_BRIDGE_ISA;
 k->revision = 0x40;
 dc->reset = vt82c686b_isa_reset;
 dc->desc = "ISA bridge";
 dc->vmsd = _via;
-/*
- * Reason: part of VIA VT82C686 southbridge, needs to be wired up,
- * e.g. by mips_fuloong2e_init()
- */
+/* Reason: part of VIA VT82C686 southbridge, needs to be wired up */
 dc->user_creatable = false;
 }
 
-static const TypeInfo via_info = {
+static const TypeInfo vt82c686b_isa_info = {
 .name  = TYPE_VT82C686B_ISA,
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(VT82C686BISAState),
-.class_init= via_class_init,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
+.parent= TYPE_VIA_ISA,
+.instance_size = sizeof(ViaISAState),
+.class_init= vt82c686b_class_init,
 };
 
 
@@ -733,7 +740,8 @@ static void vt82c686b_register_types(void)
 type_register_static(_superio_info);
 type_register_static(_superio_info);
 type_register_static(_superio_info);
-type_register_static(_info);
+type_register_static(_isa_info);
+type_register_static(_isa_info);
 }
 
 type_init(vt82c686b_register_types)
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index ea28dcc850..aa3f67eaa4 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -204,7 +204,7 @@
 #define PCI_VENDOR_ID_XILINX 0x10ee
 
 #define PCI_VENDOR_ID_VIA0x1106
-#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686
+#define PCI_DEVICE_ID_VIA_82C686B_ISA

[PATCH v5 3/8] vt82c686: Add VT8231_SUPERIO based on VIA_SUPERIO

2021-03-02 Thread BALATON Zoltan
The VT8231 south bridge is very similar to VT82C686B but there are
some differences in register addresses and functionality, e.g. the
VT8231 only has one serial port. This commit adds VT8231_SUPERIO
subclass based on the abstract VIA_SUPERIO class to emulate the
superio part of VT8231.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c | 121 ++
 1 file changed, 121 insertions(+)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 9b2ffecc79..72234bc4d1 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -489,6 +489,126 @@ static const TypeInfo vt82c686b_superio_info = {
 };
 
 
+#define TYPE_VT8231_SUPERIO "vt8231-superio"
+
+static void vt8231_superio_cfg_write(void *opaque, hwaddr addr,
+ uint64_t data, unsigned size)
+{
+ViaSuperIOState *sc = opaque;
+uint8_t idx = sc->regs[0];
+
+if (addr == 0) { /* config index register */
+sc->regs[0] = data;
+return;
+}
+
+/* config data register */
+trace_via_superio_write(idx, data);
+switch (idx) {
+case 0x00 ... 0xdf:
+case 0xe7 ... 0xef:
+case 0xf0 ... 0xf1:
+case 0xf5:
+case 0xf8:
+case 0xfd:
+/* ignore write to read only registers */
+return;
+case 0xf2: /* Function select */
+{
+data &= 0x17;
+if (data & BIT(2)) { /* Serial port enable */
+ISADevice *dev = sc->superio.serial[0];
+if (!memory_region_is_mapped(sc->serial_io[0])) {
+memory_region_add_subregion(isa_address_space_io(dev),
+dev->ioport_id, sc->serial_io[0]);
+}
+} else {
+MemoryRegion *io = isa_address_space_io(sc->superio.serial[0]);
+if (memory_region_is_mapped(sc->serial_io[0])) {
+memory_region_del_subregion(io, sc->serial_io[0]);
+}
+}
+break;
+}
+case 0xf4: /* Serial port io base address */
+{
+data &= 0xfe;
+sc->superio.serial[0]->ioport_id = data << 2;
+if (memory_region_is_mapped(sc->serial_io[0])) {
+memory_region_set_address(sc->serial_io[0], data << 2);
+}
+break;
+}
+default:
+qemu_log_mask(LOG_UNIMP,
+  "via_superio_cfg: unimplemented register 0x%x\n", idx);
+break;
+}
+sc->regs[idx] = data;
+}
+
+static const MemoryRegionOps vt8231_superio_cfg_ops = {
+.read = via_superio_cfg_read,
+.write = vt8231_superio_cfg_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
+};
+
+static void vt8231_superio_reset(DeviceState *dev)
+{
+ViaSuperIOState *s = VIA_SUPERIO(dev);
+
+memset(s->regs, 0, sizeof(s->regs));
+/* Device ID */
+s->regs[0xf0] = 0x3c;
+/* Device revision */
+s->regs[0xf1] = 0x01;
+/* Function select - all disabled */
+vt8231_superio_cfg_write(s, 0, 0xf2, 1);
+vt8231_superio_cfg_write(s, 1, 0x03, 1);
+/* Serial port base addr */
+vt8231_superio_cfg_write(s, 0, 0xf4, 1);
+vt8231_superio_cfg_write(s, 1, 0xfe, 1);
+/* Parallel port base addr */
+vt8231_superio_cfg_write(s, 0, 0xf6, 1);
+vt8231_superio_cfg_write(s, 1, 0xde, 1);
+/* Floppy ctrl base addr */
+vt8231_superio_cfg_write(s, 0, 0xf7, 1);
+vt8231_superio_cfg_write(s, 1, 0xfc, 1);
+
+vt8231_superio_cfg_write(s, 0, 0, 1);
+}
+
+static void vt8231_superio_init(Object *obj)
+{
+VIA_SUPERIO(obj)->io_ops = _superio_cfg_ops;
+}
+
+static void vt8231_superio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass);
+
+dc->reset = vt8231_superio_reset;
+sc->serial.count = 1;
+sc->parallel.count = 1;
+sc->ide.count = 0; /* emulated by via-ide */
+sc->floppy.count = 1;
+}
+
+static const TypeInfo vt8231_superio_info = {
+.name  = TYPE_VT8231_SUPERIO,
+.parent= TYPE_VIA_SUPERIO,
+.instance_size = sizeof(ViaSuperIOState),
+.instance_init = vt8231_superio_init,
+.class_size= sizeof(ISASuperIOClass),
+.class_init= vt8231_superio_class_init,
+};
+
+
 OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA)
 
 struct VT82C686BISAState {
@@ -612,6 +732,7 @@ static void vt82c686b_register_types(void)
 type_register_static(_pm_info);
 type_register_static(_superio_info);
 type_register_static(_superio_info);
+type_register_static(_superio_info);
 type_register_static(_info);
 }
 
-- 
2.21.3




[PATCH v5 6/8] hw/isa/Kconfig: Add missing dependency VIA VT82C686 -> APM

2021-03-02 Thread BALATON Zoltan
From: Philippe Mathieu-Daudé 

TYPE_VIA_PM calls apm_init() in via_pm_realize(), so
requires APM to be selected.

Reported-by: BALATON Zoltan 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: BALATON Zoltan 
---
 hw/isa/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index c7f07854f7..9c026d0c51 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -47,6 +47,7 @@ config VT82C686
 select ACPI_SMBUS
 select SERIAL_ISA
 select FDC
+select APM
 
 config SMC37C669
 bool
-- 
2.21.3




Re: [PATCH v3 3/3] vfio: Avoid disabling and enabling vectors repeatedly in VFIO migration

2021-03-02 Thread Alex Williamson


MST/Marcel,

Do you have an Ack or objection to exporting msix_masked() as below?
Thanks,

Alex

On Tue, 23 Feb 2021 10:22:25 +0800
Shenming Lu  wrote:

> In VFIO migration resume phase and some guest startups, there are
> already unmasked vectors in the vector table when calling
> vfio_msix_enable(). So in order to avoid inefficiently disabling
> and enabling vectors repeatedly, let's allocate all needed vectors
> first and then enable these unmasked vectors one by one without
> disabling.
> 
> Signed-off-by: Shenming Lu 
> ---
>  hw/pci/msix.c |  2 +-
>  hw/vfio/pci.c | 20 +---
>  include/hw/pci/msix.h |  1 +
>  3 files changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/pci/msix.c b/hw/pci/msix.c
> index ae9331cd0b..e057958fcd 100644
> --- a/hw/pci/msix.c
> +++ b/hw/pci/msix.c
> @@ -131,7 +131,7 @@ static void msix_handle_mask_update(PCIDevice *dev, int 
> vector, bool was_masked)
>  }
>  }
>  
> -static bool msix_masked(PCIDevice *dev)
> +bool msix_masked(PCIDevice *dev)
>  {
>  return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & 
> MSIX_MASKALL_MASK;
>  }
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index f74be78209..088fd41926 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -569,6 +569,9 @@ static void vfio_msix_vector_release(PCIDevice *pdev, 
> unsigned int nr)
>  
>  static void vfio_msix_enable(VFIOPCIDevice *vdev)
>  {
> +PCIDevice *pdev = >pdev;
> +unsigned int nr, max_vec = 0;
> +
>  vfio_disable_interrupts(vdev);
>  
>  vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->msix->entries);
> @@ -587,11 +590,22 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev)
>   * triggering to userspace, then immediately release the vector, leaving
>   * the physical device with no vectors enabled, but MSI-X enabled, just
>   * like the guest view.
> + * If there are already unmasked vectors (in migration resume phase and
> + * some guest startups) which will be enabled soon, we can allocate all
> + * of them here to avoid inefficiently disabling and enabling vectors
> + * repeatedly later.
>   */
> -vfio_msix_vector_do_use(>pdev, 0, NULL, NULL);
> -vfio_msix_vector_release(>pdev, 0);
> +if (!msix_masked(pdev)) {
> +for (nr = 0; nr < msix_nr_vectors_allocated(pdev); nr++) {
> +if (!msix_is_masked(pdev, nr)) {
> +max_vec = nr;
> +}
> +}
> +}
> +vfio_msix_vector_do_use(pdev, max_vec, NULL, NULL);
> +vfio_msix_vector_release(pdev, max_vec);
>  
> -if (msix_set_vector_notifiers(>pdev, vfio_msix_vector_use,
> +if (msix_set_vector_notifiers(pdev, vfio_msix_vector_use,
>vfio_msix_vector_release, NULL)) {
>  error_report("vfio: msix_set_vector_notifiers failed");
>  }
> diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h
> index 4c4a60c739..b3cd88e262 100644
> --- a/include/hw/pci/msix.h
> +++ b/include/hw/pci/msix.h
> @@ -28,6 +28,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f);
>  
>  int msix_enabled(PCIDevice *dev);
>  int msix_present(PCIDevice *dev);
> +bool msix_masked(PCIDevice *dev);
>  
>  bool msix_is_masked(PCIDevice *dev, unsigned vector);
>  void msix_set_pending(PCIDevice *dev, unsigned vector);




[PATCH v5 7/8] hw/pci-host: Add emulation of Marvell MV64361 PPC system controller

2021-03-02 Thread BALATON Zoltan
The Marvell Discovery II aka. MV64361 is a PowerPC system controller
chip that is used on the pegasos2 PPC board. This adds emulation of it
that models the device enough to boot guests on this board. The
mv643xx.h header with register definitions is taken from Linux 4.15.10
only fixing white space errors, removing not needed parts and changing
formatting for QEMU coding style.

Signed-off-by: BALATON Zoltan 
---
 hw/pci-host/Kconfig   |   4 +
 hw/pci-host/meson.build   |   2 +
 hw/pci-host/mv64361.c | 966 ++
 hw/pci-host/mv643xx.h | 918 
 hw/pci-host/trace-events  |   6 +
 include/hw/pci-host/mv64361.h |   8 +
 include/hw/pci/pci_ids.h  |   1 +
 7 files changed, 1905 insertions(+)
 create mode 100644 hw/pci-host/mv64361.c
 create mode 100644 hw/pci-host/mv643xx.h
 create mode 100644 include/hw/pci-host/mv64361.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index 8b8c763c28..4a8615b2d0 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -68,3 +68,7 @@ config PCI_POWERNV
 
 config REMOTE_PCIHOST
 bool
+
+config MV64361
+bool
+select PCI
diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
index 1847c69905..3f9e716cfa 100644
--- a/hw/pci-host/meson.build
+++ b/hw/pci-host/meson.build
@@ -18,6 +18,8 @@ pci_ss.add(when: 'CONFIG_GRACKLE_PCI', if_true: 
files('grackle.c'))
 pci_ss.add(when: 'CONFIG_UNIN_PCI', if_true: files('uninorth.c'))
 # PowerPC E500 boards
 pci_ss.add(when: 'CONFIG_PPCE500_PCI', if_true: files('ppce500.c'))
+# Pegasos2
+pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c'))
 
 # ARM devices
 pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c'))
diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
new file mode 100644
index 00..d71402f8b5
--- /dev/null
+++ b/hw/pci-host/mv64361.c
@@ -0,0 +1,966 @@
+/*
+ * Marvell Discovery II MV64361 System Controller for
+ * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
+ *
+ * Copyright (c) 2018-2020 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/intc/i8259.h"
+#include "hw/qdev-properties.h"
+#include "exec/address-spaces.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "trace.h"
+#include "hw/pci-host/mv64361.h"
+#include "mv643xx.h"
+
+#define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge"
+
+static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k->vendor_id = PCI_VENDOR_ID_MARVELL;
+k->device_id = PCI_DEVICE_ID_MARVELL_MV6436X;
+k->class_id = PCI_CLASS_BRIDGE_HOST;
+/*
+ * PCI-facing part of the host bridge,
+ * not usable without the host-facing part
+ */
+dc->user_creatable = false;
+}
+
+static const TypeInfo mv64361_pcibridge_info = {
+.name  = TYPE_MV64361_PCI_BRIDGE,
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(PCIDevice),
+.class_init= mv64361_pcibridge_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+};
+
+
+#define TYPE_MV64361_PCI "mv64361-pcihost"
+OBJECT_DECLARE_SIMPLE_TYPE(MV64361PCIState, MV64361_PCI)
+
+struct MV64361PCIState {
+PCIHostState parent_obj;
+
+uint8_t index;
+MemoryRegion io;
+MemoryRegion mem;
+qemu_irq irq[PCI_NUM_PINS];
+
+uint32_t io_base;
+uint32_t io_size;
+uint32_t mem_base[4];
+uint32_t mem_size[4];
+uint64_t remap[5];
+};
+
+static int mv64361_pcihost_map_irq(PCIDevice *pci_dev, int n)
+{
+return (n + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
+}
+
+static void mv64361_pcihost_set_irq(void *opaque, int n, int level)
+{
+MV64361PCIState *s = opaque;
+qemu_set_irq(s->irq[n], level);
+}
+
+static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
+{
+MV64361PCIState *s = MV64361_PCI(dev);
+PCIHostState *h = PCI_HOST_BRIDGE(dev);
+char *name;
+
+name = g_strdup_printf("pci%d-io", s->index);
+memory_region_init(>io, OBJECT(dev), name, 0x1);
+g_free(name);
+name = g_strdup_printf("pci%d-mem", s->index);
+memory_region_init(>mem, OBJECT(dev), name, 1ULL << 32);
+g_free(name);
+name = g_strdup_printf("pci.%d", s->index);
+h->bus = pci_register_root_bus(dev, name, mv64361_pcihost_set_irq,
+   mv64361_pcihost_map_irq, dev,
+   >mem, >io, 0, 4, TYPE_PCI_BUS);
+g_free(name);
+pci_create_simple(h->bus, 0, TYPE_MV64361_PCI_BRIDGE);
+}
+
+static Property mv64361_pcihost_props[] = {
+

[PATCH v5 5/8] vt82c686: Add emulation of VT8231 south bridge

2021-03-02 Thread BALATON Zoltan
Add emulation of VT8231 south bridge ISA part based on the similar
VT82C686B but implemented in a separate subclass that holds the
differences while reusing parts that can be shared.

Signed-off-by: BALATON Zoltan 
---
 hw/isa/vt82c686.c | 84 +++
 include/hw/isa/vt82c686.h |  1 +
 include/hw/pci/pci_ids.h  |  1 +
 3 files changed, 86 insertions(+)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 5137f97f37..e0f2f2a5ce 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -8,6 +8,9 @@
  *
  * Contributions after 2012-01-13 are licensed under the terms of the
  * GNU GPL, version 2 or (at your option) any later version.
+ *
+ * VT8231 south bridge support and general clean up to allow it
+ * Copyright (c) 2018-2020 BALATON Zoltan
  */
 
 #include "qemu/osdep.h"
@@ -731,6 +734,86 @@ static const TypeInfo vt82c686b_isa_info = {
 .class_init= vt82c686b_class_init,
 };
 
+/* TYPE_VT8231_ISA */
+
+static void vt8231_write_config(PCIDevice *d, uint32_t addr,
+uint32_t val, int len)
+{
+ViaISAState *s = VIA_ISA(d);
+
+trace_via_isa_write(addr, val, len);
+pci_default_write_config(d, addr, val, len);
+if (addr == 0x50) {
+/* BIT(2): enable or disable superio config io ports */
+via_superio_io_enable(s->via_sio, val & BIT(2));
+}
+}
+
+static void vt8231_isa_reset(DeviceState *dev)
+{
+ViaISAState *s = VIA_ISA(dev);
+uint8_t *pci_conf = s->dev.config;
+
+pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0);
+pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
+pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
+
+pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
+pci_conf[0x67] = 0x08; /* Fast IR Config */
+pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
+}
+
+static void vt8231_realize(PCIDevice *d, Error **errp)
+{
+ViaISAState *s = VIA_ISA(d);
+DeviceState *dev = DEVICE(d);
+ISABus *isa_bus;
+qemu_irq *isa_irq;
+int i;
+
+qdev_init_gpio_out(dev, >cpu_intr, 1);
+isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
+isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
+  _fatal);
+isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq));
+i8254_pit_init(isa_bus, 0x40, 0, NULL);
+i8257_dma_init(isa_bus, 0);
+s->via_sio = VIA_SUPERIO(isa_create_simple(isa_bus, TYPE_VT8231_SUPERIO));
+mc146818_rtc_init(isa_bus, 2000, NULL);
+
+for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
+if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
+d->wmask[i] = 0;
+}
+}
+}
+
+static void vt8231_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k->realize = vt8231_realize;
+k->config_write = vt8231_write_config;
+k->vendor_id = PCI_VENDOR_ID_VIA;
+k->device_id = PCI_DEVICE_ID_VIA_8231_ISA;
+k->class_id = PCI_CLASS_BRIDGE_ISA;
+k->revision = 0x10;
+dc->reset = vt8231_isa_reset;
+dc->desc = "ISA bridge";
+dc->vmsd = _via;
+/* Reason: part of VIA VT8231 southbridge, needs to be wired up */
+dc->user_creatable = false;
+}
+
+static const TypeInfo vt8231_isa_info = {
+.name  = TYPE_VT8231_ISA,
+.parent= TYPE_VIA_ISA,
+.instance_size = sizeof(ViaISAState),
+.class_init= vt8231_class_init,
+};
+
 
 static void vt82c686b_register_types(void)
 {
@@ -742,6 +825,7 @@ static void vt82c686b_register_types(void)
 type_register_static(_superio_info);
 type_register_static(_isa_info);
 type_register_static(_isa_info);
+type_register_static(_isa_info);
 }
 
 type_init(vt82c686b_register_types)
diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index 0692b9a527..0f01aaa471 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -3,6 +3,7 @@
 
 #define TYPE_VT82C686B_ISA "vt82c686b-isa"
 #define TYPE_VT82C686B_PM "vt82c686b-pm"
+#define TYPE_VT8231_ISA "vt8231-isa"
 #define TYPE_VT8231_PM "vt8231-pm"
 #define TYPE_VIA_AC97 "via-ac97"
 #define TYPE_VIA_MC97 "via-mc97"
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index aa3f67eaa4..ac0c23ebc7 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -210,6 +210,7 @@
 #define PCI_DEVICE_ID_VIA_82C686B_PM 0x3057
 #define PCI_DEVICE_ID_VIA_AC97   0x3058
 #define PCI_DEVICE_ID_VIA_MC97   0x3068
+#define PCI_DEVICE_ID_VIA_8231_ISA   0x8231
 #define PCI_DEVICE_ID_VIA_8231_PM0x8235
 
 #define PCI_VENDOR_ID_MARVELL0x11ab
-- 
2.21.3




[PATCH v5 2/8] vt82c686: QOM-ify superio related functionality

2021-03-02 Thread BALATON Zoltan
Collect superio functionality and its controlling config registers
handling in an abstract VIA_SUPERIO class that is a subclass of
ISA_SUPERIO and put vt82c686b specific parts in a subclass of this
abstract class.

Signed-off-by: BALATON Zoltan 
---
 hw/isa/vt82c686.c | 240 --
 include/hw/isa/vt82c686.h |   1 -
 2 files changed, 150 insertions(+), 91 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index a3353ec5db..9b2ffecc79 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -249,12 +249,21 @@ static const TypeInfo vt8231_pm_info = {
 };
 
 
-typedef struct SuperIOConfig {
+#define TYPE_VIA_SUPERIO "via-superio"
+OBJECT_DECLARE_SIMPLE_TYPE(ViaSuperIOState, VIA_SUPERIO)
+
+struct ViaSuperIOState {
+ISASuperIODevice superio;
 uint8_t regs[0x100];
+const MemoryRegionOps *io_ops;
 MemoryRegion io;
-ISASuperIODevice *superio;
 MemoryRegion *serial_io[SUPERIO_MAX_SERIAL_PORTS];
-} SuperIOConfig;
+};
+
+static inline void via_superio_io_enable(ViaSuperIOState *s, bool enable)
+{
+memory_region_set_enabled(>io, enable);
+}
 
 static MemoryRegion *find_subregion(ISADevice *d, MemoryRegion *parent,
 int offs)
@@ -270,10 +279,76 @@ static MemoryRegion *find_subregion(ISADevice *d, 
MemoryRegion *parent,
 return mr;
 }
 
-static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data,
-  unsigned size)
+static void via_superio_realize(DeviceState *d, Error **errp)
+{
+ViaSuperIOState *s = VIA_SUPERIO(d);
+ISASuperIOClass *ic = ISA_SUPERIO_GET_CLASS(s);
+int i;
+
+assert(s->io_ops);
+ic->parent_realize(d, errp);
+if (*errp) {
+return;
+}
+/* Grab io regions of serial devices so we can control them */
+for (i = 0; i < ic->serial.count; i++) {
+ISADevice *sd = s->superio.serial[i];
+MemoryRegion *io = isa_address_space_io(sd);
+MemoryRegion *mr = find_subregion(sd, io, sd->ioport_id);
+if (!mr) {
+error_setg(errp, "Could not get io region for serial %d", i);
+return;
+}
+s->serial_io[i] = mr;
+}
+
+memory_region_init_io(>io, OBJECT(d), s->io_ops, s, "via-superio", 2);
+memory_region_set_enabled(>io, false);
+/* The floppy also uses 0x3f0 and 0x3f1 but this seems to work anyway */
+memory_region_add_subregion(isa_address_space_io(ISA_DEVICE(s)), 0x3f0,
+>io);
+}
+
+static uint64_t via_superio_cfg_read(void *opaque, hwaddr addr, unsigned size)
+{
+ViaSuperIOState *sc = opaque;
+uint8_t idx = sc->regs[0];
+uint8_t val = sc->regs[idx];
+
+if (addr == 0) {
+return idx;
+}
+if (addr == 1 && idx == 0) {
+val = 0; /* reading reg 0 where we store index value */
+}
+trace_via_superio_read(idx, val);
+return val;
+}
+
+static void via_superio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass);
+
+sc->parent_realize = dc->realize;
+dc->realize = via_superio_realize;
+}
+
+static const TypeInfo via_superio_info = {
+.name  = TYPE_VIA_SUPERIO,
+.parent= TYPE_ISA_SUPERIO,
+.instance_size = sizeof(ViaSuperIOState),
+.class_size= sizeof(ISASuperIOClass),
+.class_init= via_superio_class_init,
+.abstract  = true,
+};
+
+#define TYPE_VT82C686B_SUPERIO "vt82c686b-superio"
+
+static void vt82c686b_superio_cfg_write(void *opaque, hwaddr addr,
+uint64_t data, unsigned size)
 {
-SuperIOConfig *sc = opaque;
+ViaSuperIOState *sc = opaque;
 uint8_t idx = sc->regs[0];
 
 if (addr == 0) { /* config index register */
@@ -295,29 +370,29 @@ static void superio_cfg_write(void *opaque, hwaddr addr, 
uint64_t data,
 case 0xfd ... 0xff:
 /* ignore write to read only registers */
 return;
-case 0xe2:
+case 0xe2: /* Function select */
 {
 data &= 0x1f;
 if (data & BIT(2)) { /* Serial port 1 enable */
-ISADevice *dev = sc->superio->serial[0];
+ISADevice *dev = sc->superio.serial[0];
 if (!memory_region_is_mapped(sc->serial_io[0])) {
 memory_region_add_subregion(isa_address_space_io(dev),
 dev->ioport_id, sc->serial_io[0]);
 }
 } else {
-MemoryRegion *io = isa_address_space_io(sc->superio->serial[0]);
+MemoryRegion *io = isa_address_space_io(sc->superio.serial[0]);
 if (memory_region_is_mapped(sc->serial_io[0])) {
 memory_region_del_subregion(io, sc->serial_io[0]);
 }
 }
 if (data & BIT(3)) { /* Serial port 2 enable */
-ISADevice *dev = sc->superio->serial[1];
+ISADevice *dev = sc->superio.serial[1];
 

[PATCH v5 1/8] vt82c686: Implement control of serial port io ranges via config regs

2021-03-02 Thread BALATON Zoltan
In VIA super south bridge the io ranges of superio components
(parallel and serial ports and FDC) can be controlled by superio
config registers to set their base address and enable/disable them.
This is not easy to implement in QEMU because ISA emulation is only
designed to set io base address once on creating the device and io
ranges are registered at creation and cannot easily be disabled or
moved later.

In this patch we hack around that but only for serial ports because
those have a single io range at port base that's relatively easy to
handle and it's what guests actually use and set address different
than the default.

We do not attempt to handle controlling the parallel and FDC regions
because those have multiple io ranges so handling them would be messy
and guests either don't change their deafult or don't care. We could
even get away with disabling and not emulating them, but since they
are already there, this patch leaves them mapped at their default
address just in case this could be useful for a guest in the future.

Signed-off-by: BALATON Zoltan 
---
 hw/isa/vt82c686.c | 84 +--
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 05d084f698..a3353ec5db 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -252,8 +252,24 @@ static const TypeInfo vt8231_pm_info = {
 typedef struct SuperIOConfig {
 uint8_t regs[0x100];
 MemoryRegion io;
+ISASuperIODevice *superio;
+MemoryRegion *serial_io[SUPERIO_MAX_SERIAL_PORTS];
 } SuperIOConfig;
 
+static MemoryRegion *find_subregion(ISADevice *d, MemoryRegion *parent,
+int offs)
+{
+MemoryRegion *subregion, *mr = NULL;
+
+QTAILQ_FOREACH(subregion, >subregions, subregions_link) {
+if (subregion->addr == offs) {
+mr = subregion;
+break;
+}
+}
+return mr;
+}
+
 static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data,
   unsigned size)
 {
@@ -279,7 +295,53 @@ static void superio_cfg_write(void *opaque, hwaddr addr, 
uint64_t data,
 case 0xfd ... 0xff:
 /* ignore write to read only registers */
 return;
-/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */
+case 0xe2:
+{
+data &= 0x1f;
+if (data & BIT(2)) { /* Serial port 1 enable */
+ISADevice *dev = sc->superio->serial[0];
+if (!memory_region_is_mapped(sc->serial_io[0])) {
+memory_region_add_subregion(isa_address_space_io(dev),
+dev->ioport_id, sc->serial_io[0]);
+}
+} else {
+MemoryRegion *io = isa_address_space_io(sc->superio->serial[0]);
+if (memory_region_is_mapped(sc->serial_io[0])) {
+memory_region_del_subregion(io, sc->serial_io[0]);
+}
+}
+if (data & BIT(3)) { /* Serial port 2 enable */
+ISADevice *dev = sc->superio->serial[1];
+if (!memory_region_is_mapped(sc->serial_io[1])) {
+memory_region_add_subregion(isa_address_space_io(dev),
+dev->ioport_id, sc->serial_io[1]);
+}
+} else {
+MemoryRegion *io = isa_address_space_io(sc->superio->serial[1]);
+if (memory_region_is_mapped(sc->serial_io[1])) {
+memory_region_del_subregion(io, sc->serial_io[1]);
+}
+}
+break;
+}
+case 0xe7: /* Serial port 1 io base address */
+{
+data &= 0xfe;
+sc->superio->serial[0]->ioport_id = data << 2;
+if (memory_region_is_mapped(sc->serial_io[0])) {
+memory_region_set_address(sc->serial_io[0], data << 2);
+}
+break;
+}
+case 0xe8: /* Serial port 2 io base address */
+{
+data &= 0xfe;
+sc->superio->serial[1]->ioport_id = data << 2;
+if (memory_region_is_mapped(sc->serial_io[1])) {
+memory_region_set_address(sc->serial_io[1], data << 2);
+}
+break;
+}
 default:
 qemu_log_mask(LOG_UNIMP,
   "via_superio_cfg: unimplemented register 0x%x\n", idx);
@@ -385,6 +447,7 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp)
 DeviceState *dev = DEVICE(d);
 ISABus *isa_bus;
 qemu_irq *isa_irq;
+ISASuperIOClass *ic;
 int i;
 
 qdev_init_gpio_out(dev, >cpu_intr, 1);
@@ -394,7 +457,9 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp)
 isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq));
 i8254_pit_init(isa_bus, 0x40, 0, NULL);
 i8257_dma_init(isa_bus, 0);
-isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO);
+s->superio_cfg.superio = ISA_SUPERIO(isa_create_simple(isa_bus,
+  TYPE_VT82C686B_SUPERIO));
+ic = 

[PATCH v5 0/8] Pegasos2 emulation

2021-03-02 Thread BALATON Zoltan
Hello,

This is adding a new PPC board called pegasos2. More info on it can be
found at:

https://osdn.net/projects/qmiga/wiki/SubprojectPegasos2

Currently it needs a firmware ROM image that I cannot include due to
original copyright holder (bPlan) did not release it under a free
licence but I have plans to write a replacement in the future. With
the original board firmware it can boot MorphOS now as:

qemu-system-ppc -M pegasos2 -cdrom morphos.iso -device ati-vga,romfile="" 
-serial stdio

then enter "boot cd boot.img" at the firmware "ok" prompt as described
in the MorphOS.readme. To boot Linux use same command line with e.g.
-cdrom debian-8.11.0-powerpc-netinst.iso then enter
"boot cd install/pegasos"

The last patch adds the actual board code after previous patches
adding VT8231 and MV64361 system controller chip emulation.

Regards,
BALATON Zoltan

v5: Changes for review comments from David and Philippe

V4: Rename pegasos2_reset to pegasos2_cpu_reset
Add new files to MAINTAINERS

BALATON Zoltan (7):
  vt82c686: Implement control of serial port io ranges via config regs
  vt82c686: QOM-ify superio related functionality
  vt82c686: Add VT8231_SUPERIO based on VIA_SUPERIO
  vt82c686: Introduce abstract TYPE_VIA_ISA and base vt82c686b_isa on it
  vt82c686: Add emulation of VT8231 south bridge
  hw/pci-host: Add emulation of Marvell MV64361 PPC system controller
  hw/ppc: Add emulation of Genesi/bPlan Pegasos II

Philippe Mathieu-Daudé (1):
  hw/isa/Kconfig: Add missing dependency VIA VT82C686 -> APM

 MAINTAINERS |  10 +
 default-configs/devices/ppc-softmmu.mak |   2 +
 hw/isa/Kconfig  |   1 +
 hw/isa/vt82c686.c   | 515 +++--
 hw/pci-host/Kconfig |   4 +
 hw/pci-host/meson.build |   2 +
 hw/pci-host/mv64361.c   | 966 
 hw/pci-host/mv643xx.h   | 918 ++
 hw/pci-host/trace-events|   6 +
 hw/ppc/Kconfig  |   9 +
 hw/ppc/meson.build  |   2 +
 hw/ppc/pegasos2.c   | 144 
 include/hw/isa/vt82c686.h   |   2 +-
 include/hw/pci-host/mv64361.h   |   8 +
 include/hw/pci/pci_ids.h|   4 +-
 15 files changed, 2510 insertions(+), 83 deletions(-)
 create mode 100644 hw/pci-host/mv64361.c
 create mode 100644 hw/pci-host/mv643xx.h
 create mode 100644 hw/ppc/pegasos2.c
 create mode 100644 include/hw/pci-host/mv64361.h

-- 
2.21.3




Re: [PATCH] meson: add tests option

2021-03-02 Thread Romain Naour
Hello,

Le 02/03/2021 à 12:08, Paolo Bonzini a écrit :
> On 02/03/21 11:22, Thomas Huth wrote:
>> On 26/02/2021 23.07, Romain Naour wrote:
>>> tests/fp/fp-bench.c use fenv.h that is not always provided
>>> by the libc (uClibc).
>>
>> For such  problem it might be better to check for the availability of the
>> header and then to only disable the single test that depends on it if the
>> header is not available.

You're right, I thought about adding a header check but I noticed that was no
option to disable all tests. Buildroot try to avoid as much as possible building
tests program.

>>
>> Anyway, a switch to disable the tests completely could still be handy in some
>> cases, so FWIW:

It can save some build time:

qemu build with tests disabled
real3m27,310s
user19m56,887s
sys 2m1,738s

qemu build with tests enabled
real4m0,638s
user23m34,963s
sys 2m32,944s


>>
>> Acked-by: Thomas Huth 
> 
> I disagree, without a use case the right thing to do is to check for fenv.h. 
> It's as easy as this:

Is it ok if I take your patch to disable fp tests when fenv.h is missing and
resend my patch with an updated commit log to disable all tests to save some
build time?

Best regards,
Romain

> 
> diff --git a/tests/meson.build b/tests/meson.build
> index 0c939f89f7..3b9b2f0483 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -281,7 +281,7 @@ test('decodetree', sh,
>   workdir: meson.current_source_dir() / 'decode',
>   suite: 'decodetree')
> 
> -if 'CONFIG_TCG' in config_all
> +if 'CONFIG_TCG' in config_all and cc.has_header('fenv.h')
>    subdir('fp')
>  endif
> 
> Thanks,
> 
> Paolo
> 




Re: [RFC PATCH 00/26] Confidential guest live migration

2021-03-02 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210302204822.81901-1-dovmu...@linux.vnet.ibm.com/



Hi,

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

Type: series
Message-id: 20210302204822.81901-1-dovmu...@linux.vnet.ibm.com
Subject: [RFC PATCH 00/26] Confidential guest live migration

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20210302175524.1290840-1-berra...@redhat.com -> 
patchew/20210302175524.1290840-1-berra...@redhat.com
 * [new tag] patchew/20210302204822.81901-1-dovmu...@linux.vnet.ibm.com 
-> patchew/20210302204822.81901-1-dovmu...@linux.vnet.ibm.com
Switched to a new branch 'test'
f283a35 docs: Add confidential guest live migration documentation
08f3c3b target/i386: SEV: Allow migration unless there are no aux vcpus
99d1efb migration: Add start-migrate-incoming QMP command
6ca0894 target/i386: Re-sync kvm-clock after confidential guest migration
47e02a0 hw/isa/lpc_ich9: Allow updating an already-running VM
af25d7b migration: Call migration handler cleanup routines
48db1fb migration: When starting target, don't sync auxiliary vcpus
5eb9336 migration: Don't sync vcpus when migrating confidential guests
af9b2fa migration: Stop non-aux vcpus before copying the last pages
2789368 migration: Stop VM after loading confidential RAM
4692252 migration: Load confidential guest RAM using migration helper
e041f58 migration: Save confidential guest RAM using migration helper
328a888 migration: Introduce gpa_inside_migration_helper_shared_area
b71be10 migration: Add helpers to load confidential RAM
32bdb2e migration: Add helpers to save confidential RAM
8d2fccb softmmu: Add pause_all_vcpus_except_aux
ed10484 softmmu: Add cpu_synchronize_without_aux_post_init
e68df04 softmmu: Don't sync aux vcpus in pre_loadvm
17bfe19 hw/i386: Set CPUState.aux=true for auxiliary vcpus
808eb76 cpu: Add boolean aux field to CPUState
34d94b2 hw/acpi: Don't include auxiliary vcpus in ACPI tables
2e9bc24 hw/i386: Mark auxiliary vcpus in possible_cpus
3d07b10 hw/boards: Add aux flag to CPUArchId
0e07c01 machine: Add auxcpus=N suboption to -smp
49124f3 kvm: add support to sync the page encryption state bitmap
47f202b linux-headers: Add definitions of KVM page encryption bitmap ioctls

=== OUTPUT BEGIN ===
1/26 Checking commit 47f202b0bc8c (linux-headers: Add definitions of KVM page 
encryption bitmap ioctls)
2/26 Checking commit 49124f3bf03f (kvm: add support to sync the page encryption 
state bitmap)
ERROR: use qemu_real_host_page_size instead of getpagesize()
#51: FILE: accel/kvm/kvm-all.c:615:
+ram_addr_t pages = int128_get64(section->size) / getpagesize();

ERROR: use qemu_real_host_page_size instead of getpagesize()
#171: FILE: include/exec/ram_addr.h:398:
+unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE;

WARNING: line over 80 characters
#197: FILE: include/exec/ram_addr.h:424:
+qatomic_xchg([DIRTY_MEMORY_ENCRYPTED][idx][offset], 
temp);

total: 2 errors, 1 warnings, 340 lines checked

Patch 2/26 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

3/26 Checking commit 0e07c0168e00 (machine: Add auxcpus=N suboption to -smp)
4/26 Checking commit 3d07b103b36f (hw/boards: Add aux flag to CPUArchId)
5/26 Checking commit 2e9bc24b9064 (hw/i386: Mark auxiliary vcpus in 
possible_cpus)
6/26 Checking commit 34d94b2baa07 (hw/acpi: Don't include auxiliary vcpus in 
ACPI tables)
7/26 Checking commit 808eb7693543 (cpu: Add boolean aux field to CPUState)
8/26 Checking commit 17bfe1902081 (hw/i386: Set CPUState.aux=true for auxiliary 
vcpus)
WARNING: line over 80 characters
#26: FILE: hw/i386/x86.c:104:
+void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, bool aux, Error 
**errp)

WARNING: line over 80 characters
#58: FILE: include/hw/i386/x86.h:88:
+void x86_cpu_new(X86MachineState *pcms, int64_t apic_id, bool aux, Error 
**errp);

total: 0 errors, 2 warnings, 34 lines checked

Patch 8/26 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/26 Checking commit e68df046c12e (softmmu: Don't sync aux vcpus in pre_loadvm)
10/26 Checking commit ed104842e25d (softmmu: Add 
cpu_synchronize_without_aux_post_init)
11/26 Checking commit 8d2fccbd9cf9 (softmmu: Add pause_all_vcpus_except_aux)
WARNING: Block comments use a leading /* on a separate line
#88: FILE: softmmu/cpus.c:614:
+/* We need to drop the replay_lock so any vCPU threads woken up

total: 0 errors, 1 warnings, 78 lines checked

Patch 11/26 has style problems, please review.  If any 

Re: [PATCH v2 18/42] esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of pdma_buf

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:29, Mark Cave-Ayland a écrit :
> ESP SCSI commands are already accumulated in cmdbuf and so there is no need to
> keep a separate pdma_buf buffer. Accumulate SCSI commands for PDMA transfers 
> in
> cmdbuf instead of pdma_buf so update cmdlen accordingly and change pdma_origin
> for PDMA transfers to CMD which allows the PDMA origin to be removed.
> 
> This commit also removes a stray memcpy() from get_cmd() which is a no-op 
> because
> cmdlen is always zero at the start of a command.
> 
> Notionally the removal of pdma_buf from vmstate_esp_pdma also breaks migration
> compatibility for the PDMA subsection until its complete removal by the end of
> the series.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 56 +++
>  include/hw/scsi/esp.h |  2 --
>  2 files changed, 25 insertions(+), 33 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 7134c0aff4..b846f022fb 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -139,8 +139,6 @@ static void set_pdma(ESPState *s, enum pdma_origin_id 
> origin,
>  static uint8_t *get_pdma_buf(ESPState *s)
>  {
>  switch (s->pdma_origin) {
> -case PDMA:
> -return s->pdma_buf;
>  case TI:
>  return s->ti_buf;
>  case CMD:
> @@ -161,14 +159,12 @@ static uint8_t esp_pdma_read(ESPState *s)
>  }
>  
>  switch (s->pdma_origin) {
> -case PDMA:
> -val = s->pdma_buf[s->pdma_cur++];
> -break;
>  case TI:
>  val = s->ti_buf[s->pdma_cur++];
>  break;
>  case CMD:
> -val = s->cmdbuf[s->pdma_cur++];
> +val = s->cmdbuf[s->cmdlen++];
> +s->pdma_cur++;
>  break;
>  case ASYNC:
>  val = s->async_buf[s->pdma_cur++];
> @@ -193,14 +189,12 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>  }
>  
>  switch (s->pdma_origin) {
> -case PDMA:
> -s->pdma_buf[s->pdma_cur++] = val;
> -break;
>  case TI:
>  s->ti_buf[s->pdma_cur++] = val;
>  break;
>  case CMD:
> -s->cmdbuf[s->pdma_cur++] = val;
> +s->cmdbuf[s->cmdlen++] = val;
> +s->pdma_cur++;
>  break;
>  case ASYNC:
>  s->async_buf[s->pdma_cur++] = val;
> @@ -256,8 +250,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, 
> uint8_t buflen)
>  if (s->dma_memory_read) {
>  s->dma_memory_read(s->dma_opaque, buf, dmalen);
>  } else {
> -memcpy(s->pdma_buf, buf, dmalen);
> -set_pdma(s, PDMA, 0, dmalen);
> +set_pdma(s, CMD, 0, dmalen);
>  esp_raise_drq(s);
>  return 0;
>  }
> @@ -316,24 +309,24 @@ static void satn_pdma_cb(ESPState *s)
>  if (get_cmd_cb(s) < 0) {
>  return;
>  }
> -if (s->pdma_cur != s->pdma_start) {
> -do_cmd(s, get_pdma_buf(s) + s->pdma_start);
> +s->do_cmd = 0;
> +if (s->cmdlen) {
> +do_cmd(s, s->cmdbuf);
>  }
>  }
>  
>  static void handle_satn(ESPState *s)
>  {
> -uint8_t buf[32];
> -int len;
> -
>  if (s->dma && !s->dma_enabled) {
>  s->dma_cb = handle_satn;
>  return;
>  }
>  s->pdma_cb = satn_pdma_cb;
> -len = get_cmd(s, buf, sizeof(buf));
> -if (len) {
> -do_cmd(s, buf);
> +s->cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
> +if (s->cmdlen) {
> +do_cmd(s, s->cmdbuf);
> +} else {
> +s->do_cmd = 1;
>  }
>  }
>  
> @@ -342,24 +335,24 @@ static void s_without_satn_pdma_cb(ESPState *s)
>  if (get_cmd_cb(s) < 0) {
>  return;
>  }
> -if (s->pdma_cur != s->pdma_start) {
> +s->do_cmd = 0;
> +if (s->cmdlen) {
>  do_busid_cmd(s, get_pdma_buf(s) + s->pdma_start, 0);
>  }
>  }
>  
>  static void handle_s_without_atn(ESPState *s)
>  {
> -uint8_t buf[32];
> -int len;
> -
>  if (s->dma && !s->dma_enabled) {
>  s->dma_cb = handle_s_without_atn;
>  return;
>  }
>  s->pdma_cb = s_without_satn_pdma_cb;
> -len = get_cmd(s, buf, sizeof(buf));
> -if (len) {
> -do_busid_cmd(s, buf, 0);
> +s->cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
> +if (s->cmdlen) {
> +do_busid_cmd(s, s->cmdbuf, 0);
> +} else {
> +s->do_cmd = 1;
>  }
>  }
>  
> @@ -368,7 +361,7 @@ static void satn_stop_pdma_cb(ESPState *s)
>  if (get_cmd_cb(s) < 0) {
>  return;
>  }
> -s->cmdlen = s->pdma_cur - s->pdma_start;
> +s->do_cmd = 0;
>  if (s->cmdlen) {
>  trace_esp_handle_satn_stop(s->cmdlen);
>  s->do_cmd = 1;
> @@ -394,6 +387,8 @@ static void handle_satn_stop(ESPState *s)
>  s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
>  s->rregs[ESP_RSEQ] = SEQ_CD;
>  esp_raise_irq(s);
> +} else {
> +s->do_cmd = 1;
>  }
>  }
>  
> @@ -865,11 +860,10 @@ static bool esp_pdma_needed(void *opaque)
>  
>  static const VMStateDescription 

Re: [PATCH 1/3] qapi, audio: add query-audiodev command

2021-03-02 Thread Philippe Mathieu-Daudé
On 3/2/21 6:55 PM, Daniel P. Berrangé wrote:
> Way back in QEMU 4.0, the -audiodev command line option was introduced
> for configuring audio backends. This CLI option does not use QemuOpts
> so it is not visible for introspection in 'query-command-line-options',
> instead using the QAPI Audiodev type.  Unfortunately there is also no
> QMP command that uses the Audiodev type, so it is not introspectable
> with 'query-qmp-schema' either.
> 
> This introduces a 'query-audiodev' command that simply reflects back
> the list of configured -audiodev command line options. This in turn
> makes Audiodev introspectable via 'query-qmp-schema'.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  audio/audio.c   | 19 +++
>  qapi/audio.json | 13 +
>  2 files changed, 32 insertions(+)

> +
> +##
> +# @query-audiodevs:
> +#
> +# Returns information about audiodev configuration
> +#
> +# Returns: array of @Audiodev
> +#
> +# Since: 6.0
> +#
> +##
> +{ 'command': 'query-audiodevs',
> +  'returns': ['Audiodev'] }
> 

Can we use 'query-audiodev-backends' similarly to
'query-chardev-backends'?




Re: [PATCH v2 21/42] esp: remove redundant pdma_start from ESPState

2021-03-02 Thread Laurent Vivier
Le 09/02/2021 à 20:29, Mark Cave-Ayland a écrit :
> Now that PDMA SCSI commands are accumulated in cmdbuf in the same way as 
> normal
> commands, the existing logic for locating the start of the SCSI command in
> cmdbuf via cmdlen can be used. This enables the PDMA-specific pdma_start and
> also get_pdma_buf() to be removed.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/scsi/esp.c | 19 ++-
>  include/hw/scsi/esp.h |  1 -
>  2 files changed, 2 insertions(+), 18 deletions(-)
> 
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 7055520a26..91f65a5d9b 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -131,24 +131,10 @@ static void set_pdma(ESPState *s, enum pdma_origin_id 
> origin,
>   uint32_t index, uint32_t len)
>  {
>  s->pdma_origin = origin;
> -s->pdma_start = index;
>  s->pdma_cur = index;
>  s->pdma_len = len;
>  }
>  
> -static uint8_t *get_pdma_buf(ESPState *s)
> -{
> -switch (s->pdma_origin) {
> -case TI:
> -return s->ti_buf;
> -case CMD:
> -return s->cmdbuf;
> -case ASYNC:
> -return s->async_buf;
> -}
> -return NULL;
> -}
> -
>  static uint8_t esp_pdma_read(ESPState *s)
>  {
>  uint32_t dmalen = esp_get_tc(s);
> @@ -339,7 +325,7 @@ static void s_without_satn_pdma_cb(ESPState *s)
>  }
>  s->do_cmd = 0;
>  if (s->cmdlen) {
> -do_busid_cmd(s, get_pdma_buf(s) + s->pdma_start, 0);
> +do_busid_cmd(s, s->cmdbuf, 0);
>  }
>  }
>  
> @@ -441,7 +427,7 @@ static void esp_dma_done(ESPState *s)
>  static void do_dma_pdma_cb(ESPState *s)
>  {
>  int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
> -int len = s->pdma_cur - s->pdma_start;
> +int len = s->pdma_cur;
>  
>  if (s->do_cmd) {
>  s->ti_size = 0;
> @@ -868,7 +854,6 @@ static const VMStateDescription vmstate_esp_pdma = {
>  .fields = (VMStateField[]) {
>  VMSTATE_INT32(pdma_origin, ESPState),
>  VMSTATE_UINT32(pdma_len, ESPState),
> -VMSTATE_UINT32(pdma_start, ESPState),
>  VMSTATE_UINT32(pdma_cur, ESPState),
>  VMSTATE_END_OF_LIST()
>  }
> diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
> index c323d43f70..578d936214 100644
> --- a/include/hw/scsi/esp.h
> +++ b/include/hw/scsi/esp.h
> @@ -58,7 +58,6 @@ struct ESPState {
>  void (*dma_cb)(ESPState *s);
>  int pdma_origin;
>  uint32_t pdma_len;
> -uint32_t pdma_start;
>  uint32_t pdma_cur;
>  void (*pdma_cb)(ESPState *s);
>  
> 

Reviewed-by: Laurent Vivier 



Re: [PATCH v2 18/42] esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of pdma_buf

2021-03-02 Thread Laurent Vivier
Le 02/03/2021 à 20:29, Mark Cave-Ayland a écrit :
> On 02/03/2021 17:59, Laurent Vivier wrote:
> 
>> Le 02/03/2021 à 18:34, Mark Cave-Ayland a écrit :
>>> On 02/03/2021 17:02, Laurent Vivier wrote:
>>>
 Le 09/02/2021 à 20:29, Mark Cave-Ayland a écrit :
> ESP SCSI commands are already accumulated in cmdbuf and so there is no 
> need to
> keep a separate pdma_buf buffer. Accumulate SCSI commands for PDMA 
> transfers in
> cmdbuf instead of pdma_buf so update cmdlen accordingly and change 
> pdma_origin
> for PDMA transfers to CMD which allows the PDMA origin to be removed.
>
> This commit also removes a stray memcpy() from get_cmd() which is a no-op 
> because
> cmdlen is always zero at the start of a command.
>
> Notionally the removal of pdma_buf from vmstate_esp_pdma also breaks 
> migration
> compatibility for the PDMA subsection until its complete removal by the 
> end of
> the series.
>
> Signed-off-by: Mark Cave-Ayland 
> ---
>    hw/scsi/esp.c | 56 +++
>    include/hw/scsi/esp.h |  2 --
>    2 files changed, 25 insertions(+), 33 deletions(-)
>
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 7134c0aff4..b846f022fb 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -139,8 +139,6 @@ static void set_pdma(ESPState *s, enum pdma_origin_id 
> origin,
>    static uint8_t *get_pdma_buf(ESPState *s)
>    {
>    switch (s->pdma_origin) {
> -    case PDMA:
> -    return s->pdma_buf;
>    case TI:
>    return s->ti_buf;
>    case CMD:
> @@ -161,14 +159,12 @@ static uint8_t esp_pdma_read(ESPState *s)
>    }
>      switch (s->pdma_origin) {
> -    case PDMA:
> -    val = s->pdma_buf[s->pdma_cur++];
> -    break;
>    case TI:
>    val = s->ti_buf[s->pdma_cur++];
>    break;
>    case CMD:
> -    val = s->cmdbuf[s->pdma_cur++];
> +    val = s->cmdbuf[s->cmdlen++];
> +    s->pdma_cur++;
>    break;
>    case ASYNC:
>    val = s->async_buf[s->pdma_cur++];
> @@ -193,14 +189,12 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
>    }
>      switch (s->pdma_origin) {
> -    case PDMA:
> -    s->pdma_buf[s->pdma_cur++] = val;
> -    break;
>    case TI:
>    s->ti_buf[s->pdma_cur++] = val;
>    break;
>    case CMD:
> -    s->cmdbuf[s->pdma_cur++] = val;
> +    s->cmdbuf[s->cmdlen++] = val;
> +    s->pdma_cur++;
>    break;
>    case ASYNC:
>    s->async_buf[s->pdma_cur++] = val;
> @@ -256,8 +250,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, 
> uint8_t buflen)
>    if (s->dma_memory_read) {
>    s->dma_memory_read(s->dma_opaque, buf, dmalen);
>    } else {
> -    memcpy(s->pdma_buf, buf, dmalen);
> -    set_pdma(s, PDMA, 0, dmalen);
> +    set_pdma(s, CMD, 0, dmalen);
>    esp_raise_drq(s);
>    return 0;
>    }
> @@ -316,24 +309,24 @@ static void satn_pdma_cb(ESPState *s)
>    if (get_cmd_cb(s) < 0) {
>    return;
>    }
> -    if (s->pdma_cur != s->pdma_start) {
> -    do_cmd(s, get_pdma_buf(s) + s->pdma_start);
> +    s->do_cmd = 0;
> +    if (s->cmdlen) {
> +    do_cmd(s, s->cmdbuf);

 I don't understant how you can remove the pdma_start: normally it is here 
 to keep track of the
 position in the pDMA if the migration is occuraing while a pDMA transfer.
>>>
>>> Hi Laurent,
>>>
>>> I was going to follow up on your reviews later this evening, however this 
>>> one caught my eye: as per
>>> the cover letter, this patchset is a migration break for the q800 machine. 
>>> As there are likely more
>>> incompatible changes for the q800 machine coming up soon, it didn't seem 
>>> worth the effort (and
>>> indeed I don't think it's possible to recreate the new internal state with 
>>> 100% accuracy from the
>>> old state).
>>>
>>> Migration for ESP devices that don't use PDMA is still supported, and I've 
>>> tested this during
>>> development with qemu-system-sparc.
>>>
>>
>> I don't mean we can't migrate from a previous version to the new one, I mean 
>> the migration between
>> two machines of the current version is not possible anymore as we don't keep 
>> track of the position
>> of the pDMA index inside the buffer.
>>
>> With a DMA, the migration cannot happen in the middle of the DMA, while with 
>> pDMA it can (as it's a
>> processor loop).
>>
>> The whole purpose of get_pdma() and set_pdma() was for the migration.
>>
>> 

Re: Plugin Address Translations Inconsistent/Incorrect?

2021-03-02 Thread Alex Bennée


Aaron Lindsay  writes:

> On Mar 02 16:06, Alex Bennée wrote:
>> 
>> Aaron Lindsay  writes:
>> 
>> > On Feb 23 15:53, Aaron Lindsay wrote:
>> >> On Feb 22 15:48, Aaron Lindsay wrote:
>> >> > On Feb 22 19:30, Alex Bennée wrote:
>> >> > > Aaron Lindsay  writes:
>> >> > > That said I think we could add an additional helper to translate a
>> >> > > hwaddr to a global address space address. I'm open to suggestions of 
>> >> > > the
>> >> > > best way to structure this.
>> >> > 
>> >> > Haven't put a ton of thought into it, but what about something like this
>> >> > (untested):
>> >> > 
>> >> > uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr 
>> >> > *haddr)
>> >> > {
>> >> > #ifdef CONFIG_SOFTMMU
>> >> > if (haddr) {
>> >> > if (!haddr->is_io) {
>> >> > RAMBlock *block;
>> >> > ram_addr_t offset;
>> >> > 
>> >> > block = qemu_ram_block_from_host((void *) 
>> >> > haddr->v.ram.hostaddr, false, );
>> >> > if (!block) {
>> >> > error_report("Bad ram pointer %"PRIx64"", 
>> >> > haddr->v.ram.hostaddr);
>> >> > abort();
>> >> > }
>> >> > 
>> >> > return block->offset + offset + block->mr->addr;
>> >> > } else {
>> >> > MemoryRegionSection *mrs = haddr->v.io.section;
>> >> > return haddr->v.io.offset + mrs->mr->addr;
>> >> > }
>> >> > }
>> >> > #endif
>> >> > return 0;
>> >> > }
>> >> 
>> >> This appears to successfully return correct physical addresses for RAM
>> >> at least, though I've not tested it thoroughly for MMIO yet.
>> >> 
>> >> If it ends up being desirable based on the discussion elsewhere on this
>> >> thread I am willing to perform more complete testing, turn this into a
>> >> patch, and submit it.
>> >
>> > Ping - Is this something worth me pursuing?
>> 
>> Yes please. 
>
> Okay, I'll work on it. Is your thinking that this would this be a
> separate call as shown above, or a replacement of the existing
> qemu_plugin_hwaddr_device_offset function? And, if a replacement, should
> we keep the name similar to retain compatibility, or make a clean break?
>
> It seemed like Peter may have been saying the device offset shouldn't be
> exposed at all (leading me to consider full replacement), but I also
> don't see a definitive resolution of that conversation.

I think a full replacement and an increment of the minimum API version.
That way people will at least query why the plugin failed to load and
hopefully will read the release notes ;-)

>
> -Aaron


-- 
Alex Bennée



Re: [PATCH 1/3] qapi, audio: add query-audiodev command

2021-03-02 Thread Philippe Mathieu-Daudé
On 3/2/21 10:10 PM, Philippe Mathieu-Daudé wrote:
> On 3/2/21 6:55 PM, Daniel P. Berrangé wrote:
>> Way back in QEMU 4.0, the -audiodev command line option was introduced
>> for configuring audio backends. This CLI option does not use QemuOpts
>> so it is not visible for introspection in 'query-command-line-options',
>> instead using the QAPI Audiodev type.  Unfortunately there is also no
>> QMP command that uses the Audiodev type, so it is not introspectable
>> with 'query-qmp-schema' either.
>>
>> This introduces a 'query-audiodev' command that simply reflects back
>> the list of configured -audiodev command line options. This in turn
>> makes Audiodev introspectable via 'query-qmp-schema'.
>>
>> Signed-off-by: Daniel P. Berrangé 
>> ---
>>  audio/audio.c   | 19 +++
>>  qapi/audio.json | 13 +
>>  2 files changed, 32 insertions(+)
> 
>> +
>> +##
>> +# @query-audiodevs:
>> +#
>> +# Returns information about audiodev configuration
>> +#
>> +# Returns: array of @Audiodev

Also with chardev we return ChardevBackendInfo. I'm not sure
if this is because I'm custom to read it, but it seems clearer.
Can we return a AudiodevBackendInfo type?

>> +#
>> +# Since: 6.0
>> +#
>> +##
>> +{ 'command': 'query-audiodevs',
>> +  'returns': ['Audiodev'] }
>>
> 
> Can we use 'query-audiodev-backends' similarly to
> 'query-chardev-backends'?
> 




Re: [PATCH v4 5/6] hw/pci-host: Add emulation of Marvell MV64361 PPC system controller

2021-03-02 Thread BALATON Zoltan

On Tue, 2 Mar 2021, Philippe Mathieu-Daudé wrote:

On 2/25/21 8:47 PM, BALATON Zoltan wrote:

The Marvell Discovery II aka. MV64361 is a PowerPC system controller
chip that is used on the pegasos2 PPC board. This adds emulation of it
that models the device enough to boot guests on this board. The
mv643xx.h header with register definitions is taken from Linux 4.15.10
only fixing end of line white space errors and removing not needed
parts, it's otherwise keeps Linux formatting.

Signed-off-by: BALATON Zoltan 
---
 hw/pci-host/Kconfig   |   3 +
 hw/pci-host/meson.build   |   2 +
 hw/pci-host/mv64361.c | 966 ++
 hw/pci-host/mv643xx.h | 919 


Maybe name this one mv643xx_regs.h?


This comes originally from Linux where it had this name so to make it 
simpler to find where it comes from I've kept the name for now. If we 
ever change the contents beyond just formatting it could be renamed too.


Regards,
BALATON Zoltan


 hw/pci-host/trace-events  |   6 +
 include/hw/pci-host/mv64361.h |   8 +
 include/hw/pci/pci_ids.h  |   1 +
 7 files changed, 1905 insertions(+)
 create mode 100644 hw/pci-host/mv64361.c
 create mode 100644 hw/pci-host/mv643xx.h
 create mode 100644 include/hw/pci-host/mv64361.h




diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index 8b8c763c28..65a983d6fd 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -68,3 +68,6 @@ config PCI_POWERNV

 config REMOTE_PCIHOST
 bool
+
+config MV64361
+bool


Missing:

  select PCI



[RFC PATCH 10/26] softmmu: Add cpu_synchronize_without_aux_post_init

2021-03-02 Thread Dov Murik
This will be used during migration on the target.

Signed-off-by: Dov Murik 
---
 include/sysemu/cpus.h |  1 +
 softmmu/cpus.c| 11 +++
 2 files changed, 12 insertions(+)

diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 868f1192de..dc24e38254 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -46,6 +46,7 @@ bool cpus_are_resettable(void);
 void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
 void cpu_synchronize_all_post_init(void);
+void cpu_synchronize_without_aux_post_init(void);
 void cpu_synchronize_all_pre_loadvm(void);
 
 #ifndef CONFIG_USER_ONLY
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index 878cf2a421..68fa4639a7 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -157,6 +157,17 @@ void cpu_synchronize_all_post_init(void)
 }
 }
 
+void cpu_synchronize_without_aux_post_init(void)
+{
+CPUState *cpu;
+
+CPU_FOREACH(cpu) {
+if (!cpu->aux) {
+cpu_synchronize_post_init(cpu);
+}
+}
+}
+
 void cpu_synchronize_all_pre_loadvm(void)
 {
 CPUState *cpu;
-- 
2.20.1




Re: [PATCH 3/3] qapi: provide a friendly string representation of QAPI classes

2021-03-02 Thread Philippe Mathieu-Daudé
On 3/2/21 6:55 PM, Daniel P. Berrangé wrote:
> If printing a QAPI schema object for debugging we get the classname and
> a hex value for the instance. With this change we instead get the
> classname and the human friendly name of the QAPI type instance.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  scripts/qapi/schema.py | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Philippe Mathieu-Daudé 




[RFC PATCH 20/26] migration: When starting target, don't sync auxiliary vcpus

2021-03-02 Thread Dov Murik
If auxiliary vcpus are defined, they are used for running the migration
helper inside the guest.  We want to keep them running and not sync
their state.

This behaves exactly like cpu_synchronize_all_post_init() when there are
no auxiliary vcpus.

Signed-off-by: Dov Murik 
---
 migration/savevm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index c5252612c3..c6af1f7bba 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2754,7 +2754,7 @@ int qemu_loadvm_state(QEMUFile *f)
 }
 
 qemu_loadvm_state_cleanup();
-cpu_synchronize_all_post_init();
+cpu_synchronize_without_aux_post_init();
 
 return ret;
 }
-- 
2.20.1




Re: [PATCH v2 0/2] gitlab-ci.yml: Add jobs to test CFI

2021-03-02 Thread Daniele Buono

On 3/2/2021 11:40 AM, Daniel P. Berrangé wrote:

The CFI protection is something I'd say is relevant to virtualization
use cases, not to emulation use cases

https://qemu-project.gitlab.io/qemu/system/security.html

IOW, the targets that are important to test are the ones where KVM
is available.

So that's  s390x, ppc, x86, mips, and arm.

I think we can probably ignore mips as that's fairly niche.
We can also reasonably limit ourselves to only test the 64-bit
variants of the target, on the basis that 32-bit is increasingly
legacy/niche too.

So that gives us  ppc64le, x86_64, aarch64 and s390x as the
targets we should get CI coverage for CFI.


Thanks Daniel,
I'll start working on a V3 that only contains those 4 targets, probably 
in two sets of build/check/acceptance to maintain the jobs below the 
hour mark.


These would still be x86 binaries that are not testing KVM, however,
because of the capabilities of the shared gitlab runners.

I see that there's some work from Cleber Rosa to allow running custom 
jobs on aarch64 and s390x systems. I think that, when the infrastructure 
is ready, having a KVM-based CFI test there would help a lot in terms of 
coverage for those architectures.




Re: [PATCH] vfio-ccw: Do not read region ret_code after write

2021-03-02 Thread Eric Farman




On 3/2/21 1:14 PM, Cornelia Huck wrote:

On Mon,  1 Mar 2021 20:51:43 +0100
Eric Farman  wrote:


A pwrite() call returns the number of bytes written (or -1 on error),
and vfio-ccw compares this number with the size of the region to
determine if an error had occurred or not. If they are equal, the
code reads the ret_code field from the region. However, while the
kernel sets the ret_code field as necessary, the region and thus
this field is not "written back" to the user. So the value can only
be what it was initialized to, which is zero.

Not harming anything, but it's a puzzle. Let's avoid the confusion
and just set the return code to zero for this case.


Yes, ret_code seems to be pretty much useless for us: we don't even
look at it when we read the region for interrupt handling. Thankfully,
we don't seem to really need it, as we can rely on errno. (Probably
worth double checking that this is indeed the case.)


I didn't see any scenario on either the kernel or qemu side that made me 
worried.




I don't suppose we need to handle a hypothetical broken kernel that
returns the wrong size with errno==0?


Well, that would be silly of it. :) But, since I'm in here, sure I can 
add in some suspenders.


Thanks,
Eric





Suggested-by: Matthew Rosato 
Signed-off-by: Eric Farman 
---
  hw/vfio/ccw.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index bc78a0ad76..bfd5fd07a5 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -106,7 +106,7 @@ again:
  error_report("vfio-ccw: write I/O region failed with errno=%d", 
errno);
  ret = -errno;
  } else {
-ret = region->ret_code;
+ret = 0;
  }
  switch (ret) {
  case 0:
@@ -194,7 +194,7 @@ again:
  error_report("vfio-ccw: write cmd region failed with errno=%d", 
errno);
  ret = -errno;
  } else {
-ret = region->ret_code;
+ret = 0;
  }
  switch (ret) {
  case 0:
@@ -234,7 +234,7 @@ again:
  error_report("vfio-ccw: write cmd region failed with errno=%d", 
errno);
  ret = -errno;
  } else {
-ret = region->ret_code;
+ret = 0;
  }
  switch (ret) {
  case 0:






Re: [PATCH v1 7/9] memory: introduce RAM_NORESERVE and wire it up in qemu_ram_mmap()

2021-03-02 Thread David Hildenbrand

On 02.03.21 21:54, Peter Xu wrote:

On Tue, Mar 02, 2021 at 08:02:34PM +0100, David Hildenbrand wrote:

@@ -174,12 +175,18 @@ void *qemu_ram_mmap(int fd,
   size_t align,
   bool readonly,
   bool shared,
-bool is_pmem)
+bool is_pmem,
+bool noreserve)


Maybe at some point we should use flags too here to cover all bools.



Right. I guess the main point was to not reuse RAM_XXX.

Should I introduce RAM_MMAP_XXX ?


Maybe we can directly use MAP_*?  Since I see qemu_ram_mmap() should only exist


I think the issue is that there is for example no flag that corresponds 
to "is_pmem" - and the fallback logic in our mmap code to make "is_pmem" 
still work is a little bit more involved. In addition, "readonly" 
translates to PROT_READ ...



with CONFIG_POSIX.  However indeed I see no sign to extend more bools in the
near future either, so maybe also fine to keep it as is, as 4 bools still looks
okay - your call. :)


Well, I had the same idea when I added yet another bool :) But I guess 
we won't be adding a lot of additional flags in the near future. 
(MAP_POPULATE? ;) fortunately we use a different approach to populate 
memory)


I'll think about it, not sure yet if this is worth proper flags. Thanks!

--
Thanks,

David / dhildenb




[RFC PATCH 15/26] migration: Save confidential guest RAM using migration helper

2021-03-02 Thread Dov Murik
When saving RAM pages of a confidential guest, check whether a page is
encrypted.  If it is, ask the in-guest migration helper to encrypt the
page for transmission.

This relies on ability to track the encryption status of each page
according to guest's reports, and thus requires the relevant patches in
the guest OS and OVMF and the host KVM and QEMU.  This is all
encapsulated in is_page_encrypted; the implementation can be modified
according to the underlying implementation of page encryption status
tracking (bitmap / KVM shared regions list / user-side list)

Signed-off-by: Dov Murik 
---
 migration/ram.c | 91 +
 1 file changed, 91 insertions(+)

diff --git a/migration/ram.c b/migration/ram.c
index 997f90cc5b..8e55ed49fd 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -53,10 +53,13 @@
 #include "block.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/cpu-throttle.h"
+#include "sysemu/kvm.h"
 #include "savevm.h"
 #include "qemu/iov.h"
 #include "multifd.h"
 #include "sysemu/runstate.h"
+#include "hw/boards.h"
+#include "confidential-ram.h"
 
 #if defined(__linux__)
 #include "qemu/userfaultfd.h"
@@ -81,6 +84,7 @@
 #define RAM_SAVE_FLAG_XBZRLE   0x40
 /* 0x80 is reserved in migration.h start with 0x100 next */
 #define RAM_SAVE_FLAG_COMPRESS_PAGE0x100
+#define RAM_SAVE_FLAG_GUEST_ENCRYPTED_PAGE0x200
 
 static inline bool memcrypt_enabled(void)
 {
@@ -94,6 +98,13 @@ static inline bool is_zero_range(uint8_t *p, uint64_t size)
 return buffer_is_zero(p, size);
 }
 
+static inline bool confidential_guest(void)
+{
+MachineState *ms = MACHINE(qdev_get_machine());
+
+return ms->cgs;
+}
+
 XBZRLECacheStats xbzrle_counters;
 
 /* struct contains XBZRLE cache and a static page
@@ -660,6 +671,23 @@ static void mig_throttle_guest_down(uint64_t 
bytes_dirty_period,
 }
 }
 
+/**
+ * is_page_encrypted: check if the page is encrypted
+ *
+ * Returns a bool indicating whether the page is encrypted.
+ */
+static bool is_page_encrypted(RAMState *rs, RAMBlock *block, unsigned long 
page)
+{
+/* ROM devices contain unencrypted data */
+if (memory_region_is_romd(block->mr) ||
+memory_region_is_rom(block->mr) ||
+!memory_region_is_ram(block->mr)) {
+return false;
+}
+
+return test_bit(page, block->encbmap);
+}
+
 /**
  * xbzrle_cache_zero_page: insert a zero page in the XBZRLE cache
  *
@@ -1928,6 +1956,45 @@ static bool save_compress_page(RAMState *rs, RAMBlock 
*block, ram_addr_t offset)
 return false;
 }
 
+/**
+ * ram_save_encrypted_page - send the given encrypted page to the stream
+ *
+ * Return the number of pages written (=1).
+ */
+static int ram_save_encrypted_page(RAMState *rs, PageSearchStatus *pss,
+   bool last_stage)
+{
+int ret;
+uint8_t *p;
+RAMBlock *block = pss->block;
+ram_addr_t offset = pss->page << TARGET_PAGE_BITS;
+ram_addr_t gpa;
+uint64_t bytes_sent;
+
+p = block->host + offset;
+
+/* Find the GPA of the page */
+if (!kvm_physical_memory_addr_from_host(kvm_state, p, )) {
+error_report("%s failed to get gpa for offset %" PRIu64 " block %s",
+ __func__, offset, memory_region_name(block->mr));
+return -1;
+}
+
+ram_counters.transferred +=
+save_page_header(rs, rs->f, block,
+offset | RAM_SAVE_FLAG_GUEST_ENCRYPTED_PAGE);
+
+ret = cgs_mh_save_encrypted_page(rs->f, gpa, TARGET_PAGE_SIZE, 
_sent);
+if (ret) {
+return -1;
+}
+
+ram_counters.transferred += bytes_sent;
+ram_counters.normal++;
+
+return 1;
+}
+
 /**
  * ram_save_target_page: save one target page
  *
@@ -1948,6 +2015,26 @@ static int ram_save_target_page(RAMState *rs, 
PageSearchStatus *pss,
 return res;
 }
 
+/*
+ * If memory encryption is enabled then skip saving the data pages used by
+ * the migration handler.
+ */
+if (confidential_guest() &&
+gpa_inside_migration_helper_shared_area(offset)) {
+return 0;
+}
+
+/*
+ * If memory encryption is enabled then use memory encryption APIs
+ * to write the outgoing buffer to the wire. The encryption APIs
+ * will take care of accessing the guest memory and re-encrypt it
+ * for the transport purposes.
+ */
+if (confidential_guest() &&
+is_page_encrypted(rs, pss->block, pss->page)) {
+return ram_save_encrypted_page(rs, pss, last_stage);
+}
+
 if (save_compress_page(rs, block, offset)) {
 return 1;
 }
@@ -2776,6 +2863,10 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 return -1;
 }
 
+if (confidential_guest()) {
+cgs_mh_init();
+}
+
 /* migration has already setup the bitmap, reuse it. */
 if (!migration_in_colo_state()) {
 if (ram_init_all(rsp) != 0) {
-- 
2.20.1




[RFC PATCH 05/26] hw/i386: Mark auxiliary vcpus in possible_cpus

2021-03-02 Thread Dov Murik
Mark the last aux_cpus vcpus in the machine state's possible_cpus as
auxiliary.

Signed-off-by: Dov Murik 
---
 hw/i386/x86.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 6329f90ef9..be23fad650 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -448,6 +448,7 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState 
*ms)
 {
 X86MachineState *x86ms = X86_MACHINE(ms);
 unsigned int max_cpus = ms->smp.max_cpus;
+unsigned int aux_cpus_start_at = max_cpus - ms->smp.aux_cpus;
 X86CPUTopoInfo topo_info;
 int i;
 
@@ -475,6 +476,7 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState 
*ms)
 x86_cpu_apic_id_from_index(x86ms, i);
 x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
  _info, _ids);
+ms->possible_cpus->cpus[i].aux = i >= aux_cpus_start_at;
 ms->possible_cpus->cpus[i].props.has_socket_id = true;
 ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id;
 if (x86ms->smp_dies > 1) {
-- 
2.20.1




[RFC PATCH 08/26] hw/i386: Set CPUState.aux=true for auxiliary vcpus

2021-03-02 Thread Dov Murik
On x86 machines, when initializing the CPUState structs, set the aux
flag to true for auxiliary vcpus.

Signed-off-by: Dov Murik 
---
 include/hw/i386/x86.h | 2 +-
 hw/i386/x86.c | 8 ++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 56080bd1fb..f9ec6af9b7 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -85,7 +85,7 @@ void init_topo_info(X86CPUTopoInfo *topo_info, const 
X86MachineState *x86ms);
 uint32_t x86_cpu_apic_id_from_index(X86MachineState *pcms,
 unsigned int cpu_index);
 
-void x86_cpu_new(X86MachineState *pcms, int64_t apic_id, Error **errp);
+void x86_cpu_new(X86MachineState *pcms, int64_t apic_id, bool aux, Error 
**errp);
 void x86_cpus_init(X86MachineState *pcms, int default_cpu_version);
 CpuInstanceProperties x86_cpu_index_to_props(MachineState *ms,
  unsigned cpu_index);
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index be23fad650..bc17b53180 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -101,13 +101,16 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState 
*x86ms,
 }
 
 
-void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
+void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, bool aux, Error 
**errp)
 {
 Object *cpu = object_new(MACHINE(x86ms)->cpu_type);
 
 if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
 goto out;
 }
+if (!object_property_set_bool(cpu, "aux", aux, errp)) {
+goto out;
+}
 qdev_realize(DEVICE(cpu), NULL, errp);
 
 out:
@@ -135,7 +138,8 @@ void x86_cpus_init(X86MachineState *x86ms, int 
default_cpu_version)
   ms->smp.max_cpus - 1) + 
1;
 possible_cpus = mc->possible_cpu_arch_ids(ms);
 for (i = 0; i < ms->smp.cpus; i++) {
-x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, _fatal);
+x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id,
+possible_cpus->cpus[i].aux, _fatal);
 }
 }
 
-- 
2.20.1




Re: [PATCH v1 7/9] memory: introduce RAM_NORESERVE and wire it up in qemu_ram_mmap()

2021-03-02 Thread Peter Xu
On Tue, Mar 02, 2021 at 08:02:34PM +0100, David Hildenbrand wrote:
> > > @@ -174,12 +175,18 @@ void *qemu_ram_mmap(int fd,
> > >   size_t align,
> > >   bool readonly,
> > >   bool shared,
> > > -bool is_pmem)
> > > +bool is_pmem,
> > > +bool noreserve)
> > 
> > Maybe at some point we should use flags too here to cover all bools.
> > 
> 
> Right. I guess the main point was to not reuse RAM_XXX.
> 
> Should I introduce RAM_MMAP_XXX ?

Maybe we can directly use MAP_*?  Since I see qemu_ram_mmap() should only exist
with CONFIG_POSIX.  However indeed I see no sign to extend more bools in the
near future either, so maybe also fine to keep it as is, as 4 bools still looks
okay - your call. :)

-- 
Peter Xu




[RFC PATCH 26/26] docs: Add confidential guest live migration documentation

2021-03-02 Thread Dov Murik
The new page is linked from the main index, otherwise sphinx complains
that "document isn't included in any toctree"; I assume there would be a
better place for it in the documentation tree.

Signed-off-by: Dov Murik 
---
 docs/confidential-guest-live-migration.rst | 142 +
 docs/confidential-guest-support.txt|   5 +
 docs/index.rst |   1 +
 3 files changed, 148 insertions(+)
 create mode 100644 docs/confidential-guest-live-migration.rst

diff --git a/docs/confidential-guest-live-migration.rst 
b/docs/confidential-guest-live-migration.rst
new file mode 100644
index 00..dc59df8f9c
--- /dev/null
+++ b/docs/confidential-guest-live-migration.rst
@@ -0,0 +1,142 @@
+=
+Confidential Guest Live Migration
+=
+
+When migrating regular QEMU guests, QEMU reads the guest's RAM and sends it
+over to the migration target host, where QEMU there writes it into the target
+guest's RAM and starts the VM.  This mechanism doesn't work when the guest
+memory is encrypted or QEMU is prevented from reading it in another way.
+
+In order to support live migration in such scenarios, QEMU relies on an
+in-guest migration helper which can securely extract RAM content from the
+guest in order to send it to the target.  The migration helper is implemented 
as
+part of the VM's firmware in OVMF.
+
+
+Migration flow
+==
+
+Source VM
+-
+
+The source VM is started with an extra auxiliary vcpu which is not listed in 
the
+ACPI tables.  OVMF uses this vcpu and starts a dedicated migration helper on 
it;
+the migration helper simply waits for commands from QEMU.  When migration 
starts
+using the ``migrate`` command, QEMU starts saving the state of the different
+devices.  When it reaches saving RAM pages, it'll check for each page whether 
it
+is encrypted or not; for encrypted pages, it'll send a command to the migration
+helper to extract the given page.  The migration helper receives this command,
+reads the page content, encrypts it with a transport key, and returns the
+newly-encrypted page to QEMU.  QEMU saves those pages to the outgoing migration
+stream using a new page flag ``RAM_SAVE_FLAG_GUEST_ENCRYPTED_PAGE``.
+
+When QEMU reaches the last stage of RAM migration, it stops the source VM to
+avoid dirtying the last pages of RAM.  However, the auxiliary vcpu must be kept
+running so the migration helper can still extract pages from the guest memory.
+
+Target VM
+-
+
+Usually QEMU migration target VMs are started with the ``-incoming``
+command-line option which starts the VM paused.  However, in order to migrate
+confidential guests we must have the migration helper running inside the guest;
+in such a case, we start the target with a special ``-fw_cfg`` value that tells
+OVMF to enter a CPU dead loop on all vcpus except the auxiliary vcpu, which 
runs
+the migration helper.  After this short "boot" completes, QEMU can switch to 
the
+"migration incoming" mode; we do that with the new ``start-migrate-incoming``
+QMP command that makes the target VM listen for incoming migration connections.
+
+QEMU will load the state of VM devices as it arrives from the incoming 
migration
+stream.  When it encounters a RAM page with the
+``RAM_SAVE_FLAG_GUEST_ENCRYPTED_PAGE`` flag, it will send its
+transport-encrypted content and guest physical address to the migration helper.
+The migration helper running inside the guest will decrypt the page using the
+transport key and place the content in memory (again, that memory page is not
+accessible to host due to the confidential guest properties; for example, in 
SEV
+it is hardware-encrypted with a VM-specific key).
+
+
+Usage
+=
+
+In order to start the source and target VMs with auxiliary CPUs, the auxcpus=
+option must be passed to ``-smp`` . For example::
+
+# ${QEMU} -smp 5,auxcpus=1 ...
+
+This command starts a VM with 5 vcpus of which 4 are main vcpus (available for
+the guest OS) and 1 is auxliary vcpu.
+
+Moreover, in both the source and target we need to instruct OVMF to start the
+migration helper running in the auxiliary vcpu.  This is achieved using the
+following command-line option::
+
+# ${QEMU} -fw_cfg name=opt/ovmf/PcdSevIsMigrationHelper,string=0 ...
+
+In the target VM we need to add another ``-fw_cfg`` entry to instruct OVMF to
+start only the migration helepr, which will wait for incoming pages (the target
+cannot be started with ``-incoming`` because that option completely pauses the
+VM, not allowing the migration helper to run). Because the migration helper 
must
+be running when the incoming RAM pages are received, starting the target VM 
with
+the ``-incoming`` option doesn't work (with that option, the VM doesn't start
+executing).  Instead, start the target VM without ``-incoming`` but with the
+following option::
+
+# ${QEMU} -fw_cfg name=opt/ovmf/PcdSevIsMigrationTarget,string=1 ...
+
+After the VM 

[RFC PATCH 21/26] migration: Call migration handler cleanup routines

2021-03-02 Thread Dov Murik
From: Tobin Feldman-Fitzthum 

Signed-off-by: Tobin Feldman-Fitzthum 
Signed-off-by: Dov Murik 
---
 migration/ram.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/migration/ram.c b/migration/ram.c
index 82a1d13f5f..ce551c1d2f 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3054,6 +3054,10 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
 ram_control_after_iterate(f, RAM_CONTROL_FINISH);
 }
 
+if (confidential_guest()) {
+cgs_mh_cleanup();
+}
+
 if (ret >= 0) {
 multifd_send_sync_main(rs->f);
 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
@@ -3549,6 +3553,10 @@ static int ram_load_cleanup(void *opaque)
 rb->receivedmap = NULL;
 }
 
+if (confidential_guest()) {
+cgs_mh_cleanup();
+}
+
 return 0;
 }
 
-- 
2.20.1




[RFC PATCH 18/26] migration: Stop non-aux vcpus before copying the last pages

2021-03-02 Thread Dov Murik
From: Tobin Feldman-Fitzthum 

Co-Author: Dov Murik 
Signed-off-by: Dov Murik 
Signed-off-by: Tobin Feldman-Fitzthum 
---
 migration/migration.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index a5ddf43559..7ec25bd006 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -24,6 +24,7 @@
 #include "sysemu/runstate.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/cpu-throttle.h"
+#include "sysemu/cpus.h"
 #include "rdma.h"
 #include "ram.h"
 #include "migration/global_state.h"
@@ -3156,14 +3157,14 @@ static void migration_completion(MigrationState *s)
 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 s->vm_was_running = runstate_is_running();
 ret = global_state_store();
+pause_all_vcpus_except_aux();
+qemu_mutex_unlock_iothread();
 
 if (!ret) {
 bool inactivate = !migrate_colo_enabled();
-ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
-if (ret >= 0) {
-ret = migration_maybe_pause(s, _active_state,
-MIGRATION_STATUS_DEVICE);
-}
+ret = migration_maybe_pause(s, _active_state,
+MIGRATION_STATUS_DEVICE);
+
 if (ret >= 0) {
 qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
 ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
@@ -3173,7 +3174,7 @@ static void migration_completion(MigrationState *s)
 s->block_inactive = true;
 }
 }
-qemu_mutex_unlock_iothread();
+runstate_set(RUN_STATE_FINISH_MIGRATE);
 
 if (ret < 0) {
 goto fail;
-- 
2.20.1




[RFC PATCH 17/26] migration: Stop VM after loading confidential RAM

2021-03-02 Thread Dov Murik
Register a dummy device state (EndOfConfidentialRAMState) with high
priority so it is the first device which is loaded in the target.  The
post_load handler of this device stops the VM, which makes things easier
when loading devices' states which expect the VM not to be running at
the same time.

Signed-off-by: Dov Murik 
---
 migration/confidential-ram.h |  2 ++
 migration/confidential-ram.c | 31 +++
 softmmu/runstate.c   |  1 +
 target/i386/sev.c|  2 ++
 4 files changed, 36 insertions(+)

diff --git a/migration/confidential-ram.h b/migration/confidential-ram.h
index 9a1027bdaf..2822c5ee3d 100644
--- a/migration/confidential-ram.h
+++ b/migration/confidential-ram.h
@@ -18,4 +18,6 @@ int cgs_mh_save_encrypted_page(QEMUFile *f, ram_addr_t 
src_gpa, uint32_t size,
 
 int cgs_mh_load_encrypted_page(QEMUFile *f, ram_addr_t dest_gpa);
 
+void register_end_of_confidential_ram(void);
+
 #endif
diff --git a/migration/confidential-ram.c b/migration/confidential-ram.c
index 0b821af774..982cf9b874 100644
--- a/migration/confidential-ram.c
+++ b/migration/confidential-ram.c
@@ -8,6 +8,8 @@
 #include "io/channel.h"
 #include "qapi/error.h"
 #include "exec/memory.h"
+#include "migration/vmstate.h"
+#include "sysemu/runstate.h"
 #include "trace.h"
 #include "confidential-ram.h"
 
@@ -225,3 +227,32 @@ int cgs_mh_load_encrypted_page(QEMUFile *f, ram_addr_t 
dest_gpa)
 }
 return ret;
 }
+
+typedef struct {
+bool dummy;
+} EndOfConfidentialRAMState;
+
+static EndOfConfidentialRAMState end_of_confidential_ram_state = { .dummy = 
false };
+
+static int end_of_confidential_ram_post_load(void *opaque, int version_id)
+{
+vm_stop(RUN_STATE_INMIGRATE);
+return 0;
+}
+
+static const VMStateDescription vmstate_end_of_confidential_ram = {
+.name = "end-of-confidential-ram",
+.priority = MIG_PRI_GICV3, /* TODO define new (higher) priority level */
+.version_id = 1,
+.post_load = end_of_confidential_ram_post_load,
+.fields = (VMStateField[]) {
+VMSTATE_BOOL(dummy, EndOfConfidentialRAMState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+void register_end_of_confidential_ram(void)
+{
+vmstate_register(NULL, 0, _end_of_confidential_ram,
+ _of_confidential_ram_state);
+}
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index 2874417b61..193413246d 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -131,6 +131,7 @@ static const RunStateTransition runstate_transitions_def[] 
= {
 { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
 { RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
 { RUN_STATE_RUNNING, RUN_STATE_PAUSED },
+{ RUN_STATE_RUNNING, RUN_STATE_INMIGRATE },
 { RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
 { RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
 { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 0f414df02f..da2d0cc699 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -33,6 +33,7 @@
 #include "exec/address-spaces.h"
 #include "monitor/monitor.h"
 #include "exec/confidential-guest-support.h"
+#include "migration/confidential-ram.h"
 #include "hw/i386/pc.h"
 
 #define TYPE_SEV_GUEST "sev-guest"
@@ -1011,6 +1012,7 @@ static void
 sev_register_types(void)
 {
 type_register_static(_guest_info);
+register_end_of_confidential_ram();
 }
 
 type_init(sev_register_types);
-- 
2.20.1




[RFC PATCH 00/26] Confidential guest live migration

2021-03-02 Thread Dov Murik
This is an RFC series for fast migration of confidential guests using an
in-guest migration helper that lives in OVMF.  QEMU VM live migration
needs to read source VM's RAM and write it in the target VM; this
mechanism doesn't work when the guest memory is encrypted or QEMU is
prevented from reading it in another way.  In order to support live
migration in such scenarios, we introduce an in-guest migration helper
which can securely extract RAM content from the guest in order to send
it to the target.  The migration helper is implemented as part of the
VM's firmware in OVMF.

We've implemented and tested this on AMD SEV, but expect most of the
processes can be used with other technologies that prevent direct access
of hypervisor to the guest's memory.  Specifically, we don't use SEV's
PSP migration commands (SEV_SEND_START, SEV_RECEIVE_START, etc) at all.

Corresponding RFC patches for OVMF have been posted by my colleague
Tobin Feldman-Fitzthum on edk2-devel.  Those include the crux of the
migration helper: a mailbox protocol over a shared memory page which
allows communication between QEMU and the migration helper.  In the
source VM this is used to read a page and encrypt it for transport; in
the target it is used to decrypt the incoming page and storing the
content in the correct address in the guest memory.  All encryption and
decryption operations occur inside the trusted context in the VM, and
therefore the VM's memory plaintext content is never accessible to the
hosts participating in the migration.

In order to allow OVMF to run the migration helper in parallel to the
guest OS, we introduce the notion of auxiliary vcpus, which are usable
for OVMF but are hidden from the guest OS.  These might have other
future uses for in-guest operations/agents.

In the target VM we need the migration handler running to receive
incoming RAM pages; to achieve that, we boot the VM into OVMF with a
special fw_cfg value that causes OVMF to not boot the guest OS; we then
allow QEMU to receive an incoming migration by issuing a new
start-migrate-incoming QMP command.

The confidential RAM migration requires checking whether a given guest
RAM page is encrypted or not.  This is currently achieved using AMD's
patches which track the encryption status of guest pages in KVM, using
hypercalls from OVMF and guest Linux to report changes of such status.
The QEMU side of these patches is included as the first two patches in
this series.  The concrete implementation of this page encryption tracking
is currently in flux in the KVM mailing list, but the underlying
implementation doesn't affect our confidential RAM migration as long as
it can check whether a given guest address is encrypted.

List of patches in this series:

1-2: reposting AMD encrypted page bitmap support.
3-11: introduce the notion of auxiliary vcpus.
12-21: introduce the migration specifics.
22-23: fix devices issues when loading state into a live VM
24: introduce the start-migrate-incoming QMP command to switch the
target into accepting the incoming migration.
25: remove SEV migration blocker
26: add documentation


Brijesh Singh (1):
  kvm: add support to sync the page encryption state bitmap

Dov Murik (21):
  linux-headers: Add definitions of KVM page encryption bitmap ioctls
  machine: Add auxcpus=N suboption to -smp
  hw/boards: Add aux flag to CPUArchId
  hw/i386: Mark auxiliary vcpus in possible_cpus
  cpu: Add boolean aux field to CPUState
  hw/i386: Set CPUState.aux=true for auxiliary vcpus
  softmmu: Don't sync aux vcpus in pre_loadvm
  softmmu: Add cpu_synchronize_without_aux_post_init
  migration: Add helpers to save confidential RAM
  migration: Add helpers to load confidential RAM
  migration: Introduce gpa_inside_migration_helper_shared_area
  migration: Save confidential guest RAM using migration helper
  migration: Load confidential guest RAM using migration helper
  migration: Stop VM after loading confidential RAM
  migration: Don't sync vcpus when migrating confidential guests
  migration: When starting target, don't sync auxiliary vcpus
  hw/isa/lpc_ich9: Allow updating an already-running VM
  target/i386: Re-sync kvm-clock after confidential guest migration
  migration: Add start-migrate-incoming QMP command
  target/i386: SEV: Allow migration unless there are no aux vcpus
  docs: Add confidential guest live migration documentation

Tobin Feldman-Fitzthum (4):
  hw/acpi: Don't include auxiliary vcpus in ACPI tables
  softmmu: Add pause_all_vcpus_except_aux
  migration: Stop non-aux vcpus before copying the last pages
  migration: Call migration handler cleanup routines

 docs/confidential-guest-live-migration.rst | 142 
 docs/confidential-guest-support.txt|   5 +
 docs/index.rst |   1 +
 qapi/migration.json|  26 +++
 include/exec/ram_addr.h| 197 
 include/exec/ramblock.h|   3 +
 include/exec/ramlist.h   

[RFC PATCH 22/26] hw/isa/lpc_ich9: Allow updating an already-running VM

2021-03-02 Thread Dov Murik
The post_load function crashed when we were loading the device state in
to an already-running guest.  This was because an existing memory region
as not deleted in ich9_lpc_rcba_update.

Signed-off-by: Dov Murik 
---
 hw/isa/lpc_ich9.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index d3145bf014..1fc1af3491 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -529,9 +529,10 @@ ich9_lpc_pmcon_update(ICH9LPCState *lpc)
 static int ich9_lpc_post_load(void *opaque, int version_id)
 {
 ICH9LPCState *lpc = opaque;
+uint32_t rcba_old = pci_get_long(lpc->d.config + ICH9_LPC_RCBA);
 
 ich9_lpc_pmbase_sci_update(lpc);
-ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RCBA_EN */);
+ich9_lpc_rcba_update(lpc, rcba_old);
 ich9_lpc_pmcon_update(lpc);
 return 0;
 }
-- 
2.20.1




[RFC PATCH 13/26] migration: Add helpers to load confidential RAM

2021-03-02 Thread Dov Murik
QEMU cannot write directly to the memory of memory-encrypted guests;
this breaks normal RAM-load in the migration target.  Instead, QEMU
asks a migration helper running on an auxiliary vcpu in the guest to
restore encrypted pages as they were received from the source to a
specific GPA.

The migration helper running inside the guest can safely decrypt the
pages arrived from the source and load them into their proper location
in the guest's memory.

Loading pages uses the same shared (unencrypted) pages which both QEMU
and the guest can read from and write to.

Signed-off-by: Dov Murik 
---
 migration/confidential-ram.h |  2 ++
 migration/confidential-ram.c | 37 
 migration/trace-events   |  1 +
 3 files changed, 40 insertions(+)

diff --git a/migration/confidential-ram.h b/migration/confidential-ram.h
index 0d49718d31..ebe4073bce 100644
--- a/migration/confidential-ram.h
+++ b/migration/confidential-ram.h
@@ -14,4 +14,6 @@ void cgs_mh_cleanup(void);
 int cgs_mh_save_encrypted_page(QEMUFile *f, ram_addr_t src_gpa, uint32_t size,
uint64_t *bytes_sent);
 
+int cgs_mh_load_encrypted_page(QEMUFile *f, ram_addr_t dest_gpa);
+
 #endif
diff --git a/migration/confidential-ram.c b/migration/confidential-ram.c
index 65a588e7f6..fe317ee74b 100644
--- a/migration/confidential-ram.c
+++ b/migration/confidential-ram.c
@@ -182,3 +182,40 @@ int cgs_mh_save_encrypted_page(QEMUFile *f, ram_addr_t 
src_gpa, uint32_t size,
 
 return ret;
 }
+
+int cgs_mh_load_encrypted_page(QEMUFile *f, ram_addr_t dest_gpa)
+{
+int ret = 1;
+uint32_t page_hdr_len, enc_page_len;
+
+init_cgs_mig_helper_if_needed();
+
+assert((dest_gpa & TARGET_PAGE_MASK) == dest_gpa);
+
+/* Read page header */
+page_hdr_len = qemu_get_be32(f);
+if (page_hdr_len > 1024) {
+error_report("confidential-ram: page header is too large (%d bytes) "
+ "when loading gpa %" PRIu64, page_hdr_len, dest_gpa);
+return -EINVAL;
+}
+cmhs.io_page_hdr->len = page_hdr_len;
+qemu_get_buffer(f, cmhs.io_page_hdr->data, page_hdr_len);
+
+/* Read encrypted page */
+enc_page_len = qemu_get_be32(f);
+if (enc_page_len != TARGET_PAGE_SIZE) {
+error_report("confidential-ram: encrypted page is too large (%d bytes) 
"
+ "when loading gpa %" PRIu64, enc_page_len, dest_gpa);
+return -EINVAL;
+}
+qemu_get_buffer(f, cmhs.io_page, enc_page_len);
+
+trace_encrypted_ram_load_page(page_hdr_len, enc_page_len, dest_gpa);
+ret = send_command_to_cgs_mig_helper(CGS_MIG_HELPER_CMD_DECRYPT, dest_gpa);
+if (ret) {
+error_report("confidential-ram: failed loading page at dest_gpa "
+ "%" PRIu64 ": ret=%d", dest_gpa, ret);
+}
+return ret;
+}
diff --git a/migration/trace-events b/migration/trace-events
index 929de4ca98..ef31cf78cb 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -345,4 +345,5 @@ migration_pagecache_init(int64_t max_num_items) "Setting 
cache buckets to %" PRI
 migration_pagecache_insert(void) "Error allocating page"
 
 # confidential-ram.c
+encrypted_ram_load_page(uint32_t hdr_len, uint32_t trans_len, uint64_t gpa) 
"hdr_len: %u, trans_len: %u, gpa: 0x%" PRIx64
 encrypted_ram_save_page(uint32_t size, uint64_t gpa) "size: %u, gpa: 0x%" 
PRIx64
-- 
2.20.1




[RFC PATCH 14/26] migration: Introduce gpa_inside_migration_helper_shared_area

2021-03-02 Thread Dov Murik
The gpa_inside_migration_helper_shared_area will be used to skip
migrating RAM pages that are used by the migration helper at the target.

Signed-off-by: Dov Murik 
---
 migration/confidential-ram.h | 2 ++
 migration/confidential-ram.c | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/migration/confidential-ram.h b/migration/confidential-ram.h
index ebe4073bce..9a1027bdaf 100644
--- a/migration/confidential-ram.h
+++ b/migration/confidential-ram.h
@@ -8,6 +8,8 @@
 #include "exec/cpu-common.h"
 #include "qemu-file.h"
 
+bool gpa_inside_migration_helper_shared_area(ram_addr_t gpa);
+
 void cgs_mh_init(void);
 void cgs_mh_cleanup(void);
 
diff --git a/migration/confidential-ram.c b/migration/confidential-ram.c
index fe317ee74b..0b821af774 100644
--- a/migration/confidential-ram.c
+++ b/migration/confidential-ram.c
@@ -68,6 +68,12 @@ static CGSMigHelperState cmhs = {0};
 #define MH_SHARED_CMD_PARAMS_ADDR0x82
 #define MH_SHARED_IO_PAGE_HDR_ADDR   (MH_SHARED_CMD_PARAMS_ADDR + 0x800)
 #define MH_SHARED_IO_PAGE_ADDR   (MH_SHARED_CMD_PARAMS_ADDR + 0x1000)
+#define MH_SHARED_LAST_BYTE  (MH_SHARED_CMD_PARAMS_ADDR + 0x1fff)
+
+bool gpa_inside_migration_helper_shared_area(ram_addr_t gpa)
+{
+return gpa >= MH_SHARED_CMD_PARAMS_ADDR && gpa <= MH_SHARED_LAST_BYTE;
+}
 
 void cgs_mh_init(void)
 {
-- 
2.20.1




[RFC PATCH 24/26] migration: Add start-migrate-incoming QMP command

2021-03-02 Thread Dov Murik
This command forces a running VM into a migrate-incoming state.  When
using guest-assisted migration (for confidential guests), the target
must be started so that its auxiliary vcpu is running the migration
helper; after it is ready we can start receiving the incoming migration
connection.

Signed-off-by: Dov Murik 
---
 qapi/migration.json   | 26 ++
 migration/migration.c |  5 +
 2 files changed, 31 insertions(+)

diff --git a/qapi/migration.json b/qapi/migration.json
index 6e5943fbb4..c7361e0038 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1569,6 +1569,32 @@
 ##
 { 'command': 'migrate-incoming', 'data': {'uri': 'str' } }
 
+##
+# @start-migrate-incoming:
+#
+# Force start an incoming migration even in a running VM.  This is used by the
+# target VM in guest-assisted migration of a confidential guest.
+#
+# @uri: The Uniform Resource Identifier identifying the source or
+#   address to listen on
+#
+# Returns: nothing on success
+#
+# Since: 6.0
+#
+# Notes:
+#
+# The uri format is the same as the -incoming command-line option.
+#
+# Example:
+#
+# -> { "execute": "start-migrate-incoming",
+#  "arguments": { "uri": "tcp::4446" } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'start-migrate-incoming', 'data': {'uri': 'str' } }
+
 ##
 # @xen-save-devices-state:
 #
diff --git a/migration/migration.c b/migration/migration.c
index 7ec25bd006..4729b89bef 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2098,6 +2098,11 @@ void qmp_migrate_incoming(const char *uri, Error **errp)
 once = false;
 }
 
+void qmp_start_migrate_incoming(const char *uri, Error **errp)
+{
+qemu_start_incoming_migration(uri, errp);
+}
+
 void qmp_migrate_recover(const char *uri, Error **errp)
 {
 MigrationIncomingState *mis = migration_incoming_get_current();
-- 
2.20.1




[RFC PATCH 23/26] target/i386: Re-sync kvm-clock after confidential guest migration

2021-03-02 Thread Dov Murik
If confidential guest support is active, set TSC to 0 on the target when
loading the CPU state.  This causes the guest OS to re-sync with
kvm-clock.

Without this change, the guest clocks after migration are stuck (don't
advance), except the *_COARSE clocks which advance normally.

Signed-off-by: Dov Murik 
---
 target/i386/machine.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/target/i386/machine.c b/target/i386/machine.c
index 3768a753af..36c52ec02e 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -297,8 +297,17 @@ static int cpu_post_load(void *opaque, int version_id)
 X86CPU *cpu = opaque;
 CPUState *cs = CPU(cpu);
 CPUX86State *env = >env;
+MachineState *ms = MACHINE(qdev_get_machine());
 int i;
 
+/*
+ * When loading the state of a confidential guest, set TSC to zero at allow
+ * the guest OS to re-sync with kvmclock.
+ */
+if (ms->cgs) {
+env->tsc = 0;
+}
+
 if (env->tsc_khz && env->user_tsc_khz &&
 env->tsc_khz != env->user_tsc_khz) {
 error_report("Mismatch between user-specified TSC frequency and "
-- 
2.20.1




  1   2   3   4   5   >