Re: [PATCH v6 3/4] qcow2: add zoned emulation capability

2023-11-26 Thread Damien Le Moal
On 11/27/23 13:37, Sam Li wrote:
> By adding zone operations and zoned metadata, the zoned emulation
> capability enables full emulation support of zoned device using
> a qcow2 file. The zoned device metadata includes zone type,
> zoned device state and write pointer of each zone, which is stored
> to an array of unsigned integers.
> 
> Each zone of a zoned device makes state transitions following
> the zone state machine. The zone state machine mainly describes
> five states, IMPLICIT OPEN, EXPLICIT OPEN, FULL, EMPTY and CLOSED.
> READ ONLY and OFFLINE states will generally be affected by device
> internal events. The operations on zones cause corresponding state
> changing.
> 
> Zoned devices have a limit on zone resources, which puts constraints on
> write operations into zones. It is managed by active zone lists
> following LRU policy.
> 
> Signed-off-by: Sam Li 
> ---
>  block/qcow2.c| 741 ++-
>  block/trace-events   |   2 +
>  include/qemu/queue.h |   1 +
>  3 files changed, 742 insertions(+), 2 deletions(-)
> 
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 9a92cd242c..26f2bb4a87 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -195,6 +195,179 @@ qcow2_extract_crypto_opts(QemuOpts *opts, const char 
> *fmt, Error **errp)
>  return cryptoopts_qdict;
>  }
>  
> +#define QCOW2_ZT_IS_CONV(wp)(wp & 1ULL << 59)
> +
> +/*
> + * To emulate a real zoned device, closed, empty and full states are
> + * preserved after a power cycle. Open states are in-memory and will
> + * be lost after closing the device. Read-only and offline states are
> + * device-internal events, which are not considered for simplicity.
> + */
> +static inline BlockZoneState qcow2_get_zone_state(BlockDriverState *bs,
> +  uint32_t index)
> +{
> +BDRVQcow2State *s = bs->opaque;
> +Qcow2ZoneListEntry *zone_entry = >zone_list_entries[index];
> +uint64_t zone_wp = bs->wps->wp[index];
> +uint64_t zone_start;
> +
> +if (QCOW2_ZT_IS_CONV(zone_wp)) {
> +return BLK_ZS_NOT_WP;
> +}
> +
> +if (QLIST_IS_INSERTED(zone_entry, exp_open_zone_entry)) {
> +return BLK_ZS_EOPEN;
> +}
> +if (QLIST_IS_INSERTED(zone_entry, imp_open_zone_entry)) {
> +return BLK_ZS_IOPEN;
> +}
> +
> +zone_start = index * bs->bl.zone_size;
> +if (zone_wp == zone_start) {
> +return BLK_ZS_EMPTY;
> +}
> +if (zone_wp >= zone_start + bs->bl.zone_capacity) {
> +return BLK_ZS_FULL;
> +}
> +if (zone_wp > zone_start) {
> +return BLK_ZS_CLOSED;
> +}
> +return BLK_ZS_NOT_WP;
> +}
> +
> +/*
> + * Write the new wp value to the dedicated location of the image file.
> + */
> +static int qcow2_write_wp_at(BlockDriverState *bs, uint64_t *wp,
> + uint32_t index) {
> +BDRVQcow2State *s = bs->opaque;
> +uint64_t wpv = *wp;
> +int ret;
> +
> +ret = bdrv_pwrite(bs->file, s->zoned_header.zonedmeta_offset
> ++ sizeof(uint64_t) * index, sizeof(uint64_t), wp, 0);
> +if (ret < 0) {
> +goto exit;
> +}
> +trace_qcow2_wp_tracking(index, *wp >> BDRV_SECTOR_BITS);
> +return ret;
> +
> +exit:
> +*wp = wpv;
> +error_report("Failed to write metadata with file");
> +return ret;
> +}
> +
> +static bool qcow2_can_activate_zone(BlockDriverState *bs)
> +{
> +BDRVQcow2State *s = bs->opaque;

A white line here after the declaration would be nice.

> +/* When the max active zone is zero, there is no limit on active zones */
> +if (!s->zoned_header.max_active_zones) {
> +return true;
> +}
> +
> +/* The active zones are zones with the states of open and closed */

/* Active zones are zones that are open or closed */

> +if (s->nr_zones_exp_open + s->nr_zones_imp_open + s->nr_zones_closed
> +< s->zoned_header.max_active_zones) {

return s->nr_zones_exp_open + s->nr_zones_imp_open +
s->nr_zones_closed < s->zoned_header.max_active_zones;

> +return true;
> +}
> +
> +return false;
> +}
> +
> +/*
> + * This function manages open zones under active zones limit. It checks
> + * if a zone can transition to open state while maintaining max open and
> + * active zone limits.
> + */
> +static bool qcow2_can_open_zone(BlockDriverState *bs)
> +{
> +BDRVQcow2State *s = bs->opaque;
> +Qcow2ZoneListEntry *zone_entry;
> +
> +/* When the max open zone is zero, there is no limit on open zones */
> +if (!s->zoned_header.max_open_zones) {
> +return true;
> +}
> +
> +/*
> + * The open zones are zones with the states of explicitly and
> + * implicitly open.
> + */
> +if (s->nr_zones_imp_open + s->nr_zones_exp_open <
> +s->zoned_header.max_open_zones) {
> +return true;
> +}
> +
> +/*
> + * Zones are managed once at a time. Thus, the number of implicitly open


Re: [PATCH v2 for-8.2] ppc/amigaone: Allow running AmigaOS without firmware image

2023-11-26 Thread Nicholas Piggin
On Sun Nov 26, 2023 at 2:34 AM AEST, BALATON Zoltan wrote:
> The machine uses a modified U-Boot under GPL license but the sources
> of it are lost with only a binary available so it cannot be included
> in QEMU. Allow running without the firmware image with -bios none
> which can be used when calling a boot loader directly and thus
> simplifying booting guests. We need a small routine that AmigaOS calls
> from ROM which is added in this case to allow booting AmigaOS without
> external firmware image.
>
> Signed-off-by: BALATON Zoltan 
> ---
> v2: Unfortunately AmigaOS needs some additional ROM part which is added
> Please merge for 8.2 as it allows booting AmigaOS simpler without
> having to download separate firmware.

How to test this?

>
>  hw/ppc/amigaone.c | 20 +---
>  1 file changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c
> index 992a55e632..a11d2d5556 100644
> --- a/hw/ppc/amigaone.c
> +++ b/hw/ppc/amigaone.c
> @@ -40,6 +40,16 @@
>  #define PROM_ADDR 0xfff0
>  #define PROM_SIZE (512 * KiB)
>  
> +/* AmigaOS calls this routine from ROM, use this if -bios none */
> +static const char dummy_fw[] = {
> +0x38, 0x00, 0x00, 0x08, /* li  r0,8 */
> +0x7c, 0x09, 0x03, 0xa6, /* mtctr   r0 */
> +0x54, 0x63, 0xf8, 0x7e, /* srwir3,r3,1 */
> +0x42, 0x00, 0xff, 0xfc, /* bdnz0x8 */
> +0x7c, 0x63, 0x18, 0xf8, /* not r3,r3 */
> +0x4e, 0x80, 0x00, 0x20, /* blr */
> +};

This is clever, but does anything else create blobs like this?
It could be put into a .S in pc-bios, which might be a bit more
consistent.

We might make a ppc/ subdirectory under there, but that's for
another time.

Thanks,
Nick

> +
>  static void amigaone_cpu_reset(void *opaque)
>  {
>  PowerPCCPU *cpu = opaque;
> @@ -94,17 +104,21 @@ static void amigaone_init(MachineState *machine)
>  }
>  
>  /* allocate and load firmware */
> +rom = g_new(MemoryRegion, 1);
> +memory_region_init_rom(rom, NULL, "rom", PROM_SIZE, _fatal);
> +memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom);
>  filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, fwname);
>  if (filename) {
> -rom = g_new(MemoryRegion, 1);
> -memory_region_init_rom(rom, NULL, "rom", PROM_SIZE, _fatal);
> -memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom);
>  sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE);
>  if (sz <= 0 || sz > PROM_SIZE) {
>  error_report("Could not load firmware '%s'", filename);
>  exit(1);
>  }
>  g_free(filename);
> +} else if (!strcmp(fwname, "none")) {
> +address_space_write_rom(_space_memory, 0xfff7ff80,
> +MEMTXATTRS_UNSPECIFIED, dummy_fw,
> +ARRAY_SIZE(dummy_fw));
>  } else if (!qtest_enabled()) {
>  error_report("Could not find firmware '%s'", fwname);
>  exit(1);




[PATCH 2/4] tests/qtest: Reorganize common code in ivshmem-test

2023-11-26 Thread Gustavo Romero
This commit reorganizes the ivshmem-test qtest by moving common structs,
functions, and code that can be utilized by other ivshmem qtests into
two new files: ivshmem-utils.h and ivshmem-utils.c.

Enum Reg, struct ServerThread, and mktempshm() have been relocated to
these new files. Two new functions have been introduced to handle the
ivshmem server start/stop: test_ivshmem_server_{start,stop}.

To accommodate the new way for starting/stopping the ivshmem server,
struct ServerThread now includes two new members: 'server', previously
present but not a member of any struct; and 'status', a new member of a
new type, ServerStartStatus, used to track and handle service
termination properly.

Additionally, a new function, mktempsocket(), has been added to help
create a unix socket filename, similar to what mktempshm() does for the
creation of a shm file.

Finally, the ivshmem-test qtest has been adapted to use the new ivhsmem
utils. Adjustments in that sense have also been made to meson.build;
also 'rt' have been removed as a lib dependency for ivhsmem-test.c.

Two lines unrelated to these changes have had their line indentation
also fixed in meson.build.

Signed-off-by: Gustavo Romero 
---
 tests/qtest/ivshmem-test.c  | 113 ++
 tests/qtest/ivshmem-utils.c | 155 
 tests/qtest/ivshmem-utils.h |  56 +
 tests/qtest/meson.build |   6 +-
 4 files changed, 221 insertions(+), 109 deletions(-)
 create mode 100644 tests/qtest/ivshmem-utils.c
 create mode 100644 tests/qtest/ivshmem-utils.h

diff --git a/tests/qtest/ivshmem-test.c b/tests/qtest/ivshmem-test.c
index 9bf8e78df6..5ce43e2f76 100644
--- a/tests/qtest/ivshmem-test.c
+++ b/tests/qtest/ivshmem-test.c
@@ -3,17 +3,17 @@
  *
  * Copyright (c) 2014 SUSE LINUX Products GmbH
  * Copyright (c) 2015 Red Hat, Inc.
+ * Copyright (c) 2023 Linaro Ltd.
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
 
-#include "qemu/osdep.h"
-#include 
-#include "contrib/ivshmem-server/ivshmem-server.h"
+#include "ivshmem-utils.h"
 #include "libqos/libqos-pc.h"
 #include "libqos/libqos-spapr.h"
-#include "libqtest.h"
+
+static ServerThread thread;
 
 #define TMPSHMSIZE (1 << 20)
 static char *tmpshm;
@@ -45,13 +45,6 @@ typedef struct _IVState {
 QPCIDevice *dev;
 } IVState;
 
-enum Reg {
-INTRMASK = 0,
-INTRSTATUS = 4,
-IVPOSITION = 8,
-DOORBELL = 12,
-};
-
 static const char* reg2str(enum Reg reg) {
 switch (reg) {
 case INTRMASK:
@@ -241,54 +234,6 @@ static void test_ivshmem_pair(void)
 g_free(data);
 }
 
-typedef struct ServerThread {
-GThread *thread;
-IvshmemServer *server;
-int pipe[2]; /* to handle quit */
-} ServerThread;
-
-static void *server_thread(void *data)
-{
-ServerThread *t = data;
-IvshmemServer *server = t->server;
-
-while (true) {
-fd_set fds;
-int maxfd, ret;
-
-FD_ZERO();
-FD_SET(t->pipe[0], );
-maxfd = t->pipe[0] + 1;
-
-ivshmem_server_get_fds(server, , );
-
-ret = select(maxfd, , NULL, NULL, NULL);
-
-if (ret < 0) {
-if (errno == EINTR) {
-continue;
-}
-
-g_critical("select error: %s\n", strerror(errno));
-break;
-}
-if (ret == 0) {
-continue;
-}
-
-if (FD_ISSET(t->pipe[0], )) {
-break;
-}
-
-if (ivshmem_server_handle_fds(server, , maxfd) < 0) {
-g_critical("ivshmem_server_handle_fds() failed\n");
-break;
-}
-}
-
-return NULL;
-}
-
 static void setup_vm_with_server(IVState *s, int nvectors)
 {
 char *cmd;
@@ -304,27 +249,12 @@ static void setup_vm_with_server(IVState *s, int nvectors)
 
 static void test_ivshmem_server(void)
 {
-g_autoptr(GError) err = NULL;
 IVState state1, state2, *s1, *s2;
-ServerThread thread;
-IvshmemServer server;
 int ret, vm1, vm2;
 int nvectors = 2;
 guint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
 
-ret = ivshmem_server_init(, tmpserver, tmpshm, true,
-  TMPSHMSIZE, nvectors,
-  g_test_verbose());
-g_assert_cmpint(ret, ==, 0);
-
-ret = ivshmem_server_start();
-g_assert_cmpint(ret, ==, 0);
-
-thread.server = 
-g_unix_open_pipe(thread.pipe, FD_CLOEXEC, );
-g_assert_no_error(err);
-thread.thread = g_thread_new("ivshmem-server", server_thread, );
-g_assert(thread.thread != NULL);
+test_ivshmem_server_start(, tmpserver, tmpshm, nvectors);
 
 setup_vm_with_server(, nvectors);
 s1 = 
@@ -367,15 +297,7 @@ static void test_ivshmem_server(void)
 cleanup_vm(s2);
 cleanup_vm(s1);
 
-if (qemu_write_full(thread.pipe[1], "q", 1) != 1) {
-g_error("qemu_write_full: %s", g_strerror(errno));
-}
-
-

[PATCH 4/4] hw/misc/ivshmem: Rename ivshmem to ivshmem-pci

2023-11-26 Thread Gustavo Romero
Because now there is also an MMIO ivshmem device (ivshmem-flat.c), and
ivshmem.c is a PCI specific implementation, rename it to ivshmem-pci.c.

Signed-off-by: Gustavo Romero 
---
 hw/misc/{ivshmem.c => ivshmem-pci.c} | 0
 hw/misc/meson.build  | 2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename hw/misc/{ivshmem.c => ivshmem-pci.c} (100%)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem-pci.c
similarity index 100%
rename from hw/misc/ivshmem.c
rename to hw/misc/ivshmem-pci.c
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 7b03fc1345..6f0a7c31cd 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -37,7 +37,7 @@ system_ss.add(when: 'CONFIG_SIFIVE_U_PRCI', if_true: 
files('sifive_u_prci.c'))
 subdir('macio')
 
 # ivshmem devices
-system_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem.c'))
+system_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem-pci.c'))
 system_ss.add(when: 'CONFIG_IVSHMEM_FLAT_DEVICE', if_true: 
files('ivshmem-flat.c'))
 
 system_ss.add(when: 'CONFIG_ALLWINNER_SRAMC', if_true: 
files('allwinner-sramc.c'))
-- 
2.34.1




[PATCH 3/4] tests/qtest: Add ivshmem-flat test

2023-11-26 Thread Gustavo Romero
Add qtest for the ivshmem-flat device.

Based-on: <20231113230149.321304-1-gustavo.rom...@linaro.org>
Signed-off-by: Gustavo Romero 
---
 tests/qtest/ivshmem-flat-test.c | 319 
 tests/qtest/meson.build |   2 +
 2 files changed, 321 insertions(+)
 create mode 100644 tests/qtest/ivshmem-flat-test.c

diff --git a/tests/qtest/ivshmem-flat-test.c b/tests/qtest/ivshmem-flat-test.c
new file mode 100644
index 00..7a4547637c
--- /dev/null
+++ b/tests/qtest/ivshmem-flat-test.c
@@ -0,0 +1,319 @@
+/*
+ * Inter-VM Shared Memory Flat Device qtests
+ *
+ * SPDX-FileCopyrightText: 2023 Linaro Ltd.
+ * SPDX-FileContributor: Gustavo Romero 
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ */
+
+#include "ivshmem-utils.h"
+
+#define IVSHMEM_FLAT_MMR_ADDR 0x400FF000
+#define IVSHMEM_FLAT_SHM_ADDR 0x4010
+#define SHM_SIZE 131072 /* 128k */
+
+static ServerThread thread;
+
+uint32_t *shm_ptr;
+char *shm_rel_path;
+char *server_socket_path;
+
+static void cleanup(void)
+{
+if (shm_ptr) {
+munmap(shm_ptr, SHM_SIZE);
+shm_ptr = NULL;
+}
+
+if (shm_rel_path) {
+shm_unlink(shm_rel_path);
+shm_rel_path = NULL;
+}
+
+if (server_socket_path) {
+unlink(server_socket_path);
+server_socket_path = NULL;
+}
+}
+
+static void abort_handler(void *data)
+{
+test_ivshmem_server_stop();
+cleanup();
+}
+
+/*
+ * Check if exactly 1 positive pulse (low->high->low) on 'irq' IRQ line happens
+ * in 'timeout' second(s). 'irq' must be intercepted using 
qtest_irq_intercept_*
+ * before this function can be used on it. It returns 0 when pulse is detected,
+ * otherwise 1.
+ */
+static int test_ivshmem_flat_irq_positive_pulse(QTestState *qts, int irq,
+int timeout)
+{
+uint64_t num_raises = 0;
+uint64_t num_lows = 0;
+uint64_t end_time;
+
+end_time = g_get_monotonic_time() + timeout * G_TIME_SPAN_SECOND;
+do {
+if ((num_raises = qtest_get_irq_raised_counter(qts, 0))) {
+num_lows = qtest_get_irq_lowered_counter(qts, 0);
+/* Check for 1 raise and 1 low IRQ event. */
+if (num_raises == num_lows && num_lows == 1) {
+return 0;
+} else {
+g_message("%s: Timeout expired", __func__);
+return 1;
+}
+}
+qtest_clock_step(qts, 1);
+} while (g_get_monotonic_time() < end_time);
+
+return 1;
+}
+
+static inline uint32_t read_reg(QTestState *qts, enum Reg reg)
+{
+uint32_t v;
+
+qtest_memread(qts, IVSHMEM_FLAT_MMR_ADDR + reg, , sizeof(v));
+
+return v;
+}
+
+static inline void write_reg(QTestState *qts, enum Reg reg, uint32_t v)
+{
+qtest_memwrite(qts, IVSHMEM_FLAT_MMR_ADDR + reg, , sizeof(v));
+}
+
+/*
+ * Setup a test VM with ivshmem-flat device attached, IRQ properly set, and
+ * connected to the ivshmem-server.
+ */
+static QTestState *setup_vm(void)
+{
+QTestState *qts;
+const char *cmd_line;
+
+cmd_line = g_strdup_printf("-machine lm3s6965evb "
+   "-chardev socket,path=%s,id=ivshm "
+   "-device ivshmem-flat,chardev=ivshm,"
+   
"x-irq-qompath='/machine/unattached/device[1]/nvic/unnamed-gpio-in[0]',"
+   "x-bus-qompath='/sysbus',shmem-size=%d",
+   server_socket_path, SHM_SIZE);
+qts = qtest_init(cmd_line);
+
+return qts;
+}
+
+static void test_ivshmem_flat_irq(void)
+{
+QTestState *vm_state;
+uint16_t own_id;
+
+vm_state = setup_vm();
+
+qtest_irq_intercept_out_named(vm_state,
+  "/machine/peripheral-anon/device[0]",
+  "irq-output");
+
+/* IVPOSTION has the device's own ID distributed by the ivshmem-server. */
+own_id = read_reg(vm_state, IVPOSITION);
+
+/* Make device notify itself. */
+write_reg(vm_state, DOORBELL, (own_id << 16) | 0 /* vector 0 */);
+
+/*
+ * Check intercepted device's IRQ output line. Named IRQ line 'irq-output'
+ * was associated to qtest IRQ 0 and after self notification qtest IRQ 0
+ * must be toggled by the device. The test fails if no toggling is detected
+ * in 2 seconds.
+ */
+g_assert(test_ivshmem_flat_irq_positive_pulse(vm_state, 0, 2) == 0);
+
+qtest_quit(vm_state);
+}
+
+static void test_ivshmem_flat_shm_write(void)
+{
+QTestState *vm_state;
+int num_elements, i;
+uint32_t  *data;
+
+vm_state = setup_vm();
+
+/* Prepare test data with random values. */
+data = g_malloc(SHM_SIZE);
+num_elements = SHM_SIZE/sizeof(*data);
+for (i = 0; i < num_elements; i++) {
+data[i] = g_test_rand_int();
+}
+
+/*
+ * Write test data to VM address IVSHMEM_FLAT_SHM_ADDR, where the shared
+ * memory region is located.
+ */
+qtest_memwrite(vm_state, 

[PATCH 1/4] Add ivshmem-flat device

2023-11-26 Thread Gustavo Romero
Add a new device, ivshmem-flat, which is similar to the ivshmem PCI but
does not require a PCI bus. It's meant to be used on machines like those
with Cortex-M MCUs, which usually lack a PCI/PCIe bus, e.g. lm3s6965evb
and mps2-an385.

The device currently only supports the sysbus bus.

The following is an example on how to create the ivshmem-flat device on
a Stellaris machine:

$ qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic
  -net none -chardev stdio,id=con,mux=on
  -serial chardev:con -mon chardev=con,mode=readline
  -chardev socket,path=/tmp/ivshmem_socket,id=ivf
  -device 
ivshmem-flat,x-irq-qompath=/machine/unattached/device[1]/nvic/unnamed-gpio-in[0],x-bus-qompath="/sysbus",chardev=ivf
  -kernel zephyr_qemu.elf

The new device, just like the ivshmem PCI device, supports both peer
notification via hardware interrupts and shared memory.

The IRQ QOM path for the target machine can be determined by creating
the VM without the ivshmem-flat device, going to the QEMU console and
listing the QOM nodes with 'info qom-tree'. In the Stellaris example
above the input IRQ is in the NVIC IC.

The MMRs for status and control (notification) are mapped to the MMIO
region at 0x400FF000 (default), whilst the shared memory region start
is mapped at addr. 0x4010 (default), but both addresses can be set
when creating the device by using 'x-bus-address-{mmr,shmem}' options,
respectively.

The device shared memory size can be set using the 'shmem-size' option
and it defaults to 4 MiB, which is the default size of shmem allocated
by the ivshmem server.

Signed-off-by: Gustavo Romero 
---
 docs/system/devices/ivshmem-flat.rst |  89 +
 hw/arm/mps2.c|   2 +
 hw/arm/stellaris.c   |   5 +-
 hw/arm/virt.c|   2 +
 hw/core/sysbus-fdt.c |   1 +
 hw/misc/Kconfig  |   5 +
 hw/misc/ivshmem-flat.c   | 477 +++
 hw/misc/meson.build  |   2 +
 hw/misc/trace-events |  18 +
 include/hw/misc/ivshmem-flat.h   |  72 
 10 files changed, 672 insertions(+), 1 deletion(-)
 create mode 100644 docs/system/devices/ivshmem-flat.rst
 create mode 100644 hw/misc/ivshmem-flat.c
 create mode 100644 include/hw/misc/ivshmem-flat.h

diff --git a/docs/system/devices/ivshmem-flat.rst 
b/docs/system/devices/ivshmem-flat.rst
new file mode 100644
index 00..a10446a18f
--- /dev/null
+++ b/docs/system/devices/ivshmem-flat.rst
@@ -0,0 +1,89 @@
+Inter-VM Shared Memory Flat Device
+--
+
+The ivshmem-flat device is meant to be used on machines that lack a PCI bus,
+making them unsuitable for the use of the traditional ivshmem device modeled as
+a PCI device. Machines like those with a Cortex-M MCU are good candidates to 
use
+the ivshmem-flat device. Also, since the flat version maps the control and
+status registers directly to the memory, it requires a quite tiny "device
+driver" to interact with other VMs, which is useful in some RTOSes, like
+Zephyr, which usually run on constrained resource targets.
+
+Similar to the ivshmem device, the ivshmem-flat device supports both peer
+notification via HW interrupts and Inter-VM shared memory. This allows the
+device to be used together with the traditional ivshmem, enabling communication
+between, for instance, an aarch64 VM  (using the traditional ivshmem device and
+running Linux), and an arm VM (using the ivshmem-flat device and running Zephyr
+instead).
+
+The ivshmem-flat device does not support the use of a ``memdev`` option (see
+ivshmem.rst for more details). It relies on the ivshmem server to create and
+distribute the proper shared memory file descriptor and the eventfd(s) to 
notify
+(interrupt) the peers. Therefore, to use this device, it is always necessary to
+have an ivshmem server up and running for proper device creation.
+
+Although the ivshmem-flat supports both peer notification (interrupts) and
+shared memory, the interrupt mechanism is optional. If no input IRQ is
+specified for the device it is disabled, preventing the VM from notifying or
+being notified by other VMs (a warning will be displayed to the user to inform
+the IRQ mechanism is disabled). The shared memory region is always present.
+
+The MMRs (INTRMASK, INTRSTATUS, IVPOSITION, and DOORBELL registers) offsets at
+the MMR region, and their functions, follow the ivshmem spec, so they work
+exactly as in the ivshmem PCI device (see ./specs/ivshmem-spec.txt).
+
+
+Device Options
+--
+
+The only required options to create an ivshmem-flat device are: (a) the UNIX
+socket where the ivshmem server is listening, usually ``/tmp/ivshmem_socket``;
+and (b) the bus type to be used by the device, which currently only supports
+"/sysbus" bus type.
+
+Example:
+
+.. parsed-literal::
+
+|qemu-system-arm| -chardev 

[PATCH 0/4] Add ivshmem-flat device

2023-11-26 Thread Gustavo Romero
This patchset introduces a new device, ivshmem-flat, which is similar to the
current ivshmem device but does not require a PCI bus. It implements the ivshmem
status and control registers as MMRs and the shared memory as a directly
accessible memory region in the VM memory layout. It's meant to be used on
machines like those with Cortex-M MCUs, which usually lack a PCI bus, e.g.,
lm3s6965evb and mps2-an385. Additionally, it has the benefit of requiring a tiny
'device driver,' which is helpful on some RTOSes, like Zephyr, that run on
memory-constrained resource targets.

The patchset includes a QTest for the ivshmem-flat device, however, it's also
possible to experiment with it in two ways:

(a) using two Cortex-M VMs running Zephyr; or
(b) using one aarch64 VM running Linux with the ivshmem PCI device and another
arm (Cortex-M) VM running Zephyr with the new ivshmem-flat device.

Please note that for running the ivshmem-flat QTests the following patch, which
is not committed to the tree yet, must be applied:

https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg03176.html

--

To experiment with (a), clone this Zephyr repo [0], set the Zephyr build
environment [1], and follow the instructions in the 'ivshmem' sample main.c [2].

[0] https://github.com/gromero/zephyr/tree/ivshmem
[1] https://docs.zephyrproject.org/latest/develop/getting_started/index.html
[2] 
https://github.com/gromero/zephyr/commit/73fbd481e352b25ae5483ba5048a2182b90b7f00#diff-16fa1f481a49b995d0d1a62da37b9f33033f5ee477035e73465e7208521ddbe0R9-R70

To experiment with (b):

$ git clone -b uio_ivshmem --single-branch https://github.com/gromero/linux.git
$ cd linux
$ wget 
https://people.linaro.org/~gustavo.romero/ivshmem/arm64_uio_ivshmem.config -O 
.config

If in an x86_64 machine, cross compile the kernel, for instance:

$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j 36

Install image in some directory, let's say, in ~/linux:

$ mkdir ~/linux
$ export INSTALL_PATH=~/linux
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j 36 install

or, if you prefer, download the compiled image from:

$ wget 
https://people.linaro.org/~gustavo.romero/ivshmem/vmlinuz-6.6.0-rc1-g28f3f88ee261

... and then the rootfs:

$ wget https://people.linaro.org/~gustavo.romero/ivshmem/rootfs.qcow2

Now, build QEMU with this patchset applied:

$ mkdir build && cd build
$ ../configure --target-list=arm-softmmu,aarch64-softmmu
$ make -j 36

Start the ivshmem server:

$ contrib/ivshmem-server/ivshmem-server -F

Start the aarch64 VM + Linux + ivshmem PCI device:

$ ./qemu-system-aarch64 -kernel ~/linux/vmlinuz-6.6.0-rc1-g28f3f88ee261 -append 
"root=/dev/vda initrd=/bin/bash console=ttyAMA0,115200" -drive 
file=~/linux/rootfs.qcow2,media=disk,if=virtio -machine virt-6.2 -nographic 
-accel tcg -cpu cortex-a57 -m 8192 -netdev 
bridge,id=hostnet0,br=virbr0,helper=/usr/lib/qemu/qemu-bridge-helper -device 
pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 
-device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:d9:d1:12,bus=pci.1,addr=0x0 
-device ivshmem-doorbell,vectors=2,chardev=ivshmem -chardev 
socket,path=/tmp/ivshmem_socket,id=ivshmem

Log into the VM with user/pass: root/abc123

# dmesg | grep uio

should show:

[2.656367] uio_ivshmem :00:02.0: ivshmem-mmr at 0x10203000, 
size 0x1000
[2.656931] uio_ivshmem :00:02.0: ivshmem-shmem at 0x0080, 
size 0x0040
[2.662554] uio_ivshmem :00:02.0: module successfully loaded

In another console, clone and build Zephyr image from 'uio_ivhsmem' branch:

$ git clone -b uio_ivshmem --single-branch https://github.com/gromero/zephyr
$ west -v --verbose build -p always -b qemu_cortex_m3 ./samples/uio_ivshmem/

... and then start the arm VM + Zephyr image + ivshmem-flat device:

$ ./qemu-system-arm -machine lm3s6965evb -nographic -net none -chardev 
socket,path=/tmp/ivshmem_socket,id=ivshmem_flat -device 
ivshmem-flat,chardev=ivshmem_flat,x-irq-qompath='/machine/unattached/device[1]/nvic/unnamed-gpio-in[0]',x-bus-qompath='/sysbus'
 -kernel 
~/zephyrproject/zephyr/build/qemu_cortex_m3/uio_ivshmem/zephyr/zephyr.elf

You should see something like:

*** Booting Zephyr OS build zephyr-v3.3.0-8350-gfb003e583600 ***
*** Board: qemu_cortex_m3
*** Installing direct IRQ handler for external IRQ0 (Exception #16)...
*** Enabling IRQ0 in the NVIC logic...
*** Received IVSHMEM PEER ID: 7
*** Waiting notification from peers to start...

Now, from the Linux terminal, notify the arm VM (use the "IVSHMEM PEER ID"
reported by Zephyr as the third arg, in this example: 7):

# ./zephyr_ivshmem_test /dev/uio0 7
MMRs mapped at 0x8fb28000 in VMA.
shmem mapped at 0x8f728000 in VMA.
mmr0: 0 0
mmr1: 0 0
mmr2: 6 6
mmr3: 0 0
Data ok. 4194304 byte(s) checked.
#

The arm VM should report something like:

*** Got interrupt at vector 0!
*** Writting constant 0xb5b5b5b5 to shmem... done!
*** Notifying back peer ID 6 at vector 0...


Cheers,

Re: [PATCH-for-9.0 v2 5/8] hw: Prefer qdev_prop_set_bit over object_property_set_bool for QDev

2023-11-26 Thread Harsh Prateek Bora




On 11/23/23 20:08, Philippe Mathieu-Daudé wrote:

The QOM API is lower level than the QDev one. When an instance is
QDev and setting the property can not fail (using _abort),
prefer qdev_prop_set_bit() over object_property_set_bool().

Mechanical transformation using the following coccinelle patch:

   @@
   expression o, p, v;
   @@
   -object_property_set_bool(OBJECT(o), p, v, _abort)
   +qdev_prop_set_bit(DEVICE(o), p, v)
   
   -object_property_set_bool(o, p, v, _abort)
   +qdev_prop_set_bit(DEVICE(o), p, v)

manually adding the missing "hw/qdev-properties.h" header.

In hw/arm/armsse.c we use the available 'cpudev' instead of 'cpuobj'.

Suggested-by: Markus Armbruster 
Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/acpi/cpu_hotplug.c   |  7 +++
  hw/acpi/ich9.c  |  4 ++--
  hw/acpi/piix4.c |  4 ++--
  hw/arm/armsse.c |  3 +--
  hw/arm/armv7m.c |  3 +--
  hw/arm/aspeed_ast2400.c |  3 +--
  hw/arm/aspeed_ast2600.c |  9 +++--
  hw/arm/bcm2835_peripherals.c|  3 +--
  hw/arm/bcm2836.c|  4 ++--
  hw/arm/boot.c   |  4 ++--
  hw/arm/fsl-imx25.c  |  3 +--
  hw/arm/fsl-imx31.c  |  3 +--
  hw/arm/fsl-imx6.c   | 12 
  hw/arm/fsl-imx6ul.c |  8 
  hw/arm/fsl-imx7.c   | 10 --
  hw/arm/npcm7xx.c|  9 +++--
  hw/arm/xlnx-versal.c|  9 +++--
  hw/arm/xlnx-zynqmp.c|  9 +++--
  hw/core/bus.c   |  2 +-
  hw/core/qdev.c  |  2 +-
  hw/i386/pc_piix.c   | 19 ++-
  hw/microblaze/petalogix_ml605_mmu.c |  5 ++---
  hw/microblaze/xlnx-zynqmp-pmu.c | 18 +++---
  hw/mips/cps.c   |  3 +--
  hw/ppc/e500.c   |  3 +--
  hw/ppc/spapr_pci.c  |  3 +--


For spapr:
Reviewed-by: Harsh Prateek Bora 


  hw/rx/rx-gdbsim.c   |  4 ++--
  hw/sparc/sun4m.c|  3 +--
  28 files changed, 64 insertions(+), 105 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 634bbecb31..1338c037b5 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -12,6 +12,7 @@
  #include "qemu/osdep.h"
  #include "hw/acpi/cpu_hotplug.h"
  #include "qapi/error.h"
+#include "hw/qdev-properties.h"
  #include "hw/core/cpu.h"
  #include "hw/i386/pc.h"
  #include "hw/pci/pci.h"
@@ -41,8 +42,7 @@ static void cpu_status_write(void *opaque, hwaddr addr, 
uint64_t data,
   */
  if (addr == 0 && data == 0) {
  AcpiCpuHotplug *cpus = opaque;
-object_property_set_bool(cpus->device, "cpu-hotplug-legacy", false,
- _abort);
+qdev_prop_set_bit(DEVICE(cpus->device), "cpu-hotplug-legacy", false);
  }
  }
  
@@ -66,8 +66,7 @@ static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu)
  
  cpu_id = k->get_arch_id(cpu);

  if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
-object_property_set_bool(g->device, "cpu-hotplug-legacy", false,
- _abort);
+qdev_prop_set_bit(DEVICE(g->device), "cpu-hotplug-legacy", false);
  return;
  }
  
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c

index 25e2c7243e..64b00673fe 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -30,6 +30,7 @@
  #include "hw/pci/pci.h"
  #include "migration/vmstate.h"
  #include "qemu/timer.h"
+#include "hw/qdev-properties.h"
  #include "hw/core/cpu.h"
  #include "sysemu/reset.h"
  #include "sysemu/runstate.h"
@@ -197,8 +198,7 @@ static bool vmstate_test_use_cpuhp(void *opaque)
  static int vmstate_cpuhp_pre_load(void *opaque)
  {
  ICH9LPCPMRegs *s = opaque;
-Object *obj = OBJECT(s->gpe_cpu.device);
-object_property_set_bool(obj, "cpu-hotplug-legacy", false, _abort);
+qdev_prop_set_bit(DEVICE(s->gpe_cpu.device), "cpu-hotplug-legacy", false);
  return 0;
  }
  
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c

index dd523d2e4c..215929ac6a 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -203,8 +203,8 @@ static bool vmstate_test_use_cpuhp(void *opaque)
  
  static int vmstate_cpuhp_pre_load(void *opaque)

  {
-Object *obj = OBJECT(opaque);
-object_property_set_bool(obj, "cpu-hotplug-legacy", false, _abort);
+DeviceState *dev = DEVICE(opaque);
+qdev_prop_set_bit(dev, "cpu-hotplug-legacy", false);
  return 0;
  }
  
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c

index 4672df180f..546b15e658 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -1022,8 +1022,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
   * later if necessary.
   */
  if (extract32(info->cpuwait_rst, i, 1)) {
-

Re: [PATCH-for-9.0 v2 1/8] hw/ppc/spapr_cpu_core: Access QDev properties with proper API

2023-11-26 Thread Harsh Prateek Bora




On 11/23/23 20:08, Philippe Mathieu-Daudé wrote:

CPUState::start_powered_off field is part of the internal
implementation of a QDev CPU. It is exposed as the QDev
"start-powered-off" property. External components should
use the qdev properties API to access it.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Harsh Prateek Bora 


---
  hw/ppc/spapr_cpu_core.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 91fae56573..24f759ba26 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -306,7 +306,7 @@ static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int 
i, Error **errp)
   * All CPUs start halted. CPU0 is unhalted from the machine level reset 
code
   * and the rest are explicitly started up by the guest using an RTAS call.
   */
-cs->start_powered_off = true;
+qdev_prop_set_bit(DEVICE(obj), "start-powered-off", true);
  cs->cpu_index = cc->core_id + i;
  if (!spapr_set_vcpu_id(cpu, cs->cpu_index, errp)) {
  return NULL;




[PATCH v6 0/4] Add full zoned storage emulation to qcow2 driver

2023-11-26 Thread Sam Li
This patch series add a new extension - zoned format - to the
qcow2 driver thereby allowing full zoned storage emulation on
the qcow2 img file. Users can attach such a qcow2 file to the
guest as a zoned device.

Write pointer are preserved in the zoned metadata. It will be
recovered after power cycle. Meanwhile, any open (implicit or
explicit) zone will show up as closed.

Zone states are in memory. Read-only and offline states are
device-internal events, which are not considerred in qcow2
emulation for simplicity. The other zone states
(closed, empty, full) can be inferred from write poiner
values, presistent across QEMU reboots. The open states are
kept in memory using open zone lists.

Zoned extension feature is optional. We only set it to host-manged 
when emulating a zoned device. For non-zoned devices, it does not 
need to consider setting this option.

To create a qcow2 image with zoned format feature, use command like
this:
$path/to/qemu-img create -f qcow2 zbc.qcow2 -o size=768M
-o zone.size=64M -o zone.capacity=64M -o zone.conventional_zones=0
-o zone.max_append_bytes=4096 -o zone.max_open_zones=10
-o zone.max_active_zones=12 -o zone.mode=host-managed


Then add it to the QEMU command line:
-blockdev 
node-name=drive1,driver=qcow2,file.driver=file,file.filename=../qemu/test.qcow2 
\
-device virtio-blk-pci,drive=drive1 \

v5->v6:
- fix docs and specs [Eric, Markus, Stefan]
- add general sanity checks for zoned device configurations while creation and 
opening [Eric]
- fix LRU when implicitly open a zone for a long time [Stefan]

v4->v5:
- add incompatible bit for zoned format [Eric]
- fix and manage zone resources via LRU [Damien]
- renaming functions and fields, spec changes [Markus, Damien]
- add closed zone list
- make qemu iotests for zoned device consecutive [Stefan]

v3->v4:
- use QLIST for implicit, explicit open zones management [Stefan]
- keep zone states in memory and drop state bits in wp metadata structure 
[Damien, Stefan]
- change zone resource management and iotests accordingly
- add tracing for number of implicit zones
- address review comments [Stefan, Markus]:
  * documentation, config, style

v2->v3:
- drop zoned_profile option [Klaus]
- reformat doc comments of qcow2 [Markus]
- add input validation and checks for zoned information [Stefan]
- code style: format, comments, documentation, naming [Stefan]
- add tracing function for wp tracking [Stefan]
- reconstruct io path in check_zone_resources [Stefan]

v1->v2:
- add more tests to qemu-io zoned commands
- make zone append change state to full when wp reaches end
- add documentation to qcow2 zoned extension header
- address review comments (Stefan):
  * fix zoned_mata allocation size
  * use bitwise or than addition
  * fix wp index overflow and locking
  * cleanups: comments, naming

Sam Li (4):
  docs/qcow2: add the zoned format feature
  qcow2: add configurations for zoned format extension
  qcow2: add zoned emulation capability
  iotests: test the zoned format feature for qcow2 file

 block/qcow2.c| 972 ++-
 block/qcow2.h|  36 +-
 block/trace-events   |   2 +
 docs/interop/qcow2.txt   |  99 ++-
 docs/system/qemu-block-drivers.rst.inc   |  35 +
 include/block/block_int-common.h |  13 +
 include/qemu/queue.h |   1 +
 qapi/block-core.json |  63 +-
 tests/qemu-iotests/tests/zoned-qcow2 | 126 +++
 tests/qemu-iotests/tests/zoned-qcow2.out | 118 +++
 10 files changed, 1460 insertions(+), 5 deletions(-)
 create mode 100755 tests/qemu-iotests/tests/zoned-qcow2
 create mode 100644 tests/qemu-iotests/tests/zoned-qcow2.out

-- 
2.40.1




[PATCH v6 4/4] iotests: test the zoned format feature for qcow2 file

2023-11-26 Thread Sam Li
The zoned format feature can be tested by:
$ tests/qemu-iotests/check -qcow2 zoned-qcow2

Signed-off-by: Sam Li 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qemu-iotests/tests/zoned-qcow2 | 126 +++
 tests/qemu-iotests/tests/zoned-qcow2.out | 118 +
 2 files changed, 244 insertions(+)
 create mode 100755 tests/qemu-iotests/tests/zoned-qcow2
 create mode 100644 tests/qemu-iotests/tests/zoned-qcow2.out

diff --git a/tests/qemu-iotests/tests/zoned-qcow2 
b/tests/qemu-iotests/tests/zoned-qcow2
new file mode 100755
index 00..d7141a35aa
--- /dev/null
+++ b/tests/qemu-iotests/tests/zoned-qcow2
@@ -0,0 +1,126 @@
+#!/usr/bin/env bash
+#
+# Test zone management operations for qcow2 file.
+#
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+status=1 # failure is the default!
+
+file_name="zbc.qcow2"
+_cleanup()
+{
+  _cleanup_test_img
+  _rm_test_img "$file_name"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ../common.rc
+. ../common.filter
+. ../common.qemu
+
+# This test only runs on Linux hosts with qcow2 image files.
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+echo
+echo "=== Initial image setup ==="
+echo
+
+$QEMU_IMG create -f qcow2 $file_name -o size=768M -o zone.size=64M -o \
+zone.capacity=64M -o zone.conventional_zones=0 -o zone.max_append_bytes=131072 
\
+-o zone.max_open_zones=10 -o zone.max_active_zones=12 -o zone.mode=host-managed
+
+IMG="--image-opts -n driver=qcow2,file.driver=file,file.filename=$file_name"
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
+
+echo
+echo "=== Testing a qcow2 img with zoned format ==="
+echo
+echo "case 1: test zone operations one by one"
+
+echo "(1) report zones[0]:"
+$QEMU_IO $IMG -c "zrp 0 1"
+echo
+echo "report zones[0~9]:"
+$QEMU_IO $IMG -c "zrp 0 10"
+echo
+echo "report zones[-1]:"  # zones[-1] dictates the last zone
+$QEMU_IO $IMG -c "zrp 0x2C00 2" # 0x2C00 / 512 = 0x16
+echo
+echo
+echo "(2) open zones[0], zones[1], zones[-1] then close, finish, reset:"
+$QEMU_IO $IMG << EOF
+zo 0 0x400 # 0x400 / 512 = 0x2
+zrp 0 1
+zo 0x400 0x400
+zrp 0x400 1
+zo 0x2C00 0x400
+zrp 0x2C00 2
+zc 0 0x400
+zrp 0 1
+zc 0x2C00 0x400
+zrp 0x2C00 2
+zf 0 0x400
+zrp 0 1
+zf 64M 64M
+zrp 0x400 2
+zf 0x2C00 0x400
+zrp 0x2C00 2
+zrs 0 0x400
+zrp 0 1
+zrs 0x400 0x400
+zrp 0x400 1
+zrs 0x2C00 0x400
+zrp 0x2C00 2
+EOF
+
+echo
+echo "(3) append write with (4k, 8k) data"
+$QEMU_IO $IMG -c "zrp 0 12" # the physical block size of the device is 4096
+echo "Append write zones[0], zones[1] twice"
+$QEMU_IO $IMG << EOF
+zap -p 0 0x1000 0x2000
+zrp 0 1
+zap -p 0 0x1000 0x2000
+zrp 0 1
+zap -p 0x400 0x1000 0x2000
+zrp 0x400 1
+zap -p 0x400 0x1000 0x2000
+zrp 0x400 1
+EOF
+
+echo
+echo "Reset all:"
+$QEMU_IO $IMG -c "zrs 0 768M" -c "zrp 0 12"
+echo
+echo
+
+echo "case 2: test a sets of ops that works or not"
+echo "(1) append write (4k, 4k) and then write to full"
+$QEMU_IO $IMG << EOF
+zap -p 0 0x1000 0x1000 # wrote (4k, 4k):
+zrp 0 1
+zap -p 0 0x1000 0x3ffd000
+zrp 0 1
+EOF
+
+echo "Reset zones[0]:"
+$QEMU_IO $IMG -c "zrs 0 64M" -c "zrp 0 1"
+
+echo "(2) write in zones[0], zones[3], zones[8], and then reset all"
+$QEMU_IO $IMG << EOF
+zap -p 0 0x1000 0x1000
+zap -p 0xc00 0x1000 0x1000
+zap -p 0x2000 0x1000 0x1000
+zrp 0 12
+zrs 0 768M
+zrp 0 12
+EOF
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/tests/zoned-qcow2.out 
b/tests/qemu-iotests/tests/zoned-qcow2.out
new file mode 100644
index 00..3b30ef545b
--- /dev/null
+++ b/tests/qemu-iotests/tests/zoned-qcow2.out
@@ -0,0 +1,118 @@
+QA output created by zoned-qcow2
+
+=== Initial image setup ===
+
+Formatting 'zbc.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off 
compression_type=zlib zone.mode=host-managed zone.size=67108864 
zone.capacity=67108864 zone.conventional_zones=0 zone.max_append_bytes=131072 
zone.max_active_zones=12 zone.max_open_zones=10 size=805306368 
lazy_refcounts=off refcount_bits=16
+
+=== Testing a qcow2 img with zoned format ===
+
+case 1: test zone operations one by one
+(1) report zones[0]:
+start: 0x0, len 0x2, cap 0x2, wptr 0x0, zcond:1, [type: 2]
+
+report zones[0~9]:
+start: 0x0, len 0x2, cap 0x2, wptr 0x0, zcond:1, [type: 2]
+start: 0x2, len 0x2, cap 0x2, wptr 0x2, zcond:1, [type: 2]
+start: 0x4, len 0x2, cap 0x2, wptr 0x4, zcond:1, [type: 2]
+start: 0x6, len 0x2, cap 0x2, wptr 0x6, zcond:1, [type: 2]
+start: 0x8, len 0x2, cap 0x2, wptr 0x8, zcond:1, [type: 2]
+start: 0xa, len 0x2, cap 0x2, wptr 0xa, zcond:1, [type: 2]
+start: 0xc, len 0x2, cap 0x2, wptr 0xc, zcond:1, [type: 2]
+start: 0xe, len 0x2, cap 0x2, wptr 0xe, zcond:1, [type: 2]
+start: 0x10, len 0x2, cap 0x2, 

[PATCH v6 2/4] qcow2: add configurations for zoned format extension

2023-11-26 Thread Sam Li
To configure the zoned format feature on the qcow2 driver, it
requires settings as: the device size, zone model, zone size,
zone capacity, number of conventional zones, limits on zone
resources (max append bytes, max open zones, and max_active_zones).

To create a qcow2 image with zoned format feature, use command like
this:
$path/to/qemu-img create -f qcow2 zbc.qcow2 -o size=768M
-o zone.size=64M -o zone.capacity=64M -o zone.conventional_zones=0
-o zone.max_append_bytes=4096 -o zone.max_open_zones=10
-o zone.max_active_zones=12 -o zone.mode=host-managed

Signed-off-by: Sam Li 
---
 block/qcow2.c| 233 ++-
 block/qcow2.h|  36 -
 docs/interop/qcow2.txt   |  99 -
 include/block/block_int-common.h |  13 ++
 qapi/block-core.json |  63 -
 5 files changed, 440 insertions(+), 4 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 13e032bd5e..9a92cd242c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -73,6 +73,7 @@ typedef struct {
 #define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
 #define  QCOW2_EXT_MAGIC_BITMAPS 0x23852875
 #define  QCOW2_EXT_MAGIC_DATA_FILE 0x44415441
+#define  QCOW2_EXT_MAGIC_ZONED_FORMAT 0x007a6264
 
 static int coroutine_fn
 qcow2_co_preadv_compressed(BlockDriverState *bs,
@@ -194,6 +195,55 @@ qcow2_extract_crypto_opts(QemuOpts *opts, const char *fmt, 
Error **errp)
 return cryptoopts_qdict;
 }
 
+/*
+ * Passing by the zoned device configurations by a zoned_header struct, check
+ * if the zone device options are under constraints. Return false when some
+ * option is invalid
+ */
+static inline bool
+qcow2_check_zone_options(Qcow2ZonedHeaderExtension *zone_opt)
+{
+if (zone_opt) {
+if (zone_opt->zone_size == 0) {
+error_report("Zoned extension header zone_size field "
+ "can not be 0");
+return false;
+}
+
+if (zone_opt->zone_capacity > zone_opt->zone_size) {
+error_report("zone capacity %" PRIu32 "B exceeds zone size "
+ "%" PRIu32"B", zone_opt->zone_capacity,
+ zone_opt->zone_size);
+return false;
+}
+
+if (zone_opt->max_active_zones > zone_opt->nr_zones) {
+error_report("Max_active_zones %" PRIu32 " exceeds "
+ "nr_zones %" PRIu32". Set it to nr_zones.",
+ zone_opt->max_active_zones, zone_opt->nr_zones);
+zone_opt->max_active_zones = zone_opt->nr_zones;
+}
+
+if (zone_opt->max_open_zones > zone_opt->max_active_zones) {
+error_report("Max_open_zones %" PRIu32 " exceeds "
+ "max_active_zones %" PRIu32". Set it to "
+ "max_active_zones.",
+ zone_opt->max_open_zones,
+ zone_opt->max_active_zones);
+zone_opt->max_open_zones = zone_opt->max_active_zones;
+}
+
+if (zone_opt->max_open_zones > zone_opt->nr_zones) {
+error_report("Max_open_zones field can not be larger "
+ "than the number of zones. Set it to nr_zones.");
+zone_opt->max_open_zones = zone_opt->nr_zones;
+}
+
+return true;
+}
+return false;
+}
+
 /*
  * read qcow2 extension and fill bs
  * start reading from start_offset
@@ -211,6 +261,7 @@ qcow2_read_extensions(BlockDriverState *bs, uint64_t 
start_offset,
 uint64_t offset;
 int ret;
 Qcow2BitmapHeaderExt bitmaps_ext;
+Qcow2ZonedHeaderExtension zoned_ext;
 
 if (need_update_header != NULL) {
 *need_update_header = false;
@@ -432,6 +483,51 @@ qcow2_read_extensions(BlockDriverState *bs, uint64_t 
start_offset,
 break;
 }
 
+case QCOW2_EXT_MAGIC_ZONED_FORMAT:
+{
+if (ext.len < sizeof(zoned_ext)) {
+/* Missing fields */
+error_setg(errp, "zoned_ext: len=%" PRIu32 " too small "
+   "(<%zu)", ext.len, sizeof(zoned_ext));
+return -EINVAL;
+}
+ret = bdrv_pread(bs->file, offset, ext.len, _ext, 0);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "zoned_ext: "
+ "Could not read ext header");
+return ret;
+}
+
+zoned_ext.zone_size = be32_to_cpu(zoned_ext.zone_size);
+zoned_ext.zone_capacity = be32_to_cpu(zoned_ext.zone_capacity);
+zoned_ext.conventional_zones =
+be32_to_cpu(zoned_ext.conventional_zones);
+zoned_ext.nr_zones = be32_to_cpu(zoned_ext.nr_zones);
+zoned_ext.max_open_zones = be32_to_cpu(zoned_ext.max_open_zones);
+zoned_ext.max_active_zones =
+be32_to_cpu(zoned_ext.max_active_zones);
+zoned_ext.max_append_bytes =
+

[PATCH v6 3/4] qcow2: add zoned emulation capability

2023-11-26 Thread Sam Li
By adding zone operations and zoned metadata, the zoned emulation
capability enables full emulation support of zoned device using
a qcow2 file. The zoned device metadata includes zone type,
zoned device state and write pointer of each zone, which is stored
to an array of unsigned integers.

Each zone of a zoned device makes state transitions following
the zone state machine. The zone state machine mainly describes
five states, IMPLICIT OPEN, EXPLICIT OPEN, FULL, EMPTY and CLOSED.
READ ONLY and OFFLINE states will generally be affected by device
internal events. The operations on zones cause corresponding state
changing.

Zoned devices have a limit on zone resources, which puts constraints on
write operations into zones. It is managed by active zone lists
following LRU policy.

Signed-off-by: Sam Li 
---
 block/qcow2.c| 741 ++-
 block/trace-events   |   2 +
 include/qemu/queue.h |   1 +
 3 files changed, 742 insertions(+), 2 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 9a92cd242c..26f2bb4a87 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -195,6 +195,179 @@ qcow2_extract_crypto_opts(QemuOpts *opts, const char 
*fmt, Error **errp)
 return cryptoopts_qdict;
 }
 
+#define QCOW2_ZT_IS_CONV(wp)(wp & 1ULL << 59)
+
+/*
+ * To emulate a real zoned device, closed, empty and full states are
+ * preserved after a power cycle. Open states are in-memory and will
+ * be lost after closing the device. Read-only and offline states are
+ * device-internal events, which are not considered for simplicity.
+ */
+static inline BlockZoneState qcow2_get_zone_state(BlockDriverState *bs,
+  uint32_t index)
+{
+BDRVQcow2State *s = bs->opaque;
+Qcow2ZoneListEntry *zone_entry = >zone_list_entries[index];
+uint64_t zone_wp = bs->wps->wp[index];
+uint64_t zone_start;
+
+if (QCOW2_ZT_IS_CONV(zone_wp)) {
+return BLK_ZS_NOT_WP;
+}
+
+if (QLIST_IS_INSERTED(zone_entry, exp_open_zone_entry)) {
+return BLK_ZS_EOPEN;
+}
+if (QLIST_IS_INSERTED(zone_entry, imp_open_zone_entry)) {
+return BLK_ZS_IOPEN;
+}
+
+zone_start = index * bs->bl.zone_size;
+if (zone_wp == zone_start) {
+return BLK_ZS_EMPTY;
+}
+if (zone_wp >= zone_start + bs->bl.zone_capacity) {
+return BLK_ZS_FULL;
+}
+if (zone_wp > zone_start) {
+return BLK_ZS_CLOSED;
+}
+return BLK_ZS_NOT_WP;
+}
+
+/*
+ * Write the new wp value to the dedicated location of the image file.
+ */
+static int qcow2_write_wp_at(BlockDriverState *bs, uint64_t *wp,
+ uint32_t index) {
+BDRVQcow2State *s = bs->opaque;
+uint64_t wpv = *wp;
+int ret;
+
+ret = bdrv_pwrite(bs->file, s->zoned_header.zonedmeta_offset
++ sizeof(uint64_t) * index, sizeof(uint64_t), wp, 0);
+if (ret < 0) {
+goto exit;
+}
+trace_qcow2_wp_tracking(index, *wp >> BDRV_SECTOR_BITS);
+return ret;
+
+exit:
+*wp = wpv;
+error_report("Failed to write metadata with file");
+return ret;
+}
+
+static bool qcow2_can_activate_zone(BlockDriverState *bs)
+{
+BDRVQcow2State *s = bs->opaque;
+/* When the max active zone is zero, there is no limit on active zones */
+if (!s->zoned_header.max_active_zones) {
+return true;
+}
+
+/* The active zones are zones with the states of open and closed */
+if (s->nr_zones_exp_open + s->nr_zones_imp_open + s->nr_zones_closed
+< s->zoned_header.max_active_zones) {
+return true;
+}
+
+return false;
+}
+
+/*
+ * This function manages open zones under active zones limit. It checks
+ * if a zone can transition to open state while maintaining max open and
+ * active zone limits.
+ */
+static bool qcow2_can_open_zone(BlockDriverState *bs)
+{
+BDRVQcow2State *s = bs->opaque;
+Qcow2ZoneListEntry *zone_entry;
+
+/* When the max open zone is zero, there is no limit on open zones */
+if (!s->zoned_header.max_open_zones) {
+return true;
+}
+
+/*
+ * The open zones are zones with the states of explicitly and
+ * implicitly open.
+ */
+if (s->nr_zones_imp_open + s->nr_zones_exp_open <
+s->zoned_header.max_open_zones) {
+return true;
+}
+
+/*
+ * Zones are managed once at a time. Thus, the number of implicitly open
+ * zone can never be over the open zone limit. When the active zone limit
+ * is not reached, close only one implicitly open zone.
+ */
+if (qcow2_can_activate_zone(bs)) {
+/*
+ * The LRU policy is used for handling active zone lists. When
+ * removing a random zone entry, we discard the least recently used
+ * list item. The list item at the last is the least recently used
+ * one. The zone list maintained this property by removing the last
+ * entry and inserting before the first entry.
+ */
+  

[PATCH v6 1/4] docs/qcow2: add the zoned format feature

2023-11-26 Thread Sam Li
Add the specs for the zoned format feature of the qcow2 driver.
The qcow2 file then can emulate real zoned devices, either passed
through by virtio-blk device or NVMe ZNS drive to the guest
given zoned information.

Signed-off-by: Sam Li 
Reviewed-by: Stefan Hajnoczi 
---
 docs/system/qemu-block-drivers.rst.inc | 35 ++
 1 file changed, 35 insertions(+)

diff --git a/docs/system/qemu-block-drivers.rst.inc 
b/docs/system/qemu-block-drivers.rst.inc
index 105cb9679c..955fea271e 100644
--- a/docs/system/qemu-block-drivers.rst.inc
+++ b/docs/system/qemu-block-drivers.rst.inc
@@ -172,6 +172,41 @@ This section describes each format and the options that 
are supported for it.
 filename`` to check if the NOCOW flag is set or not (Capital 'C' is
 NOCOW flag).
 
+  .. option:: zone.mode
+If this is set to ``host-managed``, the image is an emulated zoned
+block device. This option is only valid to emulated zoned device files.
+
+  .. option:: zone.size
+
+The size of a zone in bytes. The device is divided into zones of this
+size with the exception of the last zone, which may be smaller.
+
+  .. option:: zone.capacity
+
+The initial capacity value, in bytes, for all zones. The capacity must
+be less than or equal to zone size. If the last zone is smaller, then
+its capacity is capped.
+
+The zone capacity is per zone and may be different between zones in real
+devices. QCow2 sets all zones to the same capacity.
+
+  .. option:: zone.conventional_zones
+
+The number of conventional zones of the zoned device.
+
+  .. option:: zone.max_open_zones
+
+The maximal allowed open zones.
+
+  .. option:: zone.max_active_zones
+
+The limit of the zones with implicit open, explicit open or closed state.
+
+  .. option:: zone.max_append_bytes
+
+The number of bytes in a zone append request that can be issued to the
+device. It must be 512-byte aligned.
+
 .. program:: image-formats
 .. option:: qed
 
-- 
2.40.1




Re: [PATCH-for-9.0 16/16] target/arm/kvm: Have kvm_arm_hw_debug_active take a ARMCPU argument

2023-11-26 Thread Gavin Shan

Hi Phil,

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)



With the following comments addressed:

Reviewed-by: Gavin Shan 


diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 1f6da5529f..cbfea689cc 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1455,11 +1455,11 @@ int kvm_arch_process_async_events(CPUState *cs)
  
  /**

   * kvm_arm_hw_debug_active:
- * @cs: CPU State
+ * @cpu: ARMCPU
   *
   * Return: TRUE if any hardware breakpoints in use.
   */
-static bool kvm_arm_hw_debug_active(CPUState *cs)
+static bool kvm_arm_hw_debug_active(ARMCPU *cpu)
  {
  return ((cur_hw_wps > 0) || (cur_hw_bps > 0));
  }


Either @cs or @cpu isn't dereferenced in kvm_arm_hw_debug_active(). So I guess
the argument can be simply droped?


@@ -1493,7 +1493,7 @@ void kvm_arch_update_guest_debug(CPUState *cs, struct 
kvm_guest_debug *dbg)
  if (kvm_sw_breakpoints_active(cs)) {
  dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
  }
-if (kvm_arm_hw_debug_active(cs)) {
+if (kvm_arm_hw_debug_active(ARM_CPU(cs))) {
  dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW;
  kvm_arm_copy_hw_debug_data(>arch);
  }


Thanks,
Gavin




Re: [PATCH-for-9.0 15/16] target/arm/kvm: Have kvm_arm_handle_debug take a ARMCPU argument

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 14/16] target/arm/kvm: Have kvm_arm_handle_dabt_nisv take a ARMCPU argument

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 13/16] target/arm/kvm: Have kvm_arm_verify_ext_dabt_pending take a ARMCPU arg

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 12/16] target/arm/kvm: Have kvm_arm_[get|put]_virtual_time take ARMCPU argument

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 23 ++-
  1 file changed, 10 insertions(+), 13 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 10/16] target/arm/kvm: Have kvm_arm_vcpu_init take a ARMCPU argument

2023-11-26 Thread Gavin Shan



On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 11/16] target/arm/kvm: Have kvm_arm_vcpu_finalize take a ARMCPU argument

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 10/16] target/arm/kvm: Have kvm_arm_vcpu_init take a ARMCPU argument

