Re: [PATCH v10 3/7] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls

2022-10-03 Thread Damien Le Moal
On 2022/10/04 2:47, Stefan Hajnoczi wrote:
> On Thu, Sep 29, 2022 at 04:36:27PM +0800, Sam Li wrote:
>> Add a new zoned_host_device BlockDriver. The zoned_host_device option
>> accepts only zoned host block devices. By adding zone management
>> operations in this new BlockDriver, users can use the new block
>> layer APIs including Report Zone and four zone management operations
>> (open, close, finish, reset).
>>
>> Qemu-io uses the new APIs to perform zoned storage commands of the device:
>> zone_report(zrp), zone_open(zo), zone_close(zc), zone_reset(zrs),
>> zone_finish(zf).
>>
>> For example, to test zone_report, use following command:
>> $ ./build/qemu-io --image-opts -n driver=zoned_host_device, 
>> filename=/dev/nullb0
>> -c "zrp offset nr_zones"
>>
>> Signed-off-by: Sam Li 
>> Reviewed-by: Hannes Reinecke 
>> ---
>>  block/block-backend.c | 146 +
>>  block/file-posix.c| 340 +-
>>  block/io.c|  41 
>>  include/block/block-common.h  |   4 +
>>  include/block/block-io.h  |   7 +
>>  include/block/block_int-common.h  |  24 +++
>>  include/block/raw-aio.h   |   6 +-
>>  include/sysemu/block-backend-io.h |  17 ++
>>  meson.build   |   4 +
>>  qapi/block-core.json  |   8 +-
>>  qemu-io-cmds.c| 148 +
>>  11 files changed, 741 insertions(+), 4 deletions(-)
>>
>> diff --git a/block/block-backend.c b/block/block-backend.c
>> index d4a5df2ac2..f7f7acd6f4 100644
>> --- a/block/block-backend.c
>> +++ b/block/block-backend.c
>> @@ -1431,6 +1431,15 @@ typedef struct BlkRwCo {
>>  void *iobuf;
>>  int ret;
>>  BdrvRequestFlags flags;
>> +union {
>> +struct {
>> +unsigned int *nr_zones;
>> +BlockZoneDescriptor *zones;
>> +} zone_report;
>> +struct {
>> +BlockZoneOp op;
>> +} zone_mgmt;
>> +};
>>  } BlkRwCo;
>>  
>>  int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
>> @@ -1775,6 +1784,143 @@ int coroutine_fn blk_co_flush(BlockBackend *blk)
>>  return ret;
>>  }
>>  
>> +static void blk_aio_zone_report_entry(void *opaque) {
> 
> 
> The coroutine_fn annotation is missing:
> 
>   static void coroutine_fn blk_aio_zone_report_entry(void *opaque) {
> 
>> +BlkAioEmAIOCB *acb = opaque;
>> +BlkRwCo *rwco = >rwco;
>> +
>> +rwco->ret = blk_co_zone_report(rwco->blk, rwco->offset,
>> +   rwco->zone_report.nr_zones,
>> +   rwco->zone_report.zones);
>> +blk_aio_complete(acb);
>> +}
>> +
>> +BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
>> +unsigned int *nr_zones,
>> +BlockZoneDescriptor  *zones,
>> +BlockCompletionFunc *cb, void *opaque)
>> +{
>> +BlkAioEmAIOCB *acb;
>> +Coroutine *co;
>> +IO_CODE();
>> +
>> +blk_inc_in_flight(blk);
>> +acb = blk_aio_get(_aio_em_aiocb_info, blk, cb, opaque);
>> +acb->rwco = (BlkRwCo) {
>> +.blk= blk,
>> +.offset = offset,
>> +.ret= NOT_DONE,
>> +.zone_report = {
>> +.zones = zones,
>> +.nr_zones = nr_zones,
>> +},
>> +};
>> +acb->has_returned = false;
>> +
>> +co = qemu_coroutine_create(blk_aio_zone_report_entry, acb);
>> +bdrv_coroutine_enter(blk_bs(blk), co);
>> +
>> +acb->has_returned = true;
>> +if (acb->rwco.ret != NOT_DONE) {
>> +replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
>> + blk_aio_complete_bh, acb);
>> +}
>> +
>> +return >common;
>> +}
>> +
>> +static void blk_aio_zone_mgmt_entry(void *opaque) {
> 
> coroutine_fn is missing here.
> 
>> +BlkAioEmAIOCB *acb = opaque;
>> +BlkRwCo *rwco = >rwco;
>> +
>> +rwco->ret = blk_co_zone_mgmt(rwco->blk, rwco->zone_mgmt.op,
>> + rwco->offset, acb->bytes);
>> +blk_aio_complete(acb);
>> +}
>> +
>> +BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
>> +  int64_t offset, int64_t len,
>> +  BlockCompletionFunc *cb, void *opaque) {
>> +BlkAioEmAIOCB *acb;
>> +Coroutine *co;
>> +IO_CODE();
>> +
>> +blk_inc_in_flight(blk);
>> +acb = blk_aio_get(_aio_em_aiocb_info, blk, cb, opaque);
>> +acb->rwco = (BlkRwCo) {
>> +.blk= blk,
>> +.offset = offset,
>> +.ret= NOT_DONE,
>> +.zone_mgmt = {
>> +.op = op,
>> +},
>> +};
>> +acb->bytes = len;
>> +acb->has_returned = false;
>> +
>> +co = qemu_coroutine_create(blk_aio_zone_mgmt_entry, acb);
>> +bdrv_coroutine_enter(blk_bs(blk), co);
>> +
>> +acb->has_returned = true;
>> +if (acb->rwco.ret != NOT_DONE) {
>> +

Re: [PULL 00/18] Block layer patches

2022-10-03 Thread Stefan Hajnoczi
Applied, thanks.

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


signature.asc
Description: PGP signature


Re: [PATCH v2 04/13] hw/ppc/e500: Reduce usage of sysbus API

2022-10-03 Thread Philippe Mathieu-Daudé via

On 3/10/22 22:31, Bernhard Beschow wrote:

PlatformBusDevice has an mmio attribute which gets aliased to
SysBusDevice::mmio[0]. So PlatformbusDevice::mmio can be used directly,
avoiding the sysbus API.

Signed-off-by: Bernhard Beschow 
---
  hw/ppc/e500.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v2 00/13] ppc/e500: Add support for two types of flash, cleanup

2022-10-03 Thread Philippe Mathieu-Daudé via

Hi Daniel,

On 3/10/22 22:31, Bernhard Beschow wrote:

Cover letter:
~

This series adds support for -pflash and direct SD card access to the
PPC e500 boards. The idea is to increase compatibility with "real" firmware
images where only the bare minimum of drivers is compiled in.



Bernhard Beschow (13):
   hw/ppc/meson: Allow e500 boards to be enabled separately
   hw/gpio/meson: Introduce dedicated config switch for hw/gpio/mpc8xxx
   docs/system/ppc/ppce500: Add heading for networking chapter
   hw/ppc/e500: Reduce usage of sysbus API
   hw/ppc/mpc8544ds: Rename wrongly named method
   hw/ppc/mpc8544ds: Add platform bus
   hw/ppc/e500: Remove if statement which is now always true


This first part is mostly reviewed and can already go via your
ppc-next queue.


   hw/block/pflash_cfi01: Error out if device length isn't a power of two
   hw/ppc/e500: Implement pflash handling
   hw/sd/sdhci-internal: Unexport ESDHC defines
   hw/sd/sdhci: Rename ESDHC_* defines to USDHC_*
   hw/sd/sdhci: Implement Freescale eSDHC device model
   hw/ppc/e500: Add Freescale eSDHC to e500 boards


This second part still need work. I can take it via the sdmmc-next
queue.

Regards,

Phil.



Re: [PATCH v2 07/13] hw/ppc/e500: Remove if statement which is now always true

2022-10-03 Thread Philippe Mathieu-Daudé via

On 3/10/22 22:31, Bernhard Beschow wrote:

Now that the MPC8544DS board also has a platform bus, the if statement
is always true.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
  hw/ppc/e500.c  | 30 ++
  hw/ppc/e500.h  |  1 -
  hw/ppc/e500plat.c  |  1 -
  hw/ppc/mpc8544ds.c |  1 -
  4 files changed, 14 insertions(+), 19 deletions(-)



  /* Platform Bus Device */
-if (pmc->has_platform_bus) {
-dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
-dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
-qdev_prop_set_uint32(dev, "num_irqs", pmc->platform_bus_num_irqs);
-qdev_prop_set_uint32(dev, "mmio_size", pmc->platform_bus_size);
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
-pms->pbus_dev = PLATFORM_BUS_DEVICE(dev);
-
-s = SYS_BUS_DEVICE(pms->pbus_dev);
-for (i = 0; i < pmc->platform_bus_num_irqs; i++) {
-int irqn = pmc->platform_bus_first_irq + i;
-sysbus_connect_irq(s, i, qdev_get_gpio_in(mpicdev, irqn));
-}
+dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
+dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
+qdev_prop_set_uint32(dev, "num_irqs", pmc->platform_bus_num_irqs);
+qdev_prop_set_uint32(dev, "mmio_size", pmc->platform_bus_size);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);


Should we abort(pmc->platform_bus_size > 0) now?


+pms->pbus_dev = PLATFORM_BUS_DEVICE(dev);
  
-memory_region_add_subregion(address_space_mem,

-pmc->platform_bus_base,
->pbus_dev->mmio);
+s = SYS_BUS_DEVICE(pms->pbus_dev);
+for (i = 0; i < pmc->platform_bus_num_irqs; i++) {
+int irqn = pmc->platform_bus_first_irq + i;
+sysbus_connect_irq(s, i, qdev_get_gpio_in(mpicdev, irqn));
  }
  
+memory_region_add_subregion(address_space_mem,

+pmc->platform_bus_base,
+>pbus_dev->mmio);




Re: [PATCH v2 13/13] hw/ppc/e500: Add Freescale eSDHC to e500 boards

2022-10-03 Thread Philippe Mathieu-Daudé via

On 3/10/22 22:31, Bernhard Beschow wrote:

Adds missing functionality to emulated e500 SOCs which increases the
chance of given "real" firmware images to access SD cards.

Signed-off-by: Bernhard Beschow 
---
  docs/system/ppc/ppce500.rst | 13 +
  hw/ppc/Kconfig  |  1 +
  hw/ppc/e500.c   | 31 ++-
  3 files changed, 44 insertions(+), 1 deletion(-)



+static void dt_sdhc_create(void *fdt, const char *parent, const char *mpic)
+{
+hwaddr mmio = MPC85XX_ESDHC_REGS_OFFSET;
+hwaddr size = MPC85XX_ESDHC_REGS_SIZE;
+int irq = MPC85XX_ESDHC_IRQ;


Why not pass these 3 variable as argument?


+g_autofree char *name = NULL;
+
+name = g_strdup_printf("%s/sdhc@%" PRIx64, parent, mmio);
+qemu_fdt_add_subnode(fdt, name);
+qemu_fdt_setprop(fdt, name, "sdhci,auto-cmd12", NULL, 0);
+qemu_fdt_setprop_phandle(fdt, name, "interrupt-parent", mpic);
+qemu_fdt_setprop_cells(fdt, name, "bus-width", 4);
+qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x2);
+qemu_fdt_setprop_cells(fdt, name, "reg", mmio, size);
+qemu_fdt_setprop_string(fdt, name, "compatible", "fsl,esdhc");
+}
  
  typedef struct PlatformDevtreeData {

  void *fdt;
@@ -553,6 +573,8 @@ static int ppce500_load_device_tree(PPCE500MachineState 
*pms,
  
  dt_rtc_create(fdt, "i2c", "rtc");
  
+/* sdhc */

+dt_sdhc_create(fdt, soc, mpic);
  




Re: [PATCH v2 08/13] hw/block/pflash_cfi01: Error out if device length isn't a power of two

2022-10-03 Thread Philippe Mathieu-Daudé via

On 3/10/22 22:31, Bernhard Beschow wrote:

According to the JEDEC standard the device length is communicated to an
OS as an exponent (power of two).

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
---
  hw/block/pflash_cfi01.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)


With CFI02 similarly fixed:
Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v2 09/13] hw/ppc/e500: Implement pflash handling