2023-11-26 Thread Gavin Shan



On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 09/16] target/arm/kvm: Have kvm_arm_pmu_set_irq take a ARMCPU argument

2023-11-26 Thread Gavin Shan



On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm_arm.h | 4 ++--
  hw/arm/virt.c| 2 +-
  target/arm/kvm.c | 6 +++---
  3 files changed, 6 insertions(+), 6 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 08/16] target/arm/kvm: Have kvm_arm_pmu_init take a ARMCPU argument

2023-11-26 Thread Gavin Shan

Hi Phil,

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm_arm.h | 4 ++--
  hw/arm/virt.c| 2 +-
  target/arm/kvm.c | 6 +++---
  3 files changed, 6 insertions(+), 6 deletions(-)



One nit below, but I guess it doesn't matter.

Reviewed-by: Gavin Shan 


diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 0e12a008ab..fde1c45609 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -200,8 +200,8 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool 
*fixed_ipa);
  
  int kvm_arm_vgic_probe(void);
  
+void kvm_arm_pmu_init(ARMCPU *cpu);

  void kvm_arm_pmu_set_irq(CPUState *cs, int irq);
-void kvm_arm_pmu_init(CPUState *cs);
  


Why the order of the declaration is changed? I guess the reason would be
kvm_arm_pmu_init() is called prior to kvm_arm_pmu_set_irq().


  /**
   * kvm_arm_pvtime_init:
@@ -263,7 +263,7 @@ static inline void kvm_arm_pmu_set_irq(CPUState *cs, int 
irq)
  g_assert_not_reached();
  }
  
-static inline void kvm_arm_pmu_init(CPUState *cs)

+static inline void kvm_arm_pmu_init(ARMCPU *cpu)
  {
  g_assert_not_reached();
  }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b6efe9da4d..63f3c0b750 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2000,7 +2000,7 @@ static void virt_cpu_post_init(VirtMachineState *vms, 
MemoryRegion *sysmem)
  if (kvm_irqchip_in_kernel()) {
  kvm_arm_pmu_set_irq(cpu, VIRTUAL_PMU_IRQ);
  }
-kvm_arm_pmu_init(cpu);
+kvm_arm_pmu_init(ARM_CPU(cpu));
  }
  if (steal_time) {
  kvm_arm_pvtime_init(ARM_CPU(cpu), pvtime_reg_base
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 82c5924ab5..e7cbe1ff05 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1711,17 +1711,17 @@ static bool kvm_arm_set_device_attr(ARMCPU *cpu, struct 
kvm_device_attr *attr,
  return true;
  }
  
-void kvm_arm_pmu_init(CPUState *cs)

+void kvm_arm_pmu_init(ARMCPU *cpu)
  {
  struct kvm_device_attr attr = {
  .group = KVM_ARM_VCPU_PMU_V3_CTRL,
  .attr = KVM_ARM_VCPU_PMU_V3_INIT,
  };
  
-if (!ARM_CPU(cs)->has_pmu) {

+if (!cpu->has_pmu) {
  return;
  }
-if (!kvm_arm_set_device_attr(ARM_CPU(cs), , "PMU")) {
+if (!kvm_arm_set_device_attr(cpu, , "PMU")) {
  error_report("failed to init PMU");
  abort();
  }


Thanks,
Gavin




Re: [PATCH-for-9.0 07/16] target/arm/kvm: Have kvm_arm_pvtime_init take a ARMCPU argument

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm_arm.h | 6 +++---
  hw/arm/virt.c| 5 +++--
  target/arm/kvm.c | 6 +++---
  3 files changed, 9 insertions(+), 8 deletions(-)



Reviewed-by: Gavin Shan 




RE: [PULL v2 25/30] Hexagon HVX (target/hexagon) instruction decoding

2023-11-26 Thread Brian Cain


> -Original Message-
> From: Brian Cain
> Sent: Tuesday, November 21, 2023 9:52 AM
> To: Peter Maydell 
> Cc: qemu-devel@nongnu.org; richard.hender...@linaro.org; f4...@amsat.org
> Subject: RE: [PULL v2 25/30] Hexagon HVX (target/hexagon) instruction
> decoding
> 
> 
> 
> > -Original Message-
> > From: qemu-devel-bounces+bcain=quicinc@nongnu.org  > bounces+bcain=quicinc@nongnu.org> On Behalf Of Peter Maydell
> > Sent: Tuesday, November 21, 2023 8:33 AM
> > To: Taylor Simpson 
> > Cc: qemu-devel@nongnu.org; richard.hender...@linaro.org;
> f4...@amsat.org
> > Subject: Re: [PULL v2 25/30] Hexagon HVX (target/hexagon) instruction
> > decoding
> >
> > WARNING: This email originated from outside of Qualcomm. Please be wary
> of
> > any links or attachments, and do not enable macros.
> >
> > On Wed, 3 Nov 2021 at 21:17, Taylor Simpson 
> wrote:
> > >
> > > Add new file to target/hexagon/meson.build
> > >
> > > Acked-by: Richard Henderson 
> > > Signed-off-by: Taylor Simpson 
> >
> > Hi; Coverity points out a variable written to and then
> > overwritten before it's ever used in this function (CID 1527408):
> >
> >
> >
> >
> > > +static void
> > > +check_new_value(Packet *pkt)
> > > +{
> > > +/* .new value for a MMVector store */
> > > +int i, j;
> > > +const char *reginfo;
> > > +const char *destletters;
> > > +const char *dststr = NULL;
> > > +uint16_t def_opcode;
> > > +char letter;
> > > +int def_regnum;
> >
> > def_regnum has function level scope...
> >
> > > +
> > > +for (i = 1; i < pkt->num_insns; i++) {
> > > +uint16_t use_opcode = pkt->insn[i].opcode;
> > > +if (GET_ATTRIB(use_opcode, A_DOTNEWVALUE) &&
> > > +GET_ATTRIB(use_opcode, A_CVI) &&
> > > +GET_ATTRIB(use_opcode, A_STORE)) {
> > > +int use_regidx = strchr(opcode_reginfo[use_opcode], 's') -
> > > +opcode_reginfo[use_opcode];
> > > +/*
> > > + * What's encoded at the N-field is the offset to who's 
> > > producing
> > > + * the value.
> > > + * Shift off the LSB which indicates odd/even register.
> > > + */
> > > +int def_off = ((pkt->insn[i].regno[use_regidx]) >> 1);
> > > +int def_oreg = pkt->insn[i].regno[use_regidx] & 1;
> > > +int def_idx = -1;
> > > +for (j = i - 1; (j >= 0) && (def_off >= 0); j--) {
> > > +if (!GET_ATTRIB(pkt->insn[j].opcode, A_CVI)) {
> > > +continue;
> > > +}
> > > +def_off--;
> > > +if (def_off == 0) {
> > > +def_idx = j;
> > > +break;
> > > +}
> > > +}
> > > +/*
> > > + * Check for a badly encoded N-field which points to an 
> > > instruction
> > > + * out-of-range
> > > + */
> > > +g_assert(!((def_off != 0) || (def_idx < 0) ||
> > > +   (def_idx > (pkt->num_insns - 1;
> > > +
> > > +/* def_idx is the index of the producer */
> > > +def_opcode = pkt->insn[def_idx].opcode;
> > > +reginfo = opcode_reginfo[def_opcode];
> > > +destletters = "dexy";
> > > +for (j = 0; (letter = destletters[j]) != 0; j++) {
> > > +dststr = strchr(reginfo, letter);
> > > +if (dststr != NULL) {
> > > +break;
> > > +}
> > > +}
> > > +if ((dststr == NULL)  && GET_ATTRIB(def_opcode, 
> > > A_CVI_GATHER))
> {
> > > +def_regnum = 0;
> >
> > In this half of the if() we set it to 0...
> >
> > > +pkt->insn[i].regno[use_regidx] = def_oreg;
> > > +pkt->insn[i].new_value_producer_slot = 
> > > pkt->insn[def_idx].slot;
> > > +} else {
> > > +if (dststr == NULL) {
> > > +/* still not there, we have a bad packet */
> > > +g_assert_not_reached();
> > > +}
> > > +def_regnum = pkt->insn[def_idx].regno[dststr - reginfo];
> > > +/* Now patch up the consumer with the register number */
> > > +pkt->insn[i].regno[use_regidx] = def_regnum ^ def_oreg;
> > > +/* special case for (Vx,Vy) */
> > > +dststr = strchr(reginfo, 'y');
> > > +if (def_oreg && strchr(reginfo, 'x') && dststr) {
> > > +def_regnum = pkt->insn[def_idx].regno[dststr - 
> > > reginfo];
> > > +pkt->insn[i].regno[use_regidx] = def_regnum;
> > > +}
> >
> > ...but the only place we read def_regnum is in this other half of the
> > if(), and if we get here then we've set it to something out of pxt->insn.
> >
> > Were we supposed to do something with def_regnum outside this if(),
> > or could we instead drop the 

Re: [PATCH-for-9.0 06/16] target/arm/kvm: Have kvm_arm_set_device_attr take a ARMCPU argument

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 12 ++--
  1 file changed, 6 insertions(+), 6 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 05/16] target/arm/kvm: Have kvm_arm_sve_get_vls take a ARMCPU argument

2023-11-26 Thread Gavin Shan

Hi Phil,

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm_arm.h | 6 +++---
  target/arm/cpu64.c   | 2 +-
  target/arm/kvm.c | 2 +-
  3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 6fb8a5f67e..84f87f5ed7 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -129,13 +129,13 @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
  
  /**

   * kvm_arm_sve_get_vls:
- * @cs: CPUState
+ * @cpu: ARMCPU
   *
   * Get all the SVE vector lengths supported by the KVM host, setting
   * the bits corresponding to their length in quadwords minus one
   * (vq - 1) up to ARM_MAX_VQ.  Return the resulting map.
   */
-uint32_t kvm_arm_sve_get_vls(CPUState *cs);
+uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu);
  


Either @cs or @cpu isn't dereferenced in kvm_arm_sve_get_vls(). So I guess
the argument can be simply droped?


  /**
   * kvm_arm_set_cpu_features_from_host:
@@ -278,7 +278,7 @@ static inline void kvm_arm_steal_time_finalize(ARMCPU *cpu, 
Error **errp)
  g_assert_not_reached();
  }
  
-static inline uint32_t kvm_arm_sve_get_vls(CPUState *cs)

+static inline uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
  {
  g_assert_not_reached();
  }
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 1e9c6c85ae..8e30a7993e 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -66,7 +66,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
   */
  if (kvm_enabled()) {
  if (kvm_arm_sve_supported()) {
-cpu->sve_vq.supported = kvm_arm_sve_get_vls(CPU(cpu));
+cpu->sve_vq.supported = kvm_arm_sve_get_vls(cpu);
  vq_supported = cpu->sve_vq.supported;
  } else {
  assert(!cpu_isar_feature(aa64_sve, cpu));
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 71833a845a..766a077bcf 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1803,7 +1803,7 @@ bool kvm_arm_sve_supported(void)
  
  QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
  
-uint32_t kvm_arm_sve_get_vls(CPUState *cs)

+uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
  {
  /* Only call this function if kvm_arm_sve_supported() returns true. */
  static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS];


Thanks,
Gavin




Re: [PATCH-for-9.0 04/16] target/arm/kvm: Have kvm_arm_sve_set_vls take a ARMCPU argument

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm.c | 7 +++
  1 file changed, 3 insertions(+), 4 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 03/16] target/arm/kvm: Have kvm_arm_add_vcpu_properties take a ARMCPU argument

2023-11-26 Thread Gavin Shan

Hi Phil,

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Unify the "kvm_arm.h" API: All functions related to ARM vCPUs
take a ARMCPU* argument. Use the CPU() QOM cast macro When
calling the generic vCPU API from "sysemu/kvm.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm_arm.h | 4 ++--
  target/arm/cpu.c | 2 +-
  target/arm/kvm.c | 4 ++--
  3 files changed, 5 insertions(+), 5 deletions(-)



With the following comments resolved:

Reviewed-by: Gavin Shan 


diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 50967f4ae9..6fb8a5f67e 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -153,7 +153,7 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
   * Add all KVM specific CPU properties to the CPU object. These
   * are the CPU properties with "kvm-" prefixed names.
   */
-void kvm_arm_add_vcpu_properties(Object *obj);
+void kvm_arm_add_vcpu_properties(ARMCPU *cpu);
  


The function's description needs to be modified since @obj has been
renamed to @cpu?

  /**
   * kvm_arm_add_vcpu_properties:
   * @obj: The CPU object to add the properties to
   *
   */


  /**
   * kvm_arm_steal_time_finalize:
@@ -243,7 +243,7 @@ static inline void 
kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
  g_assert_not_reached();
  }
  
-static inline void kvm_arm_add_vcpu_properties(Object *obj)

+static inline void kvm_arm_add_vcpu_properties(ARMCPU *cpu)
  {
  g_assert_not_reached();
  }
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 25e9d2ae7b..97081e0c70 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1686,7 +1686,7 @@ void arm_cpu_post_init(Object *obj)
  }
  
  if (kvm_enabled()) {

-kvm_arm_add_vcpu_properties(obj);
+kvm_arm_add_vcpu_properties(cpu);
  }
  
  #ifndef CONFIG_USER_ONLY

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 6e3fea1879..03195f5627 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -495,10 +495,10 @@ static void kvm_steal_time_set(Object *obj, bool value, 
Error **errp)
  }
  
  /* KVM VCPU properties should be prefixed with "kvm-". */

-void kvm_arm_add_vcpu_properties(Object *obj)
+void kvm_arm_add_vcpu_properties(ARMCPU *cpu)
  {
-ARMCPU *cpu = ARM_CPU(obj);
  CPUARMState *env = >env;
+Object *obj = OBJECT(cpu);
  
  if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {

  cpu->kvm_adjvtime = true;


Thanks,
Gavin




[PATCH] hw/loongarch/virt: Align high memory base address with super page size

2023-11-26 Thread Bibo Mao
With LoongArch virt machine, there is low memory space with region
0--0x1000, and high memory space with started from 0x9000.
High memory space is aligned with 256M, it will be better if it is
aligned with 1G, which is super page aligned for 4K page size.

Currently linux kernel and uefi bios has no limitation with high
memory base address, it is ok to set high memory base address
with 0x8000.

Signed-off-by: Bibo Mao 
Change-Id: Iac1af728bf6fd35c9c2f4e7dbdae6e3c0fbab623
---
 include/hw/loongarch/virt.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 674f4655e0..db0831b471 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -25,7 +25,7 @@
 
 #define VIRT_LOWMEM_BASE0
 #define VIRT_LOWMEM_SIZE0x1000
-#define VIRT_HIGHMEM_BASE   0x9000
+#define VIRT_HIGHMEM_BASE   0x8000
 #define VIRT_GED_EVT_ADDR   0x100e
 #define VIRT_GED_MEM_ADDR   (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
 #define VIRT_GED_REG_ADDR   (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
-- 
2.39.3




Re: [PATCH-for-9.0 02/16] target/arm/kvm: Remove unused includes

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

Both MemoryRegion and Error types are forward declared
in "qemu/typedefs.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/kvm_arm.h | 2 --
  1 file changed, 2 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH-for-9.0 01/16] hw/intc/arm_gicv3: Include missing 'qemu/error-report.h' header

2023-11-26 Thread Gavin Shan

On 11/24/23 05:35, Philippe Mathieu-Daudé wrote:

kvm_arm_its_reset_hold() calls warn_report(), itself declared
in "qemu/error-report.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/intc/arm_gicv3_its_kvm.c | 1 +
  1 file changed, 1 insertion(+)



Reviewed-by: Gavin Shan 




[PATCH] avr: Fix wrong initial value of stack pointer

2023-11-26 Thread Gihun Nam
The current implementation initializes the stack pointer of AVR devices
to 0, but it should be set to RAMEND according to the specs.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1525
Signed-off-by: Gihun Nam 
---
 hw/avr/atmega.c  | 3 +++
 target/avr/cpu.c | 2 +-
 target/avr/cpu.h | 3 +++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
index a34803e642..3a8caccf99 100644
--- a/hw/avr/atmega.c
+++ b/hw/avr/atmega.c
@@ -233,6 +233,9 @@ static void atmega_realize(DeviceState *dev, Error **errp)
 
 /* CPU */
 object_initialize_child(OBJECT(dev), "cpu", >cpu, mc->cpu_type);
+
+s->cpu.init_sp = mc->io_size + mc->sram_size - 1;
+
 qdev_realize(DEVICE(>cpu), NULL, _abort);
 cpudev = DEVICE(>cpu);
 
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 44de1e18d1..1da7d7dbf3 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -95,7 +95,7 @@ static void avr_cpu_reset_hold(Object *obj)
 env->rampY = 0;
 env->rampZ = 0;
 env->eind = 0;
-env->sp = 0;
+env->sp = cpu->init_sp;
 
 env->skip = 0;
 
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 8a17862737..7960c5c57a 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -145,6 +145,9 @@ struct ArchCPU {
 CPUState parent_obj;
 
 CPUAVRState env;
+
+/* Initial value of stack pointer */
+uint32_t init_sp;
 };
 
 /**
-- 
2.39.2




[PATCH v2] target/i386/kvm: Refine VMX controls setting for backward compatibility

2023-11-26 Thread EwanHai
Commit 4a910e1 ("target/i386: do not set unsupported VMX secondary
execution controls") implemented a workaround for hosts that have
specific CPUID features but do not support the corresponding VMX
controls, e.g., hosts support RDSEED but do not support RDSEED-Exiting.

In detail, commit 4a910e1 introduced a flag `has_msr_vmx_procbased_clts2`.
If KVM has `MSR_IA32_VMX_PROCBASED_CTLS2` in its msr list, QEMU would
use KVM's settings, avoiding any modifications to this MSR.

However, this commit (4a910e1) didn't account for cases in older Linux
kernels(<5.3) where `MSR_IA32_VMX_PROCBASED_CTLS2` is in
`kvm_feature_msrs`-obtained by ioctl(KVM_GET_MSR_FEATURE_INDEX_LIST),
but not in `kvm_msr_list`-obtained by ioctl(KVM_GET_MSR_INDEX_LIST).
As a result,it did not set the `has_msr_vmx_procbased_clts2` flag based
on `kvm_msr_list` alone, even though KVM maintains the value of this MSR.

This patch supplements the above logic, ensuring that
`has_msr_vmx_procbased_clts2` is correctly set by checking both MSR
lists, thus maintaining compatibility with older kernels.

Signed-off-by: EwanHai 
---
In response to the suggestions from ZhaoLiu(zhao1@intel.com),
the following changes have been implemented in v2:
- Adjusted some punctuation in the commit message as per the
  suggestions.
- Added comments to the newly added code to indicate that it is a
  compatibility fix.

v1 link:
https://lore.kernel.org/all/20230925071453.14908-1-ewanhai...@zhaoxin.com/
---
 target/i386/kvm/kvm.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 11b8177eff..c8f6c0b531 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2296,6 +2296,7 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
 static int kvm_get_supported_feature_msrs(KVMState *s)
 {
 int ret = 0;
+int i;
 
 if (kvm_feature_msrs != NULL) {
 return 0;
@@ -2330,6 +2331,19 @@ static int kvm_get_supported_feature_msrs(KVMState *s)
 return ret;
 }
 
+/*
+ * Compatibility fix:
+ * Older Linux kernels(<5.3) include the MSR_IA32_VMX_PROCBASED_CTLS2
+ * only in feature msr list, but not in regular msr list. This lead to
+ * an issue in older kernel versions where QEMU, through the regular
+ * MSR list check, assumes the kernel doesn't maintain this msr,
+ * resulting in incorrect settings by QEMU for this msr.
+ */
+for (i = 0; i < kvm_feature_msrs->nmsrs; i++) {
+if (kvm_feature_msrs->indices[i] == MSR_IA32_VMX_PROCBASED_CTLS2) {
+has_msr_vmx_procbased_ctls2 = true;
+}
+}
 return 0;
 }
 
-- 
2.34.1




Re: [PATCH-for-9.0 20/25] hw: Simplify memory_region_init_ram() calls

2023-11-26 Thread Andrew Jeffery
On Mon, 2023-11-20 at 22:32 +0100, Philippe Mathieu-Daudé wrote:
> Mechanical change using the following coccinelle script:
> 
> @@
> expression mr, owner, arg3, arg4, errp;
> @@
> -   memory_region_init_ram(mr, owner, arg3, arg4, );
> if (
> -   errp
> +   !memory_region_init_ram(mr, owner, arg3, arg4, )
> ) {
> ...
> return;
> }
> 
> and removing the local Error variable.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/arm/aspeed_ast2400.c | 6 ++
>  hw/arm/aspeed_ast2600.c | 6 ++

For my own benefit it looks like the motivating thread for this series
is: 

https://lore.kernel.org/qemu-devel/936e1ac4-cef8-08b4-c688-e5b1e0572...@linaro.org/

Anyway,

Reviewed-by: Andrew Jeffery  # aspeed



Re: [PATCH 21/21] target/arm/kvm: Unexport kvm_arm_vm_state_change

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 2 --
  target/arm/kvm.c | 2 +-
  2 files changed, 1 insertion(+), 3 deletions(-)



Reviewed-by: Gavin Shan 




[PATCH v2 1/2] vhost: Add worker backend callouts

2023-11-26 Thread Mike Christie
This adds the vhost backend callouts for the worker ioctls added in the
6.4 linux kernel commit:

c1ecd8e95007 ("vhost: allow userspace to create workers")

Signed-off-by: Mike Christie 
---
 hw/virtio/vhost-backend.c | 28 
 include/hw/virtio/vhost-backend.h | 14 ++
 2 files changed, 42 insertions(+)

diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 17f3fc6a0823..833804dd40f2 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -158,6 +158,30 @@ static int vhost_kernel_set_vring_busyloop_timeout(struct 
vhost_dev *dev,
 return vhost_kernel_call(dev, VHOST_SET_VRING_BUSYLOOP_TIMEOUT, s);
 }
 
+static int vhost_kernel_new_worker(struct vhost_dev *dev,
+   struct vhost_worker_state *worker)
+{
+return vhost_kernel_call(dev, VHOST_NEW_WORKER, worker);
+}
+
+static int vhost_kernel_free_worker(struct vhost_dev *dev,
+struct vhost_worker_state *worker)
+{
+return vhost_kernel_call(dev, VHOST_FREE_WORKER, worker);
+}
+
+static int vhost_kernel_attach_vring_worker(struct vhost_dev *dev,
+struct vhost_vring_worker *worker)
+{
+return vhost_kernel_call(dev, VHOST_ATTACH_VRING_WORKER, worker);
+}
+
+static int vhost_kernel_get_vring_worker(struct vhost_dev *dev,
+ struct vhost_vring_worker *worker)
+{
+return vhost_kernel_call(dev, VHOST_GET_VRING_WORKER, worker);
+}
+
 static int vhost_kernel_set_features(struct vhost_dev *dev,
  uint64_t features)
 {
@@ -313,6 +337,10 @@ const VhostOps kernel_ops = {
 .vhost_set_vring_err = vhost_kernel_set_vring_err,
 .vhost_set_vring_busyloop_timeout =
 vhost_kernel_set_vring_busyloop_timeout,
+.vhost_get_vring_worker = vhost_kernel_get_vring_worker,
+.vhost_attach_vring_worker = vhost_kernel_attach_vring_worker,
+.vhost_new_worker = vhost_kernel_new_worker,
+.vhost_free_worker = vhost_kernel_free_worker,
 .vhost_set_features = vhost_kernel_set_features,
 .vhost_get_features = vhost_kernel_get_features,
 .vhost_set_backend_cap = vhost_kernel_set_backend_cap,
diff --git a/include/hw/virtio/vhost-backend.h 
b/include/hw/virtio/vhost-backend.h
index 96ccc18cd33b..9f16d0884e8f 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -33,6 +33,8 @@ struct vhost_memory;
 struct vhost_vring_file;
 struct vhost_vring_state;
 struct vhost_vring_addr;
+struct vhost_vring_worker;
+struct vhost_worker_state;
 struct vhost_scsi_target;
 struct vhost_iotlb_msg;
 struct vhost_virtqueue;
@@ -73,6 +75,14 @@ typedef int (*vhost_set_vring_err_op)(struct vhost_dev *dev,
   struct vhost_vring_file *file);
 typedef int (*vhost_set_vring_busyloop_timeout_op)(struct vhost_dev *dev,
struct vhost_vring_state 
*r);
+typedef int (*vhost_attach_vring_worker_op)(struct vhost_dev *dev,
+struct vhost_vring_worker *worker);
+typedef int (*vhost_get_vring_worker_op)(struct vhost_dev *dev,
+ struct vhost_vring_worker *worker);
+typedef int (*vhost_new_worker_op)(struct vhost_dev *dev,
+   struct vhost_worker_state *worker);
+typedef int (*vhost_free_worker_op)(struct vhost_dev *dev,
+struct vhost_worker_state *worker);
 typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
  uint64_t features);
 typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
@@ -151,6 +161,10 @@ typedef struct VhostOps {
 vhost_set_vring_call_op vhost_set_vring_call;
 vhost_set_vring_err_op vhost_set_vring_err;
 vhost_set_vring_busyloop_timeout_op vhost_set_vring_busyloop_timeout;
+vhost_new_worker_op vhost_new_worker;
+vhost_free_worker_op vhost_free_worker;
+vhost_get_vring_worker_op vhost_get_vring_worker;
+vhost_attach_vring_worker_op vhost_attach_vring_worker;
 vhost_set_features_op vhost_set_features;
 vhost_get_features_op vhost_get_features;
 vhost_set_backend_cap_op vhost_set_backend_cap;
-- 
2.34.1




[PATCH v2 0/2] vhost-scsi: Support worker ioctls

2023-11-26 Thread Mike Christie
The following patches allow users to configure the vhost worker threads
for vhost-scsi. With vhost-net we get a worker thread per rx/tx virtqueue
pair, but for vhost-scsi we get one worker for all workqueues. This
becomes a bottlneck after 2 queues are used.

In the upstream linux kernel commit:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/vhost/vhost.c?id=c1ecd8e9500797748ae4f79657971955d452d69d

we enabled the vhost layer to be able to create a worker thread and
attach it to a virtqueue.

This patchset adds support to vhost-scsi to use these ioctls so we are
no longer limited to the single worker.

v2:
- Make config option a bool instead of an int.





[PATCH v2 2/2] vhost-scsi: Add support for a worker thread per virtqueue

2023-11-26 Thread Mike Christie
This adds support for vhost-scsi to be able to create a worker thread
per virtqueue. Right now for vhost-net we get a worker thread per
tx/rx virtqueue pair which scales nicely as we add more virtqueues and
CPUs, but for scsi we get the single worker thread that's shared by all
virtqueues. When trying to send IO to more than 2 virtqueues the single
thread becomes a bottlneck.

This patch adds a new setting, workers_per_virtqueue, which can be set
to:

false: Existing behavior where we get the single worker thread.
true: Create a worker per IO virtqueue.

Signed-off-by: Mike Christie 
---
 hw/scsi/vhost-scsi.c| 60 +
 include/hw/virtio/virtio-scsi.h |  1 +
 2 files changed, 61 insertions(+)

diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 3126df9e1d9d..77eef9474c23 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -165,6 +165,57 @@ static const VMStateDescription vmstate_virtio_vhost_scsi 
= {
 .pre_save = vhost_scsi_pre_save,
 };
 
+static int vhost_scsi_set_workers(VHostSCSICommon *vsc, bool per_virtqueue)
+{
+struct vhost_dev *dev = >dev;
+struct vhost_vring_worker vq_worker;
+struct vhost_worker_state worker;
+int i, ret;
+
+/* Use default worker */
+if (!per_virtqueue || dev->nvqs == VHOST_SCSI_VQ_NUM_FIXED + 1) {
+return 0;
+}
+
+/*
+ * ctl/evt share the first worker since it will be rare for them
+ * to send cmds while IO is running.
+ */
+for (i = VHOST_SCSI_VQ_NUM_FIXED + 1; i < dev->nvqs; i++) {
+memset(, 0, sizeof(worker));
+
+ret = dev->vhost_ops->vhost_new_worker(dev, );
+if (ret == -ENOTTY) {
+/*
+ * worker ioctls are not implemented so just ignore and
+ * and continue device setup.
+ */
+ret = 0;
+break;
+} else if (ret) {
+break;
+}
+
+memset(_worker, 0, sizeof(vq_worker));
+vq_worker.worker_id = worker.worker_id;
+vq_worker.index = i;
+
+ret = dev->vhost_ops->vhost_attach_vring_worker(dev, _worker);
+if (ret == -ENOTTY) {
+/*
+ * It's a bug for the kernel to have supported the worker creation
+ * ioctl but not attach.
+ */
+dev->vhost_ops->vhost_free_worker(dev, );
+break;
+} else if (ret) {
+break;
+}
+}
+
+return ret;
+}
+
 static void vhost_scsi_realize(DeviceState *dev, Error **errp)
 {
 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
@@ -232,6 +283,13 @@ static void vhost_scsi_realize(DeviceState *dev, Error 
**errp)
 goto free_vqs;
 }
 
+ret = vhost_scsi_set_workers(vsc, vs->conf.worker_per_virtqueue);
+if (ret < 0) {
+error_setg(errp, "vhost-scsi: vhost worker setup failed: %s",
+   strerror(-ret));
+goto free_vqs;
+}
+
 /* At present, channel and lun both are 0 for bootable vhost-scsi disk */
 vsc->channel = 0;
 vsc->lun = 0;
@@ -297,6 +355,8 @@ static Property vhost_scsi_properties[] = {
  VIRTIO_SCSI_F_T10_PI,
  false),
 DEFINE_PROP_BOOL("migratable", VHostSCSICommon, migratable, false),
+DEFINE_PROP_BOOL("worker_per_virtqueue", VirtIOSCSICommon,
+ conf.worker_per_virtqueue, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index 779568ab5d28..0e9a1867665e 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -51,6 +51,7 @@ typedef struct virtio_scsi_config VirtIOSCSIConfig;
 struct VirtIOSCSIConf {
 uint32_t num_queues;
 uint32_t virtqueue_size;
+bool worker_per_virtqueue;
 bool seg_max_adjust;
 uint32_t max_sectors;
 uint32_t cmd_per_lun;
-- 
2.34.1




Re: [PATCH 20/21] target/arm/kvm: Unexport and tidy kvm_arm_sync_mpstate_to_{kvm, qemu}

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Drop fprintfs and actually use the return values in the callers.

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 20 
  target/arm/kvm.c | 23 ++-
  2 files changed, 6 insertions(+), 37 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 19/21] target/arm/kvm: Unexport kvm_{get,put}_vcpu_events

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 20 
  target/arm/kvm.c | 20 ++--
  2 files changed, 18 insertions(+), 22 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 18/21] target/arm/kvm: Init cap_has_inject_serror_esr in kvm_arch_init

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

There is no need to do this in kvm_arch_init_vcpu per vcpu.
Inline kvm_arm_init_serror_injection rather than keep separate.

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h |  8 
  target/arm/kvm.c | 13 -
  2 files changed, 4 insertions(+), 17 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 17/21] target/arm/kvm: Unexport kvm_arm_init_cpreg_list

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 12 
  target/arm/kvm.c | 10 --
  2 files changed, 8 insertions(+), 14 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 16/21] target/arm/kvm: Unexport kvm_arm_vcpu_finalize

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 14 --
  target/arm/kvm.c | 14 +-
  2 files changed, 13 insertions(+), 15 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 15/21] target/arm/kvm: Unexport kvm_arm_vcpu_init

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 12 
  target/arm/kvm.c | 12 +++-
  2 files changed, 11 insertions(+), 13 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 14/21] target/arm/kvm: Merge kvm64.c into kvm.c

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Since kvm32.c was removed, there is no need to keep them separate.
This will allow more symbols to be unexported.

Signed-off-by: Richard Henderson 
---
  target/arm/kvm.c   | 789 +++
  target/arm/kvm64.c | 820 -
  target/arm/meson.build |   2 +-
  3 files changed, 790 insertions(+), 821 deletions(-)
  delete mode 100644 target/arm/kvm64.c



With Phil's comments addressed:

Reviewed-by: Gavin Shan 




Re: [PATCH 13/21] target/arm/kvm: Move kvm_arm_reg_syncs_via_cpreg_list and unexport

2023-11-26 Thread Gavin Shan

Hi Richard,

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 10 --
  target/arm/kvm.c | 23 +++
  target/arm/kvm64.c   | 15 ---
  3 files changed, 23 insertions(+), 25 deletions(-)



With the following nits addressed:

Reviewed-by: Gavin Shan 


diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 2755ee8366..1043123cc7 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -77,16 +77,6 @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t 
devid, uint64_t group,
   */
  int kvm_arm_init_cpreg_list(ARMCPU *cpu);
  
-/**

- * kvm_arm_reg_syncs_via_cpreg_list:
- * @regidx: KVM register index
- *
- * Return true if this KVM register should be synchronized via the
- * cpreg list of arbitrary system registers, false if it is synchronized
- * by hand using code in kvm_arch_get/put_registers().
- */
-bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx);
-
  /**
   * write_list_to_kvmstate:
   * @cpu: ARMCPU
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index dadc3fd755..9bca6baf35 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -740,6 +740,29 @@ static uint64_t *kvm_arm_get_cpreg_ptr(ARMCPU *cpu, 
uint64_t regidx)
  return >cpreg_values[res - cpu->cpreg_indexes];
  }
  
+/**

+ * kvm_arm_reg_syncs_via_cpreg_list:
+ * @regidx: KVM register index
+ *
+ * Return true if this KVM register should be synchronized via the
+ * cpreg list of arbitrary system registers, false if it is synchronized
+ * by hand using code in kvm_arch_get/put_registers().
+ */
+static bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
+{
+/* Return true if the regidx is a register we should synchronize
+ * via the cpreg_tuples array (ie is not a core or sve reg that
+ * we sync by hand in kvm_arch_get/put_registers())
+ */


The comments are fully or partially duplicate to the function's description 
above.
I think the comments here can be dropped or combined to the function's 
descrption
above.


+switch (regidx & KVM_REG_ARM_COPROC_MASK) {
+case KVM_REG_ARM_CORE:
+case KVM_REG_ARM64_SVE:
+return false;
+default:
+return true;
+}
+}
+
  /* Initialize the ARMCPU cpreg list according to the kernel's
   * definition of what CPU registers it knows about (and throw away
   * the previous TCG-created cpreg list).
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index a184cca4dc..52c0a6d3af 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -346,21 +346,6 @@ int kvm_arch_destroy_vcpu(CPUState *cs)
  return 0;
  }
  
-bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)

-{
-/* Return true if the regidx is a register we should synchronize
- * via the cpreg_tuples array (ie is not a core or sve reg that
- * we sync by hand in kvm_arch_get/put_registers())
- */
-switch (regidx & KVM_REG_ARM_COPROC_MASK) {
-case KVM_REG_ARM_CORE:
-case KVM_REG_ARM64_SVE:
-return false;
-default:
-return true;
-}
-}
-
  /* Callers must hold the iothread mutex lock */
  static void kvm_inject_arm_sea(CPUState *c)
  {


Thanks,
Gavin




Re: [PATCH 12/21] target/arm/kvm: Move kvm_arm_cpreg_level and unexport

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h |  9 -
  target/arm/kvm.c | 22 ++
  target/arm/kvm64.c   | 15 ---
  3 files changed, 22 insertions(+), 24 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 11/21] target/arm/kvm: Use a switch for kvm_arm_cpreg_level

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Use a switch instead of a linear search through data.

Signed-off-by: Richard Henderson 
---
  target/arm/kvm64.c | 32 +---
  1 file changed, 9 insertions(+), 23 deletions(-)



With the following nits addressed:

Reviewed-by: Gavin Shan 


diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 504526b24c..61fb9dbde0 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -361,32 +361,18 @@ bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
  }
  }
  
-typedef struct CPRegStateLevel {

-uint64_t regidx;
-int level;
-} CPRegStateLevel;
-
-/* All system registers not listed in the following table are assumed to be
- * of the level KVM_PUT_RUNTIME_STATE. If a register should be written less
- * often, you must add it to this table with a state of either
- * KVM_PUT_RESET_STATE or KVM_PUT_FULL_STATE.
- */
-static const CPRegStateLevel non_runtime_cpregs[] = {
-{ KVM_REG_ARM_TIMER_CNT, KVM_PUT_FULL_STATE },
-{ KVM_REG_ARM_PTIMER_CNT, KVM_PUT_FULL_STATE },
-};
-
  int kvm_arm_cpreg_level(uint64_t regidx)
  {
-int i;
-
-for (i = 0; i < ARRAY_SIZE(non_runtime_cpregs); i++) {
-const CPRegStateLevel *l = _runtime_cpregs[i];
-if (l->regidx == regidx) {
-return l->level;
-}
+/*
+ * All system registers are assumed to be level KVM_PUT_RUNTIME_STATE.
+ * If a register should be written less often, you must add it here
+ * with a state of either KVM_PUT_RESET_STATE or KVM_PUT_FULL_STATE.
+ */
+switch (regidx) {
+case KVM_REG_ARM_TIMER_CNT:
+case KVM_REG_ARM_PTIMER_CNT:
+return KVM_PUT_FULL_STATE;
  }
-

  

It is unrelated change and needs to be dropped?


  return KVM_PUT_RUNTIME_STATE;
  }
  


Thanks,
Gavin




Re: [PATCH 10/21] target/arm/kvm: Move kvm_arm_get_host_cpu_features and unexport

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h |  22 
  target/arm/kvm.c | 265 +++
  target/arm/kvm64.c   | 254 -
  3 files changed, 265 insertions(+), 276 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 09/21] target/arm/kvm: Inline kvm_arm_steal_time_supported

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