2022-10-03 Thread Philippe Mathieu-Daudé via

On 3/10/22 22:31, Bernhard Beschow wrote:

Allows e500 boards to have their root file system reside on flash using
only builtin devices located in the eLBC memory region.

Note that the flash memory area is only created when a -pflash argument is
given, and that the size is determined by the given file. The idea is to
put users into control.

Signed-off-by: Bernhard Beschow 
---
  docs/system/ppc/ppce500.rst | 12 ++
  hw/ppc/Kconfig  |  1 +
  hw/ppc/e500.c   | 76 +
  3 files changed, 89 insertions(+)



@@ -856,6 +892,7 @@ void ppce500_init(MachineState *machine)
  unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4};
  IrqLines *irqs;
  DeviceState *dev, *mpicdev;
+DriveInfo *dinfo;
  CPUPPCState *firstenv = NULL;
  MemoryRegion *ccsr_addr_space;
  SysBusDevice *s;
@@ -1024,6 +1061,45 @@ void ppce500_init(MachineState *machine)
  pmc->platform_bus_base,
  >pbus_dev->mmio);
  
+dinfo = drive_get(IF_PFLASH, 0, 0);

+if (dinfo) {
+BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+BlockDriverState *bs = blk_bs(blk);
+uint64_t size = bdrv_getlength(bs);
+uint64_t mmio_size = pms->pbus_dev->mmio.size;
+uint32_t sector_len = 64 * KiB;
+
+if (ctpop64(size) != 1) {
+error_report("Size of pflash file must be a power of two.");


This is a PFLASH restriction (which you already fixed in the previous
patch), not a board one.


+exit(1);
+}
+
+if (size > mmio_size) {
+error_report("Size of pflash file must not be bigger than %" PRIu64
+ " bytes.", mmio_size);


There is no hardware limitation here, you can wire flash bigger than the
memory aperture. What is above the aperture will simply be ignored.

Should we display a warning here instead of a fatal error?


+exit(1);
+}
+
+assert(QEMU_IS_ALIGNED(size, sector_len));


Similarly, this doesn't seem a problem the board code should worry
about: better to defer it to PFLASH realize().


+dev = qdev_new(TYPE_PFLASH_CFI01);
+qdev_prop_set_drive(dev, "drive", blk);
+qdev_prop_set_uint32(dev, "num-blocks", size / sector_len);
+qdev_prop_set_uint64(dev, "sector-length", sector_len);
+qdev_prop_set_uint8(dev, "width", 2);
+qdev_prop_set_bit(dev, "big-endian", true);
+qdev_prop_set_uint16(dev, "id0", 0x89);
+qdev_prop_set_uint16(dev, "id1", 0x18);
+qdev_prop_set_uint16(dev, "id2", 0x);
+qdev_prop_set_uint16(dev, "id3", 0x0);
+qdev_prop_set_string(dev, "name", "e500.flash");
+s = SYS_BUS_DEVICE(dev);
+sysbus_realize_and_unref(s, _fatal);
+
+memory_region_add_subregion(>pbus_dev->mmio, 0,
+sysbus_mmio_get_region(s, 0));
+}
+
  /*
   * Smart firmware defaults ahead!
   *





[PATCH v2 08/13] hw/block/pflash_cfi01: Error out if device length isn't a power of two

2022-10-03 Thread Bernhard Beschow
According to the JEDEC standard the device length is communicated to an
OS as an exponent (power of two).

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
---
 hw/block/pflash_cfi01.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 0cbc2fb4cb..8c9b3f518a 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -690,7 +690,7 @@ static const MemoryRegionOps pflash_cfi01_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl)
+static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl, Error **errp)
 {
 uint64_t blocks_per_device, sector_len_per_device, device_len;
 int num_devices;
@@ -708,6 +708,10 @@ static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl)
 sector_len_per_device = pfl->sector_len / num_devices;
 }
 device_len = sector_len_per_device * blocks_per_device;
+if (ctpop64(device_len) != 1) {
+error_setg(errp, "Device size must be a power of two.");
+return;
+}
 
 /* Hardcoded CFI table */
 /* Standard "QRY" string */
@@ -865,7 +869,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
  */
 pfl->cmd = 0x00;
 pfl->status = 0x80; /* WSM ready */
-pflash_cfi01_fill_cfi_table(pfl);
+pflash_cfi01_fill_cfi_table(pfl, errp);
 }
 
 static void pflash_cfi01_system_reset(DeviceState *dev)
-- 
2.37.3




[PATCH v2 13/13] hw/ppc/e500: Add Freescale eSDHC to e500 boards

2022-10-03 Thread Bernhard Beschow
Adds missing functionality to emulated e500 SOCs which increases the
chance of given "real" firmware images to access SD cards.

Signed-off-by: Bernhard Beschow 
---
 docs/system/ppc/ppce500.rst | 13 +
 hw/ppc/Kconfig  |  1 +
 hw/ppc/e500.c   | 31 ++-
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst
index 1ed6c36599..c758aa51eb 100644
--- a/docs/system/ppc/ppce500.rst
+++ b/docs/system/ppc/ppce500.rst
@@ -19,6 +19,7 @@ The ``ppce500`` machine supports the following devices:
 * Power-off functionality via one GPIO pin
 * 1 Freescale MPC8xxx PCI host controller
 * VirtIO devices via PCI bus
+* 1 Freescale Enhanced Secure Digital Host controller (eSDHC)
 * 1 Freescale Enhanced Triple Speed Ethernet controller (eTSEC)
 
 Hardware configuration information
@@ -131,6 +132,18 @@ be used as follows:
   -drive if=pflash,file=/path/to/rootfs.ext2,format=raw \
   -append "rootwait root=/dev/mtdblock0"
 
+Alternatively, the root file system can also reside on an emulated SD card
+whose size must again be a power of two:
+
+.. code-block:: bash
+
+  $ qemu-system-ppc{64|32} -M ppce500 -cpu e500mc -smp 4 -m 2G \
+  -display none -serial stdio \
+  -kernel vmlinux \
+  -device sd-card,drive=mydrive \
+  -drive id=mydrive,if=none,file=/path/to/rootfs.ext2,format=raw \
+  -append "rootwait root=/dev/mmcblk0"
+
 Running U-Boot
 --
 
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 769a1ead1c..6e31f568ba 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -129,6 +129,7 @@ config E500
 select PFLASH_CFI01
 select PLATFORM_BUS
 select PPCE500_PCI
+select SDHCI
 select SERIAL
 select MPC_I2C
 select FDT_PPC
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 2b1430fca4..379d89bf2d 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -48,6 +48,7 @@
 #include "hw/net/fsl_etsec/etsec.h"
 #include "hw/i2c/i2c.h"
 #include "hw/irq.h"
+#include "hw/sd/sdhci.h"
 
 #define EPAPR_MAGIC(0x45504150)
 #define DTC_LOAD_PAD   0x180
@@ -66,11 +67,14 @@
 #define MPC8544_SERIAL1_REGS_OFFSET 0x4600ULL
 #define MPC8544_PCI_REGS_OFFSET0x8000ULL
 #define MPC8544_PCI_REGS_SIZE  0x1000ULL
+#define MPC85XX_ESDHC_REGS_OFFSET  0x2e000ULL
+#define MPC85XX_ESDHC_REGS_SIZE0x1000ULL
 #define MPC8544_UTIL_OFFSET0xeULL
 #define MPC8XXX_GPIO_OFFSET0x000FF000ULL
 #define MPC8544_I2C_REGS_OFFSET0x3000ULL
 #define MPC8XXX_GPIO_IRQ   47
 #define MPC8544_I2C_IRQ43
+#define MPC85XX_ESDHC_IRQ  72
 #define RTC_REGS_OFFSET0x68
 
 #define PLATFORM_CLK_FREQ_HZ   (400 * 1000 * 1000)
@@ -203,6 +207,22 @@ static void dt_i2c_create(void *fdt, const char *soc, 
const char *mpic,
 g_free(i2c);
 }
 
+static void dt_sdhc_create(void *fdt, const char *parent, const char *mpic)
+{
+hwaddr mmio = MPC85XX_ESDHC_REGS_OFFSET;
+hwaddr size = MPC85XX_ESDHC_REGS_SIZE;
+int irq = MPC85XX_ESDHC_IRQ;
+g_autofree char *name = NULL;
+
+name = g_strdup_printf("%s/sdhc@%" PRIx64, parent, mmio);
+qemu_fdt_add_subnode(fdt, name);
+qemu_fdt_setprop(fdt, name, "sdhci,auto-cmd12", NULL, 0);
+qemu_fdt_setprop_phandle(fdt, name, "interrupt-parent", mpic);
+qemu_fdt_setprop_cells(fdt, name, "bus-width", 4);
+qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x2);
+qemu_fdt_setprop_cells(fdt, name, "reg", mmio, size);
+qemu_fdt_setprop_string(fdt, name, "compatible", "fsl,esdhc");
+}
 
 typedef struct PlatformDevtreeData {
 void *fdt;
@@ -553,6 +573,8 @@ static int ppce500_load_device_tree(PPCE500MachineState 
*pms,
 
 dt_rtc_create(fdt, "i2c", "rtc");
 
+/* sdhc */
+dt_sdhc_create(fdt, soc, mpic);
 
 gutil = g_strdup_printf("%s/global-utilities@%llx", soc,
 MPC8544_UTIL_OFFSET);
@@ -982,7 +1004,8 @@ void ppce500_init(MachineState *machine)
0, qdev_get_gpio_in(mpicdev, 42), 399193,
serial_hd(1), DEVICE_BIG_ENDIAN);
 }
-/* I2C */
+
+/* I2C */
 dev = qdev_new("mpc-i2c");
 s = SYS_BUS_DEVICE(dev);
 sysbus_realize_and_unref(s, _fatal);