This function is only used once, and is quite simple.

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 13 -
  target/arm/kvm64.c   |  7 +--
  2 files changed, 1 insertion(+), 19 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 08/21] target/arm/kvm: Unexport kvm_arm_{get, put}_virtual_time

2023-11-26 Thread Gavin Shan



On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 16 
  target/arm/kvm.c | 16 ++--
  2 files changed, 14 insertions(+), 18 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 07/21] target/arm/kvm: Move kvm_arm_handle_debug and unexport

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h |  9 --
  target/arm/kvm.c | 77 
  target/arm/kvm64.c   | 70 
  3 files changed, 77 insertions(+), 79 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 06/21] target/arm/kvm: Move kvm_arm_hw_debug_active and unexport

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h |  8 
  target/arm/kvm.c | 11 +++
  target/arm/kvm64.c   |  5 -
  3 files changed, 11 insertions(+), 13 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 05/21] target/arm/kvm: Move kvm_arm_copy_hw_debug_data and unexport

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 10 --
  target/arm/kvm.c | 24 
  target/arm/kvm64.c   | 17 -
  3 files changed, 24 insertions(+), 27 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 04/21] target/arm/kvm: Move kvm_arm_verify_ext_dabt_pending and unexport

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h | 10 
  target/arm/kvm.c | 57 
  target/arm/kvm64.c   | 49 -
  3 files changed, 57 insertions(+), 59 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 03/21] target/arm/kvm: Merge kvm_arm_init_debug into kvm_arch_init

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/arm/kvm_arm.h |  8 
  target/arm/kvm.c |  8 +++-
  target/arm/kvm64.c   | 12 
  3 files changed, 7 insertions(+), 21 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 02/21] target/arm: kvm64: remove a redundant KVM_CAP_SET_GUEST_DEBUG probe

2023-11-26 Thread Gavin Shan

On 11/23/23 15:42, Richard Henderson wrote:

From: Chao Du 

The KVM_CAP_SET_GUEST_DEBUG is probed during kvm_init().
gdbserver will fail to start if the CAP is not supported.
So no need to make another probe here, like other targets.

Signed-off-by: Chao Du 
Reviewed-by: Richard Henderson 
Message-Id: <20231025070726.22689-1-duc...@eswincomputing.com>
Signed-off-by: Richard Henderson 
---
  target/arm/kvm64.c | 28 +++-
  1 file changed, 7 insertions(+), 21 deletions(-)



Reviewed-by: Gavin Shan 




Re: [PATCH 01/21] accel/kvm: Make kvm_has_guest_debug static

2023-11-26 Thread Gavin Shan

On 11/23/23 15:41, Richard Henderson wrote:

This variable is not used or declared outside kvm-all.c.

Signed-off-by: Richard Henderson 
---
  accel/kvm/kvm-all.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)



Reviewed-by: Gavin Shan 




[PATCH v7 5/8] hw/arm/virt: Check CPU type in machine_run_board_init()

2023-11-26 Thread Gavin Shan
Set mc->valid_cpu_types so that the user specified CPU type can be
validated in machine_run_board_init(). We needn't to do the check
by ourselves.