@@ -992,6 +1015,12 @@ void ppce500_init(MachineState *machine)
 i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
 i2c_slave_create_simple(i2c, "ds1338", RTC_REGS_OFFSET);
 
+/* eSDHC */
+dev = qdev_new(TYPE_FSL_ESDHC);
+s = SYS_BUS_DEVICE(dev);
+sysbus_realize_and_unref(s, _fatal);
+sysbus_mmio_map(s, 0, pmc->ccsrbar_base + MPC85XX_ESDHC_REGS_OFFSET);
+sysbus_connect_irq(s, 0, qdev_get_gpio_in(mpicdev, MPC85XX_ESDHC_IRQ));
 
 /* General Utility device */
 dev = qdev_new("mpc8544-guts");
-- 
2.37.3




[PATCH v2 09/13] hw/ppc/e500: Implement pflash handling

2022-10-03 Thread Bernhard Beschow
Allows e500 boards to have their root file system reside on flash using
only builtin devices located in the eLBC memory region.

Note that the flash memory area is only created when a -pflash argument is
given, and that the size is determined by the given file. The idea is to
put users into control.

Signed-off-by: Bernhard Beschow 
---
 docs/system/ppc/ppce500.rst | 12 ++
 hw/ppc/Kconfig  |  1 +
 hw/ppc/e500.c   | 76 +
 3 files changed, 89 insertions(+)

diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst
index ba6bcb7314..1ed6c36599 100644
--- a/docs/system/ppc/ppce500.rst
+++ b/docs/system/ppc/ppce500.rst
@@ -119,6 +119,18 @@ To boot the 32-bit Linux kernel:
   -initrd /path/to/rootfs.cpio \
   -append "root=/dev/ram"
 
+Rather than using a root file system on ram disk, it is possible to have it on
+emulated flash. Given an ext2 image whose size must be a power of two, it can
+be used as follows:
+
+.. code-block:: bash
+
+  $ qemu-system-ppc{64|32} -M ppce500 -cpu e500mc -smp 4 -m 2G \
+  -display none -serial stdio \
+  -kernel vmlinux \
+  -drive if=pflash,file=/path/to/rootfs.ext2,format=raw \
+  -append "rootwait root=/dev/mtdblock0"
+
 Running U-Boot
 --
 
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 791fe78a50..769a1ead1c 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -126,6 +126,7 @@ config E500
 select ETSEC
 select GPIO_MPC8XXX
 select OPENPIC
+select PFLASH_CFI01
 select PLATFORM_BUS
 select PPCE500_PCI
 select SERIAL
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 3e950ea3ba..2b1430fca4 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -23,8 +23,10 @@
 #include "e500-ccsr.h"
 #include "net/net.h"
 #include "qemu/config-file.h"
+#include "hw/block/flash.h"
 #include "hw/char/serial.h"
 #include "hw/pci/pci.h"
+#include "sysemu/block-backend-io.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
 #include "sysemu/reset.h"
@@ -267,6 +269,31 @@ static void sysbus_device_create_devtree(SysBusDevice 
*sbdev, void *opaque)
 }
 }
 
+static void create_devtree_flash(SysBusDevice *sbdev,
+ PlatformDevtreeData *data)
+{
+g_autofree char *name = NULL;
+uint64_t num_blocks = object_property_get_uint(OBJECT(sbdev),
+   "num-blocks",
+   _fatal);
+uint64_t sector_length = object_property_get_uint(OBJECT(sbdev),
+  "sector-length",
+  _fatal);
+uint64_t bank_width = object_property_get_uint(OBJECT(sbdev),
+   "width",
+   _fatal);
+hwaddr flashbase = 0;
+hwaddr flashsize = num_blocks * sector_length;
+void *fdt = data->fdt;
+
+name = g_strdup_printf("%s/nor@%" PRIx64, data->node, flashbase);
+qemu_fdt_add_subnode(fdt, name);
+qemu_fdt_setprop_string(fdt, name, "compatible", "cfi-flash");
+qemu_fdt_setprop_sized_cells(fdt, name, "reg",
+ 1, flashbase, 1, flashsize);
+qemu_fdt_setprop_cell(fdt, name, "bank-width", bank_width);
+}
+
 static void platform_bus_create_devtree(PPCE500MachineState *pms,
 void *fdt, const char *mpic)
 {
@@ -276,6 +303,8 @@ static void platform_bus_create_devtree(PPCE500MachineState 
*pms,
 uint64_t addr = pmc->platform_bus_base;
 uint64_t size = pmc->platform_bus_size;
 int irq_start = pmc->platform_bus_first_irq;
+SysBusDevice *sbdev;
+bool ambiguous;
 
 /* Create a /platform node that we can put all devices into */
 
@@ -302,6 +331,13 @@ static void 
platform_bus_create_devtree(PPCE500MachineState *pms,
 /* Loop through all dynamic sysbus devices and create nodes for them */
 foreach_dynamic_sysbus_device(sysbus_device_create_devtree, );
 
+sbdev = SYS_BUS_DEVICE(object_resolve_path_type("", TYPE_PFLASH_CFI01,
+));
+if (sbdev) {
+assert(!ambiguous);
+create_devtree_flash(sbdev, );
+}
+
 g_free(node);
 }
 
@@ -856,6 +892,7 @@ void ppce500_init(MachineState *machine)
 unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4};
 IrqLines *irqs;
 DeviceState *dev, *mpicdev;
+DriveInfo *dinfo;
 CPUPPCState *firstenv = NULL;
 MemoryRegion *ccsr_addr_space;
 SysBusDevice *s;
@@ -1024,6 +1061,45 @@ void ppce500_init(MachineState *machine)
 pmc->platform_bus_base,
 >pbus_dev->mmio);
 
+dinfo = drive_get(IF_PFLASH, 0, 0);
+if (dinfo) {
+BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+BlockDriverState *bs = blk_bs(blk);
+uint64_t size = bdrv_getlength(bs);

[PATCH v2 12/13] hw/sd/sdhci: Implement Freescale eSDHC device model

2022-10-03 Thread Bernhard Beschow
Will allow e500 boards to access SD cards using just their own devices.

Signed-off-by: Bernhard Beschow 
---
 hw/sd/sdhci.c | 147 +-
 include/hw/sd/sdhci.h |   3 +
 2 files changed, 149 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 306070c872..ff92c6c4e5 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1369,6 +1369,7 @@ void sdhci_initfn(SDHCIState *s)
 s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, 
s);
 
 s->io_ops = _mmio_ops;
+s->io_registers_map_size = SDHC_REGISTERS_MAP_SIZE;
 }
 
 void sdhci_uninitfn(SDHCIState *s)
@@ -1392,7 +1393,7 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
 s->fifo_buffer = g_malloc0(s->buf_maxsz);
 
 memory_region_init_io(>iomem, OBJECT(s), s->io_ops, s, "sdhci",
-  SDHC_REGISTERS_MAP_SIZE);
+  s->io_registers_map_size);
 }
 
 void sdhci_common_unrealize(SDHCIState *s)
@@ -1575,6 +1576,149 @@ static const TypeInfo sdhci_bus_info = {
 .class_init = sdhci_bus_class_init,
 };
 
+/* --- qdev Freescale eSDHC --- */
+
+/* Watermark Level Register */
+#define ESDHC_WML0x44
+
+/* Host Controller Capabilities Register 2 */
+#define ESDHC_CAPABILITIES_10x114
+
+/* Control Register for DMA transfer */
+#define ESDHC_DMA_SYSCTL0x40c
+
+#define ESDHC_REGISTERS_MAP_SIZE0x410
+
+static uint64_t esdhci_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint64_t ret;
+
+if (size != 4) {
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx
+  " wrong size\n", size, offset);
+return 0;
+}
+
+if (offset & 0x3) {
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx
+  " unaligned\n", size, offset);
+return 0;
+}
+
+switch (offset) {
+case SDHC_SYSAD:
+case SDHC_BLKSIZE:
+case SDHC_ARGUMENT:
+case SDHC_TRNMOD:
+case SDHC_RSPREG0:
+case SDHC_RSPREG1:
+case SDHC_RSPREG2:
+case SDHC_RSPREG3:
+case SDHC_BDATA:
+case SDHC_PRNSTS:
+case SDHC_HOSTCTL:
+case SDHC_CLKCON:
+case SDHC_NORINTSTS:
+case SDHC_NORINTSTSEN:
+case SDHC_NORINTSIGEN:
+case SDHC_ACMD12ERRSTS:
+case SDHC_CAPAB:
+case SDHC_SLOT_INT_STATUS:
+ret = sdhci_read(opaque, offset, size);
+break;
+
+case ESDHC_WML:
+case ESDHC_DMA_SYSCTL:
+ret = 0;
+qemu_log_mask(LOG_UNIMP, "ESDHC rd_%ub @0x%02" HWADDR_PRIx
+  " not implemented\n", size, offset);
+break;
+
+default:
+ret = 0;
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx
+  " unknown offset\n", size, offset);
+break;
+}
+
+return ret;
+}
+
+static void esdhci_write(void *opaque, hwaddr offset, uint64_t val,
+ unsigned size)
+{
+if (size != 4) {
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx
+  " <- 0x%08lx wrong size\n", size, offset, val);
+return;
+}
+
+if (offset & 0x3) {
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx
+  " <- 0x%08lx unaligned\n", size, offset, val);
+return;
+}
+
+switch (offset) {
+case SDHC_SYSAD:
+case SDHC_BLKSIZE:
+case SDHC_ARGUMENT:
+case SDHC_TRNMOD:
+case SDHC_BDATA:
+case SDHC_HOSTCTL:
+case SDHC_CLKCON:
+case SDHC_NORINTSTS:
+case SDHC_NORINTSTSEN:
+case SDHC_NORINTSIGEN:
+case SDHC_FEAER:
+sdhci_write(opaque, offset, val, size);
+break;
+
+case ESDHC_WML:
+case ESDHC_DMA_SYSCTL:
+qemu_log_mask(LOG_UNIMP, "ESDHC wr_%ub @0x%02" HWADDR_PRIx " <- 
0x%08lx "
+  "not implemented\n", size, offset, val);
+break;
+
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx
+  " <- 0x%08lx unknown offset\n", size, offset, val);
+break;
+}
+}
+
+static const MemoryRegionOps esdhc_mmio_ops = {
+.read = esdhci_read,
+.write = esdhci_write,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+.unaligned = false
+},
+.endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void esdhci_init(Object *obj)
+{
+DeviceState *dev = DEVICE(obj);
+SDHCIState *s = SYSBUS_SDHCI(obj);
+
+s->io_ops = _mmio_ops;
+s->io_registers_map_size = ESDHC_REGISTERS_MAP_SIZE;
+
+/*
+ * Compatible with:
+ * - SD Host Controller Specification Version 2.0 Part A2
+ */
+qdev_prop_set_uint8(dev, "sd-spec-version", 2);
+}
+
+static const TypeInfo esdhc_info = {
+.name = TYPE_FSL_ESDHC,
+.parent = TYPE_SYSBUS_SDHCI,
+.instance_init = esdhci_init,
+};
+
 /* --- qdev i.MX eSDHC --- */
 
 #define USDHC_MIX_CTRL  0x48
@@ -1907,6 

Re: [PATCH v2 12/13] hw/sd/sdhci: Implement Freescale eSDHC device model

2022-10-03 Thread Philippe Mathieu-Daudé via

On 3/10/22 22:31, Bernhard Beschow wrote:

Will allow e500 boards to access SD cards using just their own devices.

Signed-off-by: Bernhard Beschow 
---
  hw/sd/sdhci.c | 147 +-
  include/hw/sd/sdhci.h |   3 +
  2 files changed, 149 insertions(+), 1 deletion(-)



+/* --- qdev Freescale eSDHC --- */
+
+/* Watermark Level Register */
+#define ESDHC_WML0x44
+
+/* Host Controller Capabilities Register 2 */
+#define ESDHC_CAPABILITIES_10x114


Not used?


+
+/* Control Register for DMA transfer */
+#define ESDHC_DMA_SYSCTL0x40c
+
+#define ESDHC_REGISTERS_MAP_SIZE0x410
+
+static uint64_t esdhci_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint64_t ret;
+
+if (size != 4) {
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx
+  " wrong size\n", size, offset);
+return 0;
+}
+
+if (offset & 0x3) {
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx
+  " unaligned\n", size, offset);
+return 0;


Isn't it already enforced by esdhc_mmio_ops.valid.unaligned = false?


+}
+
+switch (offset) {
+case SDHC_SYSAD:
+case SDHC_BLKSIZE:
+case SDHC_ARGUMENT:
+case SDHC_TRNMOD:
+case SDHC_RSPREG0:
+case SDHC_RSPREG1:
+case SDHC_RSPREG2:
+case SDHC_RSPREG3:
+case SDHC_BDATA:
+case SDHC_PRNSTS:
+case SDHC_HOSTCTL:
+case SDHC_CLKCON:
+case SDHC_NORINTSTS:
+case SDHC_NORINTSTSEN:
+case SDHC_NORINTSIGEN:
+case SDHC_ACMD12ERRSTS:
+case SDHC_CAPAB:
+case SDHC_SLOT_INT_STATUS:
+ret = sdhci_read(opaque, offset, size);
+break;
+
+case ESDHC_WML:
+case ESDHC_DMA_SYSCTL:
+ret = 0;
+qemu_log_mask(LOG_UNIMP, "ESDHC rd_%ub @0x%02" HWADDR_PRIx
+  " not implemented\n", size, offset);
+break;
+
+default:
+ret = 0;
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx
+  " unknown offset\n", size, offset);
+break;
+}
+
+return ret;
+}
+
+static void esdhci_write(void *opaque, hwaddr offset, uint64_t val,
+ unsigned size)
+{
+if (size != 4) {
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx
+  " <- 0x%08lx wrong size\n", size, offset, val);
+return;
+}
+
+if (offset & 0x3) {
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx
+  " <- 0x%08lx unaligned\n", size, offset, val);
+return;
+}
+
+switch (offset) {
+case SDHC_SYSAD:
+case SDHC_BLKSIZE:
+case SDHC_ARGUMENT:
+case SDHC_TRNMOD:
+case SDHC_BDATA:
+case SDHC_HOSTCTL:
+case SDHC_CLKCON:
+case SDHC_NORINTSTS:
+case SDHC_NORINTSTSEN:
+case SDHC_NORINTSIGEN:
+case SDHC_FEAER:
+sdhci_write(opaque, offset, val, size);
+break;
+
+case ESDHC_WML:
+case ESDHC_DMA_SYSCTL:
+qemu_log_mask(LOG_UNIMP, "ESDHC wr_%ub @0x%02" HWADDR_PRIx " <- 0x%08lx 
"
+  "not implemented\n", size, offset, val);
+break;
+
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx
+  " <- 0x%08lx unknown offset\n", size, offset, val);
+break;
+}
+}
+
+static const MemoryRegionOps esdhc_mmio_ops = {
+.read = esdhci_read,
+.write = esdhci_write,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+.unaligned = false
+},
+.endianness = DEVICE_BIG_ENDIAN,
+};




Re: [PATCH v2 05/13] hw/ppc/mpc8544ds: Rename wrongly named method

2022-10-03 Thread Philippe Mathieu-Daudé via

On 3/10/22 22:31, Bernhard Beschow wrote:

Signed-off-by: Bernhard Beschow 
---
  hw/ppc/mpc8544ds.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v2 10/13] hw/sd/sdhci-internal: Unexport ESDHC defines

2022-10-03 Thread Bernhard Beschow
These defines aren't used outside of sdhci.c, so can be defined there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/sd/sdhci-internal.h | 20 
 hw/sd/sdhci.c  | 19 +++
 2 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index e8c753d6d1..964570f8e8 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -288,26 +288,6 @@ enum {
 
 extern const VMStateDescription sdhci_vmstate;
 
-
-#define ESDHC_MIX_CTRL  0x48
-
-#define ESDHC_VENDOR_SPEC   0xc0
-#define ESDHC_IMX_FRC_SDCLK_ON  (1 << 8)
-
-#define ESDHC_DLL_CTRL  0x60
-
-#define ESDHC_TUNING_CTRL   0xcc
-#define ESDHC_TUNE_CTRL_STATUS  0x68
-#define ESDHC_WTMK_LVL  0x44
-
-/* Undocumented register used by guests working around erratum ERR004536 */
-#define ESDHC_UNDOCUMENTED_REG270x6c
-
-#define ESDHC_CTRL_4BITBUS  (0x1 << 1)
-#define ESDHC_CTRL_8BITBUS  (0x2 << 1)
-
-#define ESDHC_PRNSTS_SDSTB  (1 << 3)
-
 /*
  * Default SD/MMC host controller features information, which will be
  * presented in CAPABILITIES register of generic SD host controller at reset.
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 0e5e988927..6da5e2c781 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1577,6 +1577,25 @@ static const TypeInfo sdhci_bus_info = {
 
 /* --- qdev i.MX eSDHC --- */
 
+#define ESDHC_MIX_CTRL  0x48
+
+#define ESDHC_VENDOR_SPEC   0xc0
+#define ESDHC_IMX_FRC_SDCLK_ON  (1 << 8)
+
+#define ESDHC_DLL_CTRL  0x60
+
+#define ESDHC_TUNING_CTRL   0xcc
+#define ESDHC_TUNE_CTRL_STATUS  0x68
+#define ESDHC_WTMK_LVL  0x44
+
+/* Undocumented register used by guests working around erratum ERR004536 */
+#define ESDHC_UNDOCUMENTED_REG270x6c
+
+#define ESDHC_CTRL_4BITBUS  (0x1 << 1)
+#define ESDHC_CTRL_8BITBUS  (0x2 << 1)
+
+#define ESDHC_PRNSTS_SDSTB  (1 << 3)
+
 static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
 {
 SDHCIState *s = SYSBUS_SDHCI(opaque);
-- 
2.37.3




[PATCH v2 04/13] hw/ppc/e500: Reduce usage of sysbus API

2022-10-03 Thread Bernhard Beschow
PlatformBusDevice has an mmio attribute which gets aliased to
SysBusDevice::mmio[0]. So PlatformbusDevice::mmio can be used directly,
avoiding the sysbus API.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/e500.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 32495d0123..496c61b612 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1023,7 +1023,7 @@ void ppce500_init(MachineState *machine)
 
 memory_region_add_subregion(address_space_mem,
 pmc->platform_bus_base,
-sysbus_mmio_get_region(s, 0));
+>pbus_dev->mmio);
 }
 
 /*
-- 
2.37.3




[PATCH v2 07/13] hw/ppc/e500: Remove if statement which is now always true

2022-10-03 Thread Bernhard Beschow
Now that the MPC8544DS board also has a platform bus, the if statement
is always true.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/ppc/e500.c  | 30 ++
 hw/ppc/e500.h  |  1 -
 hw/ppc/e500plat.c  |  1 -
 hw/ppc/mpc8544ds.c |  1 -
 4 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 496c61b612..3e950ea3ba 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1007,25 +1007,23 @@ void ppce500_init(MachineState *machine)
 }
 
 /* Platform Bus Device */