Signed-off-by: Gavin Shan 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 hw/arm/virt.c | 62 +++
 1 file changed, 23 insertions(+), 39 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 668c0d3194..04f9f5fa56 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -204,40 +204,6 @@ static const int a15irqmap[] = {
 [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
 };
 
-static const char *valid_cpus[] = {
-#ifdef CONFIG_TCG
-ARM_CPU_TYPE_NAME("cortex-a7"),
-ARM_CPU_TYPE_NAME("cortex-a15"),
-ARM_CPU_TYPE_NAME("cortex-a35"),
-ARM_CPU_TYPE_NAME("cortex-a55"),
-ARM_CPU_TYPE_NAME("cortex-a72"),
-ARM_CPU_TYPE_NAME("cortex-a76"),
-ARM_CPU_TYPE_NAME("cortex-a710"),
-ARM_CPU_TYPE_NAME("a64fx"),
-ARM_CPU_TYPE_NAME("neoverse-n1"),
-ARM_CPU_TYPE_NAME("neoverse-v1"),
-ARM_CPU_TYPE_NAME("neoverse-n2"),
-#endif
-ARM_CPU_TYPE_NAME("cortex-a53"),
-ARM_CPU_TYPE_NAME("cortex-a57"),
-#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
-ARM_CPU_TYPE_NAME("host"),
-#endif
-ARM_CPU_TYPE_NAME("max"),
-};
-
-static bool cpu_type_valid(const char *cpu)
-{
-int i;
-
-for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) {
-if (strcmp(cpu, valid_cpus[i]) == 0) {
-return true;
-}
-}
-return false;
-}
-
 static void create_randomness(MachineState *ms, const char *node)
 {
 struct {
@@ -2041,11 +2007,6 @@ static void machvirt_init(MachineState *machine)
 unsigned int smp_cpus = machine->smp.cpus;
 unsigned int max_cpus = machine->smp.max_cpus;
 
-if (!cpu_type_valid(machine->cpu_type)) {
-error_report("mach-virt: CPU type %s not supported", 
machine->cpu_type);
-exit(1);
-}
-
 possible_cpus = mc->possible_cpu_arch_ids(machine);
 
 /*
@@ -2939,6 +2900,28 @@ static void virt_machine_class_init(ObjectClass *oc, 
void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+static const char * const valid_cpu_types[] = {
+#ifdef CONFIG_TCG
+ARM_CPU_TYPE_NAME("cortex-a7"),
+ARM_CPU_TYPE_NAME("cortex-a15"),
+ARM_CPU_TYPE_NAME("cortex-a35"),
+ARM_CPU_TYPE_NAME("cortex-a55"),
+ARM_CPU_TYPE_NAME("cortex-a72"),
+ARM_CPU_TYPE_NAME("cortex-a76"),
+ARM_CPU_TYPE_NAME("cortex-a710"),
+ARM_CPU_TYPE_NAME("a64fx"),
+ARM_CPU_TYPE_NAME("neoverse-n1"),
+ARM_CPU_TYPE_NAME("neoverse-v1"),
+ARM_CPU_TYPE_NAME("neoverse-n2"),
+#endif
+ARM_CPU_TYPE_NAME("cortex-a53"),
+ARM_CPU_TYPE_NAME("cortex-a57"),
+#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
+ARM_CPU_TYPE_NAME("host"),
+#endif
+ARM_CPU_TYPE_NAME("max"),
+NULL
+};
 
 mc->init = machvirt_init;
 /* Start with max_cpus set to 512, which is the maximum supported by KVM.
@@ -2965,6 +2948,7 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 #else
 mc->default_cpu_type = ARM_CPU_TYPE_NAME("max");
 #endif
+mc->valid_cpu_types = valid_cpu_types;
 mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
 mc->kvm_type = virt_kvm_type;
 assert(!mc->get_hotplug_handler);
-- 
2.42.0




[PATCH v7 8/8] hw/riscv/shakti_c: Check CPU type in machine_run_board_init()

2023-11-26 Thread Gavin Shan
Set mc->valid_cpu_types so that the user specified CPU type can
be validated in machine_run_board_init(). We needn't to do it
by ourselves.

Signed-off-by: Gavin Shan 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/riscv/shakti_c.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
index 12ea74b032..3888034c2b 100644
--- a/hw/riscv/shakti_c.c
+++ b/hw/riscv/shakti_c.c
@@ -28,7 +28,6 @@
 #include "exec/address-spaces.h"
 #include "hw/riscv/boot.h"
 
-
 static const struct MemmapEntry {
 hwaddr base;
 hwaddr size;
@@ -47,12 +46,6 @@ static void shakti_c_machine_state_init(MachineState *mstate)
 ShaktiCMachineState *sms = RISCV_SHAKTI_MACHINE(mstate);
 MemoryRegion *system_memory = get_system_memory();
 
-/* Allow only Shakti C CPU for this platform */
-if (strcmp(mstate->cpu_type, TYPE_RISCV_CPU_SHAKTI_C) != 0) {
-error_report("This board can only be used with Shakti C CPU");
-exit(1);
-}
-
 /* Initialize SoC */
 object_initialize_child(OBJECT(mstate), "soc", >soc,
 TYPE_RISCV_SHAKTI_SOC);
@@ -82,9 +75,15 @@ static void shakti_c_machine_instance_init(Object *obj)
 static void shakti_c_machine_class_init(ObjectClass *klass, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(klass);
+static const char * const valid_cpu_types[] = {
+RISCV_CPU_TYPE_NAME("shakti-c"),
+NULL
+};
+
 mc->desc = "RISC-V Board compatible with Shakti SDK";
 mc->init = shakti_c_machine_state_init;
 mc->default_cpu_type = TYPE_RISCV_CPU_SHAKTI_C;
+mc->valid_cpu_types = valid_cpu_types;
 mc->default_ram_id = "riscv.shakti.c.ram";
 }
 
-- 
2.42.0




[PATCH v7 1/8] machine: Use error handling when CPU type is checked

2023-11-26 Thread Gavin Shan
QEMU will be terminated if the specified CPU type isn't supported
in machine_run_board_init(). The list of supported CPU type names
is tracked by mc->valid_cpu_types.

The error handling can be used to propagate error messages, to be
consistent how the errors are handled for other situations in the
same function.

No functional change intended.

Suggested-by: Igor Mammedov 
Signed-off-by: Gavin Shan 
---
v7: Add 'return' after error_propagate() to avoid calling into
mc->init() in the failing case(Marcin)
---
 hw/core/machine.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 0c17398141..b3ef325936 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1394,6 +1394,7 @@ void machine_run_board_init(MachineState *machine, const 
char *mem_path, Error *
 MachineClass *machine_class = MACHINE_GET_CLASS(machine);
 ObjectClass *oc = object_class_by_name(machine->cpu_type);
 CPUClass *cc;
+Error *local_err = NULL;
 
 /* This checkpoint is required by replay to separate prior clock
reading from the other reads, because timer polling functions query
@@ -1466,15 +1467,17 @@ void machine_run_board_init(MachineState *machine, 
const char *mem_path, Error *
 
 if (!machine_class->valid_cpu_types[i]) {
 /* The user specified CPU is not valid */
-error_report("Invalid CPU type: %s", machine->cpu_type);
-error_printf("The valid types are: %s",
- machine_class->valid_cpu_types[0]);
+error_setg(_err, "Invalid CPU type: %s", machine->cpu_type);
+error_append_hint(_err, "The valid types are: %s",
+  machine_class->valid_cpu_types[0]);
 for (i = 1; machine_class->valid_cpu_types[i]; i++) {
-error_printf(", %s", machine_class->valid_cpu_types[i]);
+error_append_hint(_err, ", %s",
+  machine_class->valid_cpu_types[i]);
 }
-error_printf("\n");
+error_append_hint(_err, "\n");
 
-exit(1);
+error_propagate(errp, local_err);
+return;
 }
 }
 
-- 
2.42.0




[PATCH v7 3/8] machine: Print CPU model name instead of CPU type

2023-11-26 Thread Gavin Shan
The names of supported CPU models instead of CPU types should be
printed when the user specified CPU type isn't supported, to be
consistent with the output from '-cpu ?'.

Correct the error messages to print CPU model names instead of CPU
type names.

Signed-off-by: Gavin Shan 
---
 hw/core/machine.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 05e1922b89..898c25552a 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1392,6 +1392,7 @@ static void is_cpu_type_supported(const MachineState 
*machine, Error **errp)
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 ObjectClass *oc = object_class_by_name(machine->cpu_type);
 CPUClass *cc;
+char *model;
 int i;
 
 /*
@@ -1408,17 +1409,25 @@ static void is_cpu_type_supported(const MachineState 
*machine, Error **errp)
 
 /* The user specified CPU type isn't valid */
 if (!mc->valid_cpu_types[i]) {
-error_setg(errp, "Invalid CPU type: %s", machine->cpu_type);
+model = cpu_model_from_type(machine->cpu_type);
+g_assert(model != NULL);
+error_setg(errp, "Invalid CPU type: %s", model);
+g_free(model);
+
+model = cpu_model_from_type(mc->valid_cpu_types[0]);
+g_assert(model != NULL);
 if (!mc->valid_cpu_types[1]) {
-error_append_hint(errp, "The only valid type is: %s",
-  mc->valid_cpu_types[0]);
+error_append_hint(errp, "The only valid type is: %s", model);
 } else {
-error_append_hint(errp, "The valid types are: %s",
-  mc->valid_cpu_types[0]);
+error_append_hint(errp, "The valid types are: %s", model);
 }
+g_free(model);
 
 for (i = 1; mc->valid_cpu_types[i]; i++) {
-error_append_hint(errp, ", %s", mc->valid_cpu_types[i]);
+model = cpu_model_from_type(mc->valid_cpu_types[i]);
+g_assert(model != NULL);
+error_append_hint(errp, ", %s", model);
+g_free(model);
 }
 
 error_append_hint(errp, "\n");
-- 
2.42.0




[PATCH v7 6/8] hw/arm/sbsa-ref: Check CPU type in machine_run_board_init()

2023-11-26 Thread Gavin Shan
Set mc->valid_cpu_types so that the user specified CPU type can
be validated in machine_run_board_init(). We needn't to do it
by ourselves.

Signed-off-by: Gavin Shan 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Leif Lindholm 
Reviewed-by: Richard Henderson 
---
 hw/arm/sbsa-ref.c | 36 ++--
 1 file changed, 10 insertions(+), 26 deletions(-)

diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index f3c9704693..477dca0637 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -145,27 +145,6 @@ static const int sbsa_ref_irqmap[] = {
 [SBSA_GWDT_WS0] = 16,
 };
 
-static const char * const valid_cpus[] = {
-ARM_CPU_TYPE_NAME("cortex-a57"),
-ARM_CPU_TYPE_NAME("cortex-a72"),
-ARM_CPU_TYPE_NAME("neoverse-n1"),
-ARM_CPU_TYPE_NAME("neoverse-v1"),
-ARM_CPU_TYPE_NAME("neoverse-n2"),
-ARM_CPU_TYPE_NAME("max"),
-};
-
-static bool cpu_type_valid(const char *cpu)
-{
-int i;
-
-for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) {
-if (strcmp(cpu, valid_cpus[i]) == 0) {
-return true;
-}
-}
-return false;
-}
-
 static uint64_t sbsa_ref_cpu_mp_affinity(SBSAMachineState *sms, int idx)
 {
 uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
@@ -733,11 +712,6 @@ static void sbsa_ref_init(MachineState *machine)
 const CPUArchIdList *possible_cpus;
 int n, sbsa_max_cpus;
 
-if (!cpu_type_valid(machine->cpu_type)) {
-error_report("sbsa-ref: CPU type %s not supported", machine->cpu_type);
-exit(1);
-}
-
 if (kvm_enabled()) {
 error_report("sbsa-ref: KVM is not supported for this machine");
 exit(1);
@@ -898,10 +872,20 @@ static void sbsa_ref_instance_init(Object *obj)
 static void sbsa_ref_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
+static const char * const valid_cpu_types[] = {
+ARM_CPU_TYPE_NAME("cortex-a57"),
+ARM_CPU_TYPE_NAME("cortex-a72"),
+ARM_CPU_TYPE_NAME("neoverse-n1"),
+ARM_CPU_TYPE_NAME("neoverse-v1"),
+ARM_CPU_TYPE_NAME("neoverse-n2"),
+ARM_CPU_TYPE_NAME("max"),
+NULL,
+};
 
 mc->init = sbsa_ref_init;
 mc->desc = "QEMU 'SBSA Reference' ARM Virtual Machine";
 mc->default_cpu_type = ARM_CPU_TYPE_NAME("neoverse-n1");
+mc->valid_cpu_types = valid_cpu_types;
 mc->max_cpus = 512;
 mc->pci_allow_0_address = true;
 mc->minimum_page_bits = 12;
-- 
2.42.0




[PATCH v7 2/8] machine: Introduce helper is_cpu_type_supported()

2023-11-26 Thread Gavin Shan
The logic, to check if the specified CPU type is supported in
machine_run_board_init(), is independent enough. Factor it out into
helper is_cpu_type_supported(). machine_run_board_init() looks a bit
clean with this. Since we're here, @machine_class is renamed to @mc
to avoid multiple line spanning of code. The error messages and comments
are tweaked a bit either.

No functional change intended.

Signed-off-by: Gavin Shan 
---
 hw/core/machine.c | 90 +++
 1 file changed, 51 insertions(+), 39 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index b3ef325936..05e1922b89 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1387,13 +1387,57 @@ out:
 return r;
 }
 
+static void is_cpu_type_supported(const MachineState *machine, Error **errp)
+{
+MachineClass *mc = MACHINE_GET_CLASS(machine);
+ObjectClass *oc = object_class_by_name(machine->cpu_type);
+CPUClass *cc;
+int i;
+
+/*
+ * Check if the user specified CPU type is supported when the valid
+ * CPU types have been determined. Note that the user specified CPU
+ * type is provided through '-cpu' option.
+ */
+if (mc->valid_cpu_types && machine->cpu_type) {
+for (i = 0; mc->valid_cpu_types[i]; i++) {
+if (object_class_dynamic_cast(oc, mc->valid_cpu_types[i])) {
+break;
+}
+}
+
+/* The user specified CPU type isn't valid */
+if (!mc->valid_cpu_types[i]) {
+error_setg(errp, "Invalid CPU type: %s", machine->cpu_type);
+if (!mc->valid_cpu_types[1]) {
+error_append_hint(errp, "The only valid type is: %s",
+  mc->valid_cpu_types[0]);
+} else {
+error_append_hint(errp, "The valid types are: %s",
+  mc->valid_cpu_types[0]);
+}
+
+for (i = 1; mc->valid_cpu_types[i]; i++) {
+error_append_hint(errp, ", %s", mc->valid_cpu_types[i]);
+}
+
+error_append_hint(errp, "\n");
+return;
+}
+}
+
+/* Check if CPU type is deprecated and warn if so */
+cc = CPU_CLASS(oc);
+if (cc && cc->deprecation_note) {
+warn_report("CPU model %s is deprecated -- %s",
+machine->cpu_type, cc->deprecation_note);
+}
+}
 
 void machine_run_board_init(MachineState *machine, const char *mem_path, Error 
**errp)
 {
 ERRP_GUARD();
 MachineClass *machine_class = MACHINE_GET_CLASS(machine);
-ObjectClass *oc = object_class_by_name(machine->cpu_type);
-CPUClass *cc;
 Error *local_err = NULL;
 
 /* This checkpoint is required by replay to separate prior clock
@@ -1449,43 +1493,11 @@ void machine_run_board_init(MachineState *machine, 
const char *mem_path, Error *
 machine->ram = machine_consume_memdev(machine, machine->memdev);
 }
 
-/* If the machine supports the valid_cpu_types check and the user
- * specified a CPU with -cpu check here that the user CPU is supported.
- */
-if (machine_class->valid_cpu_types && machine->cpu_type) {
-int i;
-
-for (i = 0; machine_class->valid_cpu_types[i]; i++) {
-if (object_class_dynamic_cast(oc,
-  machine_class->valid_cpu_types[i])) {
-/* The user specified CPU is in the valid field, we are
- * good to go.
- */
-break;
-}
-}
-
-if (!machine_class->valid_cpu_types[i]) {
-/* The user specified CPU is not valid */
-error_setg(_err, "Invalid CPU type: %s", machine->cpu_type);
-error_append_hint(_err, "The valid types are: %s",
-  machine_class->valid_cpu_types[0]);
-for (i = 1; machine_class->valid_cpu_types[i]; i++) {
-error_append_hint(_err, ", %s",
-  machine_class->valid_cpu_types[i]);
-}
-error_append_hint(_err, "\n");
-
-error_propagate(errp, local_err);
-return;
-}
-}
-
-/* Check if CPU type is deprecated and warn if so */
-cc = CPU_CLASS(oc);
-if (cc && cc->deprecation_note) {
-warn_report("CPU model %s is deprecated -- %s", machine->cpu_type,
-cc->deprecation_note);
+/* Check if the CPU type is supported */
+is_cpu_type_supported(machine, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
 }
 
 if (machine->cgs) {
-- 
2.42.0




[PATCH v7 0/8] Unified CPU type check

2023-11-26 Thread Gavin Shan
This series bases on Phil's repository because the prepatory commits
have been queued to the branch.

  https://gitlab.com/philmd/qemu.git (branch: cpus-next)

There are two places where the user specified CPU type is checked to see
if it's supported or allowed by the board: machine_run_board_init() and
mc->init(). We don't have to maintain two duplicate sets of logic. This
series intends to move the check to machine_run_board_init() so that we
have unified CPU type check.

PATCH[1-3] refactors the logic to validate CPU type in machine_run_board_init()
PATCH[4-8] validates the CPU type in machine_run_board_init() for the
   individual boards

v1: https://lists.nongnu.org/archive/html/qemu-arm/2023-07/msg00302.html
v2: https://lists.nongnu.org/archive/html/qemu-arm/2023-07/msg00528.html
v3: https://lists.nongnu.org/archive/html/qemu-arm/2023-09/msg00157.html
v4: https://lists.nongnu.org/archive/html/qemu-arm/2023-11/msg5.html
v5: https://lists.nongnu.org/archive/html/qemu-arm/2023-11/msg00611.html
v6: https://lists.nongnu.org/archive/html/qemu-arm/2023-11/msg00768.html

Testing
===

Before the series is applied:

  [gshan@gshan q]$ ./build/qemu-system-aarch64 -M virt -cpu cortex-a8
  qemu-system-aarch64: mach-virt: CPU type cortex-a8-arm-cpu not supported
  [gshan@gshan q]$ ./build/qemu-system-aarch64 -M sbsa-ref -cpu cortex-a53
  qemu-system-aarch64: sbsa-ref: CPU type cortex-a53-arm-cpu not supported
  [gshan@gshan q]$ ./build/qemu-system-aarch64 -M sbsa-ref -cpu sa1100
  qemu-system-aarch64: sbsa-ref: CPU type sa1100-arm-cpu not supported
  [gshan@gshan q]$ ./build/qemu-system-aarch64 -M sbsa-ref -cpu host
  qemu-system-aarch64: unable to find CPU model 'host'

After the series is applied:

  [gshan@gshan q]$ ./build/qemu-system-aarch64 -M virt -cpu cortex-a8
  qemu-system-aarch64: Invalid CPU type: cortex-a8
  The valid types are: cortex-a7, cortex-a15, cortex-a35, cortex-a55, \
   cortex-a72, cortex-a76, cortex-a710, a64fx,\
   neoverse-n1, neoverse-v1, neoverse-n2, cortex-a53, \
   cortex-a57, max
  [gshan@gshan q]$ ./build/qemu-system-aarch64 -M sbsa-ref -cpu cortex-a53
  qemu-system-aarch64: Invalid CPU type: cortex-a53
  The valid types are: cortex-a57, cortex-a72, neoverse-n1, neoverse-v1,  \
   neoverse-n2, max
  [gshan@gshan q]$ ./build/qemu-system-aarch64 -M sbsa-ref -cpu sa1100
  qemu-system-aarch64: Invalid CPU type: sa1100
  The valid types are: cortex-a57, cortex-a72, neoverse-n1, neoverse-v1,  \
   neoverse-n2, max
  [gshan@gshan q]$ ./build/qemu-system-aarch64 -M sbsa-ref -cpu host
  qemu-system-aarch64: unable to find CPU model 'host'

Changelog
=
v7:
  * Add 'return' after error_propagate() in machine_run_board_init()
to avoid calling mc->init() in the failing case  (Marcin)
v6:
  * Drop PATCH[v5 01-23], queued by Phil (Phil)
  * Clearer hint if only one CPU type is supported and have
'const MachineState *' in is_cpu_type_supported()(Phil)
  * Move valid_cpu_types[] to board's class_init() function  (Phil)
v5:
  * PATCH[v5 01] to remove CPU class 'ev67' for alpha(Ricard/Igor)
  * PATCH[v5 02] to remove object_class_is_abstract() for hppa   (Gavin)
  * Don't move cpu_class_by_name()   (Richard)
  * PATCH[v5 04] to remove 'oc == NULL' since the check has
been covered in object_class_dynamic_cast()  (Igor)
  * Introduce generic cpu_list(), shared by most of the targets  (Richard)
  * Use g_str_has_suffix and g_auto_free (Richard)
  * Collect r-bs from Igor and Richard   (Gavin)
v4:
  * Integrate Philippe's patches where cpu_class_by_name()
is consolidated and my duplicate code is dropped(Philippe)
  * Simplified changelog and improvements   (Thomas)
  * g_assert() on the return value from cpu_model_from_type()
in is_cpu_type_supported()  (Philippe)
  * Collected r-bs from Philippe Mathieu-Daudé, Leif Lindholm,
Bastian Koppelmann, Daniel Henrique Barboza, Cédric Le Goater,
Gavin Shan  (Gavin)
v3:
  * Generic helper cpu_model_from_type()(Igor)
  * Apply cpu_model_from_type() to the individual targets   (Igor)
  * Implement cpu_list() for the missed targets (Gavin)
  * Remove mc->valid_cpu_models (Richard)
  * Separate patch to constify mc->validate_cpu_types   (Gavin)
v2:
  * Constify mc->valid_cpu_types(Richard)
  * Print the supported CPU models, instead of typenames(Peter)
  * Misc improvements for the hleper to do the check(Igor)
  * More patches to move the check  (Marcin)

Gavin Shan (8):
  machine: 

[PATCH v7 4/8] hw/arm/virt: Hide host CPU model for tcg

2023-11-26 Thread Gavin Shan
The 'host' CPU model isn't available until KVM or HVF is enabled.
For example, the following error messages are seen when the guest
is started with option '-cpu cortex-a8' on tcg after the next commit
is applied to check the CPU type in machine_run_board_init().

  ERROR:../hw/core/machine.c:1423:is_cpu_type_supported: \
  assertion failed: (model != NULL)
  Bail out! ERROR:../hw/core/machine.c:1423:is_cpu_type_supported: \
  assertion failed: (model != NULL)
  Aborted (core dumped)

Hide 'host' CPU model until KVM or HVF is enabled. With this applied,
the valid CPU models can be shown.

  qemu-system-aarch64: Invalid CPU type: cortex-a8
  The valid types are: cortex-a7, cortex-a15, cortex-a35, \
  cortex-a55, cortex-a72, cortex-a76, cortex-a710, a64fx, \
  neoverse-n1, neoverse-v1, neoverse-n2, cortex-a53,  \
  cortex-a57, max

Signed-off-by: Gavin Shan 
Reviewed-by: Richard Henderson 
---
 hw/arm/virt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index be2856c018..668c0d3194 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -220,7 +220,9 @@ static const char *valid_cpus[] = {
 #endif
 ARM_CPU_TYPE_NAME("cortex-a53"),
 ARM_CPU_TYPE_NAME("cortex-a57"),
+#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
 ARM_CPU_TYPE_NAME("host"),
+#endif
 ARM_CPU_TYPE_NAME("max"),
 };
 
-- 
2.42.0




[PATCH v7 7/8] hw/arm: Check CPU type in machine_run_board_init()

2023-11-26 Thread Gavin Shan
Set mc->valid_cpu_types so that the user specified CPU type can
be validated in machine_run_board_init(). We needn't to do it by
ourselves.

Signed-off-by: Gavin Shan 
Reviewed-by: Richard Henderson 
---
 hw/arm/bananapi_m2u.c   | 12 ++--
 hw/arm/cubieboard.c | 12 ++--
 hw/arm/mps2-tz.c| 26 --
 hw/arm/mps2.c   | 26 --
 hw/arm/msf2-som.c   | 12 ++--
 hw/arm/musca.c  | 12 +---
 hw/arm/npcm7xx_boards.c | 12 +---
 hw/arm/orangepi.c   | 12 ++--
 8 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c
index 8f24b18d8c..0a4b6f29b1 100644
--- a/hw/arm/bananapi_m2u.c
+++ b/hw/arm/bananapi_m2u.c
@@ -71,12 +71,6 @@ static void bpim2u_init(MachineState *machine)
 exit(1);
 }
 
-/* Only allow Cortex-A7 for this board */
-if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a7")) != 0) {
-error_report("This board can only be used with cortex-a7 CPU");
-exit(1);
-}
-
 r40 = AW_R40(object_new(TYPE_AW_R40));
 object_property_add_child(OBJECT(machine), "soc", OBJECT(r40));
 object_unref(OBJECT(r40));
@@ -133,12 +127,18 @@ static void bpim2u_init(MachineState *machine)
 
 static void bpim2u_machine_init(MachineClass *mc)
 {
+static const char * const valid_cpu_types[] = {
+ARM_CPU_TYPE_NAME("cortex-a7"),
+NULL
+};
+
 mc->desc = "Bananapi M2U (Cortex-A7)";
 mc->init = bpim2u_init;
 mc->min_cpus = AW_R40_NUM_CPUS;
 mc->max_cpus = AW_R40_NUM_CPUS;
 mc->default_cpus = AW_R40_NUM_CPUS;
 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
+mc->valid_cpu_types = valid_cpu_types;
 mc->default_ram_size = 1 * GiB;
 mc->default_ram_id = "bpim2u.ram";
 }
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index 29146f5018..b976727eef 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -52,12 +52,6 @@ static void cubieboard_init(MachineState *machine)
 exit(1);
 }
 
-/* Only allow Cortex-A8 for this board */
-if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a8")) != 0) {
-error_report("This board can only be used with cortex-a8 CPU");
-exit(1);
-}
-
 a10 = AW_A10(object_new(TYPE_AW_A10));
 object_property_add_child(OBJECT(machine), "soc", OBJECT(a10));
 object_unref(OBJECT(a10));
@@ -114,8 +108,14 @@ static void cubieboard_init(MachineState *machine)
 
 static void cubieboard_machine_init(MachineClass *mc)
 {
+static const char * const valid_cpu_types[] = {
+ARM_CPU_TYPE_NAME("cortex-a8"),
+NULL
+};
+
 mc->desc = "cubietech cubieboard (Cortex-A8)";
 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8");
+mc->valid_cpu_types = valid_cpu_types;
 mc->default_ram_size = 1 * GiB;
 mc->init = cubieboard_init;
 mc->block_default_type = IF_IDE;
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index 668db5ed61..5d8cdc1a4c 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -813,12 +813,6 @@ static void mps2tz_common_init(MachineState *machine)
 int num_ppcs;
 int i;
 
-if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
-error_report("This board can only be used with CPU %s",
- mc->default_cpu_type);
-exit(1);
-}
-
 if (machine->ram_size != mc->default_ram_size) {
 char *sz = size_to_str(mc->default_ram_size);
 error_report("Invalid RAM size, should be %s", sz);
@@ -1318,6 +1312,10 @@ static void mps2tz_an505_class_init(ObjectClass *oc, 
void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
 MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
+static const char * const valid_cpu_types[] = {
+ARM_CPU_TYPE_NAME("cortex-m33"),
+NULL
+};
 
 mc->desc = "ARM MPS2 with AN505 FPGA image for Cortex-M33";
 mc->default_cpus = 1;
@@ -1325,6 +1323,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void 
*data)
 mc->max_cpus = mc->default_cpus;
 mmc->fpga_type = FPGA_AN505;
 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
+mc->valid_cpu_types = valid_cpu_types;
 mmc->scc_id = 0x41045050;
 mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
 mmc->apb_periph_frq = mmc->sysclk_frq;
@@ -1347,6 +1346,10 @@ static void mps2tz_an521_class_init(ObjectClass *oc, 
void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
 MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
+static const char * const valid_cpu_types[] = {
+ARM_CPU_TYPE_NAME("cortex-m33"),
+NULL
+};
 
 mc->desc = "ARM MPS2 with AN521 FPGA image for dual Cortex-M33";
 mc->default_cpus = 2;
@@ -1354,6 +1357,7 @@ static void mps2tz_an521_class_init(ObjectClass *oc, void 
*data)
 mc->max_cpus = mc->default_cpus;
 mmc->fpga_type = FPGA_AN521;
 mc->default_cpu_type = 

Re: [PATCH] qemu/timer: Don't use RDTSC on i486

2023-11-26 Thread Petr Cvek
Dne 26. 11. 23 v 16:56 Paolo Bonzini napsal(a):
> 
> 
> Il sab 25 nov 2023, 13:23 Petr Cvek  > ha scritto:
> 
> GCC defines __i386__ for i386 and i486, which both lack RDTSC instruction.
> The i386 seems to be impossible to distinguish, but i486 can be identified
> by checking for undefined __i486__.
> 
> 
> As far as I know QEMU cannot be run on i486 anyway since TCG assumes the 
> presence of CPUID. Have you actually tried?
> 

Yes I tried running x86_64 mesa3d glxgears on amd 5x86. It worked with about 5 
fps :). Latest 486 CPUs supports CPUID btw.

> Paolo
> 
> 
> Signed-off-by: Petr Cvek  >
> ---
>  include/qemu/timer.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/qemu/timer.h b/include/qemu/timer.h
> index 9a366e551f..7baa5d1d41 100644
> --- a/include/qemu/timer.h
> +++ b/include/qemu/timer.h
> @@ -872,7 +872,7 @@ static inline int64_t cpu_get_host_ticks(void)
>      return retval;
>  }
> 
> -#elif defined(__i386__)
> +#elif defined(__i386__) && !defined(__i486__)
> 
>  static inline int64_t cpu_get_host_ticks(void)
>  {
> -- 
> 2.43.0
> 



[PATCH v3 0/4] Fix IRQ routing in via south bridge

2023-11-26 Thread BALATON Zoltan
Philippe,

Could this be merged for 8.2 as it fixes USB on the amigaone machine?
This would be useful as usb-storage is the simplest way to share data
with the host with these machines.

This is a slight change from v2 adding more comments and improving
commit messages and clean things a bit but otherwise should be the
same as previous versions. Even v1 worked the same as this one and v2,
the additional check to avoid stuck bits is just paranoia, it does not
happen in practice as IRQ mappings are quite static, they are set once
at boot and don't change afterwards.

The rest is just some explanation on how we got here but can be
skipped if not interested in history.

This is going back to my original implementation of this IRQ routing
that I submitted already for 8.0 in the beginning of this year
(https://patchew.org/QEMU/cover.1677004414.git.bala...@eik.bme.hu/)
but Mark had concerns about that because he wanted to use PCI
interrupt routing instead. I've already told back then that won't work
but I could not convince reviewers about that. Now with the amigaone
machine this can also be seen and that's why this series is needed now.

The routing code in PCIBus cannot be used as that only considers the 4
PCI interrupts but there are about 12 interrupt sources in this chip
that need to be routed to ISA IRQs (the embedded chip functions and
the 4 PCI interrupts that are coming in through 4 pins of the chip).
Also the chip does not own the PCIBus, that's part of the north bridge
so it should not change the PCI interrupt routing of a bus it does not
own. (Piix calling pci_bus_irqs() I think is also wrong because the
PCI bus in that machine is also owned by the north bridge and piix
should not take over routing of IRQs on a bus it's connected to.)
Another concern from Mark was that this makes chip functions specific
to the chip and they cannot be used as individual PCI devices. Well,
yes, they are chip functions, are not user creatable and don't exist
as individual devices so it does not make sense to use them without
the actual VIA chip they are a function of so that's not a real
concern. These functions are also not actual PCI devices, they are
PCIDevice because they appear as PCI functions of the chip but are
connected internally and this series also models that correctly. This
seems to be supported by comments in Linux about how these VIA chip
function aren't following PCI standards and use ISA IRQs instead:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/pci/quirks.c?h=v6.5.6#n1172

Therefore I think Mark's proposals are not improving this model so I
went back to the original approach which was tested to work and is
also simpler and easier to understand than trying to reuse PCI
intrrupt routing which does not work and would be more complex anyway
for no good reason.

Regards,
BALATON Zoltan

BALATON Zoltan (4):
  hw/isa/vt82c686: Bring back via_isa_set_irq()
  hw/usb/vt82c686-uhci-pci: Use ISA instead of PCI interrupts
  hw/isa/vt82c686: Route PIRQ inputs using via_isa_set_irq()
  hw/audio/via-ac97: Route interrupts using via_isa_set_irq()

 hw/audio/via-ac97.c|  8 ++--
 hw/isa/vt82c686.c  | 79 +-
 hw/usb/vt82c686-uhci-pci.c |  9 +
 include/hw/isa/vt82c686.h  |  2 +
 4 files changed, 67 insertions(+), 31 deletions(-)

-- 
2.30.9




[PATCH v3 1/4] hw/isa/vt82c686: Bring back via_isa_set_irq()

2023-11-26 Thread BALATON Zoltan
The VIA integrated south bridge chips combine several functions and
allow routing their interrupts to any of the ISA IRQs also allowing
multiple sources to share the same ISA IRQ. E.g. pegasos2 firmware
configures everything to use IRQ 9 but amigaone routes them to
separate ISA IRQs so the current simplified routing does not work.
Bring back via_isa_set_irq() and change it to take the component that
wants to change an IRQ and keep track of interrupt status of each
source separately and do the mapping to ISA IRQ within the ISA bridge.

This may not handle cases when an ISA IRQ is controlled by devices
directly, not going through via_isa_set_irq() such as serial, parallel
or keyboard but these IRQs being conventionally fixed are not likely
to be change by guests or share with other devices so this does not
cause a problem in practice.

This reverts commit 4e5a20b6da9b1f6d2e9621ed7eb8b239560104ae.

Signed-off-by: BALATON Zoltan 
---
 hw/isa/vt82c686.c | 41 +++
 include/hw/isa/vt82c686.h |  2 ++
 2 files changed, 43 insertions(+)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 57bdfb4e78..6fad8293e6 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -549,6 +549,7 @@ struct ViaISAState {
 PCIDevice dev;
 qemu_irq cpu_intr;
 qemu_irq *isa_irqs_in;
+uint16_t irq_state[ISA_NUM_IRQS];
 ViaSuperIOState via_sio;
 MC146818RtcState rtc;
 PCIIDEState ide;
@@ -592,6 +593,46 @@ static const TypeInfo via_isa_info = {
 },
 };
 
+void via_isa_set_irq(PCIDevice *d, int pin, int level)
+{
+ViaISAState *s = VIA_ISA(pci_get_function_0(d));
+uint8_t irq = d->config[PCI_INTERRUPT_LINE], max_irq = 15;
+int f = PCI_FUNC(d->devfn);
+uint16_t mask = BIT(f);
+
+switch (f) {
+case 2: /* USB ports 0-1 */
+case 3: /* USB ports 2-3 */
+max_irq = 14;
+break;
+}
+
+/* Keep track of the state of all sources */
+if (level) {
+s->irq_state[0] |= mask;
+} else {
+s->irq_state[0] &= ~mask;
+}
+if (irq == 0 || irq == 0xff) {
+return; /* disabled */
+}
+if (unlikely(irq > max_irq || irq == 2)) {
+qemu_log_mask(LOG_GUEST_ERROR, "Invalid ISA IRQ routing %d for %d",
+  irq, f);
+return;
+}
+/* Record source state at mapped IRQ */
+if (level) {
+s->irq_state[irq] |= mask;
+} else {
+s->irq_state[irq] &= ~mask;
+}
+/* Make sure there are no stuck bits if mapping has changed */
+s->irq_state[irq] &= s->irq_state[0];
+/* ISA IRQ level is the OR of all sources routed to it */
+qemu_set_irq(s->isa_irqs_in[irq], !!s->irq_state[irq]);
+}
+
 static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
 {
 ViaISAState *s = opaque;
diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index b6e95b2851..da1722daf2 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -34,4 +34,6 @@ struct ViaAC97State {
 uint32_t ac97_cmd;
 };
 
+void via_isa_set_irq(PCIDevice *d, int n, int level);
+
 #endif
-- 
2.30.9




[PATCH v3 2/4] hw/usb/vt82c686-uhci-pci: Use ISA instead of PCI interrupts

2023-11-26 Thread BALATON Zoltan
This device is part of a superio/ISA bridge chip and IRQs from it are
routed to an ISA interrupt. Use via_isa_set_irq() function to implement
this in a vt82c686-uhci-pci specific irq handler.

This reverts commit 422a6e8075752bc5342afd3eace23a4990dd7d98.

Signed-off-by: BALATON Zoltan 
---
 hw/usb/vt82c686-uhci-pci.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c
index b4884c9011..6162806172 100644
--- a/hw/usb/vt82c686-uhci-pci.c
+++ b/hw/usb/vt82c686-uhci-pci.c
@@ -1,7 +1,14 @@
 #include "qemu/osdep.h"
+#include "hw/irq.h"
 #include "hw/isa/vt82c686.h"
 #include "hcd-uhci.h"
 
+static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
+{
+UHCIState *s = opaque;
+via_isa_set_irq(>dev, 0, level);
+}
+
 static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
 {
 UHCIState *s = UHCI(dev);
@@ -15,6 +22,8 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error 
**errp)
 pci_set_long(pci_conf + 0xc0, 0x2000);
 
 usb_uhci_common_realize(dev, errp);
+object_unref(s->irq);
+s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
 }
 
 static UHCIInfo uhci_info[] = {
-- 
2.30.9




[PATCH v3 4/4] hw/audio/via-ac97: Route interrupts using via_isa_set_irq()

2023-11-26 Thread BALATON Zoltan
This device is a function of VIA south bridge and should allow setting
interrupt routing within that chip. This is implemented in
via_isa_set_irq().

Fixes: eb604411a78b82c468e2b8d81a9401eb8b9c7658
Signed-off-by: BALATON Zoltan 
---
 hw/audio/via-ac97.c | 8 
 hw/isa/vt82c686.c   | 1 +
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c
index 30095a4c7a..4c127a1def 100644
--- a/hw/audio/via-ac97.c
+++ b/hw/audio/via-ac97.c
@@ -211,14 +211,14 @@ static void out_cb(void *opaque, int avail)
 AUD_set_active_out(s->vo, 0);
 }
 if (c->type & STAT_EOL) {
-pci_set_irq(>dev, 1);
+via_isa_set_irq(>dev, 0, 1);
 }
 }
 if (CLEN_IS_FLAG(c)) {
 c->stat |= STAT_FLAG;
 c->stat |= STAT_PAUSED;
 if (c->type & STAT_FLAG) {
-pci_set_irq(>dev, 1);
+via_isa_set_irq(>dev, 0, 1);
 }
 }
 if (CLEN_IS_STOP(c)) {
@@ -305,13 +305,13 @@ static void sgd_write(void *opaque, hwaddr addr, uint64_t 
val, unsigned size)
 if (val & STAT_EOL) {
 s->aur.stat &= ~(STAT_EOL | STAT_PAUSED);
 if (s->aur.type & STAT_EOL) {
-pci_set_irq(>dev, 0);
+via_isa_set_irq(>dev, 0, 0);
 }
 }
 if (val & STAT_FLAG) {
 s->aur.stat &= ~(STAT_FLAG | STAT_PAUSED);
 if (s->aur.type & STAT_FLAG) {
-pci_set_irq(>dev, 0);
+via_isa_set_irq(>dev, 0, 0);
 }
 }
 break;
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index a3eb6769fc..9c2333a277 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -622,6 +622,7 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
 break;
 case 2: /* USB ports 0-1 */
 case 3: /* USB ports 2-3 */
+case 5: /* AC97 audio */
 max_irq = 14;
 break;
 }
-- 
2.30.9




Re: [PATCH] qemu/timer: Don't use RDTSC on i486

2023-11-26 Thread Petr Cvek
Dne 26. 11. 23 v 14:03 Samuel Tardieu napsal(a):
> 
> Petr Cvek  writes:
> 
>> Actually I was thinking about mentioning it in the commit message also, but 
>> I wasn't able
>> to find any specification for that (if all compilers use it).
> 
> Note that this change would be safe: at worst, some compilers don't use 
> __tune_i386__ and the situation would be the same as today without the patch.

Good remark. You're right.

> 
>> Other problem is the __tune_i386__ is also set when -mtune=i386 (but with 
>> -march=i686).
> 
> Indeed, this is the case for GCC (not clang).
> 
>  Sam



[PATCH v3 3/4] hw/isa/vt82c686: Route PIRQ inputs using via_isa_set_irq()

2023-11-26 Thread BALATON Zoltan
The chip has 4 pins (called PIRQA-D in VT82C686B and PINTA-D in
VT8231) that are meant to be connected to PCI IRQ lines and allow
routing PCI interrupts to the ISA PIC. Route these in
via_isa_set_irq() to make it possible to share them with internal
functions that can also be routed to the same ISA IRQs.

Fixes: 2fdadd02e675caca4aba4ae26317701fe2c4c901
Signed-off-by: BALATON Zoltan 
---
 hw/isa/vt82c686.c | 65 +--
 1 file changed, 24 insertions(+), 41 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 6fad8293e6..a3eb6769fc 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -593,6 +593,21 @@ static const TypeInfo via_isa_info = {
 },
 };
 
+static int via_isa_get_pci_irq(const ViaISAState *s, int pin)
+{
+switch (pin) {
+case 0:
+return s->dev.config[0x55] >> 4;
+case 1:
+return s->dev.config[0x56] & 0xf;
+case 2:
+return s->dev.config[0x56] >> 4;
+case 3:
+return s->dev.config[0x57] >> 4;
+}
+return 0;
+}
+
 void via_isa_set_irq(PCIDevice *d, int pin, int level)
 {
 ViaISAState *s = VIA_ISA(pci_get_function_0(d));
@@ -601,6 +616,10 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
 uint16_t mask = BIT(f);
 
 switch (f) {
+case 0: /* PIRQ/PINT inputs */
+irq = via_isa_get_pci_irq(s, pin);
+f = 8 + pin; /* Use function 8-11 for PCI interrupt inputs */
+break;
 case 2: /* USB ports 0-1 */
 case 3: /* USB ports 2-3 */
 max_irq = 14;
@@ -633,50 +652,15 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
 qemu_set_irq(s->isa_irqs_in[irq], !!s->irq_state[irq]);
 }
 
-static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
-{
-ViaISAState *s = opaque;
-qemu_set_irq(s->cpu_intr, level);
-}
-
-static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
+static void via_isa_pirq(void *opaque, int pin, int level)
 {
-switch (irq_num) {
-case 0:
-return s->dev.config[0x55] >> 4;
-case 1:
-return s->dev.config[0x56] & 0xf;
-case 2:
-return s->dev.config[0x56] >> 4;
-case 3:
-return s->dev.config[0x57] >> 4;
-}
-return 0;
+via_isa_set_irq(opaque, pin, level);
 }
 
-static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
+static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
 {
 ViaISAState *s = opaque;
-PCIBus *bus = pci_get_bus(>dev);
-int i, pic_level, pic_irq = via_isa_get_pci_irq(s, irq_num);
-
-/* IRQ 0: disabled, IRQ 2,8,13: reserved */
-if (!pic_irq) {
-return;
-}
-if (unlikely(pic_irq == 2 || pic_irq == 8 || pic_irq == 13)) {
-qemu_log_mask(LOG_GUEST_ERROR, "Invalid ISA IRQ routing");
-}
-
-/* The pic level is the logical OR of all the PCI irqs mapped to it. */
-pic_level = 0;
-for (i = 0; i < PCI_NUM_PINS; i++) {
-if (pic_irq == via_isa_get_pci_irq(s, i)) {
-pic_level |= pci_bus_get_irq_level(bus, i);
-}
-}
-/* Now we change the pic irq level according to the via irq mappings. */
-qemu_set_irq(s->isa_irqs_in[pic_irq], pic_level);
+qemu_set_irq(s->cpu_intr, level);
 }
 
 static void via_isa_realize(PCIDevice *d, Error **errp)
@@ -689,6 +673,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 int i;
 
 qdev_init_gpio_out(dev, >cpu_intr, 1);
+qdev_init_gpio_in_named(dev, via_isa_pirq, "pirq", PCI_NUM_PINS);
 isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
 isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
   errp);
@@ -702,8 +687,6 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 i8254_pit_init(isa_bus, 0x40, 0, NULL);
 i8257_dma_init(isa_bus, 0);
 
-qdev_init_gpio_in_named(dev, via_isa_set_pci_irq, "pirq", PCI_NUM_PINS);
-
 /* RTC */
 qdev_prop_set_int32(DEVICE(>rtc), "base_year", 2000);
 if (!qdev_realize(DEVICE(>rtc), BUS(isa_bus), errp)) {
-- 
2.30.9




Re: pending hw/audio patches for 8.2

2023-11-26 Thread Michael S. Tsirkin
On Sun, Nov 26, 2023 at 02:32:43PM +0100, Volker Rümelin wrote:
> Hi,
> 
> there are five pending reviewed hw/audio patches for 8.2. They are all
> bug fixes. It would be good if someone could send a pull request for
> rc2. I don't think Gerd will send it.
> 
> The five patches are:
> 
> ("hw/audio/hda-codec: fix multiplication overflow")
> https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg00828.html
> 
> ("hw/audio/hda-codec: reenable the audio mixer")
> https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg00827.html
> 
> ("hw/audio/virtio-snd-pci: fix the PCI class code")
> https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg02084.html
> 
> ("virtio-snd: check AUD_register_card return value")
> https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg02545.html
> 
> ("virtio-sound: add realize() error cleanup path")
> https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg03878.html
> 
> IIRC the last patch needs a rebase.
> 
> I omitted another reviewed patch, which is a variant of
> ("hw/audio/hda-codec: reenable the audio mixer").
> ("hw/audio: Fix logic error in hda audio")
> https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg03951.html
> 
> I have a repository at https://gitlab.com/volker.ruemelin/qemu.git. The
> five rebased patches are in the hw-audio-fixes-for-8.2 branch.
> 
> With best regards,
> Volker


OK I will pick these up. Thanks!




Re: [PATCH] sh4: Coding style: Remove tabs

2023-11-26 Thread Thomas Huth

On 24/11/2023 16.30, Philippe Mathieu-Daudé wrote:

Hi,

On 24/11/23 05:45, xun wrote:

From: Yihuan Pan 

Replaces TABS with spaces to ensure have a consistent coding
style with an indentation of 4 spaces in the SH4 subsystem.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/376
Signed-off-by: Yihuan Pan 
---
  linux-user/sh4/termbits.h |  204 +++---
  target/sh4/cpu.h  |   80 +-
  target/sh4/helper.c   |  236 +++---
  target/sh4/op_helper.c    |   70 +-
  target/sh4/translate.c    | 1466 ++---
  5 files changed, 1028 insertions(+), 1028 deletions(-)



@@ -241,17 +241,17 @@ static int find_tlb_entry(CPUSH4State * env, 
target_ulong address,

  asid = env->pteh & 0xff;
  for (i = 0; i < nbtlb; i++) {
-    if (!entries[i].v)
-    continue;    /* Invalid entry */
-    if (!entries[i].sh && use_asid && entries[i].asid != asid)
-    continue;    /* Bad ASID */
-    start = (entries[i].vpn << 10) & ~(entries[i].size - 1);
-    end = start + entries[i].size - 1;
-    if (address >= start && address <= end) {    /* Match */
-    if (match != MMU_DTLB_MISS)
-    return MMU_DTLB_MULTIPLE;    /* Multiple match */
-    match = i;
-    }
+    if (!entries[i].v)
+    continue; /* Invalid entry */


Thomas, better fix the 'if { }' in this patch or a following one?


Normally I would not mind either way, but this patch is already quite big, 
so I think it would be better to fix other coding style issues in separate 
patches.
This way, you can also verify with "git show -b" that there are no other 
unwanted changes in here.


I now also quickly skimmed through the changes and the patch looks fine to 
me, so:


Reviewed-by: Thomas Huth 

Since the sh4 subsystem currently does not have a maintainer, I'll take the 
patch for my next pull request.


Thank you for tackling this!

 Thomas




Re: [PATCH] qemu/timer: Don't use RDTSC on i486

2023-11-26 Thread Paolo Bonzini
Il sab 25 nov 2023, 13:23 Petr Cvek  ha scritto:

> GCC defines __i386__ for i386 and i486, which both lack RDTSC instruction.
> The i386 seems to be impossible to distinguish, but i486 can be identified
> by checking for undefined __i486__.
>

As far as I know QEMU cannot be run on i486 anyway since TCG assumes the
presence of CPUID. Have you actually tried?

Paolo


> Signed-off-by: Petr Cvek 
> ---
>  include/qemu/timer.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/qemu/timer.h b/include/qemu/timer.h
> index 9a366e551f..7baa5d1d41 100644
> --- a/include/qemu/timer.h
> +++ b/include/qemu/timer.h
> @@ -872,7 +872,7 @@ static inline int64_t cpu_get_host_ticks(void)
>  return retval;
>  }
>
> -#elif defined(__i386__)
> +#elif defined(__i386__) && !defined(__i486__)
>
>  static inline int64_t cpu_get_host_ticks(void)
>  {
> --
> 2.43.0
>
>


[PATCH qemu 1/2] hw/arm: Add minimal support for the STM32L4x5 SoC

2023-11-26 Thread ~inesvarhol
From: Inès Varhol 

This patch adds a new STM32L4x5 SoC, it is necessary to add support for
the B-L475E-IOT01A board.
The implementation is derived from the STM32F405 SoC.
The implementation contains no peripherals, only memory regions are
implemented.

Reviewed-by: Philippe Mathieu-Daudé 

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 
---
 MAINTAINERS|   8 +
 hw/arm/Kconfig |   5 +
 hw/arm/meson.build |   1 +
 hw/arm/stm32l4x5_soc.c | 277 +
 include/hw/arm/stm32l4x5_soc.h |  68 
 5 files changed, 359 insertions(+)
 create mode 100644 hw/arm/stm32l4x5_soc.c
 create mode 100644 include/hw/arm/stm32l4x5_soc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ff1238bb98..32458d41dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1122,6 +1122,14 @@ L: qemu-...@nongnu.org
 S: Maintained
 F: hw/arm/olimex-stm32-h405.c
 
+STM32L4x5 SoC Family
+M: Arnaud Minier 
+M: Inès Varhol 
+L: qemu-...@nongnu.org
+S: Maintained
+F: hw/arm/stm32l4x5_soc.c
+F: include/hw/arm/stm32l4x5_soc.h
+
 SmartFusion2
 M: Subbaraya Sundeep 
 M: Peter Maydell 
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 3ada335a24..d2b94d9a47 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -448,6 +448,11 @@ config STM32F405_SOC
 select STM32F4XX_SYSCFG
 select STM32F4XX_EXTI
 
+config STM32L4X5_SOC
+bool
+select ARM_V7M
+select OR_IRQ
+
 config XLNX_ZYNQMP_ARM
 bool
 default y if PIXMAN
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 68245d3ad1..9766da10c4 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -42,6 +42,7 @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 
'raspi.c'))
 arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
+arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
 arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 
'xlnx-zcu102.c'))
 arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 
'xlnx-versal-virt.c'))
 arm_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 