-if (pmc->has_platform_bus) {
-dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
-dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
-qdev_prop_set_uint32(dev, "num_irqs", pmc->platform_bus_num_irqs);
-qdev_prop_set_uint32(dev, "mmio_size", pmc->platform_bus_size);
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
-pms->pbus_dev = PLATFORM_BUS_DEVICE(dev);
-
-s = SYS_BUS_DEVICE(pms->pbus_dev);
-for (i = 0; i < pmc->platform_bus_num_irqs; i++) {
-int irqn = pmc->platform_bus_first_irq + i;
-sysbus_connect_irq(s, i, qdev_get_gpio_in(mpicdev, irqn));
-}
+dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
+dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
+qdev_prop_set_uint32(dev, "num_irqs", pmc->platform_bus_num_irqs);
+qdev_prop_set_uint32(dev, "mmio_size", pmc->platform_bus_size);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
+pms->pbus_dev = PLATFORM_BUS_DEVICE(dev);
 
-memory_region_add_subregion(address_space_mem,
-pmc->platform_bus_base,
->pbus_dev->mmio);
+s = SYS_BUS_DEVICE(pms->pbus_dev);
+for (i = 0; i < pmc->platform_bus_num_irqs; i++) {
+int irqn = pmc->platform_bus_first_irq + i;
+sysbus_connect_irq(s, i, qdev_get_gpio_in(mpicdev, irqn));
 }
 
+memory_region_add_subregion(address_space_mem,
+pmc->platform_bus_base,
+>pbus_dev->mmio);
+
 /*
  * Smart firmware defaults ahead!
  *
diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
index 1e5853b032..68f754ce50 100644
--- a/hw/ppc/e500.h
+++ b/hw/ppc/e500.h
@@ -27,7 +27,6 @@ struct PPCE500MachineClass {
 
 int mpic_version;
 bool has_mpc8xxx_gpio;
-bool has_platform_bus;
 hwaddr platform_bus_base;
 hwaddr platform_bus_size;
 int platform_bus_first_irq;
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index fc911bbb7b..5bb1c603da 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -86,7 +86,6 @@ static void e500plat_machine_class_init(ObjectClass *oc, void 
*data)
 pmc->fixup_devtree = e500plat_fixup_devtree;
 pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_42;
 pmc->has_mpc8xxx_gpio = true;
-pmc->has_platform_bus = true;
 pmc->platform_bus_base = 0xfULL;
 pmc->platform_bus_size = 128 * MiB;
 pmc->platform_bus_first_irq = 5;
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 9c81477698..7dd5219736 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -46,7 +46,6 @@ static void mpc8544ds_machine_class_init(ObjectClass *oc, 
void *data)
 pmc->pci_nr_slots = 2;
 pmc->fixup_devtree = mpc8544ds_fixup_devtree;
 pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_20;
-pmc->has_platform_bus = true;
 pmc->platform_bus_base = 0xFF80ULL;
 pmc->platform_bus_size = 8 * MiB;
 pmc->platform_bus_first_irq = 5;
-- 
2.37.3




[PATCH v2 05/13] hw/ppc/mpc8544ds: Rename wrongly named method

2022-10-03 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/ppc/mpc8544ds.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 81177505f0..8e674ad195 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -36,7 +36,7 @@ static void mpc8544ds_init(MachineState *machine)
 ppce500_init(machine);
 }
 
-static void e500plat_machine_class_init(ObjectClass *oc, void *data)
+static void mpc8544ds_machine_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
 PPCE500MachineClass *pmc = PPCE500_MACHINE_CLASS(oc);
@@ -63,7 +63,7 @@ static void e500plat_machine_class_init(ObjectClass *oc, void 
*data)
 static const TypeInfo mpc8544ds_info = {
 .name  = TYPE_MPC8544DS_MACHINE,
 .parent= TYPE_PPCE500_MACHINE,
-.class_init= e500plat_machine_class_init,
+.class_init= mpc8544ds_machine_class_init,
 };
 
 static void mpc8544ds_register_types(void)
-- 
2.37.3




[PATCH v2 02/13] hw/gpio/meson: Introduce dedicated config switch for hw/gpio/mpc8xxx

2022-10-03 Thread Bernhard Beschow
Having a dedicated config switch makes dependency handling cleaner.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/gpio/Kconfig | 3 +++
 hw/gpio/meson.build | 2 +-
 hw/ppc/Kconfig  | 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
index f0e7405f6e..d2cf3accc8 100644
--- a/hw/gpio/Kconfig
+++ b/hw/gpio/Kconfig
@@ -8,6 +8,9 @@ config PL061
 config GPIO_KEY
 bool
 
+config GPIO_MPC8XXX
+bool
+
 config GPIO_PWR
 bool
 
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
index 7bd6a57264..b726e6d27a 100644
--- a/hw/gpio/meson.build
+++ b/hw/gpio/meson.build
@@ -1,5 +1,5 @@
-softmmu_ss.add(when: 'CONFIG_E500', if_true: files('mpc8xxx.c'))
 softmmu_ss.add(when: 'CONFIG_GPIO_KEY', if_true: files('gpio_key.c'))
+softmmu_ss.add(when: 'CONFIG_GPIO_MPC8XXX', if_true: files('mpc8xxx.c'))
 softmmu_ss.add(when: 'CONFIG_GPIO_PWR', if_true: files('gpio_pwr.c'))
 softmmu_ss.add(when: 'CONFIG_MAX7310', if_true: files('max7310.c'))
 softmmu_ss.add(when: 'CONFIG_PL061', if_true: files('pl061.c'))
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 22a64745d4..791fe78a50 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -124,6 +124,7 @@ config E500
 imply AT24C
 imply VIRTIO_PCI
 select ETSEC
+select GPIO_MPC8XXX
 select OPENPIC
 select PLATFORM_BUS
 select PPCE500_PCI
-- 
2.37.3




Re: [RFC 3/7] migration: Block migration comment or code is wrong

2022-10-03 Thread Stefan Hajnoczi
On Mon, Oct 03, 2022 at 05:15:56AM +0200, Juan Quintela wrote:
> And it appears that what is wrong is the code. During bulk stage we
> need to make sure that some block is dirty, but no games with
> max_size at all.
> 
> Signed-off-by: Juan Quintela 
> ---
>  migration/block.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


[PATCH v2 11/13] hw/sd/sdhci: Rename ESDHC_* defines to USDHC_*

2022-10-03 Thread Bernhard Beschow
The device model's functions start with "usdhc_", so rename the defines
accordingly for consistency.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
---
 hw/sd/sdhci.c | 66 +--
 1 file changed, 33 insertions(+), 33 deletions(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 6da5e2c781..306070c872 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1577,24 +1577,24 @@ static const TypeInfo sdhci_bus_info = {
 
 /* --- qdev i.MX eSDHC --- */
 
-#define ESDHC_MIX_CTRL  0x48
+#define USDHC_MIX_CTRL  0x48
 
-#define ESDHC_VENDOR_SPEC   0xc0
-#define ESDHC_IMX_FRC_SDCLK_ON  (1 << 8)
+#define USDHC_VENDOR_SPEC   0xc0
+#define USDHC_IMX_FRC_SDCLK_ON  (1 << 8)
 
-#define ESDHC_DLL_CTRL  0x60
+#define USDHC_DLL_CTRL  0x60
 
-#define ESDHC_TUNING_CTRL   0xcc
-#define ESDHC_TUNE_CTRL_STATUS  0x68
-#define ESDHC_WTMK_LVL  0x44
+#define USDHC_TUNING_CTRL   0xcc
+#define USDHC_TUNE_CTRL_STATUS  0x68
+#define USDHC_WTMK_LVL  0x44
 
 /* Undocumented register used by guests working around erratum ERR004536 */
-#define ESDHC_UNDOCUMENTED_REG270x6c
+#define USDHC_UNDOCUMENTED_REG270x6c
 
-#define ESDHC_CTRL_4BITBUS  (0x1 << 1)
-#define ESDHC_CTRL_8BITBUS  (0x2 << 1)
+#define USDHC_CTRL_4BITBUS  (0x1 << 1)
+#define USDHC_CTRL_8BITBUS  (0x2 << 1)
 
-#define ESDHC_PRNSTS_SDSTB  (1 << 3)
+#define USDHC_PRNSTS_SDSTB  (1 << 3)
 
 static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
 {
@@ -1615,11 +1615,11 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, 
unsigned size)
 hostctl1 = SDHC_DMA_TYPE(s->hostctl1) << (8 - 3);
 
 if (s->hostctl1 & SDHC_CTRL_8BITBUS) {
-hostctl1 |= ESDHC_CTRL_8BITBUS;
+hostctl1 |= USDHC_CTRL_8BITBUS;
 }
 
 if (s->hostctl1 & SDHC_CTRL_4BITBUS) {
-hostctl1 |= ESDHC_CTRL_4BITBUS;
+hostctl1 |= USDHC_CTRL_4BITBUS;
 }
 
 ret  = hostctl1;
@@ -1630,21 +1630,21 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, 
unsigned size)
 
 case SDHC_PRNSTS:
 /* Add SDSTB (SD Clock Stable) bit to PRNSTS */
-ret = sdhci_read(opaque, offset, size) & ~ESDHC_PRNSTS_SDSTB;
+ret = sdhci_read(opaque, offset, size) & ~USDHC_PRNSTS_SDSTB;
 if (s->clkcon & SDHC_CLOCK_INT_STABLE) {
-ret |= ESDHC_PRNSTS_SDSTB;
+ret |= USDHC_PRNSTS_SDSTB;
 }
 break;
 
-case ESDHC_VENDOR_SPEC:
+case USDHC_VENDOR_SPEC:
 ret = s->vendor_spec;
 break;
-case ESDHC_DLL_CTRL:
-case ESDHC_TUNE_CTRL_STATUS:
-case ESDHC_UNDOCUMENTED_REG27:
-case ESDHC_TUNING_CTRL:
-case ESDHC_MIX_CTRL:
-case ESDHC_WTMK_LVL:
+case USDHC_DLL_CTRL:
+case USDHC_TUNE_CTRL_STATUS:
+case USDHC_UNDOCUMENTED_REG27:
+case USDHC_TUNING_CTRL:
+case USDHC_MIX_CTRL:
+case USDHC_WTMK_LVL:
 ret = 0;
 break;
 }