'imx25_pdk.c'))
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
new file mode 100644
index 00..f476878b2c
--- /dev/null
+++ b/hw/arm/stm32l4x5_soc.c
@@ -0,0 +1,277 @@
+/*
+ * STM32L4x5 SoC family
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2023 Arnaud Minier 
+ * Copyright (c) 2023 Inès Varhol 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Heavily inspired by the stm32f405_soc by Alistair Francis.
+ * The reference used is the STMicroElectronics RM0351 Reference manual
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
+ * 
https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
+#include "hw/arm/stm32l4x5_soc.h"
+#include "hw/qdev-clock.h"
+#include "hw/misc/unimp.h"
+
+#define FLASH_BASE_ADDRESS 0x0800
+#define SRAM1_BASE_ADDRESS 0x2000
+#define SRAM1_SIZE (96 * KiB)
+#define SRAM2_BASE_ADDRESS 0x1000
+#define SRAM2_SIZE (32 * KiB)
+
+static void stm32l4x5_soc_initfn(Object *obj)
+{
+Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
+
+s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+s->refclk = qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0);
+}
+
+static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+ERRP_GUARD();
+Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
+const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
+MemoryRegion *system_memory = get_system_memory();
+DeviceState *armv7m;
+
+/*

[PATCH qemu 2/2] hw/arm: Add minimal support for the B-L475E-IOT01A board

2023-11-26 Thread ~inesvarhol
From: Inès Varhol 

This commit adds a new B-L475E-IOT01A board using the STM32L475VG SoC.
The implementation is derived from the Netduino Plus 2 machine.
There are no peripherals implemented yet, only memory regions.

Reviewed-by: Philippe Mathieu-Daudé 

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 
---
 MAINTAINERS |  7 +++
 configs/devices/arm-softmmu/default.mak |  1 +
 hw/arm/Kconfig  |  6 ++
 hw/arm/b-l475e-iot01a.c | 79 +
 hw/arm/meson.build  |  1 +
 5 files changed, 94 insertions(+)
 create mode 100644 hw/arm/b-l475e-iot01a.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 32458d41dd..6ae9ca3ef4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1130,6 +1130,13 @@ S: Maintained
 F: hw/arm/stm32l4x5_soc.c
 F: include/hw/arm/stm32l4x5_soc.h
 
+B-L475E-IOT01A IoT Node
+M: Arnaud Minier 
+M: Inès Varhol 
+L: qemu-...@nongnu.org
+S: Maintained
+F: hw/arm/b-l475e-iot01a.c
+
 SmartFusion2
 M: Subbaraya Sundeep 
 M: Peter Maydell 
diff --git a/configs/devices/arm-softmmu/default.mak 
b/configs/devices/arm-softmmu/default.mak
index 980c48a7d9..023faa2f75 100644
--- a/configs/devices/arm-softmmu/default.mak
+++ b/configs/devices/arm-softmmu/default.mak
@@ -19,6 +19,7 @@ CONFIG_ARM_VIRT=y
 # CONFIG_NSERIES=n
 # CONFIG_STELLARIS=n
 # CONFIG_STM32VLDISCOVERY=n
+# CONFIG_B_L475E_IOT01A=n
 # CONFIG_REALVIEW=n
 # CONFIG_VERSATILE=n
 # CONFIG_VEXPRESS=n
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index d2b94d9a47..7520dc5cc0 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -448,6 +448,12 @@ config STM32F405_SOC
 select STM32F4XX_SYSCFG
 select STM32F4XX_EXTI
 
+config B_L475E_IOT01A
+bool
+default y
+depends on TCG && ARM
+select STM32L4X5_SOC
+
 config STM32L4X5_SOC
 bool
 select ARM_V7M
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
new file mode 100644
index 00..16e49871cd
--- /dev/null
+++ b/hw/arm/b-l475e-iot01a.c
@@ -0,0 +1,79 @@
+/*
+ * B-L475E-IOT01A Discovery Kit machine
+ * (B-L475E-IOT01A IoT Node)
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2023 Arnaud Minier 
+ * Copyright (c) 2023 Ines Varhol 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Heavily inspired by the netduinoplus2 by Alistair Francis.
+ * The reference used is the STMicroElectronics UM2153 User manual
+ * Discovery kit for IoT node, multi-channel communication with STM32L4.
+ * https://www.st.com/en/evaluation-tools/b-l475e-iot01a.html#documentation
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-clock.h"
+#include "qemu/error-report.h"
+#include "hw/arm/stm32l4x5_soc.h"
+#include "hw/arm/boot.h"
+
+/* Main SYSCLK frequency in Hz (80MHz) */
+#define SYSCLK_FRQ 8000ULL
+
+static void b_l475e_iot01a_init(MachineState *machine)
+{
+const Stm32l4x5SocClass *sc;
+DeviceState *dev;
+Clock *sysclk;
+
+/* This clock doesn't need migration because it is fixed-frequency */
+sysclk = clock_new(OBJECT(machine), "SYSCLK");
+clock_set_hz(sysclk, SYSCLK_FRQ);
+
+dev = qdev_new(TYPE_STM32L4X5XG_SOC);
+sc = STM32L4X5_SOC_GET_CLASS(dev);
+qdev_connect_clock_in(dev, "sysclk", sysclk);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
+
+armv7m_load_kernel(ARM_CPU(first_cpu),
+   machine->kernel_filename,
+   0, sc->flash_size);
+}
+
+static void b_l475e_iot01a_machine_init(MachineClass *mc)
+{
+static const char *machine_valid_cpu_types[] = {
+ARM_CPU_TYPE_NAME("cortex-m4"),
+NULL};
+mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)";
+mc->init = b_l475e_iot01a_init;
+mc->valid_cpu_types = machine_valid_cpu_types;
+
+/* SRAM pre-allocated as part of the SoC instantiation */
+mc->default_ram_size = 0;
+}
+

[PATCH qemu 0/2] hw/arm: Add minimal support for the B-L475E-IOT01A board

2023-11-26 Thread ~inesvarhol
This patch allows to emulate the B-L475E-IOT01A ARM Cortex-M4 board.
It's a minimal version without any implemented peripherals yet.
We've corrected the patch according to the reviews of Philippe Mathieu-
Daudé (thank you !),
and additionally completed the MAINTAINERS file with the new devices.

I'm not sure whether it's alright to send this patch before peripherals
are implemented ?
If it's not, we'll resend the complete patch later on.

Reviewed-by: Philippe Mathieu-Daudé 

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 

Inès Varhol (2):
  hw/arm: Add minimal support for the STM32L4x5 SoC
  hw/arm: Add minimal support for the B-L475E-IOT01A board

 MAINTAINERS |  15 ++
 configs/devices/arm-softmmu/default.mak |   1 +
 hw/arm/Kconfig  |  11 +
 hw/arm/b-l475e-iot01a.c |  79 +++
 hw/arm/meson.build  |   2 +
 hw/arm/stm32l4x5_soc.c  | 277 
 include/hw/arm/stm32l4x5_soc.h  |  68 ++
 7 files changed, 453 insertions(+)
 create mode 100644 hw/arm/b-l475e-iot01a.c
 create mode 100644 hw/arm/stm32l4x5_soc.c
 create mode 100644 include/hw/arm/stm32l4x5_soc.h

-- 
2.38.5



Re: [PATCH-for-9.0 00/16] target/arm/kvm: Unify kvm_arm_FOO() API

2023-11-26 Thread Richard Henderson

On 11/23/23 12:35, Philippe Mathieu-Daudé wrote:

Half of the API takes CPUState, the other ARMCPU...

$ git grep -F 'CPUState *' target/arm/kvm_arm.h | wc -l
   16
$ git grep -F 'ARMCPU *' target/arm/kvm_arm.h | wc -l
   14

Since this is ARM specific, have it always take ARMCPU, and
call the generic KVM API casting with the CPU() macro.

Based-on: <20231123044219.896776-1-richard.hender...@linaro.org>
   "target/arm: kvm cleanups"
   
https://lore.kernel.org/qemu-devel/20231123044219.896776-1-richard.hender...@linaro.org/

Philippe Mathieu-Daudé (16):
   hw/intc/arm_gicv3: Include missing 'qemu/error-report.h' header
   target/arm/kvm: Remove unused includes
   target/arm/kvm: Have kvm_arm_add_vcpu_properties take a ARMCPU
 argument
   target/arm/kvm: Have kvm_arm_sve_set_vls take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_sve_get_vls take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_set_device_attr take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_pvtime_init take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_pmu_init take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_pmu_set_irq take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_vcpu_init take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_vcpu_finalize take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_[get|put]_virtual_time take ARMCPU
 argument
   target/arm/kvm: Have kvm_arm_verify_ext_dabt_pending take a ARMCPU arg
   target/arm/kvm: Have kvm_arm_handle_dabt_nisv take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_handle_debug take a ARMCPU argument
   target/arm/kvm: Have kvm_arm_hw_debug_active take a ARMCPU argument



Reviewed-by: Richard Henderson 


r~



pending hw/audio patches for 8.2

2023-11-26 Thread Volker Rümelin
Hi,

there are five pending reviewed hw/audio patches for 8.2. They are all
bug fixes. It would be good if someone could send a pull request for
rc2. I don't think Gerd will send it.

The five patches are:

("hw/audio/hda-codec: fix multiplication overflow")
https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg00828.html

("hw/audio/hda-codec: reenable the audio mixer")
https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg00827.html

("hw/audio/virtio-snd-pci: fix the PCI class code")
https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg02084.html

("virtio-snd: check AUD_register_card return value")
https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg02545.html

("virtio-sound: add realize() error cleanup path")
https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg03878.html

IIRC the last patch needs a rebase.

I omitted another reviewed patch, which is a variant of
("hw/audio/hda-codec: reenable the audio mixer").
("hw/audio: Fix logic error in hda audio")
https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg03951.html

I have a repository at https://gitlab.com/volker.ruemelin/qemu.git. The
five rebased patches are in the hw-audio-fixes-for-8.2 branch.

With best regards,
Volker




Re: [PATCH] qemu/timer: Don't use RDTSC on i486

2023-11-26 Thread Samuel Tardieu



Petr Cvek  writes:

Actually I was thinking about mentioning it in the commit 
message also, but I wasn't able

to find any specification for that (if all compilers use it).


Note that this change would be safe: at worst, some compilers 
don't use __tune_i386__ and the situation would be the same as 
today without the patch.


Other problem is the __tune_i386__ is also set when -mtune=i386 
(but with -march=i686).


Indeed, this is the case for GCC (not clang).

 Sam
--
Samuel Tardieu
Télécom Paris - Institut Polytechnique de Paris



Re: [PATCH] qemu/timer: Don't use RDTSC on i486

2023-11-26 Thread Petr Cvek
Actually I was thinking about mentioning it in the commit message also, but I 
wasn't able
to find any specification for that (if all compilers use it).

Other problem is the __tune_i386__ is also set when -mtune=i386 (but with 
-march=i686).

But if the general idea of changing the code for 486 is OK it can be added also.

Petr

Dne 26. 11. 23 v 13:37 Samuel Tardieu napsal(a):
> 
> Petr Cvek  writes:
> 
>> GCC defines __i386__ for i386 and i486, which both lack RDTSC instruction.
>> The i386 seems to be impossible to distinguish, but i486 can be identified
>> by checking for undefined __i486__.
> 
> Couldn't you check for an undefined __tune_i386__, which would be set by both 
> GCC and LLVM when using -march=i386.
> 
>  Sam



Re: [PATCH] qemu/timer: Don't use RDTSC on i486

2023-11-26 Thread Samuel Tardieu



Petr Cvek  writes:

GCC defines __i386__ for i386 and i486, which both lack RDTSC 
instruction.
The i386 seems to be impossible to distinguish, but i486 can be 
identified

by checking for undefined __i486__.


Couldn't you check for an undefined __tune_i386__, which would be 
set by both GCC and LLVM when using -march=i386.


 Sam
--
Samuel Tardieu
Télécom Paris - Institut Polytechnique de Paris



Re: [PATCH v2] linux-user/riscv: Add Zicboz extensions to hwprobe

2023-11-26 Thread Andrew Jones
On Fri, Nov 24, 2023 at 06:41:25PM +0100, Christoph Müllner wrote:
> On Fri, Nov 24, 2023 at 5:59 PM Andrew Jones  wrote:
> >
> > On Thu, Nov 23, 2023 at 07:12:59PM +0100, Christoph Muellner wrote:
> > > From: Christoph Müllner 
> > >
> > > Upstream Linux recently added RISC-V Zicboz support to the hwprobe API.
> > > This patch introduces this for QEMU's user space emulator.
> > >
> > > Signed-off-by: Christoph Müllner 
> > > ---
> > >  linux-user/syscall.c | 3 +++
> > >  1 file changed, 3 insertions(+)
> > >
> > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> > > index 65ac3ac796..2f9a1c5279 100644
> > > --- a/linux-user/syscall.c
> > > +++ b/linux-user/syscall.c
> > > @@ -8799,6 +8799,7 @@ static int do_getdents64(abi_long dirfd, abi_long 
> > > arg2, abi_long count)
> > >  #define RISCV_HWPROBE_EXT_ZBA  (1 << 3)
> > >  #define RISCV_HWPROBE_EXT_ZBB  (1 << 4)
> > >  #define RISCV_HWPROBE_EXT_ZBS  (1 << 5)
> > > +#define RISCV_HWPROBE_EXT_ZICBOZ   (1 << 6)
> > >
> > >  #define RISCV_HWPROBE_KEY_CPUPERF_0 5
> > >  #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
> > > @@ -8855,6 +8856,8 @@ static void risc_hwprobe_fill_pairs(CPURISCVState 
> > > *env,
> > >   RISCV_HWPROBE_EXT_ZBB : 0;
> > >  value |= cfg->ext_zbs ?
> > >   RISCV_HWPROBE_EXT_ZBS : 0;
> > > +value |= cfg->ext_zicboz ?
> > > + RISCV_HWPROBE_EXT_ZICBOZ : 0;
> > >  __put_user(value, >value);
> > >  break;
> > >  case RISCV_HWPROBE_KEY_CPUPERF_0:
> > > --
> > > 2.41.0
> > >
> > >
> >
> > We should also add support for getting the block size with
> > RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE.
> 
> Hi Andrew, this is already upstream, just the EXT_ZICBOZ is missing:

Oh, thanks. In that case,

Reviewed-by: Andrew Jones 

drew



Re: [PATCH v5 2/3] hw/ppc: Add nest1 chiplet model

2023-11-26 Thread Chalapathi V



On 24-11-2023 18:31, Nicholas Piggin wrote:

On Fri Nov 24, 2023 at 10:19 PM AEST, Cédric Le Goater wrote:

On 11/24/23 12:26, Nicholas Piggin wrote:

For this and actually the last patch too, it would be good to mention
(possibly in a header comment in the file too) what actual functionality
is being provided/modeled. It looks like it's just modeling behaviour of
reads and writes for some registers.

Oh, and sorry I didn't follow development and comments on this too
closely, so forgive me if I've missed things already said. I'll go
back and read through the series.

On Fri Nov 24, 2023 at 8:15 PM AEST, Chalapathi V wrote:

The nest1 chiplet handle the high speed i/o traffic over PCIe and others.
The nest1 chiplet consists of PowerBus Fabric controller,
nest Memory Management Unit, chiplet control unit and more.

This commit creates a nest1 chiplet model and initialize and realize the
pervasive chiplet model where chiplet control registers are implemented.

This commit also implement the read/write method for the powerbus scom
registers

The powerbus scom registers, are those specifically for the PowerBus
Fabric controller mentioned in the first paragraph, or is it a more
general set of registers for the chiplet?

Yes, They are for the PowerBus racetrack unit.

Signed-off-by: Chalapathi V 
---
   include/hw/ppc/pnv_nest_chiplet.h |  36 ++
   include/hw/ppc/pnv_xscom.h|   6 +
   hw/ppc/pnv_nest1_chiplet.c| 197 ++
   hw/ppc/meson.build|   1 +
   4 files changed, 240 insertions(+)
   create mode 100644 include/hw/ppc/pnv_nest_chiplet.h
   create mode 100644 hw/ppc/pnv_nest1_chiplet.c

diff --git a/include/hw/ppc/pnv_nest_chiplet.h 
b/include/hw/ppc/pnv_nest_chiplet.h
new file mode 100644
index 00..845030fb1a
--- /dev/null
+++ b/include/hw/ppc/pnv_nest_chiplet.h
@@ -0,0 +1,36 @@
+/*
+ * QEMU PowerPC nest chiplet model
+ *
+ * Copyright (c) 2023, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef PPC_PNV_NEST1_CHIPLET_H
+#define PPC_PNV_NEST1_CHIPLET_H
+
+#include "hw/ppc/pnv_pervasive.h"
+
+#define TYPE_PNV_NEST1 "pnv-nest1-chiplet"
+#define PNV_NEST1(obj) OBJECT_CHECK(PnvNest1, (obj), TYPE_PNV_NEST1)
+
+typedef struct pb_scom {
+uint64_t mode;
+uint64_t hp_mode2_curr;
+} pb_scom;
+
+typedef struct PnvNest1 {

Naming nitpicking again...

The main ifndef guard for header files should match the file name, so
the file should be called pnv_nest1_chiplet.h (and that matches the .c
file too).

I think this struct should be called Nest1Chiplet too.

I asked Chalapathi to do the exact opposit :)

Oops :)


I don't mind really, my argument was that most models represent HW logic
units or subunits of a bigger unit. I don't see the point in adding a
chip/chiplet suffix apart from PnvChip since it represents a socket or
processor.

You choose. I will keep quiet :)

Ah. I can see that side of it. And for many of the nest chiplets (MC,
PAU, PCI) that makes sense. For Nest0 and Nest1... it's a bit
overloaded. First of all, all the nest chiplets are "nest". Then
there is also some nest units inside the processor chiplets (L2, L3,
NCU are considered to be nest). And then the nest also has a Pervasive
Chiplet itself, and we also have these pervasive registers in each
chiplet, etc., etc.

So my worry is we'll run into confusion if we shorten names too much.

We can always rename things, so it won't be the end of the world, but
thinking about the pervasive chiplet, I think we can already see that
"PnvPervasive" would not be a good name for it.

The chiplets have short names actually if that would help. Nest 1 is
called N1, so we could call it PnvN1Chiplet. That seems the usual
way to refer to them in docs, so I think a better name.

Thanks,
Nick

Sure. Will rename this to PnvN1Chiplet.



Re: [PATCH v5 1/3] hw/ppc: Add pnv pervasive common chiplet units

2023-11-26 Thread Chalapathi V



On 24-11-2023 16:42, Nicholas Piggin wrote:

On Fri Nov 24, 2023 at 8:15 PM AEST, Chalapathi V wrote:

This part of the patchset creates a common pervasive chiplet model where it
houses the common units of a chiplets.

The chiplet control unit is common across chiplets and this commit implements
the pervasive chiplet model with chiplet control registers.

This might be reworded to be a bit clearer, could provide a bit of
background information too (in changelog or header comment):

  Status, configuration, and control of units in POWER chips is provided
  by the pervasive subsystem, which connects registers to the SCOM bus,
  which can be programmed by processor cores, other units on the chip,
  BMCs, or other POWER chips.

  A POWER10 chip is divided into logical pieces called chiplets. Chiplets
  are broadly divided into "core chiplets" (with the processor cores) and
  "nest chiplets" (with everything else). Each chiplet has an attachment
  to the pervasive bus (PIB) and with chiplet-specific registers. All nest
  chiplets have a common basic set of registers, which this model
  provides. They may also implement additional registers.

That's my undertsanding, does it look right? If yes and this file is
specifically for nest chiplets (not core), maybe the name should
reflect that?


Sure Will change the name to  PnvNestChipletPervasive and add some more 
details to header comment.


Thank You,

Chalapathi


Signed-off-by: Chalapathi V 
---
  include/hw/ppc/pnv_pervasive.h |  37 ++
  include/hw/ppc/pnv_xscom.h |   3 +
  hw/ppc/pnv_pervasive.c | 217 +
  hw/ppc/meson.build |   1 +
  4 files changed, 258 insertions(+)
  create mode 100644 include/hw/ppc/pnv_pervasive.h
  create mode 100644 hw/ppc/pnv_pervasive.c

diff --git a/include/hw/ppc/pnv_pervasive.h b/include/hw/ppc/pnv_pervasive.h
new file mode 100644
index 00..d83f86df7b
--- /dev/null
+++ b/include/hw/ppc/pnv_pervasive.h
@@ -0,0 +1,37 @@
+/*
+ * QEMU PowerPC pervasive common chiplet model
+ *
+ * Copyright (c) 2023, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#ifndef PPC_PNV_PERVASIVE_H
+#define PPC_PNV_PERVASIVE_H
+
+#define TYPE_PNV_PERV "pnv-pervasive-chiplet"
+#define PNV_PERV(obj) OBJECT_CHECK(PnvPerv, (obj), TYPE_PNV_PERV)
+
+typedef struct PnvPervCtrlRegs {
+#define CPLT_CTRL_SIZE 6
+uint64_t cplt_ctrl[CPLT_CTRL_SIZE];
+uint64_t cplt_cfg0;
+uint64_t cplt_cfg1;
+uint64_t cplt_stat0;
+uint64_t cplt_mask0;
+uint64_t ctrl_protect_mode;
+uint64_t ctrl_atomic_lock;
+} PnvPervCtrlRegs;
+
+typedef struct PnvPerv {

I don't want to bikeshed the name too much, but we have perv and
pervasive, I'd prefer to use pervasive consistently.

I would like the name to reflect that it is for common nest chiplet
registers too, but maybe that's getting too ambitious...

PnvNestChipletCommonRegs
PnvNestChipletPervasive

?

Sure Will modify to PnvNestChipletPervasive.



+DeviceState parent;
+char *parent_obj_name;
+MemoryRegion xscom_perv_ctrl_regs;
+PnvPervCtrlRegs control_regs;
+} PnvPerv;
+
+void pnv_perv_dt(PnvPerv *perv, uint32_t base_addr, void *fdt, int offset);
+#endif /*PPC_PNV_PERVASIVE_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index f5becbab41..d09d10f32b 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -170,6 +170,9 @@ struct PnvXScomInterfaceClass {
  #define PNV10_XSCOM_XIVE2_BASE 0x2010800
  #define PNV10_XSCOM_XIVE2_SIZE 0x400
  
+#define PNV10_XSCOM_NEST1_CTRL_CHIPLET_BASE  0x300

+#define PNV10_XSCOM_CTRL_CHIPLET_SIZE0x400
+
  #define PNV10_XSCOM_PEC_NEST_BASE  0x3011800 /* index goes downwards ... */
  #define PNV10_XSCOM_PEC_NEST_SIZE  0x100
  
diff --git a/hw/ppc/pnv_pervasive.c b/hw/ppc/pnv_pervasive.c

new file mode 100644
index 00..c925070798
--- /dev/null
+++ b/hw/ppc/pnv_pervasive.c
@@ -0,0 +1,217 @@
+/*
+ * QEMU PowerPC pervasive common chiplet model
+ *
+ * Copyright (c) 2023, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/pnv_pervasive.h"
+#include "hw/ppc/fdt.h"
+#include 
+
+#define CPLT_CONF0   0x08
+#define CPLT_CONF0_OR0x18
+#define CPLT_CONF0_CLEAR 0x28
+#define CPLT_CONF1   0x09
+#define CPLT_CONF1_OR0x19
+#define CPLT_CONF1_CLEAR 0x29
+#define CPLT_STAT0   0x100
+#define CPLT_MASK0   0x101
+#define CPLT_PROTECT_MODE0x3FE
+#define CPLT_ATOMIC_CLOCK0x3FF
+
+static uint64_t