@@ -1660,18 +1660,18 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, 
unsigned size)
 uint32_t value = (uint32_t)val;
 
 switch (offset) {
-case ESDHC_DLL_CTRL:
-case ESDHC_TUNE_CTRL_STATUS:
-case ESDHC_UNDOCUMENTED_REG27:
-case ESDHC_TUNING_CTRL:
-case ESDHC_WTMK_LVL:
+case USDHC_DLL_CTRL:
+case USDHC_TUNE_CTRL_STATUS:
+case USDHC_UNDOCUMENTED_REG27:
+case USDHC_TUNING_CTRL:
+case USDHC_WTMK_LVL:
 break;
 
-case ESDHC_VENDOR_SPEC:
+case USDHC_VENDOR_SPEC:
 s->vendor_spec = value;
 switch (s->vendor) {
 case SDHCI_VENDOR_IMX:
-if (value & ESDHC_IMX_FRC_SDCLK_ON) {
+if (value & USDHC_IMX_FRC_SDCLK_ON) {
 s->prnsts &= ~SDHC_IMX_CLOCK_GATE_OFF;
 } else {
 s->prnsts |= SDHC_IMX_CLOCK_GATE_OFF;
@@ -1740,12 +1740,12 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, 
unsigned size)
  * Second, split "Data Transfer Width" from bits 2 and 1 in to
  * bits 5 and 1
  */
-if (value & ESDHC_CTRL_8BITBUS) {
+if (value & USDHC_CTRL_8BITBUS) {
 hostctl1 |= SDHC_CTRL_8BITBUS;
 }
 
-if (value & ESDHC_CTRL_4BITBUS) {
-hostctl1 |= ESDHC_CTRL_4BITBUS;
+if (value & USDHC_CTRL_4BITBUS) {
+hostctl1 |= USDHC_CTRL_4BITBUS;
 }
 
 /*
@@ -1768,7 +1768,7 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, 
unsigned size)
 sdhci_write(opaque, offset, value, size);
 break;
 
-case ESDHC_MIX_CTRL:
+case USDHC_MIX_CTRL:
 /*
  * So, when SD/MMC stack in Linux tries to write to "Transfer
  * Mode Register", ESDHC i.MX quirk code will translate it
-- 
2.37.3




[PATCH v2 06/13] hw/ppc/mpc8544ds: Add platform bus

2022-10-03 Thread Bernhard Beschow
Models the real device more closely.

Address and size values are taken from mpc8544.dts from the linux-5.17.7
tree. The IRQ range is taken from e500plat.c.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/mpc8544ds.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 8e674ad195..9c81477698 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -14,6 +14,7 @@
 #include "sysemu/device_tree.h"
 #include "hw/ppc/openpic.h"
 #include "qemu/error-report.h"
+#include "qemu/units.h"
 #include "cpu.h"
 
 static void mpc8544ds_fixup_devtree(void *fdt)
@@ -45,6 +46,11 @@ static void mpc8544ds_machine_class_init(ObjectClass *oc, 
void *data)
 pmc->pci_nr_slots = 2;
 pmc->fixup_devtree = mpc8544ds_fixup_devtree;
 pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_20;
+pmc->has_platform_bus = true;
+pmc->platform_bus_base = 0xFF80ULL;
+pmc->platform_bus_size = 8 * MiB;
+pmc->platform_bus_first_irq = 5;
+pmc->platform_bus_num_irqs = 10;
 pmc->ccsrbar_base = 0xE000ULL;
 pmc->pci_mmio_base = 0xC000ULL;
 pmc->pci_mmio_bus_base = 0xC000ULL;
-- 
2.37.3




[PATCH v2 03/13] docs/system/ppc/ppce500: Add heading for networking chapter

2022-10-03 Thread Bernhard Beschow
The sudden change of topics is slightly confusing and makes the
networking information less visible. So separate the networking chapter
to improve comprehensibility.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
 docs/system/ppc/ppce500.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst
index 9beef39171..ba6bcb7314 100644
--- a/docs/system/ppc/ppce500.rst
+++ b/docs/system/ppc/ppce500.rst
@@ -146,6 +146,9 @@ You can specify a real world SoC device that QEMU has 
built-in support but all
 these SoCs are e500v2 based MPC85xx series, hence you cannot test anything
 built for P4080 (e500mc), P5020 (e5500) and T2080 (e6500).
 
+Networking
+--
+
 By default a VirtIO standard PCI networking device is connected as an ethernet
 interface at PCI address 0.1.0, but we can switch that to an e1000 NIC by:
 
-- 
2.37.3




[PATCH v2 01/13] hw/ppc/meson: Allow e500 boards to be enabled separately

2022-10-03 Thread Bernhard Beschow
Gives users more fine-grained control over what should be compiled into
QEMU.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
 configs/devices/ppc-softmmu/default.mak | 3 ++-
 hw/ppc/Kconfig  | 8 
 hw/ppc/meson.build  | 6 ++
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/configs/devices/ppc-softmmu/default.mak 
b/configs/devices/ppc-softmmu/default.mak
index 658a454426..a887f5438b 100644
--- a/configs/devices/ppc-softmmu/default.mak
+++ b/configs/devices/ppc-softmmu/default.mak
@@ -1,7 +1,8 @@
 # Default configuration for ppc-softmmu
 
 # For embedded PPCs:
-CONFIG_E500=y
+CONFIG_E500PLAT=y
+CONFIG_MPC8544DS=y
 CONFIG_PPC405=y
 CONFIG_PPC440=y
 CONFIG_VIRTEX=y
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 3a4418a69e..22a64745d4 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -132,6 +132,14 @@ config E500
 select FDT_PPC
 select DS1338
 
+config E500PLAT
+bool
+select E500
+
+config MPC8544DS
+bool
+select E500
+
 config VIRTEX
 bool
 select PPC4XX
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 62801923f3..32babc9b48 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -71,12 +71,10 @@ ppc_ss.add(when: 'CONFIG_MAC_OLDWORLD', if_true: 
files('mac_oldworld.c'))
 # NewWorld PowerMac
 ppc_ss.add(when: 'CONFIG_MAC_NEWWORLD', if_true: files('mac_newworld.c'))
 # e500
+ppc_ss.add(when: 'CONFIG_E500PLAT', if_true: files('e500plat.c'))
+ppc_ss.add(when: 'CONFIG_MPC8544DS', if_true: files('mpc8544ds.c'))
 ppc_ss.add(when: 'CONFIG_E500', if_true: files(
   'e500.c',
-  'mpc8544ds.c',
-  'e500plat.c'
-))
-ppc_ss.add(when: 'CONFIG_E500', if_true: files(
   'mpc8544_guts.c',
   'ppce500_spin.c'
 ))
-- 
2.37.3




[PATCH v2 00/13] ppc/e500: Add support for two types of flash, cleanup

2022-10-03 Thread Bernhard Beschow
Cover letter:
~

This series adds support for -pflash and direct SD card access to the
PPC e500 boards. The idea is to increase compatibility with "real" firmware
images where only the bare minimum of drivers is compiled in.

The series is structured as follows:

Patches 1-5 perform some general cleanup which paves the way for the rest of
the series.

Patches 6-9 add -pflash handling where memory-mapped flash can be added on
user's behalf. That is, the flash memory region in the eLBC is only added if
the -pflash argument is supplied. Note that the cfi01 device model becomes
stricter in checking the size of the emulated flash space.

Patches 10-13 add a new device model - the Freescale eSDHC - to the e500
boards which was missing so far.

User documentation is also added as the new features become available.

Tesing done:
* `qemu-system-ppc -M ppce500 -cpu e500mc -m 256 -kernel uImage -append
"console=ttyS0 rootwait root=/dev/mtdblock0 nokaslr" -drive
if=pflash,file=rootfs.ext2,format=raw`
* `qemu-system-ppc -M ppce500 -cpu e500mc -m 256 -kernel uImage -append
"console=ttyS0 rootwait root=/dev/mmcblk0" -device sd-card,drive=mydrive -drive
id=mydrive,if=none,file=rootfs.ext2,format=raw`

The load was created using latest Buildroot with `make
qemu_ppc_e500mc_defconfig` where the rootfs was configured to be of ext2 type.
In both cases it was possible to log in and explore the root file system.

v2:
~~~
Bin:
- Add source for MPC8544DS platform bus' memory map in commit message.
- Keep "ESDHC" in comment referring to Linux driver.
- Use "qemu-system-ppc{64|32} in documentation.
- Use g_autofree in device tree code.
- Remove unneeded device tree properties.
- Error out if pflash size doesn't fit into eLBC memory window.
- Remove unused ESDHC defines.
- Define macro ESDHC_WML for register offset with magic constant.
- Fix some whitespace issues when adding eSDHC device to e500.

Phil:
- Fix tense in commit message.

Bernhard Beschow (13):
  hw/ppc/meson: Allow e500 boards to be enabled separately
  hw/gpio/meson: Introduce dedicated config switch for hw/gpio/mpc8xxx
  docs/system/ppc/ppce500: Add heading for networking chapter
  hw/ppc/e500: Reduce usage of sysbus API
  hw/ppc/mpc8544ds: Rename wrongly named method
  hw/ppc/mpc8544ds: Add platform bus
  hw/ppc/e500: Remove if statement which is now always true
  hw/block/pflash_cfi01: Error out if device length isn't a power of two
  hw/ppc/e500: Implement pflash handling
  hw/sd/sdhci-internal: Unexport ESDHC defines
  hw/sd/sdhci: Rename ESDHC_* defines to USDHC_*
  hw/sd/sdhci: Implement Freescale eSDHC device model
  hw/ppc/e500: Add Freescale eSDHC to e500 boards

 configs/devices/ppc-softmmu/default.mak |   3 +-
 docs/system/ppc/ppce500.rst |  28 
 hw/block/pflash_cfi01.c |   8 +-
 hw/gpio/Kconfig |   3 +
 hw/gpio/meson.build |   2 +-
 hw/ppc/Kconfig  |  11 ++
 hw/ppc/e500.c   | 133 +--
 hw/ppc/e500.h   |   1 -
 hw/ppc/e500plat.c   |   1 -
 hw/ppc/meson.build  |   6 +-
 hw/ppc/mpc8544ds.c  |   9 +-
 hw/sd/sdhci-internal.h  |  20 ---
 hw/sd/sdhci.c   | 210 +---
 include/hw/sd/sdhci.h   |   3 +
 14 files changed, 368 insertions(+), 70 deletions(-)

-- 
2.37.3




Re: [PATCH 07/11] hw/ppc/e500: Implement pflash handling

2022-10-03 Thread B



Am 16. September 2022 17:05:13 UTC schrieb Bernhard Beschow :
>Am 16. September 2022 15:00:06 UTC schrieb Bin Meng :
>>On Thu, Sep 15, 2022 at 11:36 PM Bernhard Beschow  wrote:
>>>
>>> Allows e500 boards to have their root file system reside on flash using
>>> only builtin devices.
>>>
>>> Note that the flash memory area is only created when a -pflash argument is
>>> given, and that the size is determined by the given file. The idea is to
>>> put users into control.
>>>
>>> Signed-off-by: Bernhard Beschow 
>>> ---
>>>  docs/system/ppc/ppce500.rst | 12 +
>>>  hw/ppc/Kconfig  |  1 +
>>>  hw/ppc/e500.c   | 54 +
>>>  3 files changed, 67 insertions(+)
>>>
>>> diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst
>>> index ba6bcb7314..c3f55c6f3d 100644
>>> --- a/docs/system/ppc/ppce500.rst
>>> +++ b/docs/system/ppc/ppce500.rst
>>> @@ -119,6 +119,18 @@ To boot the 32-bit Linux kernel:
>>>-initrd /path/to/rootfs.cpio \
>>>-append "root=/dev/ram"
>>>
>>> +Rather than using a root file system on ram disk, it is possible to have 
>>> it on
>>> +emulated flash. Given an ext2 image whose size must be a power of two, it 
>>> can
>>> +be used as follows:
>>> +
>>> +.. code-block:: bash
>>> +
>>> +  $ qemu-system-ppc64 -M ppce500 -cpu e500mc -smp 4 -m 2G \
>>
>>qemu-system-ppc{64|32}
>
>Will fix.
>
>>> +  -display none -serial stdio \
>>> +  -kernel vmlinux \
>>> +  -drive if=pflash,file=/path/to/rootfs.ext2,format=raw \
>>> +  -append "rootwait root=/dev/mtdblock0"
>>> +
>>>  Running U-Boot
>>>  --
>>>
>>> diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
>>> index 791fe78a50..769a1ead1c 100644
>>> --- a/hw/ppc/Kconfig
>>> +++ b/hw/ppc/Kconfig
>>> @@ -126,6 +126,7 @@ config E500
>>>  select ETSEC
>>>  select GPIO_MPC8XXX
>>>  select OPENPIC
>>> +select PFLASH_CFI01
>>>  select PLATFORM_BUS
>>>  select PPCE500_PCI
>>>  select SERIAL
>>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>>> index 864b6f3d92..7843a4e04b 100644
>>> --- a/hw/ppc/e500.c
>>> +++ b/hw/ppc/e500.c
>>> @@ -23,8 +23,10 @@
>>>  #include "e500-ccsr.h"
>>>  #include "net/net.h"
>>>  #include "qemu/config-file.h"
>>> +#include "hw/block/flash.h"
>>>  #include "hw/char/serial.h"
>>>  #include "hw/pci/pci.h"
>>> +#include "sysemu/block-backend-io.h"
>>>  #include "sysemu/sysemu.h"
>>>  #include "sysemu/kvm.h"
>>>  #include "sysemu/reset.h"
>>> @@ -267,6 +269,34 @@ static void sysbus_device_create_devtree(SysBusDevice 
>>> *sbdev, void *opaque)
>>>  }
>>>  }
>>>
>>> +static void create_devtree_flash(SysBusDevice *sbdev,
>>> + PlatformDevtreeData *data)
>>> +{
>>> +char *name;
>>
>>Use g_autofree
>
>Yes, good idea.
>
>>> +uint64_t num_blocks = object_property_get_uint(OBJECT(sbdev),
>>> +   "num-blocks",
>>> +   _fatal);
>>> +uint64_t sector_length = object_property_get_uint(OBJECT(sbdev),
>>> +  "sector-length",
>>> +  _fatal);
>>> +uint64_t bank_width = object_property_get_uint(OBJECT(sbdev),
>>> +   "width",
>>> +   _fatal);
>>> +hwaddr flashbase = 0;
>>> +hwaddr flashsize = num_blocks * sector_length;
>>> +void *fdt = data->fdt;
>>> +
>>> +name = g_strdup_printf("%s/nor@%" PRIx64, data->node, flashbase);
>>> +qemu_fdt_add_subnode(fdt, name);
>>> +qemu_fdt_setprop_cell(fdt, name, "#address-cells", 1);
>>> +qemu_fdt_setprop_cell(fdt, name, "#size-cells", 1);
>>
>>#address-cells and #size-cells are not needed.
>
>Will remove.
>
>>> +qemu_fdt_setprop_string(fdt, name, "compatible", "cfi-flash");
>>> +qemu_fdt_setprop_sized_cells(fdt, name, "reg",
>>> + 1, flashbase, 1, flashsize);
>>> +qemu_fdt_setprop_cell(fdt, name, "bank-width", bank_width);
>>> +g_free(name);
>>> +}
>>> +
>>>  static void platform_bus_create_devtree(PPCE500MachineState *pms,
>>>  void *fdt, const char *mpic)
>>>  {
>>> @@ -276,6 +306,8 @@ static void 
>>> platform_bus_create_devtree(PPCE500MachineState *pms,
>>>  uint64_t addr = pmc->platform_bus_base;
>>>  uint64_t size = pmc->platform_bus_size;
>>>  int irq_start = pmc->platform_bus_first_irq;
>>> +SysBusDevice *sbdev;
>>> +bool ambiguous;
>>>
>>>  /* Create a /platform node that we can put all devices into */
>>>
>>> @@ -302,6 +334,13 @@ static void 
>>> platform_bus_create_devtree(PPCE500MachineState *pms,
>>>  /* Loop through all dynamic sysbus devices and create nodes for them */
>>>  foreach_dynamic_sysbus_device(sysbus_device_create_devtree, );
>>>
>>> +sbdev = 

Re: [PATCH v10 3/7] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls

2022-10-03 Thread Stefan Hajnoczi
On Thu, Sep 29, 2022 at 04:36:27PM +0800, Sam Li wrote:
> Add a new zoned_host_device BlockDriver. The zoned_host_device option
> accepts only zoned host block devices. By adding zone management
> operations in this new BlockDriver, users can use the new block
> layer APIs including Report Zone and four zone management operations
> (open, close, finish, reset).
> 
> Qemu-io uses the new APIs to perform zoned storage commands of the device:
> zone_report(zrp), zone_open(zo), zone_close(zc), zone_reset(zrs),
> zone_finish(zf).
> 
> For example, to test zone_report, use following command:
> $ ./build/qemu-io --image-opts -n driver=zoned_host_device, 
> filename=/dev/nullb0
> -c "zrp offset nr_zones"
> 
> Signed-off-by: Sam Li 
> Reviewed-by: Hannes Reinecke 
> ---
>  block/block-backend.c | 146 +
>  block/file-posix.c| 340 +-
>  block/io.c|  41 
>  include/block/block-common.h  |   4 +
>  include/block/block-io.h  |   7 +
>  include/block/block_int-common.h  |  24 +++
>  include/block/raw-aio.h   |   6 +-
>  include/sysemu/block-backend-io.h |  17 ++
>  meson.build   |   4 +
>  qapi/block-core.json  |   8 +-
>  qemu-io-cmds.c| 148 +
>  11 files changed, 741 insertions(+), 4 deletions(-)
> 
> diff --git a/block/block-backend.c b/block/block-backend.c
> index d4a5df2ac2..f7f7acd6f4 100644
> --- a/block/block-backend.c
> +++ b/block/block-backend.c
> @@ -1431,6 +1431,15 @@ typedef struct BlkRwCo {
>  void *iobuf;
>  int ret;
>  BdrvRequestFlags flags;
> +union {
> +struct {
> +unsigned int *nr_zones;
> +BlockZoneDescriptor *zones;
> +} zone_report;
> +struct {
> +BlockZoneOp op;
> +} zone_mgmt;
> +};
>  } BlkRwCo;
>  
>  int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
> @@ -1775,6 +1784,143 @@ int coroutine_fn blk_co_flush(BlockBackend *blk)
>  return ret;
>  }
>  
> +static void blk_aio_zone_report_entry(void *opaque) {


The coroutine_fn annotation is missing:

  static void coroutine_fn blk_aio_zone_report_entry(void *opaque) {

> +BlkAioEmAIOCB *acb = opaque;
> +BlkRwCo *rwco = >rwco;
> +
> +rwco->ret = blk_co_zone_report(rwco->blk, rwco->offset,
> +   rwco->zone_report.nr_zones,
> +   rwco->zone_report.zones);
> +blk_aio_complete(acb);
> +}
> +
> +BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
> +unsigned int *nr_zones,
> +BlockZoneDescriptor  *zones,
> +BlockCompletionFunc *cb, void *opaque)
> +{
> +BlkAioEmAIOCB *acb;
> +Coroutine *co;
> +IO_CODE();
> +
> +blk_inc_in_flight(blk);
> +acb = blk_aio_get(_aio_em_aiocb_info, blk, cb, opaque);
> +acb->rwco = (BlkRwCo) {
> +.blk= blk,
> +.offset = offset,
> +.ret= NOT_DONE,
> +.zone_report = {
> +.zones = zones,
> +.nr_zones = nr_zones,
> +},
> +};
> +acb->has_returned = false;
> +
> +co = qemu_coroutine_create(blk_aio_zone_report_entry, acb);
> +bdrv_coroutine_enter(blk_bs(blk), co);
> +
> +acb->has_returned = true;
> +if (acb->rwco.ret != NOT_DONE) {
> +replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
> + blk_aio_complete_bh, acb);
> +}
> +
> +return >common;
> +}
> +
> +static void blk_aio_zone_mgmt_entry(void *opaque) {

coroutine_fn is missing here.

> +BlkAioEmAIOCB *acb = opaque;
> +BlkRwCo *rwco = >rwco;
> +
> +rwco->ret = blk_co_zone_mgmt(rwco->blk, rwco->zone_mgmt.op,
> + rwco->offset, acb->bytes);
> +blk_aio_complete(acb);
> +}
> +
> +BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
> +  int64_t offset, int64_t len,
> +  BlockCompletionFunc *cb, void *opaque) {
> +BlkAioEmAIOCB *acb;
> +Coroutine *co;
> +IO_CODE();
> +
> +blk_inc_in_flight(blk);
> +acb = blk_aio_get(_aio_em_aiocb_info, blk, cb, opaque);
> +acb->rwco = (BlkRwCo) {
> +.blk= blk,
> +.offset = offset,
> +.ret= NOT_DONE,
> +.zone_mgmt = {
> +.op = op,
> +},
> +};
> +acb->bytes = len;
> +acb->has_returned = false;
> +
> +co = qemu_coroutine_create(blk_aio_zone_mgmt_entry, acb);
> +bdrv_coroutine_enter(blk_bs(blk), co);
> +
> +acb->has_returned = true;
> +if (acb->rwco.ret != NOT_DONE) {
> +replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
> + blk_aio_complete_bh, acb);
> +}
> +
> +return >common;
> +}
> +
> +/*
> + * Send a zone_report command.

Re: [PATCH v4 00/54] tests/qtest: Enable running qtest on Windows

2022-10-03 Thread Bin Meng
Hi Marc-André,

On Mon, Oct 3, 2022 at 5:26 PM Marc-André Lureau
 wrote:
>
> Hi Bin
>
> On Tue, Sep 27, 2022 at 3:18 PM Bin Meng  wrote:
>>
>> In preparation to adding virtio-9p support on Windows, this series
>> enables running qtest on Windows, so that we can run the virtio-9p
>> tests on Windows to make sure it does not break accidently.
>>
>> Changes in v4:
>> - Do not use g_autofree and g_steal_pointer
>> - Update the error reporting by using the GError "error" argument
>>   of g_dir_make_tmp()
>> - Remove the const from tmpfs declaration
>> - Replace the whole block with a g_assert_no_error()
>> - Replace the error reporting with g_assert_no_error()
>> - Update error reporting
>> - Move the new text section after the "QTest" section instead
>> - Use plural in both cases: "on POSIX hosts as well as Windows hosts"
>> - Use "The following list shows some best practices"
>> - Fix typo of delimiter
>> - New patch: "tests/qtest: boot-serial-test: Close the serial file before 
>> starting QEMU"
>> - Drop patch: "chardev/char-file: Add FILE_SHARE_WRITE when openning the 
>> file for win32"
>>
>
> Could you post a v5 rebased on the current master? thanks
>

Sure, will do.

> (I think most of the remaining patches are simple enough that I could take 
> them in a misc PR if they are not picked by subsystem maintainers)

Thank you.

Regards,
Bin



Re: [PATCH v4 00/54] tests/qtest: Enable running qtest on Windows

2022-10-03 Thread Marc-André Lureau
Hi Bin

On Tue, Sep 27, 2022 at 3:18 PM Bin Meng  wrote:

> In preparation to adding virtio-9p support on Windows, this series
> enables running qtest on Windows, so that we can run the virtio-9p
> tests on Windows to make sure it does not break accidently.
>
> Changes in v4:
> - Do not use g_autofree and g_steal_pointer
> - Update the error reporting by using the GError "error" argument
>   of g_dir_make_tmp()
> - Remove the const from tmpfs declaration
> - Replace the whole block with a g_assert_no_error()
> - Replace the error reporting with g_assert_no_error()
> - Update error reporting
> - Move the new text section after the "QTest" section instead
> - Use plural in both cases: "on POSIX hosts as well as Windows hosts"
> - Use "The following list shows some best practices"
> - Fix typo of delimiter
> - New patch: "tests/qtest: boot-serial-test: Close the serial file before
> starting QEMU"
> - Drop patch: "chardev/char-file: Add FILE_SHARE_WRITE when openning the
> file for win32"
>
>
Could you post a v5 rebased on the current master? thanks

(I think most of the remaining patches are simple enough that I could take
them in a misc PR if they are not picked by subsystem maintainers)

Changes in v3:
> - Remove unnecessary "error = NULL" statements
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Split to a separate patch
> - Split to a separate patch
> - Split to a separate patch
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Use g_steal_pointer() in create_test_img()
> - Split to a separate patch
> - Split to a separate patch
> - Split to a separate patch
> - Split to a separate patch
> - Split to a separate patch
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Split to a separate patch
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Split to a separate patch
> - Ensure g_autofree variable is initialized
> - Split to a separate patch
> - Split to a separate patch
> - Add a usleep(1) in the busy wait loop
> - Drop the host test
> - Drop patch: "tests: Change to use g_mkdir()"
> - Drop patch: "block: Unify the get_tmp_filename() implementation",
>   and send it as a separate patch
>
> Changes in v2:
> - new patch: "tests/qtest: i440fx-test: Rewrite create_blob_file() to be
> portable"
> - Use g_autofree to declare the variable
> - Change to use g_mkdir()
> - Change to use g_mkdir()
> - Change to use g_mkdir()
> - Change to skip only part of the virtio-net-test cases that require
>   socketpair() intead of disabling all of them
> - Introduce a new variable qtests_filter and add that to the
>   qtests_ARCH variables
> - Add a comment in the code to explain why test_qmp_oob test case
>   is skipped on win32
> - Replace signal by the semaphore on posix too
> - Use __declspec(selectany) for the common weak symbol on Windows
> - Introduce qemu_send_full() and use it
> - Move the enabling of building qtests on Windows to a separate
>   patch to keep bisectablity
> - Call socket_init() unconditionally
> - Add a missing CloseHandle() call
> - Drop ahci-test.c changes that are no longer needed
> - Change the place that sets IO redirection in the command line
> - Change to a busy wait after migration is canceled
> - new patch: "io/channel-watch: Drop the unnecessary cast"
> - Change the timeout limit to 90 minutes
> - new patch: Display meson test logs in the Windows CI
> - new patch: "tests/qtest: Enable qtest build on Windows"
> - Minor wording changes
> - Drop patches that were already applied in the mainline
> - Drop patch: "qga/commands-posix-ssh: Use g_mkdir_with_parents()"
> - Drop patch: "tests: Skip iotests and qtest when
> '--without-default-devices'"
> - Drop patch: "tests/qtest: Fix ERROR_SHARING_VIOLATION for win32"
>
> Bin Meng (48):
>   tests/qtest: i440fx-test: Rewrite create_blob_file() to be portable
>   semihosting/arm-compat-semi: Avoid using hardcoded /tmp
>   tcg: Avoid using hardcoded /tmp
>   util/qemu-sockets: Use g_get_tmp_dir() to get the directory for
> temporary files
>   tests/qtest: ahci-test: Avoid using hardcoded /tmp
>   tests/qtest: aspeed_smc-test: Avoid using hardcoded /tmp
>   tests/qtest: boot-serial-test: Avoid using hardcoded /tmp
>   tests/qtest: cxl-test: Avoid using hardcoded /tmp
>   tests/qtest: fdc-test: Avoid using hardcoded /tmp
>   tests/qtest: generic_fuzz: Avoid using hardcoded /tmp
>   tests/qtest: virtio_blk_fuzz: Avoid using hardcoded /tmp
>   tests/qtest: hd-geo-test: Avoid using hardcoded /tmp
>   tests/qtest: ide-test: Avoid using hardcoded /tmp
>   tests/qtest: migration-test: Avoid using hardcoded /tmp
>   tests/qtest: 

Re: [PATCH 1/2] linux-aio: use LinuxAioState from the running thread

2022-10-03 Thread Emanuele Giuseppe Esposito



Am 30/09/2022 um 17:32 schrieb Kevin Wolf:
> Am 30.09.2022 um 12:00 hat Emanuele Giuseppe Esposito geschrieben:
>>
>>
>> Am 29/09/2022 um 16:52 schrieb Kevin Wolf:
>>> Am 09.06.2022 um 15:44 hat Emanuele Giuseppe Esposito geschrieben:
 From: Paolo Bonzini 

 Remove usage of aio_context_acquire by always submitting asynchronous
 AIO to the current thread's LinuxAioState.

 Signed-off-by: Paolo Bonzini 
 Signed-off-by: Emanuele Giuseppe Esposito 
 ---
  block/file-posix.c  |  3 ++-
  block/linux-aio.c   | 13 ++---
  include/block/aio.h |  4 
  3 files changed, 8 insertions(+), 12 deletions(-)

 diff --git a/block/file-posix.c b/block/file-posix.c
 index 48cd096624..33f92f004a 100644
 --- a/block/file-posix.c
 +++ b/block/file-posix.c
 @@ -2086,7 +2086,8 @@ static int coroutine_fn raw_co_prw(BlockDriverState 
 *bs, uint64_t offset,
  #endif
  #ifdef CONFIG_LINUX_AIO
  } else if (s->use_linux_aio) {
 -LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
 +AioContext *ctx = qemu_get_current_aio_context();
 +LinuxAioState *aio = aio_get_linux_aio(ctx);
  assert(qiov->size == bytes);
  return laio_co_submit(bs, aio, s->fd, offset, qiov, type,
s->aio_max_batch);
>>>
>>> raw_aio_plug() and raw_aio_unplug() need the same change.
>>>
>>> I wonder if we should actually better remove the 'aio' parameter from
>>> the functions that linux-aio.c offers to avoid suggesting that any
>>> LinuxAioState works for any thread. Getting it from the current
>>> AioContext is something it can do by itself. But this would be code
>>> cleanup for a separate patch.
>>
>> I do not think that this would work. At least not for all functions of
>> the API. I tried removing the ctx parameter from aio_setup_linux_aio and
>> it's already problematic, as it used by raw_aio_attach_aio_context()
>> which is a .bdrv_attach_aio_context() callback, which should be called
>> by the main thread. So that function needs the aiocontext parameter.
>>
>> So maybe for now just simplify aio_get_linux_aio()? In a separate patch.
> 
> Oh, I don't mind the ctx parameter in these functions at all.
> 
> I was talking about the functions in linux-aio.c, specifically
> laio_co_submit(), laio_io_plug() and laio_io_unplug(). They could call
> aio_get_linux_aio() internally for the current thread instead of letting
> the caller do that and giving the false impression that there is more
> than one correct value for their LinuxAioState parameter.
> 
> But anyway, as I said, this would be a separate cleanup patch. For this
> one, it's just important that at least file-posix.c does the right thing
> for plug/unplug, too.
> 

Make sense

 diff --git a/block/linux-aio.c b/block/linux-aio.c
 index 4c423fcccf..1d3cc767d1 100644
 --- a/block/linux-aio.c
 +++ b/block/linux-aio.c
 @@ -16,6 +16,9 @@
  #include "qemu/coroutine.h"
  #include "qapi/error.h"
  
 +/* Only used for assertions.  */
 +#include "qemu/coroutine_int.h"
 +
  #include 
  
  /*
 @@ -56,10 +59,8 @@ struct LinuxAioState {
  io_context_t ctx;
  EventNotifier e;
  
 -/* io queue for submit at batch.  Protected by AioContext lock. */
 +/* All data is only used in one I/O thread.  */
  LaioQueue io_q;
 -
 -/* I/O completion processing.  Only runs in I/O thread.  */
  QEMUBH *completion_bh;
  int event_idx;
  int event_max;
 @@ -102,9 +103,8 @@ static void qemu_laio_process_completion(struct 
 qemu_laiocb *laiocb)
   * later.  Coroutines cannot be entered recursively so avoid doing
   * that!
   */
 -if (!qemu_coroutine_entered(laiocb->co)) {
 -aio_co_wake(laiocb->co);
 -}
 +assert(laiocb->co->ctx == laiocb->ctx->aio_context);
 +qemu_coroutine_enter_if_inactive(laiocb->co);
  }
  
  /**
 @@ -238,7 +238,6 @@ static void 
 qemu_laio_process_completions_and_submit(LinuxAioState *s)
  if (!s->io_q.plugged && !QSIMPLEQ_EMPTY(>io_q.pending)) {
  ioq_submit(s);
  }
 -aio_context_release(s->aio_context);
  }
>>>
>>> I certainly expected the aio_context_acquire() in the same function to
>>> go away, too! Am I missing something?
>>
>> ops
> 
> :-)
> 
> If it's unintentional, I'm actually surprised that locking without
> unlocking later didn't cause problems immediately.

Seems that iotests/unit tests do not trigger it.

> 
> Kevin
> 




Re: [PATCH 2/2] thread-pool: use ThreadPool from the running thread

2022-10-03 Thread Emanuele Giuseppe Esposito



Am 30/09/2022 um 17:45 schrieb Kevin Wolf:
> Am 30.09.2022 um 14:17 hat Emanuele Giuseppe Esposito geschrieben:
>> Am 29/09/2022 um 17:30 schrieb Kevin Wolf:
>>> Am 09.06.2022 um 15:44 hat Emanuele Giuseppe Esposito geschrieben:
 Remove usage of aio_context_acquire by always submitting work items
 to the current thread's ThreadPool.

 Signed-off-by: Paolo Bonzini 
 Signed-off-by: Emanuele Giuseppe Esposito 
>>>
>>> The thread pool is used by things outside of the file-* block drivers,
>>> too. Even outside the block layer. Not all of these seem to submit work
>>> in the same thread.
>>>
>>>
>>> For example:
>>>
>>> postcopy_ram_listen_thread() -> qemu_loadvm_state_main() ->
>>> qemu_loadvm_section_start_full() -> vmstate_load() ->
>>> vmstate_load_state() -> spapr_nvdimm_flush_post_load(), which has:
>>>
>>> ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
>>> ...
>>> thread_pool_submit_aio(pool, flush_worker_cb, state,
>>>spapr_nvdimm_flush_completion_cb, state);
>>>
>>> So it seems to me that we may be submitting work for the main thread
>>> from a postcopy migration thread.
>>>
>>> I believe the other direct callers of thread_pool_submit_aio() all
>>> submit work for the main thread and also run in the main thread.
>>>
>>>
>>> For thread_pool_submit_co(), pr_manager_execute() calls it with the pool
>>> it gets passed as a parameter. This is still bdrv_get_aio_context(bs) in
>>> hdev_co_ioctl() and should probably be changed the same way as for the
>>> AIO call in file-posix, i.e. use qemu_get_current_aio_context().
>>>
>>>
>>> We could consider either asserting in thread_pool_submit_aio() that we
>>> are really in the expected thread, or like I suggested for LinuxAio drop
>>> the pool parameter and always get it from the current thread (obviously
>>> this is only possible if migration could in fact schedule the work on
>>> its current thread - if it schedules it on the main thread and then
>>> exits the migration thread (which destroys the thread pool), that
>>> wouldn't be good).
>>
>> Dumb question: why not extend the already-existing poll->lock to cover
>> also the necessary fields like pool->head that are accessed by other
>> threads (only case I could find with thread_pool_submit_aio is the one
>> you pointed above)?
> 
> Other people are more familiar with this code, but I believe this could
> have performance implications. I seem to remember that this code is
> careful to avoid locking to synchronise between worker threads and the
> main thread.
> 
> But looking at the patch again, I have actually a dumb question, too:
> The locking you're removing is in thread_pool_completion_bh(). As this
> is a BH, it's running the the ThreadPool's context either way, no matter
> which thread called thread_pool_submit_aio().
> 
> I'm not sure what this aio_context_acquire/release pair is actually
> supposed to protect. Paolo's commit 1919631e6b5 introduced it. Was it
> just more careful than it needs to be?
> 

I think the goal is still to protect pool->head, but if so the
aiocontext lock is put in the wrong place, because as you said the bh is
always run in the thread pool context. Otherwise it seems to make no sense.

On the other side, thread_pool_submit_aio could be called by other
threads on behalf of the main loop, which means pool->head could be
modified (iothread calls thread_pool_submit_aio) while being read by the
main loop (another worker thread schedules thread_pool_completion_bh).

What are the performance implications? I mean, if the aiocontext lock in
the bh is actually useful and the bh really has to wait to take it,
being taken in much more places throughout the block layer won't be
better than extending the poll->lock I guess.

Thank you,
Emanuele