Re: [PATCH v5] arm/kvm: Enable support for KVM_ARM_VCPU_PMU_V3_FILTER

2024-01-25 Thread Shaoqin Huang

Hi Eric,

On 1/17/24 20:59, Eric Auger wrote:

Hi  Shaoqin,

On 1/15/24 09:01, Shaoqin Huang wrote:

The KVM_ARM_VCPU_PMU_V3_FILTER provides the ability to let the VMM decide
which PMU events are provided to the guest. Add a new option
`kvm-pmu-filter` as -cpu sub-option to set the PMU Event Filtering.
Without the filter, all PMU events are exposed from host to guest by
default. The usage of the new sub-option can be found from the updated
document (docs/system/arm/cpu-features.rst).


do not hesitate to cc qemu-...@nongnu.org for ARM specific topics.



Here is an example shows how to use the PMU Event Filtering, when

which shows

we launch a guest by use kvm, add such command line:

   # qemu-system-aarch64 \
 -accel kvm \
 -cpu host,kvm-pmu-filter="D:0x11-0x11"

Since the first action is deny, we have a global allow policy. This
disables the filtering of the cycle counter (event 0x11 being CPU_CYCLES).

Actually it filters it ;-) It would rather say this filters out the
cycle counter. But I am not a native speaker either ;-)


And then in guest, use the perf to count the cycle:

   # perf stat sleep 1

Performance counter stats for 'sleep 1':

   1.22 msec task-clock   #0.001 CPUs 
utilized
  1  context-switches #  820.695 /sec
  0  cpu-migrations   #0.000 /sec
 55  page-faults  #   45.138 K/sec
  cycles
1128954  instructions
 227031  branches #  186.323 M/sec
   8686  branch-misses#3.83% of all 
branches

1.002492480 seconds time elapsed

0.001752000 seconds user
0.0 seconds sys

As we can see, the cycle counter has been disabled in the guest, but
other pmu events are still work.

do still work


Signed-off-by: Shaoqin Huang 
---
v4->v5:
   - Change the kvm-pmu-filter as a -cpu sub-option. [Eric]
   - Comment tweak.  [Gavin]
   - Rebase to the latest branch.

v3->v4:
   - Fix the wrong check for pmu_filter_init.[Sebastian]
   - Fix multiple alignment issue.   [Gavin]
   - Report error by warn_report() instead of error_report(), and don't use
   abort() since the PMU Event Filter is an add-on and best-effort feature.
 [Gavin]
   - Add several missing {  } for single line of code.   [Gavin]
   - Use the g_strsplit() to replace strtok().   [Gavin]

v2->v3:
   - Improve commits message, use kernel doc wording, add more explaination on
 filter example, fix some typo error.[Eric]
   - Add g_free() in kvm_arch_set_pmu_filter() to prevent memory leak. [Eric]
   - Add more precise error message report.  [Eric]
   - In options doc, add pmu-filter rely on KVM_ARM_VCPU_PMU_V3_FILTER support 
in
 KVM.[Eric]

v1->v2:
   - Add more description for allow and deny meaning in
 commit message. [Sebastian]
   - Small improvement.  [Sebastian]

  docs/system/arm/cpu-features.rst | 23 ++
  include/sysemu/kvm_int.h |  1 +
  target/arm/cpu.h |  3 ++
  target/arm/kvm.c | 78 
  4 files changed, 105 insertions(+)

diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index a5fb929243..44a797c50e 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -204,6 +204,29 @@ the list of KVM VCPU features and their descriptions.
the guest scheduler behavior and/or be exposed to the guest
userspace.
  
+``kvm-pmu-filter``

+  By default kvm-pmu-filter is disabled. This means that by default all pmu
+  events will be exposed to guest.
+
+  KVM implements PMU Event Filtering to prevent a guest from being able to
+  sample certain events. It depends on the KVM_ARM_VCPU_PMU_V3_FILTER
+  attribute supported in KVM. It has the following format:
+
+  kvm-pmu-filter="{A,D}:start-end[;{A,D}:start-end...]"
+
+  The A means "allow" and D means "deny", start is the first event of the
+  range and the end is the last one. The first registered range defines
+  the global policy(global ALLOW if the first @action is DENY, global DENY
+  if the first @action is ALLOW). The start and end only support hexadecimal
+  format now. For example:
+
+  kvm-pmu-filter="A:0x11-0x11;A:0x23-0x3a;D:0x30-0x30"
+
+  Since the first action is allow, we have a global deny policy. It
+  will allow event 0x11 (The cycle counter), events 0x23 to 0x3a is

s/is/are

+  also allowed except the event 0x30 is denied, and all the other events

0x30 is/0x30 which is

+  are disallowed.

s/disallowed/denied just to match the above terminology.

+
 

Re: [PATCH v7 9/9] ppc/pnv: Test pnv i2c master and connected devices

2024-01-25 Thread Cédric Le Goater

On 1/25/24 23:48, Glenn Miles wrote:

Tests the following for both P9 and P10:
   - I2C master POR status
   - I2C master status after immediate reset

Tests the following for powernv10-ranier only:
   - Config pca9552 hotplug device pins as inputs then
 Read the INPUT0/1 registers to verify all pins are high
   - Connected GPIO pin tests of P10 PCA9552 device.  Tests
 output of pins 0-4 affect input of pins 5-9 respectively.
   - PCA9554 GPIO pins test.  Tests input and ouput functionality.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
---

Changes from previous version:
   - Moved PNV I2C register definitions from pnv-host-i2c-test.c and
 pnv_i2c.c into pnv_i2c_regs.h.
   - Moved PNV XSCOM definitions from pnv-host-i2c-test.c and
 pnv-xscom-test.c into pnv-xscom.h.
   - Renamed pnv_i2c_dev_t to PnvI2cDev.
   - Added PnvI2cCtlr structure for conveniece in passing parameters.


LGTM. Thanks for doing the proposed changes.

If you add more tests in the future, you could consider splitting "host-i2c"
in subtests. No need to resend for that.

C.




  hw/ppc/pnv_i2c.c| 131 +
  include/hw/i2c/pnv_i2c_regs.h   | 143 ++
  tests/qtest/meson.build |   1 +
  tests/qtest/pnv-host-i2c-test.c | 491 
  tests/qtest/pnv-xscom-test.c|  61 +---
  tests/qtest/pnv-xscom.h |  80 ++
  6 files changed, 717 insertions(+), 190 deletions(-)
  create mode 100644 include/hw/i2c/pnv_i2c_regs.h
  create mode 100644 tests/qtest/pnv-host-i2c-test.c
  create mode 100644 tests/qtest/pnv-xscom.h

diff --git a/hw/ppc/pnv_i2c.c b/hw/ppc/pnv_i2c.c
index 774946d6b2..4581cc5e5d 100644
--- a/hw/ppc/pnv_i2c.c
+++ b/hw/ppc/pnv_i2c.c
@@ -22,136 +22,7 @@
  
  #include 
  
-/* I2C FIFO register */

-#define I2C_FIFO_REG0x4
-#define I2C_FIFOPPC_BITMASK(0, 7)
-
-/* I2C command register */
-#define I2C_CMD_REG 0x5
-#define I2C_CMD_WITH_START  PPC_BIT(0)
-#define I2C_CMD_WITH_ADDR   PPC_BIT(1)
-#define I2C_CMD_READ_CONT   PPC_BIT(2)
-#define I2C_CMD_WITH_STOP   PPC_BIT(3)
-#define I2C_CMD_INTR_STEERING   PPC_BITMASK(6, 7) /* P9 */
-#define   I2C_CMD_INTR_STEER_HOST   1
-#define   I2C_CMD_INTR_STEER_OCC2
-#define I2C_CMD_DEV_ADDRPPC_BITMASK(8, 14)
-#define I2C_CMD_READ_NOT_WRITE  PPC_BIT(15)
-#define I2C_CMD_LEN_BYTES   PPC_BITMASK(16, 31)
-#define I2C_MAX_TFR_LEN 0xfff0ull
-
-/* I2C mode register */
-#define I2C_MODE_REG0x6
-#define I2C_MODE_BIT_RATE_DIV   PPC_BITMASK(0, 15)
-#define I2C_MODE_PORT_NUM   PPC_BITMASK(16, 21)
-#define I2C_MODE_ENHANCED   PPC_BIT(28)
-#define I2C_MODE_DIAGNOSTIC PPC_BIT(29)
-#define I2C_MODE_PACING_ALLOW   PPC_BIT(30)
-#define I2C_MODE_WRAP   PPC_BIT(31)
-
-/* I2C watermark register */
-#define I2C_WATERMARK_REG   0x7
-#define I2C_WATERMARK_HIGH  PPC_BITMASK(16, 19)
-#define I2C_WATERMARK_LOW   PPC_BITMASK(24, 27)
-
-/*
- * I2C interrupt mask and condition registers
- *
- * NB: The function of 0x9 and 0xa changes depending on whether you're reading
- * or writing to them. When read they return the interrupt condition bits
- * and on writes they update the interrupt mask register.
- *
- *  The bit definitions are the same for all the interrupt registers.
- */
-#define I2C_INTR_MASK_REG   0x8
-
-#define I2C_INTR_RAW_COND_REG   0x9 /* read */
-#define I2C_INTR_MASK_OR_REG0x9 /* write*/
-
-#define I2C_INTR_COND_REG   0xa /* read */
-#define I2C_INTR_MASK_AND_REG   0xa /* write */
-
-#define I2C_INTR_ALLPPC_BITMASK(16, 31)
-#define I2C_INTR_INVALID_CMDPPC_BIT(16)
-#define I2C_INTR_LBUS_PARITY_ERRPPC_BIT(17)
-#define I2C_INTR_BKEND_OVERRUN_ERR  PPC_BIT(18)
-#define I2C_INTR_BKEND_ACCESS_ERR   PPC_BIT(19)
-#define I2C_INTR_ARBT_LOST_ERR  PPC_BIT(20)
-#define I2C_INTR_NACK_RCVD_ERR  PPC_BIT(21)
-#define I2C_INTR_DATA_REQ   PPC_BIT(22)
-#define I2C_INTR_CMD_COMP   PPC_BIT(23)
-#define I2C_INTR_STOP_ERR   PPC_BIT(24)
-#define I2C_INTR_I2C_BUSY   PPC_BIT(25)
-#define I2C_INTR_NOT_I2C_BUSY   PPC_BIT(26)
-#define I2C_INTR_SCL_EQ_1   PPC_BIT(28)
-#define I2C_INTR_SCL_EQ_0   PPC_BIT(29)
-#define I2C_INTR_SDA_EQ_1   PPC_BIT(30)
-#define I2C_INTR_SDA_EQ_0   PPC_BIT(31)
-
-/* I2C status register */
-#define I2C_RESET_I2C_REG   0xb /* write */
-#define I2C_RESET_ERRORS0xc
-#define I2C_STAT_REG0xb /* read */
-#define I2C_STAT_INVALID_CMDPPC_BIT(0)
-#define I2C_STAT_LBUS_PARITY_ERRPPC_BIT(1)
-#define I2C_STAT_BKEND_OVERRUN_ERR  

Re: [PATCH trivial 1/2] close_all_open_fd(): move to oslib-posix.c

2024-01-25 Thread Laurent Vivier

Le 25/01/2024 à 23:29, Michael Tokarev a écrit :

Initially in async-teardown.c, but the same construct is used
elsewhere too.

Signed-off-by: Michael Tokarev 
---
  include/sysemu/os-posix.h |  1 +
  system/async-teardown.c   | 37 +
  util/oslib-posix.c| 36 
  3 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index dff32ae185..4c91d03f44 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -53,6 +53,7 @@ bool os_set_runas(const char *user_id);
  void os_set_chroot(const char *path);
  void os_setup_post(void);
  int os_mlock(void);
+void os_close_all_open_fd(int minfd);
  
  /**

   * qemu_alloc_stack:
diff --git a/system/async-teardown.c b/system/async-teardown.c
index 396963c091..41d3d94935 100644
--- a/system/async-teardown.c
+++ b/system/async-teardown.c
@@ -26,40 +26,6 @@
  
  static pid_t the_ppid;
  
-/*

- * Close all open file descriptors.
- */
-static void close_all_open_fd(void)
-{
-struct dirent *de;
-int fd, dfd;
-DIR *dir;
-
-#ifdef CONFIG_CLOSE_RANGE
-int r = close_range(0, ~0U, 0);
-if (!r) {
-/* Success, no need to try other ways. */
-return;
-}
-#endif
-
-dir = opendir("/proc/self/fd");
-if (!dir) {
-/* If /proc is not mounted, there is nothing that can be done. */
-return;
-}
-/* Avoid closing the directory. */
-dfd = dirfd(dir);
-
-for (de = readdir(dir); de; de = readdir(dir)) {
-fd = atoi(de->d_name);
-if (fd != dfd) {
-close(fd);
-}
-}
-closedir(dir);
-}
-
  static void hup_handler(int signal)
  {
  /* Check every second if this process has been reparented. */
@@ -85,9 +51,8 @@ static int async_teardown_fn(void *arg)
  /*
   * Close all file descriptors that might have been inherited from the
   * main qemu process when doing clone, needed to make libvirt happy.
- * Not using close_range for increased compatibility with older kernels.
   */
-close_all_open_fd();
+os_close_all_open_fd(0);
  
  /* Set up a handler for SIGHUP and unblock SIGHUP. */

  sigaction(SIGHUP, , NULL);
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 7c297003b9..09d0ce4da6 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -27,6 +27,7 @@
   */
  
  #include "qemu/osdep.h"

+#include 
  #include 
  
  #include 

@@ -106,6 +107,41 @@ int qemu_get_thread_id(void)
  #endif
  }
  
+/*

+ * Close all open file descriptors starting with minfd and up.
+ * Not using close_range for increased compatibility with older kernels.
+ */
+void os_close_all_open_fd(int minfd)
+{
+struct dirent *de;
+int fd, dfd;
+DIR *dir;
+
+#ifdef CONFIG_CLOSE_RANGE
+int r = close_range(minfd, ~0U, 0);
+if (!r) {
+/* Success, no need to try other ways. */
+return;
+}
+#endif
+
+dir = opendir("/proc/self/fd");
+if (!dir) {
+/* If /proc is not mounted, there is nothing that can be done. */
+return;
+}
+/* Avoid closing the directory. */
+dfd = dirfd(dir);
+
+for (de = readdir(dir); de; de = readdir(dir)) {
+fd = atoi(de->d_name);
+if (fd >= minfd && fd != dfd) {
+close(fd);
+}
+}
+closedir(dir);
+}


I think the way using sysconf(_SC_OPEN_MAX) is more portable, simpler and cleaner than the one using 
/proc/self/fd.


Thanks,
Laurent

+
  int qemu_daemon(int nochdir, int noclose)
  {
  return daemon(nochdir, noclose);





RE: [PATCH v1 1/7] ui/spice: Add an option for users to provide a preferred codec

2024-01-25 Thread Kasireddy, Vivek
Hi Marc-Andre,

> 
> Hi
> 
> On Sat, Jan 20, 2024 at 4:54 AM Vivek Kasireddy
>  wrote:
> >
> > Giving users an option to choose a particular codec will enable
> > them to make an appropriate decision based on their hardware and
> > use-case.
> >
> > Cc: Gerd Hoffmann 
> > Cc: Marc-André Lureau 
> > Cc: Frediano Ziglio 
> > Cc: Dongwon Kim 
> > Signed-off-by: Vivek Kasireddy 
> >
> > ---
> > v2:
> > - Don't override the default Spice codec if preferred-codec is not
> >   provided (Frediano)
> > ---
> >  qemu-options.hx |  5 +
> >  ui/spice-core.c | 12 
> >  2 files changed, 17 insertions(+)
> >
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index b66570ae00..caaafe01d5 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -2260,6 +2260,7 @@ DEF("spice", HAS_ARG, QEMU_OPTION_spice,
> >  "   
> > [,streaming-video=[off|all|filter]][,disable-copy-paste=on|off]\n"
> >  "   [,disable-agent-file-xfer=on|off][,agent-mouse=[on|off]]\n"
> >  "   [,playback-compression=[on|off]][,seamless-
> migration=[on|off]]\n"
> > +"   [,preferred-codec=:\n"
> 
> The SPICE API is "spice_server_set_video_codecs()", let's name the
> option: "video-codecs" to avoid confusions.
I am ok with "video-codes" instead of "preferred-codec".

> 
> >  "   [,gl=[on|off]][,rendernode=]\n"
> >  "enable spice\n"
> >  "at least one of {port, tls-port} is mandatory\n",
> > @@ -2348,6 +2349,10 @@ SRST
> >  ``seamless-migration=[on|off]``
> >  Enable/disable spice seamless migration. Default is off.
> >
> > +``preferred-codec=:``
> > +Provide the preferred codec the Spice server should use.
> > +Default would be spice:mjpeg.
> 
> The SPICE API says:
>  * @codecs: a codec string in the following format:
> encoder:codec;encoder:codec
> 
> But the doc doesn't say whether the order is important, and doesn't
> give more details on the "encoder:codec" format.
> 
> Also reading the code, it seems "auto" has a special meaning for
> default video codecs.
Although, I am using spice_server_set_video_codecs() API, my initial goal
with this option is for the user to specify one : entry
only. I guess it might be OK to have the user specify a list as long as Spice 
picks
the first entry (aka preferred) and falls back to the next if it cannot create 
or
use the encoder associated with the first entry.

> 
> > +
> >  ``gl=[on|off]``
> >  Enable/disable OpenGL context. Default is off.
> >
> > diff --git a/ui/spice-core.c b/ui/spice-core.c
> > index db21db2c94..13bfbe4e89 100644
> > --- a/ui/spice-core.c
> > +++ b/ui/spice-core.c
> > @@ -488,6 +488,9 @@ static QemuOptsList qemu_spice_opts = {
> >  },{
> >  .name = "streaming-video",
> >  .type = QEMU_OPT_STRING,
> > +},{
> > +.name = "preferred-codec",
> > +.type = QEMU_OPT_STRING,
> >  },{
> >  .name = "agent-mouse",
> >  .type = QEMU_OPT_BOOL,
> > @@ -663,6 +666,7 @@ static void qemu_spice_init(void)
> >  char *x509_key_file = NULL,
> >  *x509_cert_file = NULL,
> >  *x509_cacert_file = NULL;
> > +const char *preferred_codec = NULL;
> >  int port, tls_port, addr_flags;
> >  spice_image_compression_t compression;
> >  spice_wan_compression_t wan_compr;
> > @@ -802,6 +806,14 @@ static void qemu_spice_init(void)
> >  spice_server_set_streaming_video(spice_server,
> SPICE_STREAM_VIDEO_OFF);
> >  }
> >
> > +preferred_codec = qemu_opt_get(opts, "preferred-codec");
> > +if (preferred_codec) {
> > +if (spice_server_set_video_codecs(spice_server, preferred_codec)) {
> 
> Sadly, the API just returns 0 if one of the codec was accepted, not
> great if you want a specific set of codecs.
IIUC, although a user can specify a set of codecs, only one can by actively 
used at
any given time (at-least with Gstreamer ones, not Spice codecs) with my 
use-case (gl=on).

Thanks,
Vivek

> 
> otherwise, lgtm
> 
> 
> > +error_report("Preferred codec name is not valid");
> > +exit(1);
> > +}
> > +}
> > +
> >  spice_server_set_agent_mouse
> >  (spice_server, qemu_opt_get_bool(opts, "agent-mouse", 1));
> >  spice_server_set_playback_compression
> > --
> > 2.39.2
> >
> >
> 
> 
> --
> Marc-André Lureau


RE: [PATCH v1 3/7] ui/spice: Submit the gl_draw requests at 60 FPS for remote clients

2024-01-25 Thread Kasireddy, Vivek
Hi Marc-Andre,

> 
> Hi
> 
> On Sat, Jan 20, 2024 at 4:54 AM Vivek Kasireddy
>  wrote:
> >
> > In the specific case where the display layer (virtio-gpu) is using
> > dmabuf, and if remote clients are enabled (-spice gl=on,port=),
> > it makes sense to limit the maximum (streaming) rate to 60 FPS
> > using the GUI timer. This matches the behavior of GTK UI where the
> > display updates are submitted at 60 FPS (assuming the underlying
> > mode is WxY@60).
> 
> One of the issues with this approach is that the DMABUF isn't owned by
> the consumer. By delaying the usage of it, we risk having
> damaged/invalid updates.
This patch is only relevant with blob=true option. And, in this case, the
Guest (virtio-gpu kernel driver) is blocked (on a fence) until the Host
has consumed the buffer, which in this case happens after the encoder
signals the async to indicate that encoding is completed. Therefore,
AFAIU, there is no risk of missing or invalid updates. Ideally, the rate
should be driven by the consumer which in this case is the Spice client,
and given that it doesn't make sense to submit new frames faster than
the refresh rate, I figured it is ok to limit the producer to 60 FPS as well.
Note that Spice also does rate limiting based on network latencies and
dropped frames.


> 
> It would be great if we could have a mechanism for double/triple
> buffering with virtio-gpu, as far as I know this is not possible yet.
Given that virtio-gpu is a drm/kms driver, there can only be one buffer
in flight at any given time. And, it doesn't make sense to submit frames
faster than the refresh rate as they would simply get dropped. However,
I tried to address this issue few years ago but it did not go anywhere:
https://lore.kernel.org/all/20211014124402.46f95ebc@eldfell/T/

> 
> I wonder if setting dpy_set_ui_info() with the fixed refresh_rate is
> enough for the guest to have a fixed FPS.
I am not sure. Let me try to experiment with it and see how things work.

Thanks,
Vivek
> It will only work with gfx hw that support ui_info() though.
> 
> 
> 
> >
> > Cc: Gerd Hoffmann 
> > Cc: Marc-André Lureau 
> > Cc: Frediano Ziglio 
> > Cc: Dongwon Kim 
> > Signed-off-by: Vivek Kasireddy 
> > ---
> >  ui/spice-display.c | 38 --
> >  1 file changed, 28 insertions(+), 10 deletions(-)
> >
> > diff --git a/ui/spice-display.c b/ui/spice-display.c
> > index 384b8508d4..90c04623ec 100644
> > --- a/ui/spice-display.c
> > +++ b/ui/spice-display.c
> > @@ -841,12 +841,31 @@ static void qemu_spice_gl_block_timer(void
> *opaque)
> >  warn_report("spice: no gl-draw-done within one second");
> >  }
> >
> > +static void spice_gl_draw(SimpleSpiceDisplay *ssd,
> > +   uint32_t x, uint32_t y, uint32_t w, uint32_t h)
> > +{
> > +uint64_t cookie;
> > +
> > +cookie =
> (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
> > +spice_qxl_gl_draw_async(>qxl, x, y, w, h, cookie);
> > +}
> > +
> >  static void spice_gl_refresh(DisplayChangeListener *dcl)
> >  {
> >  SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> > -uint64_t cookie;
> > +QemuDmaBuf *dmabuf = ssd->guest_dmabuf;
> >
> > -if (!ssd->ds || qemu_console_is_gl_blocked(ssd->dcl.con)) {
> > +if (!ssd->ds) {
> > +return;
> > +}
> > +
> > +if (qemu_console_is_gl_blocked(ssd->dcl.con)) {
> > +if (remote_client && ssd->gl_updates && dmabuf) {
> > +spice_gl_draw(ssd, 0, 0, dmabuf->width, dmabuf->height);
> > +ssd->gl_updates = 0;
> > +/* To stream at 60 FPS, the (GUI) timer delay needs to be ~17 
> > ms */
> > +dcl->update_interval = 1000 / (2 *
> GUI_REFRESH_INTERVAL_DEFAULT) + 1;
> > +}
> >  return;
> >  }
> >
> > @@ -854,11 +873,8 @@ static void spice_gl_refresh(DisplayChangeListener
> *dcl)
> >  if (ssd->gl_updates && ssd->have_surface) {
> >  qemu_spice_gl_block(ssd, true);
> >  glFlush();
> > -cookie =
> (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
> > -spice_qxl_gl_draw_async(>qxl, 0, 0,
> > -surface_width(ssd->ds),
> > -surface_height(ssd->ds),
> > -cookie);
> > +spice_gl_draw(ssd, 0, 0,
> > +  surface_width(ssd->ds), surface_height(ssd->ds));
> >  ssd->gl_updates = 0;
> >  }
> >  }
> > @@ -1025,7 +1041,6 @@ static void
> qemu_spice_gl_update(DisplayChangeListener *dcl,
> >  EGLint stride = 0, fourcc = 0;
> >  bool render_cursor = false;
> >  bool y_0_top = false; /* FIXME */
> > -uint64_t cookie;
> >  int fd;
> >
> >  if (!ssd->have_scanout) {
> > @@ -1098,8 +1113,11 @@ static void
> qemu_spice_gl_update(DisplayChangeListener *dcl,
> >  trace_qemu_spice_gl_update(ssd->qxl.id, w, h, x, y);
> >  qemu_spice_gl_block(ssd, true);
> >  glFlush();
> > -cookie =
> 

RE: [PATCH v1 2/7] ui/spice: Enable gl=on option for non-local or remote clients

2024-01-25 Thread Kasireddy, Vivek
Hi Marc-Andre,

> 
> Hi
> 
> On Sat, Jan 20, 2024 at 4:54 AM Vivek Kasireddy
>  wrote:
> >
> > Newer versions of Spice server should be able to accept dmabuf
> > fds from Qemu for clients that are connected via the network.
> > In other words, when this option is enabled, Qemu would share
> > a dmabuf fd with Spice which would encode and send the data
> > associated with the fd to a client that could be located on
> > a different machine.
> >
> > Cc: Gerd Hoffmann 
> > Cc: Marc-André Lureau 
> > Cc: Frediano Ziglio 
> > Cc: Dongwon Kim 
> > Signed-off-by: Vivek Kasireddy 
> > ---
> >  include/ui/spice-display.h | 1 +
> >  ui/spice-core.c| 4 
> >  ui/spice-display.c | 1 +
> >  3 files changed, 6 insertions(+)
> >
> > diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
> > index e1a9b36185..f4922dd74b 100644
> > --- a/include/ui/spice-display.h
> > +++ b/include/ui/spice-display.h
> > @@ -151,6 +151,7 @@ struct SimpleSpiceCursor {
> >  };
> >
> >  extern bool spice_opengl;
> > +extern bool remote_client;
> >
> >  int qemu_spice_rect_is_empty(const QXLRect* r);
> >  void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
> > diff --git a/ui/spice-core.c b/ui/spice-core.c
> > index 13bfbe4e89..3b9a54685f 100644
> > --- a/ui/spice-core.c
> > +++ b/ui/spice-core.c
> > @@ -849,9 +849,13 @@ static void qemu_spice_init(void)
> >  #ifdef HAVE_SPICE_GL
> >  if (qemu_opt_get_bool(opts, "gl", 0)) {
> >  if ((port != 0) || (tls_port != 0)) {
> > +#if SPICE_SERVER_VERSION >= 0x000f03 /* release 0.15.3 */
> 
> (ok, we should wait for the Spice series to be merged)
Sure, I'll post the v2 after the Spice series gets merged.

Thanks,
Vivek

> 
> 
> > +remote_client = 1;
> > +#else
> >  error_report("SPICE GL support is local-only for now and "
> >   "incompatible with -spice port/tls-port");
> >  exit(1);
> > +#endif
> >  }
> >  egl_init(qemu_opt_get(opts, "rendernode"), DISPLAYGL_MODE_ON,
> _fatal);
> >  spice_opengl = 1;
> > diff --git a/ui/spice-display.c b/ui/spice-display.c
> > index 6eb98a5a5c..384b8508d4 100644
> > --- a/ui/spice-display.c
> > +++ b/ui/spice-display.c
> > @@ -29,6 +29,7 @@
> >  #include "ui/spice-display.h"
> >
> >  bool spice_opengl;
> > +bool remote_client;
> >
> >  int qemu_spice_rect_is_empty(const QXLRect* r)
> >  {
> > --
> > 2.39.2
> >
> >
> 
> 
> --
> Marc-André Lureau


RE: [PATCH v1 7/7] ui/spice: Create another texture with linear layout when gl=on is enabled

2024-01-25 Thread Kasireddy, Vivek
Hi Marc-Andre,

> 
> Hi
> 
> On Sat, Jan 20, 2024 at 4:54 AM Vivek Kasireddy
>  wrote:
> >
> > Since most encoders (invoked by Spice) may not work with tiled memory
> > associated with a texture, we need to create another texture that has
> > linear memory layout and use that instead.
> >
> > Note that, there does not seem to be a direct way to indicate to the
> > GL implementation that a texture's backing memory needs to be linear.
> > Instead, we have to do it in a roundabout way where we first need to
> > create a tiled texture and obtain a dmabuf fd associated with it via
> > EGL. Next, we have to create a memory object by importing the dmabuf
> > fd created earlier and finally create a linear texture by using the
> > memory object as the texture storage mechanism.
> >
> > Cc: Gerd Hoffmann 
> > Cc: Marc-André Lureau 
> > Cc: Frediano Ziglio 
> > Cc: Dongwon Kim 
> > Signed-off-by: Vivek Kasireddy 
> > ---
> >  ui/spice-display.c | 33 +
> >  1 file changed, 33 insertions(+)
> >
> > diff --git a/ui/spice-display.c b/ui/spice-display.c
> > index 08b4aec921..94cb378dbe 100644
> > --- a/ui/spice-display.c
> > +++ b/ui/spice-display.c
> > @@ -893,6 +893,7 @@ static void spice_gl_switch(DisplayChangeListener
> *dcl,
> >  {
> >  SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> >  EGLint stride, fourcc;
> > +GLuint texture = 0;
> >  int fd;
> >
> >  if (ssd->ds) {
> > @@ -912,6 +913,38 @@ static void spice_gl_switch(DisplayChangeListener
> *dcl,
> >  return;
> >  }
> >
> > +if (remote_client && surface_format(ssd->ds) != PIXMAN_r5g6b5) {
> 
> hmm
> 
> > +/*
> > + * We really want to ensure that the memory layout of the 
> > texture
> > + * is linear; otherwise, the encoder's output may show 
> > corruption.
> > + */
> > +surface_gl_create_texture_from_fd(ssd->ds, fd, );
> 
> What if the encoder actually supports tiled layout?
Right, that would be true in most cases as the Render and Encode hardware are
mostly compatible. And, my patches are not required in this case if Spice 
chooses
a hardware encoder. However, the choice of which encoder to use (hardware vs
software) is decided dynamically and is internal to Spice at this point. And, 
since
there is no easy way to know from Qemu whether an encoder chosen by Spice
would support any given tiling format, I chose to always use linear layout 
since it
is guaranteed to work with all types of encoders.

> 
> Shouldn't this conversion be done at the encoder level as necessary?
Yeah, that is probably the right place but a software encoder like x264enc is 
not
going to know how to do the conversion from various tiled formats. This is the
specific case I am trying to address given that it is not a problem with 
hardware
encoders. I guess we could add a Qemu ui/spice option to tweak this behavior
while launching the VM.

> 
> It's also strange to reuse an FD associated with a tiled texture for a
> linear layout (I am uncomfortable with all this tbh)
I have looked around but there doesn't seem to be a way for requesting the GL
implementation to create a texture with linear layout other than via importing
memory objects. As noted in the comments below, the fd's ownership is taken
over by the GL implementation as part of the import. 

Also, I have started a conversation to figure out if there is any other way to
create linear textures more efficiently:
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27067

> 
> > +
> > +/*
> > + * A successful return after glImportMemoryFdEXT() means that
> > + * the ownership of fd has been passed to GL. In other words,
> > + * the fd we got above should not be used anymore.
> > + */
> > +if (texture > 0) {
> > +fd = egl_get_fd_for_texture(texture,
> > +, ,
> > +NULL);
> > +if (fd < 0) {
> 
> I suggest adding warnings or tracing, to help debug issues...
Sure, will do that in v2.

> 
> > +glDeleteTextures(1, );
> > +fd = egl_get_fd_for_texture(ssd->ds->texture,
> > +, ,
> > +NULL);
> > +if (fd < 0) {
> > +surface_gl_destroy_texture(ssd->gls, ssd->ds);
> > +return;
> > +}
> > +} else {
> > +surface_gl_destroy_texture(ssd->gls, ssd->ds);
> > +ssd->ds->texture = texture;
> 
> Have you tried this series with virgl? (I doubt the renderer accepts
> that the scanout texture is changed)
I have tried with virgl enabled and it mostly works because my patches
don't affect virgl codepaths such as 

Re: [PATCH] vfio/pci: Clear MSI-X IRQ index always

2024-01-25 Thread Cédric Le Goater

On 1/25/24 15:42, Cédric Le Goater wrote:

When doing device assignment of a physical device, MSI-X can be
enabled with no vectors enabled and this sets the IRQ index to
VFIO_PCI_MSIX_IRQ_INDEX. However, when MSI-X is disabled, the IRQ
index is left untouched if no vectors are in use. Then, when INTx
is enabled, the IRQ index value is considered incompatible (set to
MSI-X) and VFIO_DEVICE_SET_IRQS fails. QEMU complains with :

qemu-system-x86_64: vfio :08:00.0: Failed to set up TRIGGER eventfd 
signaling for interrupt INTX-0: VFIO_DEVICE_SET_IRQS failure: Invalid argument

To avoid that, unconditionaly clear the IRQ index when MSI-X is
disabled.



Applied to vfio-next.

Thanks,

C.







[PULL 5/8] docs/interop/bitmaps: Clean up a reference to qemu-qmp-ref

2024-01-25 Thread Markus Armbruster
docs/interop/bitmaps.rst uses references like

`qemu-qmp-ref `_
`query-block `_

to refer to and into docs/interop/qemu-qmp-ref.rst.

Clean up the former: use :doc:`qemu-qmp-ref`.

I don't know how to clean up the latter.

Signed-off-by: Markus Armbruster 
Message-ID: <20240120095327.666239-5-arm...@redhat.com>
Reviewed-by: Eric Blake 
---
 docs/interop/bitmaps.rst | 4 ++--
 qapi/introspect.json | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/docs/interop/bitmaps.rst b/docs/interop/bitmaps.rst
index c731be2f01..ddf8947d54 100644
--- a/docs/interop/bitmaps.rst
+++ b/docs/interop/bitmaps.rst
@@ -167,8 +167,8 @@ Basic QMP Usage
 
 The primary interface to manipulating bitmap objects is via the QMP
 interface. If you are not familiar, see the :doc:`qmp-spec` for the
-protocol, and `qemu-qmp-ref `_ for a full
-reference of all QMP commands.
+protocol, and :doc:`qemu-qmp-ref` for a full reference of all QMP
+commands.
 
 Supported Commands
 ~~
diff --git a/qapi/introspect.json b/qapi/introspect.json
index ebc4e199d2..8df1ce85ed 100644
--- a/qapi/introspect.json
+++ b/qapi/introspect.json
@@ -260,8 +260,8 @@
 # Additional SchemaInfo members for meta-type 'alternate'.
 #
 # @members: the alternate type's members, in no particular order.  The
-# members' wire encoding is distinct, see :doc:`qapi-code-gen`
-# section Alternate types.
+# members' wire encoding is distinct, see
+# :doc:`/devel/qapi-code-gen` section Alternate types.
 #
 # On the wire, this can be any of the members.
 #
-- 
2.43.0




[PULL 8/8] qapi: Fix malformed "Since:" section tags (again)

2024-01-25 Thread Markus Armbruster
"Since X.Y" is not recognized as a tagged section, and therefore not
formatted as such in generated documentation.  Fix by adding the
required colon.

Previously fixed in commit 433a4fdc420 (qapi: Fix malformed "Since:"
section tags)

Signed-off-by: Markus Armbruster 
Message-ID: <20240120095327.666239-8-arm...@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Eric Blake 
---
 qapi/block-core.json |  4 ++--
 qapi/migration.json  | 14 +++---
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index ca390c5700..3919156d49 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1361,7 +1361,7 @@
 # target, i.e. same data and new writes are done synchronously to
 # both.
 #
-# Since 8.2
+# Since: 8.2
 ##
 { 'struct': 'BlockJobInfoMirror',
   'data': { 'actively-synced': 'bool' } }
@@ -3080,7 +3080,7 @@
 #
 # @type: The job type
 #
-# Since 8.2
+# Since: 8.2
 ##
 { 'union': 'BlockJobChangeOptions',
   'base': { 'id': 'str', 'type': 'JobType' },
diff --git a/qapi/migration.json b/qapi/migration.json
index eb2f883513..489b591c23 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1597,7 +1597,7 @@
 #
 # @file: Direct the migration stream to a file.
 #
-# Since 8.2
+# Since: 8.2
 ##
 { 'enum': 'MigrationAddressType',
   'data': [ 'socket', 'exec', 'rdma', 'file' ] }
@@ -1609,7 +1609,7 @@
 #
 # @offset: The file offset where the migration stream will start
 #
-# Since 8.2
+# Since: 8.2
 ##
 { 'struct': 'FileMigrationArgs',
   'data': { 'filename': 'str',
@@ -1620,7 +1620,7 @@
 #
 # @args: command (list head) and arguments to execute.
 #
-# Since 8.2
+# Since: 8.2
 ##
 { 'struct': 'MigrationExecCommand',
   'data': {'args': [ 'str' ] } }
@@ -1630,7 +1630,7 @@
 #
 # Migration endpoint configuration.
 #
-# Since 8.2
+# Since: 8.2
 ##
 { 'union': 'MigrationAddress',
   'base': { 'transport' : 'MigrationAddressType'},
@@ -1648,7 +1648,7 @@
 #
 # @main: Main outbound migration channel.
 #
-# Since 8.1
+# Since: 8.1
 ##
 { 'enum': 'MigrationChannelType',
   'data': [ 'main' ] }
@@ -1662,7 +1662,7 @@
 #
 # @addr: Migration endpoint configuration on destination interface.
 #
-# Since 8.1
+# Since: 8.1
 ##
 { 'struct': 'MigrationChannel',
   'data': {
@@ -2126,7 +2126,7 @@
 #
 # @millisecond: value is in milliseconds
 #
-# Since 8.2
+# Since: 8.2
 #
 ##
 { 'enum': 'TimeUnit',
-- 
2.43.0




[PULL 1/8] docs/devel/qapi-code-gen: Don't reserve types ending with 'Kind'

2024-01-25 Thread Markus Armbruster
We reserved type names ending with 'Kind' because a simple union
'SomeSimpleUnion' generated both a struct type SomeSimpleUnion and an
enum type SomeSimpleUnionKind.  Gone since commit 4e99f4b12c0 (qapi:
Drop simple unions).  The commit neglected to update the documentation
not to reserve type names ending with 'Kind'.  Do that now.

Signed-off-by: Markus Armbruster 
Message-ID: <20231221145727.835905-1-arm...@redhat.com>
Reviewed-by: Eric Blake 
---
 docs/devel/qapi-code-gen.rst | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
index ea8228518c..0c6f4201bc 100644
--- a/docs/devel/qapi-code-gen.rst
+++ b/docs/devel/qapi-code-gen.rst
@@ -737,9 +737,8 @@ Types, commands, and events share a common namespace.  
Therefore,
 generally speaking, type definitions should always use CamelCase for
 user-defined type names, while built-in types are lowercase.
 
-Type names ending with ``Kind`` or ``List`` are reserved for the
-generator, which uses them for implicit union enums and array types,
-respectively.
+Type names ending with ``List`` are reserved for the generator, which
+uses them for array types.
 
 Command names, member names within a type, and feature names should be
 all lower case with words separated by a hyphen.  However, some
-- 
2.43.0




[PULL 0/8] QAPI patches patches for 2024-01-26

2024-01-25 Thread Markus Armbruster
The following changes since commit 5bab95dc74d43bbb28c6a96d24c810a664432057:

  Merge tag 'pull-request-2024-01-24' of https://gitlab.com/thuth/qemu into 
staging (2024-01-25 12:33:42 +)

are available in the Git repository at:

  https://repo.or.cz/qemu/armbru.git tags/pull-qapi-2024-01-26

for you to fetch changes up to 37507c14a6f562036fce98453de3e869b9c0684f:

  qapi: Fix malformed "Since:" section tags (again) (2024-01-26 07:04:54 +0100)


QAPI patches patches for 2024-01-26


Markus Armbruster (8):
  docs/devel/qapi-code-gen: Don't reserve types ending with 'Kind'
  docs/devel/qapi-code-gen: Fix missing ':' in tagged section docs
  docs: Replace dangling references to docs/interop/qmp-intro.txt
  qapi: Fix dangling references to docs/devel/qapi-code-gen.txt
  docs/interop/bitmaps: Clean up a reference to qemu-qmp-ref
  qapi: Fix mangled "Returns" sections in documentation
  qapi: Indent tagged doc comment sections properly
  qapi: Fix malformed "Since:" section tags (again)

 docs/devel/qapi-code-gen.rst|  9 -
 docs/devel/writing-monitor-commands.rst |  4 ++--
 docs/interop/bitmaps.rst|  6 +++---
 qapi/block-core.json|  4 ++--
 qapi/char.json  |  4 ++--
 qapi/introspect.json|  2 +-
 qapi/machine.json   | 24 
 qapi/migration.json | 14 +++---
 qapi/misc-target.json   |  2 +-
 qapi/misc.json  | 10 +-
 qapi/net.json   | 15 +--
 qapi/qdev.json  |  5 +++--
 qapi/qom.json   | 10 ++
 qapi/yank.json  |  4 ++--
 include/qapi/visitor.h  |  2 +-
 include/qemu/yank.h |  2 +-
 qapi/qapi-util.c|  2 +-
 util/yank.c |  2 +-
 scripts/qapi/parser.py  |  2 +-
 19 files changed, 64 insertions(+), 59 deletions(-)

-- 
2.43.0




[PULL 4/8] qapi: Fix dangling references to docs/devel/qapi-code-gen.txt

2024-01-25 Thread Markus Armbruster
Conversion of docs/devel/qapi-code-gen.txt to ReST left several
dangling references behind.  Fix them to point to
docs/devel/qapi-code-gen.rst.

Fixes: f7aa076dbdfc (docs: convert qapi-code-gen.txt to ReST)
Signed-off-by: Markus Armbruster 
Message-ID: <20240120095327.666239-4-arm...@redhat.com>
Reviewed-by: Eric Blake 
---
 docs/devel/writing-monitor-commands.rst | 2 +-
 qapi/introspect.json| 4 ++--
 include/qapi/visitor.h  | 2 +-
 include/qemu/yank.h | 2 +-
 qapi/qapi-util.c| 2 +-
 util/yank.c | 2 +-
 scripts/qapi/parser.py  | 2 +-
 7 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/docs/devel/writing-monitor-commands.rst 
b/docs/devel/writing-monitor-commands.rst
index 3b3d5517a2..b6ee4fa063 100644
--- a/docs/devel/writing-monitor-commands.rst
+++ b/docs/devel/writing-monitor-commands.rst
@@ -8,7 +8,7 @@ This document doesn't discuss QMP protocol level details, nor 
does it dive
 into the QAPI framework implementation.
 
 For an in-depth introduction to the QAPI framework, please refer to
-docs/devel/qapi-code-gen.txt.  For the QMP protocol, see the
+:doc:`qapi-code-gen`.  For the QMP protocol, see the
 :doc:`/interop/qmp-spec`.
 
 New commands may be implemented in QMP only.  New HMP commands should be
diff --git a/qapi/introspect.json b/qapi/introspect.json
index 9173e60fdd..ebc4e199d2 100644
--- a/qapi/introspect.json
+++ b/qapi/introspect.json
@@ -260,8 +260,8 @@
 # Additional SchemaInfo members for meta-type 'alternate'.
 #
 # @members: the alternate type's members, in no particular order.  The
-# members' wire encoding is distinct, see
-# docs/devel/qapi-code-gen.txt section Alternate types.
+# members' wire encoding is distinct, see :doc:`qapi-code-gen`
+# section Alternate types.
 #
 # On the wire, this can be any of the members.
 #
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index d53a84c9ba..27b85d4700 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -39,7 +39,7 @@
  * limitations; see the documentation for each visitor for more
  * details on what it supports.  Also, see visitor-impl.h for the
  * callback contracts implemented by each visitor, and
- * docs/devel/qapi-code-gen.txt for more about the QAPI code
+ * docs/devel/qapi-code-gen.rst for more about the QAPI code
  * generator.
  *
  * All of the visitors are created via:
diff --git a/include/qemu/yank.h b/include/qemu/yank.h
index 1907150933..3d88af6996 100644
--- a/include/qemu/yank.h
+++ b/include/qemu/yank.h
@@ -45,7 +45,7 @@ void yank_unregister_instance(const YankInstance *instance);
  * yank_register_function: Register a yank function
  *
  * This registers a yank function. All limitations of qmp oob commands apply
- * to the yank function as well. See docs/devel/qapi-code-gen.txt under
+ * to the yank function as well. See docs/devel/qapi-code-gen.rst under
  * "An OOB-capable command handler must satisfy the following conditions".
  *
  * This function is thread-safe.
diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c
index 63596e11c5..65a7d18437 100644
--- a/qapi/qapi-util.c
+++ b/qapi/qapi-util.c
@@ -112,7 +112,7 @@ bool qapi_bool_parse(const char *name, const char *value, 
bool *obj, Error **err
  * It may be prefixed by __RFQDN_ (downstream extension), where RFQDN
  * may contain only letters, digits, hyphen and period.
  * The special exception for enumeration names is not implemented.
- * See docs/devel/qapi-code-gen.txt for more on QAPI naming rules.
+ * See docs/devel/qapi-code-gen.rst for more on QAPI naming rules.
  * Keep this consistent with scripts/qapi-gen.py!
  * If @complete, the parse fails unless it consumes @str completely.
  * Return its length on success, -1 on failure.
diff --git a/util/yank.c b/util/yank.c
index abf47c346d..eaac50539c 100644
--- a/util/yank.c
+++ b/util/yank.c
@@ -35,7 +35,7 @@ typedef struct YankInstanceEntry YankInstanceEntry;
 /*
  * This lock protects the yank_instance_list below. Because it's taken by
  * OOB-capable commands, it must be "fast", i.e. it may only be held for a
- * bounded, short time. See docs/devel/qapi-code-gen.txt for additional
+ * bounded, short time. See docs/devel/qapi-code-gen.rst for additional
  * information.
  */
 static QemuMutex yank_lock;
diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
index bf31018aef..48cd55a38c 100644
--- a/scripts/qapi/parser.py
+++ b/scripts/qapi/parser.py
@@ -71,7 +71,7 @@ class QAPISchemaParser:
 Parse QAPI schema source.
 
 Parse a JSON-esque schema file and process directives.  See
-qapi-code-gen.txt section "Schema Syntax" for the exact syntax.
+qapi-code-gen.rst section "Schema Syntax" for the exact syntax.
 Grammatical validation is handled later by `expr.check_exprs()`.
 
 :param fname: Source file name.
-- 
2.43.0




[PULL 6/8] qapi: Fix mangled "Returns" sections in documentation

2024-01-25 Thread Markus Armbruster
Commit e050e426782e (qapi: Use explicit bulleted lists) added list
markup to correct bad rendering:

A JSON block comment like this:
 Returns: nothing on success
  If @node is not a valid block device, DeviceNotFound
  If @name is not found, GenericError with an explanation

renders like this:

 Returns: nothing on success If node is not a valid block device,
 DeviceNotFound If name is not found, GenericError with an explanation

because whitespace is not significant.

Use an actual bulleted list, so that the formatting is correct.

It missed a few instances.  Commit a937b6aa739 (qapi: Reformat doc
comments to conform to current conventions) then reflowed them.

Revert the reflowing, and add list markup.

Signed-off-by: Markus Armbruster 
Message-ID: <20240120095327.666239-6-arm...@redhat.com>
Reviewed-by: Eric Blake 
---
 qapi/net.json  | 15 +--
 qapi/qdev.json |  5 +++--
 qapi/qom.json  | 10 ++
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/qapi/net.json b/qapi/net.json
index 8095b68fa8..68493d6ac9 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -18,8 +18,9 @@
 #
 # @up: true to set the link status to be up
 #
-# Returns: Nothing on success If @name is not a valid network device,
-# DeviceNotFound
+# Returns:
+# - Nothing on success
+# - If @name is not a valid network device, DeviceNotFound
 #
 # Since: 0.14
 #
@@ -44,8 +45,9 @@
 #
 # Since: 0.14
 #
-# Returns: Nothing on success If @type is not a valid network backend,
-# DeviceNotFound
+# Returns:
+# - Nothing on success
+# - If @type is not a valid network backend, DeviceNotFound
 #
 # Example:
 #
@@ -64,8 +66,9 @@
 #
 # @id: the name of the network backend to remove
 #
-# Returns: Nothing on success If @id is not a valid network backend,
-# DeviceNotFound
+# Returns:
+# - Nothing on success
+# - If @id is not a valid network backend, DeviceNotFound
 #
 # Since: 0.14
 #
diff --git a/qapi/qdev.json b/qapi/qdev.json
index 6bc5a733b8..25bac5e611 100644
--- a/qapi/qdev.json
+++ b/qapi/qdev.json
@@ -89,8 +89,9 @@
 #
 # @id: the device's ID or QOM path
 #
-# Returns: Nothing on success If @id is not a valid device,
-# DeviceNotFound
+# Returns:
+# - Nothing on success
+# - If @id is not a valid device, DeviceNotFound
 #
 # Notes: When this command completes, the device may not be removed
 # from the guest.  Hot removal is an operation that requires guest
diff --git a/qapi/qom.json b/qapi/qom.json
index 95516ba325..84af23fe24 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -1056,8 +1056,9 @@
 #
 # Create a QOM object.
 #
-# Returns: Nothing on success Error if @qom-type is not a valid class
-# name
+# Returns:
+# - Nothing on success
+# - Error if @qom-type is not a valid class name
 #
 # Since: 2.0
 #
@@ -1078,8 +1079,9 @@
 #
 # @id: the name of the QOM object to remove
 #
-# Returns: Nothing on success Error if @id is not a valid id for a QOM
-# object
+# Returns:
+# - Nothing on success
+# - Error if @id is not a valid id for a QOM object
 #
 # Since: 2.0
 #
-- 
2.43.0




[PULL 3/8] docs: Replace dangling references to docs/interop/qmp-intro.txt

2024-01-25 Thread Markus Armbruster
Deletion of docs/interop/qmp-intro.txt left two dangling references
behind.  Replace them by references to docs/interop/qmp-spec.rst.

Fixes: 0ec4468f233c (docs/interop: Delete qmp-intro.txt)
Signed-off-by: Markus Armbruster 
Message-ID: <20240120095327.666239-3-arm...@redhat.com>
Reviewed-by: Eric Blake 
---
 docs/devel/writing-monitor-commands.rst | 4 ++--
 docs/interop/bitmaps.rst| 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/docs/devel/writing-monitor-commands.rst 
b/docs/devel/writing-monitor-commands.rst
index 2c11e71665..3b3d5517a2 100644
--- a/docs/devel/writing-monitor-commands.rst
+++ b/docs/devel/writing-monitor-commands.rst
@@ -8,8 +8,8 @@ This document doesn't discuss QMP protocol level details, nor 
does it dive
 into the QAPI framework implementation.
 
 For an in-depth introduction to the QAPI framework, please refer to
-docs/devel/qapi-code-gen.txt. For documentation about the QMP protocol,
-start with docs/interop/qmp-intro.txt.
+docs/devel/qapi-code-gen.txt.  For the QMP protocol, see the
+:doc:`/interop/qmp-spec`.
 
 New commands may be implemented in QMP only.  New HMP commands should be
 implemented on top of QMP.  The typical HMP command wraps around an
diff --git a/docs/interop/bitmaps.rst b/docs/interop/bitmaps.rst
index 1de46febdc..c731be2f01 100644
--- a/docs/interop/bitmaps.rst
+++ b/docs/interop/bitmaps.rst
@@ -166,9 +166,9 @@ Basic QMP Usage
 ---
 
 The primary interface to manipulating bitmap objects is via the QMP
-interface. If you are not familiar, see docs/interop/qmp-intro.txt for a broad
-overview, and `qemu-qmp-ref `_ for a full reference of all
-QMP commands.
+interface. If you are not familiar, see the :doc:`qmp-spec` for the
+protocol, and `qemu-qmp-ref `_ for a full
+reference of all QMP commands.
 
 Supported Commands
 ~~
-- 
2.43.0




[PULL 7/8] qapi: Indent tagged doc comment sections properly

2024-01-25 Thread Markus Armbruster
docs/devel/qapi-code-gen demands that the "second and subsequent lines
of sections other than "Example"/"Examples" should be indented".
Commit a937b6aa739 (qapi: Reformat doc comments to conform to current
conventions) missed a few instances, and a few more have crept in
since.  Indent them.

Signed-off-by: Markus Armbruster 
Message-ID: <20240120095327.666239-7-arm...@redhat.com>
Reviewed-by: Eric Blake 
---
 qapi/char.json|  4 ++--
 qapi/machine.json | 24 
 qapi/misc-target.json |  2 +-
 qapi/misc.json| 10 +-
 qapi/yank.json|  4 ++--
 5 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/qapi/char.json b/qapi/char.json
index c1bab7b855..6c6ad3b10c 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -391,8 +391,8 @@
 # @rows: console height, in chars
 #
 # Note: the options are only effective when the VNC or SDL graphical
-# display backend is active. They are ignored with the GTK, Spice, VNC
-# and D-Bus display backends.
+# display backend is active.  They are ignored with the GTK,
+# Spice, VNC and D-Bus display backends.
 #
 # Since: 1.5
 ##
diff --git a/qapi/machine.json b/qapi/machine.json
index b6d634b30d..aa99fa333f 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1059,10 +1059,10 @@
 # From it we have: balloon_size = vm_ram_size - @value
 #
 # Returns:
-# - Nothing on success
-# - If the balloon driver is enabled but not functional because the
-#   KVM kernel module cannot support it, KVMMissingCap
-# - If no balloon device is present, DeviceNotActive
+# - Nothing on success
+# - If the balloon driver is enabled but not functional because
+#   the KVM kernel module cannot support it, KVMMissingCap
+# - If no balloon device is present, DeviceNotActive
 #
 # Notes: This command just issues a request to the guest.  When it
 # returns, the balloon size may not have changed.  A guest can
@@ -1097,10 +1097,10 @@
 # Return information about the balloon device.
 #
 # Returns:
-# - @BalloonInfo on success
-# - If the balloon driver is enabled but not functional because the
-#   KVM kernel module cannot support it, KVMMissingCap
-# - If no balloon device is present, DeviceNotActive
+# - @BalloonInfo on success
+# - If the balloon driver is enabled but not functional because
+#   the KVM kernel module cannot support it, KVMMissingCap
+# - If no balloon device is present, DeviceNotActive
 #
 # Since: 0.14
 #
@@ -1161,10 +1161,10 @@
 # message from the guest.
 #
 # Returns:
-# - @HvBalloonInfo on success
-# - If no hv-balloon device is present, guest memory status reporting
-#   is not enabled or no guest memory status report received yet,
-#   GenericError
+# - @HvBalloonInfo on success
+# - If no hv-balloon device is present, guest memory status
+#   reporting is not enabled or no guest memory status report
+#   received yet, GenericError
 #
 # Since: 8.2
 #
diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index 88291453ba..9195e7d26b 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -475,7 +475,7 @@
 # @port: The port number
 #
 # Returns:
-# - Nothing on success.
+# - Nothing on success.
 #
 # Since: 8.0
 #
diff --git a/qapi/misc.json b/qapi/misc.json
index 3622d98d01..2ca8c39874 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -344,9 +344,9 @@
 # @opaque: A free-form string that can be used to describe the fd.
 #
 # Returns:
-# - @AddfdInfo on success
-# - If file descriptor was not received, GenericError
-# - If @fdset-id is a negative value, GenericError
+# - @AddfdInfo on success
+# - If file descriptor was not received, GenericError
+# - If @fdset-id is a negative value, GenericError
 #
 # Notes: The list of fd sets is shared by all monitor connections.
 #
@@ -374,8 +374,8 @@
 # @fd: The file descriptor that is to be removed.
 #
 # Returns:
-# - Nothing on success
-# - If @fdset-id or @fd is not found, GenericError
+# - Nothing on success
+# - If @fdset-id or @fd is not found, GenericError
 #
 # Since: 1.2
 #
diff --git a/qapi/yank.json b/qapi/yank.json
index 87ec7cab96..60eda20816 100644
--- a/qapi/yank.json
+++ b/qapi/yank.json
@@ -77,8 +77,8 @@
 # Takes a list of @YankInstance as argument.
 #
 # Returns:
-# - Nothing on success
-# - @DeviceNotFound error, if any of the YankInstances doesn't exist
+# - Nothing on success
+# - @DeviceNotFound error, if any of the YankInstances doesn't exist
 #
 # Example:
 #
-- 
2.43.0




[PULL 2/8] docs/devel/qapi-code-gen: Fix missing ':' in tagged section docs

2024-01-25 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Message-ID: <20240120095327.666239-2-arm...@redhat.com>
Reviewed-by: Eric Blake 
---
 docs/devel/qapi-code-gen.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
index 0c6f4201bc..76be722f4c 100644
--- a/docs/devel/qapi-code-gen.rst
+++ b/docs/devel/qapi-code-gen.rst
@@ -989,8 +989,8 @@ this::
   # @feature: Description text
 
 A tagged section starts with one of the following words:
-"Note:"/"Notes:", "Since:", "Example"/"Examples", "Returns:", "TODO:".
-The section ends with the start of a new section.
+"Note:"/"Notes:", "Since:", "Example:"/"Examples:", "Returns:",
+"TODO:".  The section ends with the start of a new section.
 
 The second and subsequent lines of sections other than
 "Example"/"Examples" should be indented like this::
-- 
2.43.0




Re: [PATCH 0/7] qapi qmp: Documentation fixes

2024-01-25 Thread Markus Armbruster
Queued.




Re: [PATCH] docs/devel/qapi-code-gen: Don't reserve types ending with 'Kind'

2024-01-25 Thread Markus Armbruster
Markus Armbruster  writes:

> We reserved type names ending with 'Kind' because a simple union
> 'SomeSimpleUnion' generated both a struct type SomeSimpleUnion and an
> enum type SomeSimpleUnionKind.  Gone since commit 4e99f4b12c0 (qapi:
> Drop simple unions).  The commit neglected to update the documentation
> not to reserve type names ending with 'Kind'.  Do that now.
>
> Signed-off-by: Markus Armbruster 

Queued.




[PULL 10/15] migration: Fix use-after-free of migration state object

2024-01-25 Thread peterx
From: Fabiano Rosas 

We're currently allowing the process_incoming_migration_bh bottom-half
to run without holding a reference to the 'current_migration' object,
which leads to a segmentation fault if the BH is still live after
migration_shutdown() has dropped the last reference to
current_migration.

In my system the bug manifests as migrate_multifd() returning true
when it shouldn't and multifd_load_shutdown() calling
multifd_recv_terminate_threads() which crashes due to an uninitialized
multifd_recv_state.

Fix the issue by holding a reference to the object when scheduling the
BH and dropping it before returning from the BH. The same is already
done for the cleanup_bh at migrate_fd_cleanup_schedule().

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1969
Signed-off-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240119233922.32588-2-faro...@suse.de
Signed-off-by: Peter Xu 
---
 migration/migration.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/migration/migration.c b/migration/migration.c
index 219447dea1..cf17b68e57 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -648,6 +648,7 @@ static void process_incoming_migration_bh(void *opaque)
   MIGRATION_STATUS_COMPLETED);
 qemu_bh_delete(mis->bh);
 migration_incoming_state_destroy();
+object_unref(OBJECT(migrate_get_current()));
 }
 
 static void coroutine_fn
@@ -713,6 +714,7 @@ process_incoming_migration_co(void *opaque)
 }
 
 mis->bh = qemu_bh_new(process_incoming_migration_bh, mis);
+object_ref(OBJECT(migrate_get_current()));
 qemu_bh_schedule(mis->bh);
 return;
 fail:
-- 
2.43.0




[PULL 15/15] Make 'uri' optional for migrate QAPI

2024-01-25 Thread peterx
From: Het Gala 

'uri' argument should be optional, as 'uri' and 'channels'
arguments are mutally exclusive in nature.

Fixes: 074dbce5fcce (migration: New migrate and migrate-incoming argument 
'channels')
Signed-off-by: Het Gala 
Link: https://lore.kernel.org/r/20240123064219.40514-1-het.g...@nutanix.com
Signed-off-by: Peter Xu 
---
 qapi/migration.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/migration.json b/qapi/migration.json
index eb2f883513..197d3faa43 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1757,7 +1757,7 @@
 #
 ##
 { 'command': 'migrate',
-  'data': {'uri': 'str',
+  'data': {'*uri': 'str',
'*channels': [ 'MigrationChannel' ],
'*blk': { 'type': 'bool', 'features': [ 'deprecated' ] },
'*inc': { 'type': 'bool', 'features': [ 'deprecated' ] },
-- 
2.43.0




[PULL 09/15] migration/yank: Use channel features

2024-01-25 Thread peterx
From: Fabiano Rosas 

Stop using outside knowledge about the io channels when registering
yank functions. Query for features instead.

The yank method for all channels used with migration code currently is
to call the qio_channel_shutdown() function, so query for
QIO_CHANNEL_FEATURE_SHUTDOWN. We could add a separate feature in the
future for indicating whether a channel supports yanking, but that
seems overkill at the moment.

Signed-off-by: Fabiano Rosas 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Xu 
Link: https://lore.kernel.org/r/20230911171320.24372-9-faro...@suse.de
Signed-off-by: Peter Xu 
---
 migration/yank_functions.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/migration/yank_functions.c b/migration/yank_functions.c
index d5a710a3f2..979e60c762 100644
--- a/migration/yank_functions.c
+++ b/migration/yank_functions.c
@@ -8,12 +8,9 @@
  */
 
 #include "qemu/osdep.h"
-#include "qapi/error.h"
 #include "io/channel.h"
 #include "yank_functions.h"
 #include "qemu/yank.h"
-#include "io/channel-socket.h"
-#include "io/channel-tls.h"
 #include "qemu-file.h"
 
 void migration_yank_iochannel(void *opaque)
@@ -26,8 +23,7 @@ void migration_yank_iochannel(void *opaque)
 /* Return whether yank is supported on this ioc */
 static bool migration_ioc_yank_supported(QIOChannel *ioc)
 {
-return object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET) ||
-object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_TLS);
+return qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
 }
 
 void migration_ioc_register_yank(QIOChannel *ioc)
-- 
2.43.0




[PULL 08/15] ci: Disable migration compatibility tests for aarch64

2024-01-25 Thread peterx
From: Fabiano Rosas 

Until 9.0 is out, we need to keep the aarch64 job disabled because the
tests always use the n-1 version of migration-test. That happens to be
broken for aarch64 in 8.2. Once 9.0 is out, it will become the n-1
version and it will bring the fixed tests.

We can revert this patch when 9.0 releases.

Signed-off-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240118164951.30350-4-faro...@suse.de
[peterx: use _SKIPPED rather than _OPTIONAL]
Signed-off-by: Peter Xu 
---
 .gitlab-ci.d/buildtest.yml | 4 
 1 file changed, 4 insertions(+)

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index f0b0edc634..79bbc8585b 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -217,10 +217,14 @@ build-previous-qemu:
 - QTEST_QEMU_BINARY_DST=./qemu-system-${TARGET}
   QTEST_QEMU_BINARY=../build/qemu-system-${TARGET} 
./tests/qtest/migration-test
 
+# This job is disabled until we release 9.0. The existing
+# migration-test in 8.2 is broken on aarch64. The fix was already
+# commited, but it will only take effect once 9.0 is out.
 migration-compat-aarch64:
   extends: .migration-compat-common
   variables:
 TARGET: aarch64
+QEMU_JOB_SKIPPED: 1
 
 migration-compat-x86_64:
   extends: .migration-compat-common
-- 
2.43.0




[PULL 12/15] migration: Reference migration state around loadvm_postcopy_handle_run_bh

2024-01-25 Thread peterx
From: Fabiano Rosas 

We need to hold a reference to the current_migration object around
async calls to avoid it been freed while still in use. Even on this
load-side function, we might still use the MigrationState, e.g to
check for capabilities.

Signed-off-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240119233922.32588-4-faro...@suse.de
Signed-off-by: Peter Xu 
---
 migration/savevm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/migration/savevm.c b/migration/savevm.c
index 6410705ebe..93387350c7 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2174,6 +2174,7 @@ static void loadvm_postcopy_handle_run_bh(void *opaque)
 qemu_bh_delete(mis->bh);
 
 trace_vmstate_downtime_checkpoint("dst-postcopy-bh-vm-started");
+object_unref(OBJECT(migration_get_current()));
 }
 
 /* After all discards we can start running and asking for pages */
@@ -2189,6 +2190,7 @@ static int 
loadvm_postcopy_handle_run(MigrationIncomingState *mis)
 
 postcopy_state_set(POSTCOPY_INCOMING_RUNNING);
 mis->bh = qemu_bh_new(loadvm_postcopy_handle_run_bh, mis);
+object_ref(OBJECT(migration_get_current()));
 qemu_bh_schedule(mis->bh);
 
 /* We need to finish reading the stream from the package
-- 
2.43.0




[PULL 13/15] migration: Add a wrapper to qemu_bh_schedule

2024-01-25 Thread peterx
From: Fabiano Rosas 

Wrap qemu_bh_schedule() to ensure we always hold a reference to the
current_migration object.

Signed-off-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240119233922.32588-5-faro...@suse.de
Signed-off-by: Peter Xu 
---
 migration/migration.c | 31 ++-
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index b1213b59ce..0e7f101d64 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -199,6 +199,16 @@ void migration_object_init(void)
 dirty_bitmap_mig_init();
 }
 
+static void migration_bh_schedule(MigrationState *s, QEMUBH *bh)
+{
+/*
+ * Ref the state for bh, because it may be called when
+ * there're already no other refs
+ */
+object_ref(OBJECT(s));
+qemu_bh_schedule(bh);
+}
+
 void migration_cancel(const Error *error)
 {
 if (error) {
@@ -714,8 +724,7 @@ process_incoming_migration_co(void *opaque)
 }
 
 mis->bh = qemu_bh_new(process_incoming_migration_bh, mis);
-object_ref(OBJECT(migrate_get_current()));
-qemu_bh_schedule(mis->bh);
+migration_bh_schedule(migrate_get_current(), mis->bh);
 return;
 fail:
 migrate_set_state(>state, MIGRATION_STATUS_ACTIVE,
@@ -1332,16 +1341,6 @@ static void migrate_fd_cleanup(MigrationState *s)
 yank_unregister_instance(MIGRATION_YANK_INSTANCE);
 }
 
-static void migrate_fd_cleanup_schedule(MigrationState *s)
-{
-/*
- * Ref the state for bh, because it may be called when
- * there're already no other refs
- */
-object_ref(OBJECT(s));
-qemu_bh_schedule(s->cleanup_bh);
-}
-
 static void migrate_fd_cleanup_bh(void *opaque)
 {
 MigrationState *s = opaque;
@@ -3140,7 +3139,7 @@ static void migration_iteration_finish(MigrationState *s)
 error_report("%s: Unknown ending state %d", __func__, s->state);
 break;
 }
-migrate_fd_cleanup_schedule(s);
+migration_bh_schedule(s, s->cleanup_bh);
 bql_unlock();
 }
 
@@ -3171,7 +3170,7 @@ static void bg_migration_iteration_finish(MigrationState 
*s)
 break;
 }
 
-migrate_fd_cleanup_schedule(s);
+migration_bh_schedule(s, s->cleanup_bh);
 bql_unlock();
 }
 
@@ -3487,9 +3486,7 @@ static void *bg_migration_thread(void *opaque)
  * writes to virtio VQs memory which is in write-protected region.
  */
 s->vm_start_bh = qemu_bh_new(bg_migration_vm_start_bh, s);
-object_ref(OBJECT(s));
-qemu_bh_schedule(s->vm_start_bh);
-
+migration_bh_schedule(s, s->vm_start_bh);
 bql_unlock();
 
 while (migration_is_active(s)) {
-- 
2.43.0




[PULL 03/15] migration: Make threshold_size an uint64_t

2024-01-25 Thread peterx
From: Peter Xu 

It's always used to compare against another uint64_t.  Make it always clear
that it's never a negative.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240117075848.139045-2-pet...@redhat.com
Signed-off-by: Peter Xu 
---
 migration/migration.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/migration/migration.h b/migration/migration.h
index 17972dac34..a589ae8650 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -296,7 +296,7 @@ struct MigrationState {
  * this threshold; it's calculated from the requested downtime and
  * measured bandwidth, or avail-switchover-bandwidth if specified.
  */
-int64_t threshold_size;
+uint64_t threshold_size;
 
 /* params from 'migrate-set-parameters' */
 MigrationParameters parameters;
-- 
2.43.0




[PULL 04/15] migration: Drop unnecessary check in ram's pending_exact()

2024-01-25 Thread peterx
From: Peter Xu 

When the migration frameworks fetches the exact pending sizes, it means
this check:

  remaining_size < s->threshold_size

Must have been done already, actually at migration_iteration_run():

if (must_precopy <= s->threshold_size) {
qemu_savevm_state_pending_exact(_precopy, _postcopy);

That should be after one round of ram_state_pending_estimate().  It makes
the 2nd check meaningless and can be dropped.

To say it in another way, when reaching ->state_pending_exact(), we
unconditionally sync dirty bits for precopy.

Then we can drop migrate_get_current() there too.

Reviewed-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240117075848.139045-3-pet...@redhat.com
Signed-off-by: Peter Xu 
---
 migration/ram.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index c0cdcccb75..d5b7cd5ac2 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3213,21 +3213,20 @@ static void ram_state_pending_estimate(void *opaque, 
uint64_t *must_precopy,
 static void ram_state_pending_exact(void *opaque, uint64_t *must_precopy,
 uint64_t *can_postcopy)
 {
-MigrationState *s = migrate_get_current();
 RAMState **temp = opaque;
 RAMState *rs = *temp;
+uint64_t remaining_size;
 
-uint64_t remaining_size = rs->migration_dirty_pages * TARGET_PAGE_SIZE;
-
-if (!migration_in_postcopy() && remaining_size < s->threshold_size) {
+if (!migration_in_postcopy()) {
 bql_lock();
 WITH_RCU_READ_LOCK_GUARD() {
 migration_bitmap_sync_precopy(rs, false);
 }
 bql_unlock();
-remaining_size = rs->migration_dirty_pages * TARGET_PAGE_SIZE;
 }
 
+remaining_size = rs->migration_dirty_pages * TARGET_PAGE_SIZE;
+
 if (migrate_postcopy_ram()) {
 /* We can do postcopy, and all the data is postcopiable */
 *can_postcopy += remaining_size;
-- 
2.43.0




[PULL 02/15] migration: Plug memory leak on HMP migrate error path

2024-01-25 Thread peterx
From: Markus Armbruster 

hmp_migrate() leaks @caps when qmp_migrate() fails.  Plug the leak
with g_autoptr().

Fixes: 967f2de5c9ec (migration: Implement MigrateChannelList to hmp migration 
flow.) v8.2.0-rc0
Fixes: CID 1533125
Signed-off-by: Markus Armbruster 
Link: https://lore.kernel.org/r/20240117140722.3979657-1-arm...@redhat.com
[peterx: fix CID number as reported by Peter Maydell]
Signed-off-by: Peter Xu 
---
 migration/migration-hmp-cmds.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
index 740a219aa4..99b49df5dd 100644
--- a/migration/migration-hmp-cmds.c
+++ b/migration/migration-hmp-cmds.c
@@ -764,7 +764,7 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
 bool resume = qdict_get_try_bool(qdict, "resume", false);
 const char *uri = qdict_get_str(qdict, "uri");
 Error *err = NULL;
-MigrationChannelList *caps = NULL;
+g_autoptr(MigrationChannelList) caps = NULL;
 g_autoptr(MigrationChannel) channel = NULL;
 
 if (inc) {
@@ -789,8 +789,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
 return;
 }
 
-qapi_free_MigrationChannelList(caps);
-
 if (!detach) {
 HMPMigrationStatus *status;
 
-- 
2.43.0




[PULL 00/15] Migration 20240126 patches

2024-01-25 Thread peterx
From: Peter Xu 

The following changes since commit 5bab95dc74d43bbb28c6a96d24c810a664432057:

  Merge tag 'pull-request-2024-01-24' of https://gitlab.com/thuth/qemu into 
staging (2024-01-25 12:33:42 +)

are available in the Git repository at:

  https://gitlab.com/peterx/qemu.git tags/migration-20240126-pull-request

for you to fetch changes up to 24b0c2ec956ca225282f81470f7c26f5bb844885:

  Make 'uri' optional for migrate QAPI (2024-01-26 11:06:13 +0800)


Migration pull for 9.0

- Fabiano's patchset to fix migration state references in BHs
- Fabiano's new 'n-1' migration test for CI
- Het's fix on making "uri" optional in QMP migrate cmd
- Markus's HMP leak fix reported by Coverity
- Paolo's cleanup on uffd to replace u64 usage
- Peter's small migration cleanup series all over the places



Fabiano Rosas (9):
  tests/qtest/migration: Don't use -cpu max for aarch64
  ci: Add a migration compatibility test job
  ci: Disable migration compatibility tests for aarch64
  migration/yank: Use channel features
  migration: Fix use-after-free of migration state object
  migration: Take reference to migration state around
bg_migration_vm_start_bh
  migration: Reference migration state around
loadvm_postcopy_handle_run_bh
  migration: Add a wrapper to qemu_bh_schedule
  migration: Centralize BH creation and dispatch

Het Gala (1):
  Make 'uri' optional for migrate QAPI

Markus Armbruster (1):
  migration: Plug memory leak on HMP migrate error path

Paolo Bonzini (1):
  userfaultfd: use 1ULL to build ioctl masks

Peter Xu (3):
  migration: Make threshold_size an uint64_t
  migration: Drop unnecessary check in ram's pending_exact()
  analyze-migration.py: Remove trick on parsing ramblocks

 qapi/migration.json   |  2 +-
 migration/migration.h |  7 +-
 migration/migration-hmp-cmds.c|  4 +-
 migration/migration.c | 82 +--
 migration/postcopy-ram.c  | 16 ++---
 migration/ram.c   |  9 ++-
 migration/savevm.c|  5 +-
 migration/yank_functions.c|  6 +-
 subprojects/libvhost-user/libvhost-user.c |  2 +-
 tests/qtest/migration-test.c  |  6 +-
 .gitlab-ci.d/buildtest.yml| 64 ++
 scripts/analyze-migration.py  | 11 +--
 12 files changed, 135 insertions(+), 79 deletions(-)

-- 
2.43.0




[PULL 14/15] migration: Centralize BH creation and dispatch

2024-01-25 Thread peterx
From: Fabiano Rosas 

Now that the migration state reference counting is correct, further
wrap the bottom half dispatch process to avoid future issues.

Move BH creation and scheduling together and wrap the dispatch with an
intermediary function that will ensure we always keep the ref/unref
balanced.

Also move the responsibility of deleting the BH into the wrapper and
remove the now unnecessary pointers.

Signed-off-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240119233922.32588-6-faro...@suse.de
Signed-off-by: Peter Xu 
---
 migration/migration.h |  5 +---
 migration/migration.c | 65 +--
 migration/savevm.c|  7 +
 3 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/migration/migration.h b/migration/migration.h
index a589ae8650..f2c8b8f286 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -159,8 +159,6 @@ struct MigrationIncomingState {
 /* PostCopyFD's for external userfaultfds & handlers of shared memory */
 GArray   *postcopy_remote_fds;
 
-QEMUBH *bh;
-
 int state;
 
 /*
@@ -255,8 +253,6 @@ struct MigrationState {
 
 /*< public >*/
 QemuThread thread;
-QEMUBH *vm_start_bh;
-QEMUBH *cleanup_bh;
 /* Protected by qemu_file_lock */
 QEMUFile *to_dst_file;
 /* Postcopy specific transfer channel */
@@ -528,6 +524,7 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void 
*opaque);
 void migration_make_urgent_request(void);
 void migration_consume_urgent_request(void);
 bool migration_rate_limit(void);
+void migration_bh_schedule(QEMUBHFunc *cb, void *opaque);
 void migration_cancel(const Error *error);
 
 void migration_populate_vfio_info(MigrationInfo *info);
diff --git a/migration/migration.c b/migration/migration.c
index 0e7f101d64..d5f705ceef 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -199,8 +199,39 @@ void migration_object_init(void)
 dirty_bitmap_mig_init();
 }
 
-static void migration_bh_schedule(MigrationState *s, QEMUBH *bh)
+typedef struct {
+QEMUBH *bh;
+QEMUBHFunc *cb;
+void *opaque;
+} MigrationBH;
+
+static void migration_bh_dispatch_bh(void *opaque)
 {
+MigrationState *s = migrate_get_current();
+MigrationBH *migbh = opaque;
+
+/* cleanup this BH */
+qemu_bh_delete(migbh->bh);
+migbh->bh = NULL;
+
+/* dispatch the other one */
+migbh->cb(migbh->opaque);
+object_unref(OBJECT(s));
+
+g_free(migbh);
+}
+
+void migration_bh_schedule(QEMUBHFunc *cb, void *opaque)
+{
+MigrationState *s = migrate_get_current();
+MigrationBH *migbh = g_new0(MigrationBH, 1);
+QEMUBH *bh = qemu_bh_new(migration_bh_dispatch_bh, migbh);
+
+/* Store these to dispatch when the BH runs */
+migbh->bh = bh;
+migbh->cb = cb;
+migbh->opaque = opaque;
+
 /*
  * Ref the state for bh, because it may be called when
  * there're already no other refs
@@ -656,9 +687,7 @@ static void process_incoming_migration_bh(void *opaque)
  */
 migrate_set_state(>state, MIGRATION_STATUS_ACTIVE,
   MIGRATION_STATUS_COMPLETED);
-qemu_bh_delete(mis->bh);
 migration_incoming_state_destroy();
-object_unref(OBJECT(migrate_get_current()));
 }
 
 static void coroutine_fn
@@ -723,8 +752,7 @@ process_incoming_migration_co(void *opaque)
 goto fail;
 }
 
-mis->bh = qemu_bh_new(process_incoming_migration_bh, mis);
-migration_bh_schedule(migrate_get_current(), mis->bh);
+migration_bh_schedule(process_incoming_migration_bh, mis);
 return;
 fail:
 migrate_set_state(>state, MIGRATION_STATUS_ACTIVE,
@@ -1285,9 +1313,6 @@ void migrate_set_state(int *state, int old_state, int 
new_state)
 
 static void migrate_fd_cleanup(MigrationState *s)
 {
-qemu_bh_delete(s->cleanup_bh);
-s->cleanup_bh = NULL;
-
 g_free(s->hostname);
 s->hostname = NULL;
 json_writer_free(s->vmdesc);
@@ -1343,9 +1368,7 @@ static void migrate_fd_cleanup(MigrationState *s)
 
 static void migrate_fd_cleanup_bh(void *opaque)
 {
-MigrationState *s = opaque;
-migrate_fd_cleanup(s);
-object_unref(OBJECT(s));
+migrate_fd_cleanup(opaque);
 }
 
 void migrate_set_error(MigrationState *s, const Error *error)
@@ -1568,8 +1591,6 @@ int migrate_init(MigrationState *s, Error **errp)
  * parameters/capabilities that the user set, and
  * locks.
  */
-s->cleanup_bh = 0;
-s->vm_start_bh = 0;
 s->to_dst_file = NULL;
 s->state = MIGRATION_STATUS_NONE;
 s->rp_state.from_dst_file = NULL;
@@ -3139,7 +3160,8 @@ static void migration_iteration_finish(MigrationState *s)
 error_report("%s: Unknown ending state %d", __func__, s->state);
 break;
 }
-migration_bh_schedule(s, s->cleanup_bh);
+
+migration_bh_schedule(migrate_fd_cleanup_bh, s);
 bql_unlock();
 }
 
@@ -3170,7 +3192,7 @@ static void bg_migration_iteration_finish(MigrationState 
*s)
 break;
 }
 
-migration_bh_schedule(s, 

[PULL 05/15] analyze-migration.py: Remove trick on parsing ramblocks

2024-01-25 Thread peterx
From: Peter Xu 

RAM_SAVE_FLAG_MEM_SIZE contains the total length of ramblock idstr to know
whether scanning of ramblocks is complete.  Drop the trick.

Reviewed-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240117075848.139045-4-pet...@redhat.com
Signed-off-by: Peter Xu 
---
 scripts/analyze-migration.py | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py
index a39dfb8766..8a254a5b6a 100755
--- a/scripts/analyze-migration.py
+++ b/scripts/analyze-migration.py
@@ -151,17 +151,12 @@ def read(self):
 addr &= ~(self.TARGET_PAGE_SIZE - 1)
 
 if flags & self.RAM_SAVE_FLAG_MEM_SIZE:
-while True:
+total_length = addr
+while total_length > 0:
 namelen = self.file.read8()
-# We assume that no RAM chunk is big enough to ever
-# hit the first byte of the address, so when we see
-# a zero here we know it has to be an address, not the
-# length of the next block.
-if namelen == 0:
-self.file.file.seek(-1, 1)
-break
 self.name = self.file.readstr(len = namelen)
 len = self.file.read64()
+total_length -= len
 self.sizeinfo[self.name] = '0x%016x' % len
 if self.write_memory:
 print(self.name)
-- 
2.43.0




[PULL 11/15] migration: Take reference to migration state around bg_migration_vm_start_bh

2024-01-25 Thread peterx
From: Fabiano Rosas 

We need to hold a reference to the current_migration object around
async calls to avoid it been freed while still in use.

Signed-off-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240119233922.32588-3-faro...@suse.de
Signed-off-by: Peter Xu 
---
 migration/migration.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/migration/migration.c b/migration/migration.c
index cf17b68e57..b1213b59ce 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -3382,6 +3382,7 @@ static void bg_migration_vm_start_bh(void *opaque)
 
 vm_resume(s->vm_old_state);
 migration_downtime_end(s);
+object_unref(OBJECT(s));
 }
 
 /**
@@ -3486,6 +3487,7 @@ static void *bg_migration_thread(void *opaque)
  * writes to virtio VQs memory which is in write-protected region.
  */
 s->vm_start_bh = qemu_bh_new(bg_migration_vm_start_bh, s);
+object_ref(OBJECT(s));
 qemu_bh_schedule(s->vm_start_bh);
 
 bql_unlock();
-- 
2.43.0




[PULL 06/15] tests/qtest/migration: Don't use -cpu max for aarch64

2024-01-25 Thread peterx
From: Fabiano Rosas 

The 'max' cpu is not expected to be stable in terms of features across
QEMU versions, so it should not be expected to migrate.

While the tests currently all pass with -cpu max, that is only because
we're not testing across QEMU versions, which is the more common
use-case for migration.

We've recently introduced compatibility tests that use two different
QEMU versions and the tests are now failing for aarch64. The next
patch adds those tests to CI, so we cannot use the 'max' cpu
anymore. Replace it with the 'neoverse-n1', which has a fixed set of
features.

Suggested-by: Peter Maydell 
Signed-off-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240118164951.30350-2-faro...@suse.de
Signed-off-by: Peter Xu 
---
 tests/qtest/migration-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index 7675519cfa..15713f3666 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -820,7 +820,7 @@ static int test_migrate_start(QTestState **from, QTestState 
**to,
 memory_size = "150M";
 machine_alias = "virt";
 machine_opts = "gic-version=max";
-arch_opts = g_strdup_printf("-cpu max -kernel %s", bootpath);
+arch_opts = g_strdup_printf("-cpu neoverse-n1 -kernel %s", bootpath);
 start_address = ARM_TEST_MEM_START;
 end_address = ARM_TEST_MEM_END;
 } else {
-- 
2.43.0




[PULL 07/15] ci: Add a migration compatibility test job

2024-01-25 Thread peterx
From: Fabiano Rosas 

The migration tests have support for being passed two QEMU binaries to
test migration compatibility.

Add a CI job that builds the lastest release of QEMU and another job
that uses that version plus an already present build of the current
version and run the migration tests with the two, both as source and
destination. I.e.:

 old QEMU (n-1) -> current QEMU (development tree)
 current QEMU (development tree) -> old QEMU (n-1)

The purpose of this CI job is to ensure the code we're about to merge
will not cause a migration compatibility problem when migrating the
next release (which will contain that code) to/from the previous
release.

The version of migration-test used will be the one matching the older
QEMU. That way we can avoid special-casing new tests that wouldn't be
compatible with the older QEMU.

Note: for user forks, the version tags need to be pushed to gitlab
otherwise it won't be able to checkout a different version.

Signed-off-by: Fabiano Rosas 
Link: https://lore.kernel.org/r/20240118164951.30350-3-faro...@suse.de
Signed-off-by: Peter Xu 
---
 .gitlab-ci.d/buildtest.yml | 60 ++
 1 file changed, 60 insertions(+)

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index e1c7801598..f0b0edc634 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -167,6 +167,66 @@ build-system-centos:
   x86_64-softmmu rx-softmmu sh4-softmmu nios2-softmmu
 MAKE_CHECK_ARGS: check-build
 
+# Previous QEMU release. Used for cross-version migration tests.
+build-previous-qemu:
+  extends: .native_build_job_template
+  artifacts:
+when: on_success
+expire_in: 2 days
+paths:
+  - build-previous
+exclude:
+  - build-previous/**/*.p
+  - build-previous/**/*.a.p
+  - build-previous/**/*.fa.p
+  - build-previous/**/*.c.o
+  - build-previous/**/*.c.o.d
+  - build-previous/**/*.fa
+  needs:
+job: amd64-opensuse-leap-container
+  variables:
+IMAGE: opensuse-leap
+TARGETS: x86_64-softmmu aarch64-softmmu
+  before_script:
+- export QEMU_PREV_VERSION="$(sed 's/\([0-9.]*\)\.[0-9]*/v\1.0/' VERSION)"
+- git checkout $QEMU_PREV_VERSION
+  after_script:
+- mv build build-previous
+
+.migration-compat-common:
+  extends: .common_test_job_template
+  needs:
+- job: build-previous-qemu
+- job: build-system-opensuse
+  # The old QEMU could have bugs unrelated to migration that are
+  # already fixed in the current development branch, so this test
+  # might fail.
+  allow_failure: true
+  variables:
+IMAGE: opensuse-leap
+MAKE_CHECK_ARGS: check-build
+  script:
+# Use the migration-tests from the older QEMU tree. This avoids
+# testing an old QEMU against new features/tests that it is not
+# compatible with.
+- cd build-previous
+# old to new
+- QTEST_QEMU_BINARY_SRC=./qemu-system-${TARGET}
+  QTEST_QEMU_BINARY=../build/qemu-system-${TARGET} 
./tests/qtest/migration-test
+# new to old
+- QTEST_QEMU_BINARY_DST=./qemu-system-${TARGET}
+  QTEST_QEMU_BINARY=../build/qemu-system-${TARGET} 
./tests/qtest/migration-test
+
+migration-compat-aarch64:
+  extends: .migration-compat-common
+  variables:
+TARGET: aarch64
+
+migration-compat-x86_64:
+  extends: .migration-compat-common
+  variables:
+TARGET: x86_64
+
 check-system-centos:
   extends: .native_test_job_template
   needs:
-- 
2.43.0




[PULL 01/15] userfaultfd: use 1ULL to build ioctl masks

2024-01-25 Thread peterx
From: Paolo Bonzini 

There is no need to use the Linux-internal __u64 type, 1ULL is
guaranteed to be wide enough.

Signed-off-by: Paolo Bonzini 
Reviewed-by: Philippe Mathieu-Daudé 
Link: https://lore.kernel.org/r/20240117160313.175609-1-pbonz...@redhat.com
Signed-off-by: Peter Xu 
---
 migration/postcopy-ram.c  | 16 +++-
 subprojects/libvhost-user/libvhost-user.c |  2 +-
 tests/qtest/migration-test.c  |  4 ++--
 3 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 5408e028c6..893ec8fa89 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -102,11 +102,9 @@ void postcopy_thread_create(MigrationIncomingState *mis,
  * are target OS specific.
  */
 #if defined(__linux__)
-
 #include 
 #include 
 #include 
-#include  /* for __u64 */
 #endif
 
 #if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD)
@@ -272,8 +270,8 @@ static bool request_ufd_features(int ufd, uint64_t features)
 return false;
 }
 
-ioctl_mask = (__u64)1 << _UFFDIO_REGISTER |
- (__u64)1 << _UFFDIO_UNREGISTER;
+ioctl_mask = 1ULL << _UFFDIO_REGISTER |
+ 1ULL << _UFFDIO_UNREGISTER;
 if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) {
 error_report("Missing userfault features: %" PRIx64,
  (uint64_t)(~api_struct.ioctls & ioctl_mask));
@@ -462,9 +460,9 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState 
*mis, Error **errp)
 goto out;
 }
 
-feature_mask = (__u64)1 << _UFFDIO_WAKE |
-   (__u64)1 << _UFFDIO_COPY |
-   (__u64)1 << _UFFDIO_ZEROPAGE;
+feature_mask = 1ULL << _UFFDIO_WAKE |
+   1ULL << _UFFDIO_COPY |
+   1ULL << _UFFDIO_ZEROPAGE;
 if ((reg_struct.ioctls & feature_mask) != feature_mask) {
 error_setg(errp, "Missing userfault map features: %" PRIx64,
(uint64_t)(~reg_struct.ioctls & feature_mask));
@@ -733,11 +731,11 @@ static int ram_block_enable_notify(RAMBlock *rb, void 
*opaque)
 error_report("%s userfault register: %s", __func__, strerror(errno));
 return -1;
 }
-if (!(reg_struct.ioctls & ((__u64)1 << _UFFDIO_COPY))) {
+if (!(reg_struct.ioctls & (1ULL << _UFFDIO_COPY))) {
 error_report("%s userfault: Region doesn't support COPY", __func__);
 return -1;
 }
-if (reg_struct.ioctls & ((__u64)1 << _UFFDIO_ZEROPAGE)) {
+if (reg_struct.ioctls & (1ULL << _UFFDIO_ZEROPAGE)) {
 qemu_ram_set_uf_zeroable(rb);
 }
 
diff --git a/subprojects/libvhost-user/libvhost-user.c 
b/subprojects/libvhost-user/libvhost-user.c
index 6684057370..a3b158c671 100644
--- a/subprojects/libvhost-user/libvhost-user.c
+++ b/subprojects/libvhost-user/libvhost-user.c
@@ -684,7 +684,7 @@ generate_faults(VuDev *dev) {
  dev->postcopy_ufd, strerror(errno));
 return false;
 }
-if (!(reg_struct.ioctls & ((__u64)1 << _UFFDIO_COPY))) {
+if (!(reg_struct.ioctls & (1ULL << _UFFDIO_COPY))) {
 vu_panic(dev, "%s Region (%d) doesn't support COPY",
  __func__, i);
 return false;
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index d3066e119f..7675519cfa 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -104,8 +104,8 @@ static bool ufd_version_check(void)
 }
 uffd_feature_thread_id = api_struct.features & UFFD_FEATURE_THREAD_ID;
 
-ioctl_mask = (__u64)1 << _UFFDIO_REGISTER |
- (__u64)1 << _UFFDIO_UNREGISTER;
+ioctl_mask = 1ULL << _UFFDIO_REGISTER |
+ 1ULL << _UFFDIO_UNREGISTER;
 if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) {
 g_test_message("Skipping test: Missing userfault feature");
 return false;
-- 
2.43.0




[PATCH v11 04/11] hw/fsi: Introduce IBM's fsi-slave model

2024-01-25 Thread Ninad Palsule
This is a part of patchset where IBM's Flexible Service Interface is
introduced.

The FSI slave: The slave is the terminal point of the FSI bus for
FSI symbols addressed to it. Slaves can be cascaded off of one
another. The slave's configuration registers appear in address space
of the CFAM to which it is attached.

Signed-off-by: Andrew Jeffery 
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
 include/hw/fsi/fsi.h | 19 ++
 hw/fsi/fsi.c | 87 +++-
 hw/fsi/trace-events  |  2 +
 3 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/include/hw/fsi/fsi.h b/include/hw/fsi/fsi.h
index 50e8f5c888..6e11747dd5 100644
--- a/include/hw/fsi/fsi.h
+++ b/include/hw/fsi/fsi.h
@@ -7,7 +7,14 @@
 #ifndef FSI_FSI_H
 #define FSI_FSI_H
 
+#include "exec/memory.h"
 #include "hw/qdev-core.h"
+#include "hw/fsi/lbus.h"
+#include "qemu/bitops.h"
+
+/* Bitwise operations at the word level. */
+#define BE_BIT(x)   BIT(31 - (x))
+#define BE_GENMASK(hb, lb)  MAKE_64BIT_MASK((lb), ((hb) - (lb) + 1))
 
 #define TYPE_FSI_BUS "fsi.bus"
 OBJECT_DECLARE_SIMPLE_TYPE(FSIBus, FSI_BUS)
@@ -16,4 +23,16 @@ typedef struct FSIBus {
 BusState bus;
 } FSIBus;
 
+#define TYPE_FSI_SLAVE "fsi.slave"
+OBJECT_DECLARE_SIMPLE_TYPE(FSISlaveState, FSI_SLAVE)
+
+#define FSI_SLAVE_CONTROL_NR_REGS ((0x40 >> 2) + 1)
+
+typedef struct FSISlaveState {
+DeviceState parent;
+
+MemoryRegion iomem;
+uint32_t regs[FSI_SLAVE_CONTROL_NR_REGS];
+} FSISlaveState;
+
 #endif /* FSI_FSI_H */
diff --git a/hw/fsi/fsi.c b/hw/fsi/fsi.c
index 60cb03f7a2..528323d9cf 100644
--- a/hw/fsi/fsi.c
+++ b/hw/fsi/fsi.c
@@ -5,18 +5,101 @@
  * IBM Flexible Service Interface
  */
 #include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "trace.h"
 
 #include "hw/fsi/fsi.h"
 
+#define TO_REG(x)   ((x) >> 2)
+
 static const TypeInfo fsi_bus_info = {
 .name = TYPE_FSI_BUS,
 .parent = TYPE_BUS,
 .instance_size = sizeof(FSIBus),
 };
 
-static void fsi_bus_register_types(void)
+static uint64_t fsi_slave_read(void *opaque, hwaddr addr, unsigned size)
+{
+FSISlaveState *s = FSI_SLAVE(opaque);
+int reg = TO_REG(addr);
+
+trace_fsi_slave_read(addr, size);
+
+if (reg >= FSI_SLAVE_CONTROL_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out of bounds read: 0x%"HWADDR_PRIx" for %u\n",
+  __func__, addr, size);
+return 0;
+}
+
+return s->regs[reg];
+}
+
+static void fsi_slave_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned size)
+{
+FSISlaveState *s = FSI_SLAVE(opaque);
+int reg = TO_REG(addr);
+
+trace_fsi_slave_write(addr, size, data);
+
+if (reg >= FSI_SLAVE_CONTROL_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out of bounds write: 0x%"HWADDR_PRIx" for %u\n",
+  __func__, addr, size);
+return;
+}
+
+s->regs[reg] = data;
+}
+
+static const struct MemoryRegionOps fsi_slave_ops = {
+.read = fsi_slave_read,
+.write = fsi_slave_write,
+.endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void fsi_slave_reset(DeviceState *dev)
+{
+FSISlaveState *s = FSI_SLAVE(dev);
+int i;
+
+/* Initialize registers */
+for (i = 0; i < FSI_SLAVE_CONTROL_NR_REGS; i++) {
+s->regs[i] = 0;
+}
+}
+
+static void fsi_slave_init(Object *o)
+{
+FSISlaveState *s = FSI_SLAVE(o);
+
+memory_region_init_io(>iomem, OBJECT(s), _slave_ops,
+  s, TYPE_FSI_SLAVE, 0x400);
+}
+
+static void fsi_slave_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->bus_type = TYPE_FSI_BUS;
+dc->desc = "FSI Slave";
+dc->reset = fsi_slave_reset;
+}
+
+static const TypeInfo fsi_slave_info = {
+.name = TYPE_FSI_SLAVE,
+.parent = TYPE_DEVICE,
+.instance_init = fsi_slave_init,
+.instance_size = sizeof(FSISlaveState),
+.class_init = fsi_slave_class_init,
+};
+
+static void fsi_register_types(void)
 {
 type_register_static(_bus_info);
+type_register_static(_slave_info);
 }
 
-type_init(fsi_bus_register_types);
+type_init(fsi_register_types);
diff --git a/hw/fsi/trace-events b/hw/fsi/trace-events
index c5753e2791..8f29adb7df 100644
--- a/hw/fsi/trace-events
+++ b/hw/fsi/trace-events
@@ -1,2 +1,4 @@
 fsi_scratchpad_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size=%d"
 fsi_scratchpad_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" 
PRIx64 " size=%d value=0x%"PRIx64
+fsi_slave_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size=%d"
+fsi_slave_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " 
size=%d value=0x%"PRIx64
-- 
2.39.2




[PATCH v11 10/11] hw/fsi: Added FSI documentation

2024-01-25 Thread Ninad Palsule
Documentation for IBM FSI model.

Signed-off-by: Ninad Palsule 
---
v11:
  - Removed Cedri's signoff.
---
 docs/specs/fsi.rst   | 138 +++
 docs/specs/index.rst |   1 +
 2 files changed, 139 insertions(+)
 create mode 100644 docs/specs/fsi.rst

diff --git a/docs/specs/fsi.rst b/docs/specs/fsi.rst
new file mode 100644
index 00..05a6b6347a
--- /dev/null
+++ b/docs/specs/fsi.rst
@@ -0,0 +1,138 @@
+==
+IBM's Flexible Service Interface (FSI)
+==
+
+The QEMU FSI emulation implements hardware interfaces between ASPEED SOC, FSI
+master/slave and the end engine.
+
+FSI is a point-to-point two wire interface which is capable of supporting
+distances of up to 4 meters. FSI interfaces have been used successfully for
+many years in IBM servers to attach IBM Flexible Support Processors(FSP) to
+CPUs and IBM ASICs.
+
+FSI allows a service processor access to the internal buses of a host POWER
+processor to perform configuration or debugging. FSI has long existed in POWER
+processes and so comes with some baggage, including how it has been integrated
+into the ASPEED SoC.
+
+Working backwards from the POWER processor, the fundamental pieces of interest
+for the implementation are: (see the `FSI specification`_ for more details)
+
+1. The Common FRU Access Macro (CFAM), an address space containing various
+   "engines" that drive accesses on buses internal and external to the POWER
+   chip. Examples include the SBEFIFO and I2C masters. The engines hang off of
+   an internal Local Bus (LBUS) which is described by the CFAM configuration
+   block.
+
+2. The FSI slave: The slave is the terminal point of the FSI bus for FSI
+   symbols addressed to it. Slaves can be cascaded off of one another. The
+   slave's configuration registers appear in address space of the CFAM to
+   which it is attached.
+
+3. The FSI master: A controller in the platform service processor (e.g. BMC)
+   driving CFAM engine accesses into the POWER chip. At the hardware level
+   FSI is a bit-based protocol supporting synchronous and DMA-driven accesses
+   of engines in a CFAM.
+
+4. The On-Chip Peripheral Bus (OPB): A low-speed bus typically found in POWER
+   processors. This now makes an appearance in the ASPEED SoC due to tight
+   integration of the FSI master IP with the OPB, mainly the existence of an
+   MMIO-mapping of the CFAM address straight onto a sub-region of the OPB
+   address space.
+
+5. An APB-to-OPB bridge enabling access to the OPB from the ARM core in the
+   AST2600. Hardware limitations prevent the OPB from being directly mapped
+   into APB, so all accesses are indirect through the bridge.
+
+The LBUS is modelled to maintain the qdev bus hierarchy and to take advantages
+of the object model to automatically generate the CFAM configuration block.
+The configuration block presents engines in the order they are attached to the
+CFAM's LBUS. Engine implementations should subclass the LBusDevice and set the
+'config' member of LBusDeviceClass to match the engine's type.
+
+CFAM designs offer a lot of flexibility, for instance it is possible for a
+CFAM to be simultaneously driven from multiple FSI links. The modeling is not
+so complete; it's assumed that each CFAM is attached to a single FSI slave (as
+a consequence the CFAM subclasses the FSI slave).
+
+As for FSI, its symbols and wire-protocol are not modelled at all. This is not
+necessary to get FSI off the ground thanks to the mapping of the CFAM address
+space onto the OPB address space - the models follow this directly and map the
+CFAM memory region into the OPB's memory region.
+
+QEMU files related to FSI interface:
+ - ``hw/fsi/aspeed-apb2opb.c``
+ - ``include/hw/fsi/aspeed-apb2opb.h``
+ - ``hw/fsi/opb.c``
+ - ``include/hw/fsi/opb.h``
+ - ``hw/fsi/fsi.c``
+ - ``include/hw/fsi/fsi.h``
+ - ``hw/fsi/fsi-master.c``
+ - ``include/hw/fsi/fsi-master.h``
+ - ``hw/fsi/fsi-slave.c``
+ - ``include/hw/fsi/fsi-slave.h``
+ - ``hw/fsi/cfam.c``
+ - ``include/hw/fsi/cfam.h``
+ - ``hw/fsi/engine-scratchpad.c``
+ - ``include/hw/fsi/engine-scratchpad.h``
+ - ``include/hw/fsi/lbus.h``
+
+The following commands start the rainier machine with built-in FSI model.
+There are no model specific arguments.
+
+.. code-block:: console
+
+  qemu-system-arm -M rainier-bmc -nographic \
+  -kernel fitImage-linux.bin \
+  -dtb aspeed-bmc-ibm-rainier.dtb \
+  -initrd obmc-phosphor-initramfs.rootfs.cpio.xz \
+  -drive file=obmc-phosphor-image.rootfs.wic.qcow2,if=sd,index=2 \
+  -append "rootwait console=ttyS4,115200n8 root=PARTLABEL=rofs-a"
+
+The implementation appears as following in the qemu device tree:
+
+.. code-block:: console
+
+  (qemu) info qtree
+  bus: main-system-bus
+type System
+...
+dev: aspeed.apb2opb, id ""
+  gpio-out "sysbus-irq" 1
+  mmio 1e79b000/1000
+  bus: opb.1
+type opb
+dev: fsi.master, id ""
+  

[PATCH v11 09/11] hw/fsi: Added qtest

2024-01-25 Thread Ninad Palsule
Added basic qtests for FSI model.

Acked-by: Thomas Huth 
Signed-off-by: Ninad Palsule 
---
v11:
  - Removed Cedric's signoff
---
 tests/qtest/aspeed-fsi-test.c | 205 ++
 tests/qtest/meson.build   |   1 +
 2 files changed, 206 insertions(+)
 create mode 100644 tests/qtest/aspeed-fsi-test.c

diff --git a/tests/qtest/aspeed-fsi-test.c b/tests/qtest/aspeed-fsi-test.c
new file mode 100644
index 00..b3020dd821
--- /dev/null
+++ b/tests/qtest/aspeed-fsi-test.c
@@ -0,0 +1,205 @@
+/*
+ * QTest testcases for IBM's Flexible Service Interface (FSI)
+ *
+ * Copyright (c) 2023 IBM Corporation
+ *
+ * Authors:
+ *   Ninad Palsule 
+ *
+ * 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 "qemu/module.h"
+#include "libqtest-single.h"
+
+/* Registers from ast2600 specifications */
+#define ASPEED_FSI_ENGINER_TRIGGER   0x04
+#define ASPEED_FSI_OPB0_BUS_SELECT   0x10
+#define ASPEED_FSI_OPB1_BUS_SELECT   0x28
+#define ASPEED_FSI_OPB0_RW_DIRECTION 0x14
+#define ASPEED_FSI_OPB1_RW_DIRECTION 0x2c
+#define ASPEED_FSI_OPB0_XFER_SIZE0x18
+#define ASPEED_FSI_OPB1_XFER_SIZE0x30
+#define ASPEED_FSI_OPB0_BUS_ADDR 0x1c
+#define ASPEED_FSI_OPB1_BUS_ADDR 0x34
+#define ASPEED_FSI_INTRRUPT_CLEAR0x40
+#define ASPEED_FSI_INTRRUPT_STATUS   0x48
+#define ASPEED_FSI_OPB0_BUS_STATUS   0x80
+#define ASPEED_FSI_OPB1_BUS_STATUS   0x8c
+#define ASPEED_FSI_OPB0_READ_DATA0x84
+#define ASPEED_FSI_OPB1_READ_DATA0x90
+
+/*
+ * FSI Base addresses from the ast2600 specifications.
+ */
+#define AST2600_OPB_FSI0_BASE_ADDR 0x1e79b000
+#define AST2600_OPB_FSI1_BASE_ADDR 0x1e79b100
+
+static uint32_t aspeed_fsi_base_addr;
+
+static uint32_t aspeed_fsi_readl(QTestState *s, uint32_t reg)
+{
+return qtest_readl(s, aspeed_fsi_base_addr + reg);
+}
+
+static void aspeed_fsi_writel(QTestState *s, uint32_t reg, uint32_t val)
+{
+qtest_writel(s, aspeed_fsi_base_addr + reg, val);
+}
+
+/* Setup base address and select register */
+static void test_fsi_setup(QTestState *s, uint32_t base_addr)
+{
+uint32_t curval;
+
+aspeed_fsi_base_addr = base_addr;
+
+/* Set the base select register */
+if (base_addr == AST2600_OPB_FSI0_BASE_ADDR) {
+/* Unselect FSI1 */
+aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_SELECT, 0x0);
+curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_SELECT);
+g_assert_cmpuint(curval, ==, 0x0);
+
+/* Select FSI0 */
+aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_SELECT, 0x1);
+curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_SELECT);
+g_assert_cmpuint(curval, ==, 0x1);
+} else if (base_addr == AST2600_OPB_FSI1_BASE_ADDR) {
+/* Unselect FSI0 */
+aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_SELECT, 0x0);
+curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_SELECT);
+g_assert_cmpuint(curval, ==, 0x0);
+
+/* Select FSI1 */
+aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_SELECT, 0x1);
+curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_SELECT);
+g_assert_cmpuint(curval, ==, 0x1);
+} else {
+g_assert_not_reached();
+}
+}
+
+static void test_fsi_reg_change(QTestState *s, uint32_t reg, uint32_t newval)
+{
+uint32_t base;
+uint32_t curval;
+
+base = aspeed_fsi_readl(s, reg);
+aspeed_fsi_writel(s, reg, newval);
+curval = aspeed_fsi_readl(s, reg);
+g_assert_cmpuint(curval, ==, newval);
+aspeed_fsi_writel(s, reg, base);
+curval = aspeed_fsi_readl(s, reg);
+g_assert_cmpuint(curval, ==, base);
+}
+
+static void test_fsi0_master_regs(const void *data)
+{
+QTestState *s = (QTestState *)data;
+
+test_fsi_setup(s, AST2600_OPB_FSI0_BASE_ADDR);
+
+test_fsi_reg_change(s, ASPEED_FSI_OPB0_RW_DIRECTION, 0xF3F4F514);
+test_fsi_reg_change(s, ASPEED_FSI_OPB0_XFER_SIZE, 0xF3F4F518);
+test_fsi_reg_change(s, ASPEED_FSI_OPB0_BUS_ADDR, 0xF3F4F51c);
+test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_CLEAR, 0xF3F4F540);
+test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_STATUS, 0xF3F4F548);
+test_fsi_reg_change(s, ASPEED_FSI_OPB0_BUS_STATUS, 0xF3F4F580);
+test_fsi_reg_change(s, ASPEED_FSI_OPB0_READ_DATA, 0xF3F4F584);
+}
+
+static void test_fsi1_master_regs(const void *data)
+{
+QTestState *s = (QTestState *)data;
+
+test_fsi_setup(s, AST2600_OPB_FSI1_BASE_ADDR);
+
+test_fsi_reg_change(s, ASPEED_FSI_OPB1_RW_DIRECTION, 0xF3F4F514);
+test_fsi_reg_change(s, ASPEED_FSI_OPB1_XFER_SIZE, 0xF3F4F518);
+test_fsi_reg_change(s, ASPEED_FSI_OPB1_BUS_ADDR, 0xF3F4F51c);
+test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_CLEAR, 0xF3F4F540);
+test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_STATUS, 0xF3F4F548);
+test_fsi_reg_change(s, ASPEED_FSI_OPB1_BUS_STATUS, 0xF3F4F580);
+test_fsi_reg_change(s, ASPEED_FSI_OPB1_READ_DATA, 0xF3F4F584);
+}
+
+static void test_fsi0_getcfam_addr0(const 

[PATCH v11 06/11] hw/fsi: Introduce IBM's FSI master

2024-01-25 Thread Ninad Palsule
This is a part of patchset where IBM's Flexible Service Interface is
introduced.

This commit models the FSI master. CFAM is hanging out of FSI master which is a 
bus controller.

The FSI master: A controller in the platform service processor (e.g.
BMC) driving CFAM engine accesses into the POWER chip. At the
hardware level FSI is a bit-based protocol supporting synchronous and
DMA-driven accesses of engines in a CFAM.

Signed-off-by: Andrew Jeffery 
Signed-off-by: Cédric Le Goater 
[ clg: - move FSICFAMState object under FSIMasterState
   - introduced fsi_master_init()
   - reworked fsi_master_realize()
   - dropped FSIBus definition ]
Signed-off-by: Ninad Palsule 
---
v9:
  - Initialized registers.
  - Fixed the address check.
v11:
  - Replaced for loop with memset.
  - Removed Joel's review tag as per Cedric.
---
 include/hw/fsi/fsi-master.h |  32 +++
 hw/fsi/fsi-master.c | 170 
 hw/fsi/meson.build  |   2 +-
 hw/fsi/trace-events |   2 +
 4 files changed, 205 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/fsi/fsi-master.h
 create mode 100644 hw/fsi/fsi-master.c

diff --git a/include/hw/fsi/fsi-master.h b/include/hw/fsi/fsi-master.h
new file mode 100644
index 00..68e5f56db2
--- /dev/null
+++ b/include/hw/fsi/fsi-master.h
@@ -0,0 +1,32 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * IBM Flexible Service Interface Master
+ */
+#ifndef FSI_FSI_MASTER_H
+#define FSI_FSI_MASTER_H
+
+#include "exec/memory.h"
+#include "hw/qdev-core.h"
+#include "hw/fsi/fsi.h"
+#include "hw/fsi/cfam.h"
+
+#define TYPE_FSI_MASTER "fsi.master"
+OBJECT_DECLARE_SIMPLE_TYPE(FSIMasterState, FSI_MASTER)
+
+#define FSI_MASTER_NR_REGS ((0x2e0 >> 2) + 1)
+
+typedef struct FSIMasterState {
+DeviceState parent;
+MemoryRegion iomem;
+MemoryRegion opb2fsi;
+
+FSIBus bus;
+
+uint32_t regs[FSI_MASTER_NR_REGS];
+FSICFAMState cfam;
+} FSIMasterState;
+
+
+#endif /* FSI_FSI_H */
diff --git a/hw/fsi/fsi-master.c b/hw/fsi/fsi-master.c
new file mode 100644
index 00..49ad4b988f
--- /dev/null
+++ b/hw/fsi/fsi-master.c
@@ -0,0 +1,170 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * IBM Flexible Service Interface master
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "trace.h"
+
+#include "hw/fsi/fsi-master.h"
+
+#define TYPE_OP_BUS "opb"
+
+#define TO_REG(x)   ((x) >> 2)
+
+#define FSI_MENP0   TO_REG(0x010)
+#define FSI_MENP32  TO_REG(0x014)
+#define FSI_MSENP0  TO_REG(0x018)
+#define FSI_MLEVP0  TO_REG(0x018)
+#define FSI_MSENP32 TO_REG(0x01c)
+#define FSI_MLEVP32 TO_REG(0x01c)
+#define FSI_MCENP0  TO_REG(0x020)
+#define FSI_MREFP0  TO_REG(0x020)
+#define FSI_MCENP32 TO_REG(0x024)
+#define FSI_MREFP32 TO_REG(0x024)
+
+#define FSI_MVERTO_REG(0x074)
+#define FSI_MRESP0  TO_REG(0x0d0)
+
+#define FSI_MRESB0  TO_REG(0x1d0)
+#define   FSI_MRESB0_RESET_GENERAL  BE_BIT(0)
+#define   FSI_MRESB0_RESET_ERRORBE_BIT(1)
+
+static uint64_t fsi_master_read(void *opaque, hwaddr addr, unsigned size)
+{
+FSIMasterState *s = FSI_MASTER(opaque);
+int reg = TO_REG(addr);
+
+trace_fsi_master_read(addr, size);
+
+if (reg >= FSI_MASTER_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out of bounds read: 0x%"HWADDR_PRIx" for %u\n",
+  __func__, addr, size);
+return 0;
+}
+
+return s->regs[reg];
+}
+
+static void fsi_master_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned size)
+{
+FSIMasterState *s = FSI_MASTER(opaque);
+int reg = TO_REG(addr);
+
+trace_fsi_master_write(addr, size, data);
+
+if (reg >= FSI_MASTER_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out of bounds write: %"HWADDR_PRIx" for %u\n",
+  __func__, addr, size);
+return;
+}
+
+switch (reg) {
+case FSI_MENP0:
+s->regs[FSI_MENP0] = data;
+break;
+case FSI_MENP32:
+s->regs[FSI_MENP32] = data;
+break;
+case FSI_MSENP0:
+s->regs[FSI_MENP0] |= data;
+break;
+case FSI_MSENP32:
+s->regs[FSI_MENP32] |= data;
+break;
+case FSI_MCENP0:
+s->regs[FSI_MENP0] &= ~data;
+break;
+case FSI_MCENP32:
+s->regs[FSI_MENP32] &= ~data;
+break;
+case FSI_MRESP0:
+/* Perform necessary resets leave register 0 to indicate no errors */

[PATCH v11 01/11] hw/fsi: Introduce IBM's Local bus

2024-01-25 Thread Ninad Palsule
This is a part of patchset where IBM's Flexible Service Interface is
introduced.

The LBUS is modelled to maintain mapped memory for the devices. The
memory is mapped after CFAM config, peek table and FSI slave registers.

Signed-off-by: Andrew Jeffery 
[ clg: - removed lbus_add_device() bc unused
   - removed lbus_create_device() bc used only once
   - removed "address" property
   - updated meson.build to build fsi dir
   - included an empty hw/fsi/trace-events ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
v9:
  - Changed LBUS memory region to 1MB.
v11:
  - Split lbus and scratchpad into separate patches.
  - Added fsi_ prefix for all functions in lbus.
  - Removed FSI_LBUS* typedefs.
  - Replaced for loop with memset.
---
 meson.build   |  1 +
 hw/fsi/trace.h|  1 +
 include/hw/fsi/lbus.h | 32 
 hw/fsi/lbus.c | 43 +++
 hw/Kconfig|  1 +
 hw/fsi/Kconfig|  2 ++
 hw/fsi/meson.build|  1 +
 hw/fsi/trace-events   |  0
 hw/meson.build|  1 +
 9 files changed, 82 insertions(+)
 create mode 100644 hw/fsi/trace.h
 create mode 100644 include/hw/fsi/lbus.h
 create mode 100644 hw/fsi/lbus.c
 create mode 100644 hw/fsi/Kconfig
 create mode 100644 hw/fsi/meson.build
 create mode 100644 hw/fsi/trace-events

diff --git a/meson.build b/meson.build
index d0329966f1..7d926c6e82 100644
--- a/meson.build
+++ b/meson.build
@@ -3290,6 +3290,7 @@ if have_system
 'hw/char',
 'hw/display',
 'hw/dma',
+'hw/fsi',
 'hw/hyperv',
 'hw/i2c',
 'hw/i386',
diff --git a/hw/fsi/trace.h b/hw/fsi/trace.h
new file mode 100644
index 00..ee67c7fb04
--- /dev/null
+++ b/hw/fsi/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-hw_fsi.h"
diff --git a/include/hw/fsi/lbus.h b/include/hw/fsi/lbus.h
new file mode 100644
index 00..e8a22e22a8
--- /dev/null
+++ b/include/hw/fsi/lbus.h
@@ -0,0 +1,32 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * IBM Local bus and connected device structures.
+ */
+#ifndef FSI_LBUS_H
+#define FSI_LBUS_H
+
+#include "hw/qdev-core.h"
+#include "qemu/units.h"
+#include "exec/memory.h"
+
+#define TYPE_FSI_LBUS_DEVICE "fsi.lbus.device"
+OBJECT_DECLARE_SIMPLE_TYPE(FSILBusDevice, FSI_LBUS_DEVICE)
+
+typedef struct FSILBusDevice {
+DeviceState parent;
+
+MemoryRegion iomem;
+} FSILBusDevice;
+
+#define TYPE_FSI_LBUS "fsi.lbus"
+OBJECT_DECLARE_SIMPLE_TYPE(FSILBus, FSI_LBUS)
+
+typedef struct FSILBus {
+BusState bus;
+
+MemoryRegion mr;
+} FSILBus;
+
+#endif /* FSI_LBUS_H */
diff --git a/hw/fsi/lbus.c b/hw/fsi/lbus.c
new file mode 100644
index 00..44d2319087
--- /dev/null
+++ b/hw/fsi/lbus.c
@@ -0,0 +1,43 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * IBM Local bus where FSI slaves are connected
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/fsi/lbus.h"
+
+#include "hw/qdev-properties.h"
+
+#include "trace.h"
+
+static void fsi_lbus_init(Object *o)
+{
+FSILBus *lbus = FSI_LBUS(o);
+
+memory_region_init(>mr, OBJECT(lbus), TYPE_FSI_LBUS, 1 * MiB);
+}
+
+static const TypeInfo fsi_lbus_info = {
+.name = TYPE_FSI_LBUS,
+.parent = TYPE_BUS,
+.instance_init = fsi_lbus_init,
+.instance_size = sizeof(FSILBus),
+};
+
+static const TypeInfo fsi_lbus_device_type_info = {
+.name = TYPE_FSI_LBUS_DEVICE,
+.parent = TYPE_DEVICE,
+.instance_size = sizeof(FSILBusDevice),
+.abstract = true,
+};
+
+static void fsi_lbus_register_types(void)
+{
+type_register_static(_lbus_info);
+type_register_static(_lbus_device_type_info);
+}
+
+type_init(fsi_lbus_register_types);
diff --git a/hw/Kconfig b/hw/Kconfig
index 9ca7b38c31..2c00936c28 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -9,6 +9,7 @@ source core/Kconfig
 source cxl/Kconfig
 source display/Kconfig
 source dma/Kconfig
+source fsi/Kconfig
 source gpio/Kconfig
 source hyperv/Kconfig
 source i2c/Kconfig
diff --git a/hw/fsi/Kconfig b/hw/fsi/Kconfig
new file mode 100644
index 00..9c34a418d7
--- /dev/null
+++ b/hw/fsi/Kconfig
@@ -0,0 +1,2 @@
+config FSI
+bool
diff --git a/hw/fsi/meson.build b/hw/fsi/meson.build
new file mode 100644
index 00..93ba19dd04
--- /dev/null
+++ b/hw/fsi/meson.build
@@ -0,0 +1 @@
+system_ss.add(when: 'CONFIG_FSI', if_true: files('lbus.c'))
diff --git a/hw/fsi/trace-events b/hw/fsi/trace-events
new file mode 100644
index 00..e69de29bb2
diff --git a/hw/meson.build b/hw/meson.build
index f01fac4617..463d702683 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -44,6 +44,7 @@ subdir('virtio')
 subdir('watchdog')
 subdir('xen')
 subdir('xenpv')
+subdir('fsi')
 
 subdir('alpha')
 subdir('arm')
-- 
2.39.2




[PATCH v11 05/11] hw/fsi: Introduce IBM's cfam

2024-01-25 Thread Ninad Palsule
This is a part of patchset where IBM's Flexible Service Interface is
introduced.

The Common FRU Access Macro (CFAM), an address space containing
various "engines" that drive accesses on busses internal and external
to the POWER chip. Examples include the SBEFIFO and I2C masters. The
engines hang off of an internal Local Bus (LBUS) which is described
by the CFAM configuration block.

Signed-off-by: Andrew Jeffery 
[ clg: - moved object FSIScratchPad under FSICFAMState
   - moved FSIScratchPad code under cfam.c
   - introduced fsi_cfam_instance_init()
   - reworked fsi_cfam_realize() ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
v9:
  - Added more registers to scratchpad
  - Removed unnecessary address space
  - Removed unnecessary header file
  - Defined macros for config values.
  - Cleaned up cfam config read.
---
 include/hw/fsi/cfam.h |  34 +
 hw/fsi/cfam.c | 168 ++
 hw/fsi/meson.build|   2 +-
 hw/fsi/trace-events   |   5 ++
 4 files changed, 208 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/fsi/cfam.h
 create mode 100644 hw/fsi/cfam.c

diff --git a/include/hw/fsi/cfam.h b/include/hw/fsi/cfam.h
new file mode 100644
index 00..7abc3b287b
--- /dev/null
+++ b/include/hw/fsi/cfam.h
@@ -0,0 +1,34 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * IBM Common FRU Access Macro
+ */
+#ifndef FSI_CFAM_H
+#define FSI_CFAM_H
+
+#include "exec/memory.h"
+
+#include "hw/fsi/fsi.h"
+#include "hw/fsi/lbus.h"
+
+#define TYPE_FSI_CFAM "cfam"
+#define FSI_CFAM(obj) OBJECT_CHECK(FSICFAMState, (obj), TYPE_FSI_CFAM)
+
+/* P9-ism */
+#define CFAM_CONFIG_NR_REGS 0x28
+
+typedef struct FSICFAMState {
+/* < private > */
+FSISlaveState parent;
+
+/* CFAM config address space */
+MemoryRegion config_iomem;
+
+MemoryRegion mr;
+
+FSILBus lbus;
+FSIScratchPad scratchpad;
+} FSICFAMState;
+
+#endif /* FSI_CFAM_H */
diff --git a/hw/fsi/cfam.c b/hw/fsi/cfam.c
new file mode 100644
index 00..c118221bc3
--- /dev/null
+++ b/hw/fsi/cfam.c
@@ -0,0 +1,168 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * IBM Common FRU Access Macro
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+
+#include "qapi/error.h"
+#include "trace.h"
+
+#include "hw/fsi/cfam.h"
+#include "hw/fsi/fsi.h"
+
+#include "hw/qdev-properties.h"
+
+#define ENGINE_CONFIG_NEXTBE_BIT(0)
+#define ENGINE_CONFIG_TYPE_PEEK   (0x02 << 4)
+#define ENGINE_CONFIG_TYPE_FSI(0x03 << 4)
+#define ENGINE_CONFIG_TYPE_SCRATCHPAD (0x06 << 4)
+
+/* Valid, slots, version, type, crc */
+#define CFAM_CONFIG_REG(__VER, __TYPE, __CRC)   \
+(ENGINE_CONFIG_NEXT   |   \
+ 0x0001   |   \
+ (__VER)  |   \
+ (__TYPE) |   \
+ (__CRC))
+
+#define TO_REG(x)  ((x) >> 2)
+
+#define CFAM_CONFIG_CHIP_IDTO_REG(0x00)
+#define CFAM_CONFIG_PEEK_STATUSTO_REG(0x04)
+#define CFAM_CONFIG_CHIP_ID_P9 0xc0022d15
+#define CFAM_CONFIG_CHIP_ID_BREAK  0xc0de
+
+static uint64_t fsi_cfam_config_read(void *opaque, hwaddr addr, unsigned size)
+{
+trace_fsi_cfam_config_read(addr, size);
+
+switch (addr) {
+case 0x00:
+return CFAM_CONFIG_CHIP_ID_P9;
+case 0x04:
+return CFAM_CONFIG_REG(0x1000, ENGINE_CONFIG_TYPE_PEEK, 0xc);
+case 0x08:
+return CFAM_CONFIG_REG(0x5000, ENGINE_CONFIG_TYPE_FSI, 0xa);
+case 0xc:
+return CFAM_CONFIG_REG(0x1000, ENGINE_CONFIG_TYPE_SCRATCHPAD, 0x7);
+default:
+/*
+ * The config table contains different engines from 0xc onwards.
+ * The scratch pad is already added at address 0xc. We need to add
+ * future engines from address 0x10 onwards. Returning 0 as engine
+ * is not implemented.
+ */
+return 0;
+}
+}
+
+static void fsi_cfam_config_write(void *opaque, hwaddr addr, uint64_t data,
+  unsigned size)
+{
+FSICFAMState *cfam = FSI_CFAM(opaque);
+
+trace_fsi_cfam_config_write(addr, size, data);
+
+switch (TO_REG(addr)) {
+case CFAM_CONFIG_CHIP_ID:
+case CFAM_CONFIG_PEEK_STATUS:
+if (data == CFAM_CONFIG_CHIP_ID_BREAK) {
+bus_cold_reset(BUS(>lbus));
+}
+break;
+default:
+trace_fsi_cfam_config_write_noaddr(addr, size, data);
+}
+}
+
+static const struct MemoryRegionOps cfam_config_ops = {
+.read = fsi_cfam_config_read,
+.write = fsi_cfam_config_write,
+.valid.max_access_size = 4,
+.valid.min_access_size = 4,
+.impl.max_access_size = 4,
+.impl.min_access_size = 4,
+.endianness = DEVICE_BIG_ENDIAN,
+};
+
+static uint64_t fsi_cfam_unimplemented_read(void *opaque, hwaddr addr,
+unsigned size)
+{
+

[PATCH v11 11/11] hw/fsi: Update MAINTAINER list

2024-01-25 Thread Ninad Palsule
Added maintainer for IBM FSI model

Signed-off-by: Ninad Palsule 
---
v11:
 - Added Cedric as reviewer.
---
 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index dfaca8323e..39deb8ee1f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3585,6 +3585,15 @@ F: tests/qtest/adm1272-test.c
 F: tests/qtest/max34451-test.c
 F: tests/qtest/isl_pmbus_vr-test.c
 
+FSI
+M: Ninad Palsule 
+R: Cédric Le Goater 
+S: Maintained
+F: hw/fsi/*
+F: include/hw/fsi/*
+F: docs/specs/fsi.rst
+F: tests/qtest/fsi-test.c
+
 Firmware schema specifications
 M: Philippe Mathieu-Daudé 
 R: Daniel P. Berrange 
-- 
2.39.2




[PATCH v11 02/11] hw/fsi: Introduce IBM's scratchpad device

2024-01-25 Thread Ninad Palsule
This is a part of patchset where IBM's Flexible Service Interface is
introduced.

The scratchpad provides a set of non-functional registers. The firmware
is free to use them, hardware does not support any special management
support. The scratchpad registers can be read or written from LBUS
slave. The scratch pad is managed under FSI CFAM state.

Signed-off-by: Andrew Jeffery 
[ clg: - moved object FSIScratchPad under FSICFAMState
   - moved FSIScratchPad code under cfam.c ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
 include/hw/fsi/lbus.h | 11 +++
 hw/fsi/lbus.c | 69 +++
 hw/fsi/trace-events   |  2 ++
 3 files changed, 82 insertions(+)

diff --git a/include/hw/fsi/lbus.h b/include/hw/fsi/lbus.h
index e8a22e22a8..558268c013 100644
--- a/include/hw/fsi/lbus.h
+++ b/include/hw/fsi/lbus.h
@@ -29,4 +29,15 @@ typedef struct FSILBus {
 MemoryRegion mr;
 } FSILBus;
 
+#define TYPE_FSI_SCRATCHPAD "fsi.scratchpad"
+#define SCRATCHPAD(obj) OBJECT_CHECK(FSIScratchPad, (obj), TYPE_FSI_SCRATCHPAD)
+
+#define FSI_SCRATCHPAD_NR_REGS 4
+
+typedef struct FSIScratchPad {
+FSILBusDevice parent;
+
+uint32_t regs[FSI_SCRATCHPAD_NR_REGS];
+} FSIScratchPad;
+
 #endif /* FSI_LBUS_H */
diff --git a/hw/fsi/lbus.c b/hw/fsi/lbus.c
index 44d2319087..5ab7d0a741 100644
--- a/hw/fsi/lbus.c
+++ b/hw/fsi/lbus.c
@@ -13,6 +13,8 @@
 
 #include "trace.h"
 
+#define TO_REG(offset) ((offset) >> 2)
+
 static void fsi_lbus_init(Object *o)
 {
 FSILBus *lbus = FSI_LBUS(o);
@@ -34,10 +36,77 @@ static const TypeInfo fsi_lbus_device_type_info = {
 .abstract = true,
 };
 
+static uint64_t fsi_scratchpad_read(void *opaque, hwaddr addr, unsigned size)
+{
+FSIScratchPad *s = SCRATCHPAD(opaque);
+int reg = TO_REG(addr);
+
+trace_fsi_scratchpad_read(addr, size);
+
+if (reg >= FSI_SCRATCHPAD_NR_REGS) {
+return 0;
+}
+
+return s->regs[reg];
+}
+
+static void fsi_scratchpad_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned size)
+{
+FSIScratchPad *s = SCRATCHPAD(opaque);
+
+trace_fsi_scratchpad_write(addr, size, data);
+int reg = TO_REG(addr);
+
+if (reg >= FSI_SCRATCHPAD_NR_REGS) {
+return;
+}
+
+s->regs[reg] = data;
+}
+
+static const struct MemoryRegionOps scratchpad_ops = {
+.read = fsi_scratchpad_read,
+.write = fsi_scratchpad_write,
+.endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void fsi_scratchpad_realize(DeviceState *dev, Error **errp)
+{
+FSILBusDevice *ldev = FSI_LBUS_DEVICE(dev);
+
+memory_region_init_io(>iomem, OBJECT(ldev), _ops,
+  ldev, TYPE_FSI_SCRATCHPAD, 0x400);
+}
+
+static void fsi_scratchpad_reset(DeviceState *dev)
+{
+FSIScratchPad *s = SCRATCHPAD(dev);
+
+memset(s->regs, 0, sizeof(s->regs));
+}
+
+static void fsi_scratchpad_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->bus_type = TYPE_FSI_LBUS;
+dc->realize = fsi_scratchpad_realize;
+dc->reset = fsi_scratchpad_reset;
+}
+
+static const TypeInfo fsi_scratchpad_info = {
+.name = TYPE_FSI_SCRATCHPAD,
+.parent = TYPE_FSI_LBUS_DEVICE,
+.instance_size = sizeof(FSIScratchPad),
+.class_init = fsi_scratchpad_class_init,
+};
+
 static void fsi_lbus_register_types(void)
 {
 type_register_static(_lbus_info);
 type_register_static(_lbus_device_type_info);
+type_register_static(_scratchpad_info);
 }
 
 type_init(fsi_lbus_register_types);
diff --git a/hw/fsi/trace-events b/hw/fsi/trace-events
index e69de29bb2..c5753e2791 100644
--- a/hw/fsi/trace-events
+++ b/hw/fsi/trace-events
@@ -0,0 +1,2 @@
+fsi_scratchpad_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size=%d"
+fsi_scratchpad_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" 
PRIx64 " size=%d value=0x%"PRIx64
-- 
2.39.2




[PATCH v11 08/11] hw/arm: Hook up FSI module in AST2600

2024-01-25 Thread Ninad Palsule
This patchset introduces IBM's Flexible Service Interface(FSI).

Time for some fun with inter-processor buses. FSI allows a service
processor access to the internal buses of a host POWER processor to
perform configuration or debugging.

FSI has long existed in POWER processes and so comes with some baggage,
including how it has been integrated into the ASPEED SoC.

Working backwards from the POWER processor, the fundamental pieces of
interest for the implementation are:

1. The Common FRU Access Macro (CFAM), an address space containing
   various "engines" that drive accesses on buses internal and external
   to the POWER chip. Examples include the SBEFIFO and I2C masters. The
   engines hang off of an internal Local Bus (LBUS) which is described
   by the CFAM configuration block.

2. The FSI slave: The slave is the terminal point of the FSI bus for
   FSI symbols addressed to it. Slaves can be cascaded off of one
   another. The slave's configuration registers appear in address space
   of the CFAM to which it is attached.

3. The FSI master: A controller in the platform service processor (e.g.
   BMC) driving CFAM engine accesses into the POWER chip. At the
   hardware level FSI is a bit-based protocol supporting synchronous and
   DMA-driven accesses of engines in a CFAM.

4. The On-Chip Peripheral Bus (OPB): A low-speed bus typically found in
   POWER processors. This now makes an appearance in the ASPEED SoC due
   to tight integration of the FSI master IP with the OPB, mainly the
   existence of an MMIO-mapping of the CFAM address straight onto a
   sub-region of the OPB address space.

5. An APB-to-OPB bridge enabling access to the OPB from the ARM core in
   the AST2600. Hardware limitations prevent the OPB from being directly
   mapped into APB, so all accesses are indirect through the bridge.

The implementation appears as following in the qemu device tree:

(qemu) info qtree
bus: main-system-bus
  type System
  ...
  dev: aspeed.apb2opb, id ""
gpio-out "sysbus-irq" 1
mmio 1e79b000/1000
bus: opb.1
  type opb
  dev: fsi.master, id ""
bus: fsi.bus.1
  type fsi.bus
  dev: cfam.config, id ""
  dev: cfam, id ""
bus: fsi.lbus.1
  type lbus
  dev: scratchpad, id ""
address = 0 (0x0)
bus: opb.0
  type opb
  dev: fsi.master, id ""
bus: fsi.bus.0
  type fsi.bus
  dev: cfam.config, id ""
  dev: cfam, id ""
bus: fsi.lbus.0
  type lbus
  dev: scratchpad, id ""
address = 0 (0x0)

The LBUS is modelled to maintain the qdev bus hierarchy and to take
advantage of the object model to automatically generate the CFAM
configuration block. The configuration block presents engines in the
order they are attached to the CFAM's LBUS. Engine implementations
should subclass the LBusDevice and set the 'config' member of
LBusDeviceClass to match the engine's type.

CFAM designs offer a lot of flexibility, for instance it is possible for
a CFAM to be simultaneously driven from multiple FSI links. The modeling
is not so complete; it's assumed that each CFAM is attached to a single
FSI slave (as a consequence the CFAM subclasses the FSI slave).

As for FSI, its symbols and wire-protocol are not modelled at all. This
is not necessary to get FSI off the ground thanks to the mapping of the
CFAM address space onto the OPB address space - the models follow this
directly and map the CFAM memory region into the OPB's memory region.
Future work includes supporting more advanced accesses that drive the
FSI master directly rather than indirectly via the CFAM mapping, which
will require implementing the FSI state machine and methods for each of
the FSI symbols on the slave. Further down the track we can also look at
supporting the bitbanged SoftFSI drivers in Linux by extending the FSI
slave model to resolve sequences of GPIO IRQs into FSI symbols, and
calling the associated symbol method on the slave to map the access onto
the CFAM.

Testing:
Tested by reading cfam config address 0 on rainier machine type.

root@p10bmc:~# pdbg -a getcfam 0x0
p0: 0x0 = 0xc0022d15

Signed-off-by: Andrew Jeffery 
Signed-off-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
 include/hw/arm/aspeed_soc.h |  4 
 hw/arm/aspeed_ast2600.c | 19 +++
 2 files changed, 23 insertions(+)

diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index cb832bc1ee..563767af35 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -36,6 +36,7 @@
 #include "hw/misc/aspeed_lpc.h"
 #include "hw/misc/unimp.h"
 #include "hw/misc/aspeed_peci.h"
+#include "hw/fsi/aspeed_apb2opb.h"
 #include 

[PATCH v11 03/11] hw/fsi: Introduce IBM's FSI Bus

2024-01-25 Thread Ninad Palsule
This is a part of patchset where FSI bus is introduced.

The FSI bus is a simple bus where FSI master is attached.

Signed-off-by: Andrew Jeffery 
[ clg: - removed include/hw/fsi/engine-scratchpad.h and
 hw/fsi/engine-scratchpad.c
   - dropped FSI_SCRATCHPAD
   - included FSIBus definition
   - dropped hw/fsi/trace-events changes ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
v11:
  - Split the patch.
---
 include/hw/fsi/fsi.h | 19 +++
 hw/fsi/fsi.c | 22 ++
 hw/fsi/meson.build   |  2 +-
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/fsi/fsi.h
 create mode 100644 hw/fsi/fsi.c

diff --git a/include/hw/fsi/fsi.h b/include/hw/fsi/fsi.h
new file mode 100644
index 00..50e8f5c888
--- /dev/null
+++ b/include/hw/fsi/fsi.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * IBM Flexible Service Interface
+ */
+#ifndef FSI_FSI_H
+#define FSI_FSI_H
+
+#include "hw/qdev-core.h"
+
+#define TYPE_FSI_BUS "fsi.bus"
+OBJECT_DECLARE_SIMPLE_TYPE(FSIBus, FSI_BUS)
+
+typedef struct FSIBus {
+BusState bus;
+} FSIBus;
+
+#endif /* FSI_FSI_H */
diff --git a/hw/fsi/fsi.c b/hw/fsi/fsi.c
new file mode 100644
index 00..60cb03f7a2
--- /dev/null
+++ b/hw/fsi/fsi.c
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * IBM Flexible Service Interface
+ */
+#include "qemu/osdep.h"
+
+#include "hw/fsi/fsi.h"
+
+static const TypeInfo fsi_bus_info = {
+.name = TYPE_FSI_BUS,
+.parent = TYPE_BUS,
+.instance_size = sizeof(FSIBus),
+};
+
+static void fsi_bus_register_types(void)
+{
+type_register_static(_bus_info);
+}
+
+type_init(fsi_bus_register_types);
diff --git a/hw/fsi/meson.build b/hw/fsi/meson.build
index 93ba19dd04..574f5f9289 100644
--- a/hw/fsi/meson.build
+++ b/hw/fsi/meson.build
@@ -1 +1 @@
-system_ss.add(when: 'CONFIG_FSI', if_true: files('lbus.c'))
+system_ss.add(when: 'CONFIG_FSI', if_true: files('lbus.c','fsi.c'))
-- 
2.39.2




[PATCH v11 00/11] Introduce model for IBM's FSI

2024-01-25 Thread Ninad Palsule
Hello,
 
Please review the patch-set version 11. 
I have incorporated review comments from Cedric.
v10:
  - Moved aspeed-apb2opb to hw/fsi directory
  - Split some patches.
  - Fixed crash.
  - make check
Ok: 319 
Expected Fail:  0   
Fail:   0   
Unexpected Pass:0   
Skipped:9   
Timeout:0   


Ninad Palsule (11):
  hw/fsi: Introduce IBM's Local bus
  hw/fsi: Introduce IBM's scratchpad device
  hw/fsi: Introduce IBM's FSI Bus
  hw/fsi: Introduce IBM's fsi-slave model
  hw/fsi: Introduce IBM's cfam
  hw/fsi: Introduce IBM's FSI master
  hw/fsi: Aspeed APB2OPB & On-chip peripheral bus
  hw/arm: Hook up FSI module in AST2600
  hw/fsi: Added qtest
  hw/fsi: Added FSI documentation
  hw/fsi: Update MAINTAINER list

 MAINTAINERS |   9 +
 docs/specs/fsi.rst  | 138 ++
 docs/specs/index.rst|   1 +
 meson.build |   1 +
 hw/fsi/trace.h  |   1 +
 include/hw/arm/aspeed_soc.h |   4 +
 include/hw/fsi/aspeed_apb2opb.h |  46 +
 include/hw/fsi/cfam.h   |  34 
 include/hw/fsi/fsi-master.h |  32 
 include/hw/fsi/fsi.h|  38 
 include/hw/fsi/lbus.h   |  43 +
 hw/arm/aspeed_ast2600.c |  19 ++
 hw/fsi/aspeed_apb2opb.c | 322 
 hw/fsi/cfam.c   | 168 +
 hw/fsi/fsi-master.c | 170 +
 hw/fsi/fsi.c| 105 +++
 hw/fsi/lbus.c   | 112 +++
 tests/qtest/aspeed-fsi-test.c   | 205 
 hw/Kconfig  |   1 +
 hw/arm/Kconfig  |   1 +
 hw/fsi/Kconfig  |   7 +
 hw/fsi/meson.build  |   2 +
 hw/fsi/trace-events |  13 ++
 hw/meson.build  |   1 +
 tests/qtest/meson.build |   1 +
 25 files changed, 1474 insertions(+)
 create mode 100644 docs/specs/fsi.rst
 create mode 100644 hw/fsi/trace.h
 create mode 100644 include/hw/fsi/aspeed_apb2opb.h
 create mode 100644 include/hw/fsi/cfam.h
 create mode 100644 include/hw/fsi/fsi-master.h
 create mode 100644 include/hw/fsi/fsi.h
 create mode 100644 include/hw/fsi/lbus.h
 create mode 100644 hw/fsi/aspeed_apb2opb.c
 create mode 100644 hw/fsi/cfam.c
 create mode 100644 hw/fsi/fsi-master.c
 create mode 100644 hw/fsi/fsi.c
 create mode 100644 hw/fsi/lbus.c
 create mode 100644 tests/qtest/aspeed-fsi-test.c
 create mode 100644 hw/fsi/Kconfig
 create mode 100644 hw/fsi/meson.build
 create mode 100644 hw/fsi/trace-events

-- 
2.39.2




[PATCH v11 07/11] hw/fsi: Aspeed APB2OPB & On-chip peripheral bus

2024-01-25 Thread Ninad Palsule
This is a part of patchset where IBM's Flexible Service Interface is
introduced.

An APB-to-OPB bridge enabling access to the OPB from the ARM core in
the AST2600. Hardware limitations prevent the OPB from being directly
mapped into APB, so all accesses are indirect through the bridge.

The On-Chip Peripheral Bus (OPB): A low-speed bus typically found in
POWER processors. This now makes an appearance in the ASPEED SoC due
to tight integration of the FSI master IP with the OPB, mainly the
existence of an MMIO-mapping of the CFAM address straight onto a
sub-region of the OPB address space.

Signed-off-by: Andrew Jeffery 
[ clg: - moved FSIMasterState under AspeedAPB2OPBState
   - modified fsi_opb_fsi_master_address() and
 fsi_opb_opb2fsi_address()
   - instroduced fsi_aspeed_apb2opb_init()
   - reworked fsi_aspeed_apb2opb_realize()
   - removed FSIMasterState object and fsi_opb_realize()
   - simplified OPBus ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
v9:
  - Removed unused parameters from function.
  - Used qdev_realize() instead of qdev_realize_and_undef
  - Given a name to the opb memory region.

v10:
  - Combine Aspeed APB2OPB and on-chip pheripheral bus
---
 include/hw/fsi/aspeed_apb2opb.h |  46 +
 hw/fsi/aspeed_apb2opb.c | 322 
 hw/arm/Kconfig  |   1 +
 hw/fsi/Kconfig  |   5 +
 hw/fsi/meson.build  |   1 +
 hw/fsi/trace-events |   2 +
 6 files changed, 377 insertions(+)
 create mode 100644 include/hw/fsi/aspeed_apb2opb.h
 create mode 100644 hw/fsi/aspeed_apb2opb.c

diff --git a/include/hw/fsi/aspeed_apb2opb.h b/include/hw/fsi/aspeed_apb2opb.h
new file mode 100644
index 00..f6a2387abf
--- /dev/null
+++ b/include/hw/fsi/aspeed_apb2opb.h
@@ -0,0 +1,46 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * ASPEED APB2OPB Bridge
+ * IBM On-Chip Peripheral Bus
+ */
+#ifndef FSI_ASPEED_APB2OPB_H
+#define FSI_ASPEED_APB2OPB_H
+
+#include "exec/memory.h"
+#include "hw/fsi/fsi-master.h"
+#include "hw/sysbus.h"
+
+#define TYPE_FSI_OPB "fsi.opb"
+
+#define TYPE_OP_BUS "opb"
+OBJECT_DECLARE_SIMPLE_TYPE(OPBus, OP_BUS)
+
+typedef struct OPBus {
+BusState bus;
+
+MemoryRegion mr;
+AddressSpace as;
+} OPBus;
+
+#define TYPE_ASPEED_APB2OPB "aspeed.apb2opb"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedAPB2OPBState, ASPEED_APB2OPB)
+
+#define ASPEED_APB2OPB_NR_REGS ((0xe8 >> 2) + 1)
+
+#define ASPEED_FSI_NUM 2
+
+typedef struct AspeedAPB2OPBState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+
+uint32_t regs[ASPEED_APB2OPB_NR_REGS];
+qemu_irq irq;
+
+OPBus opb[ASPEED_FSI_NUM];
+FSIMasterState fsi[ASPEED_FSI_NUM];
+} AspeedAPB2OPBState;
+
+#endif /* FSI_ASPEED_APB2OPB_H */
diff --git a/hw/fsi/aspeed_apb2opb.c b/hw/fsi/aspeed_apb2opb.c
new file mode 100644
index 00..997ae30060
--- /dev/null
+++ b/hw/fsi/aspeed_apb2opb.c
@@ -0,0 +1,322 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2024 IBM Corp.
+ *
+ * ASPEED APB-OPB FSI interface
+ * IBM On-chip Peripheral Bus
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "trace.h"
+
+#include "hw/fsi/aspeed_apb2opb.h"
+#include "hw/qdev-core.h"
+
+#define TO_REG(x) (x >> 2)
+
+#define APB2OPB_VERSIONTO_REG(0x00)
+#define APB2OPB_TRIGGERTO_REG(0x04)
+
+#define APB2OPB_CONTROLTO_REG(0x08)
+#define   APB2OPB_CONTROL_OFF  BE_GENMASK(31, 13)
+
+#define APB2OPB_OPB2FSITO_REG(0x0c)
+#define   APB2OPB_OPB2FSI_OFF  BE_GENMASK(31, 22)
+
+#define APB2OPB_OPB0_SEL   TO_REG(0x10)
+#define APB2OPB_OPB1_SEL   TO_REG(0x28)
+#define   APB2OPB_OPB_SEL_EN   BIT(0)
+
+#define APB2OPB_OPB0_MODE  TO_REG(0x14)
+#define APB2OPB_OPB1_MODE  TO_REG(0x2c)
+#define   APB2OPB_OPB_MODE_RD  BIT(0)
+
+#define APB2OPB_OPB0_XFER  TO_REG(0x18)
+#define APB2OPB_OPB1_XFER  TO_REG(0x30)
+#define   APB2OPB_OPB_XFER_FULLBIT(1)
+#define   APB2OPB_OPB_XFER_HALFBIT(0)
+
+#define APB2OPB_OPB0_ADDR  TO_REG(0x1c)
+#define APB2OPB_OPB0_WRITE_DATATO_REG(0x20)
+
+#define APB2OPB_OPB1_ADDR  TO_REG(0x34)
+#define APB2OPB_OPB1_WRITE_DATA  TO_REG(0x38)
+
+#define APB2OPB_IRQ_STSTO_REG(0x48)
+#define   APB2OPB_IRQ_STS_OPB1_TX_ACK  BIT(17)
+#define   APB2OPB_IRQ_STS_OPB0_TX_ACK  BIT(16)
+
+#define APB2OPB_OPB0_WRITE_WORD_ENDIAN TO_REG(0x4c)
+#define   APB2OPB_OPB0_WRITE_WORD_ENDIAN_BE 0x0011101b
+#define APB2OPB_OPB0_WRITE_BYTE_ENDIAN TO_REG(0x50)
+#define   APB2OPB_OPB0_WRITE_BYTE_ENDIAN_BE 0x0c330f3f
+#define APB2OPB_OPB1_WRITE_WORD_ENDIAN TO_REG(0x54)
+#define 

Re: [PATCH v7 10/16] i386/cpu: Introduce cluster-id to X86CPU

2024-01-25 Thread Zhao Liu
Hi Xiaoyao,

> > > > generic cluster just means the cluster of processors, i.e, a group of
> > > > cpus/lps. It is just a middle level between die and core.
> > > 
> > > Not sure if you mean the "cluster" device for TCG GDB? "cluster" device
> > > is different with "cluster" option in -smp.
> > 
> > No, I just mean the word 'cluster'. And I thought what you called "generic
> > cluster" means "a cluster of logical processors"
> > 
> > Below I quote the description of Yanan's commit 864c3b5c32f0:
> > 
> > A cluster generally means a group of CPU cores which share L2 cache
> > or other mid-level resources, and it is the shared resources that
> > is used to improve scheduler's behavior. From the point of view of
> > the size range, it's between CPU die and CPU core. For example, on
> > some ARM64 Kunpeng servers, we have 6 clusters in each NUMA node,
> > and 4 CPU cores in each cluster. The 4 CPU cores share a separate
> > L2 cache and a L3 cache tag, which brings cache affinity advantage.
> > 
> > What I get from it, is, cluster is just a middle level between CPU die and
> > CPU core.
> 
> Here the words "a group of CPU" is not the software concept, but a hardware
> topology.

When I found this material:

https://www.kernel.org/doc/Documentation/devicetree/bindings/cpu/cpu-topology.txt

I realized the most essential difference between cluster and module is
that cluster supports nesting, i.e. it can have nesting clusters as a
layer of CPU topology.

Even though QEMU's description of cluster looked similar to module when
it was introduced, it is impossible to envision whether ARM/RISCV and
other device tree-based arches will continue to introduce nesting
clusters in the future.

To avoid potential conflicts, it would be better to introduce modules
for x86 to differentiate them from clusters.

Thanks,
Zhao




Re: [PATCH 03/17] migration: Rename default_channel to main_channel

2024-01-25 Thread Peter Xu
On Thu, Jan 25, 2024 at 06:25:14PM +0200, Avihai Horon wrote:
> migration_ioc_process_incoming() uses the term "default_channel" to
> describe the main migration channel. Rename it to the more commonly used
> and informative term "main_channel".
> 
> Signed-off-by: Avihai Horon 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH 02/17] migration: Move local_err check in migration_ioc_process_incoming()

2024-01-25 Thread Peter Xu
On Thu, Jan 25, 2024 at 06:25:13PM +0200, Avihai Horon wrote:
> local_err in migration_ioc_process_incoming() is used only in the
> multifd if branch. Move the local_err check under the multifd branch,
> where it is actually used.
> 
> Signed-off-by: Avihai Horon 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH 01/17] migration: Fix logic of channels and transport compatibility check

2024-01-25 Thread Peter Xu
On Thu, Jan 25, 2024 at 06:25:12PM +0200, Avihai Horon wrote:
> The commit in the fixes line mistakenly modified the channels and
> transport compatibility check logic so it now checks multi-channel
> support only for socket transport type.
> 
> Thus, running multifd migration using a transport other than socket that
> is incompatible with multi-channels (such as "exec") would lead to a
> segmentation fault instead of an error message.
> For example:
>   (qemu) migrate_set_capability multifd on
>   (qemu) migrate -d "exec:cat > /tmp/vm_state"
>   Segmentation fault (core dumped)
> 
> Fix it by checking multi-channel compatibility for all transport types.
> 
> Fixes: d95533e1cdcc ("migration: modify 
> migration_channels_and_uri_compatible() for new QAPI syntax")
> Signed-off-by: Avihai Horon 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v10 5/9] hw/fsi: Aspeed APB2OPB interface, Onchip perif bus

2024-01-25 Thread Ninad Palsule

Hello Cedric,




Signed-off-by: Andrew Jeffery 
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
Reviewed-by: Joel Stanley 


Nah. Joel you should re-review next respin :)

Removed Joel's review tag.




---
  include/hw/misc/aspeed-apb2opb.h |  50 +
  hw/misc/aspeed-apb2opb.c | 338 +++


As said in the cover letter, I think now that hw/fsi is a better place
for these files and should be compiled if CONSG_ASPEED_SOC. Sorry about
that. Also,please use 'aspeed_' for the file names.

Transferred to the old location and rename with "aspeed_" prefix.




+
+#define TYPE_OP_BUS "opb"
+OBJECT_DECLARE_SIMPLE_TYPE(OPBus, OP_BUS)
+
+typedef struct OPBus {
+    /*< private >*/


please remove the private and public comment.

Removed.



+    BusState bus;
+
+    /*< public >*/
+    MemoryRegion mr;
+    AddressSpace as;


indent is wrong.

Fixed indent.




+static void fsi_aspeed_apb2opb_init(Object *o)
+{
+    AspeedAPB2OPBState *s = ASPEED_APB2OPB(o);
+    int i;
+
+    for (i = 0; i < ASPEED_FSI_NUM; i++) {
+    qbus_init(>opb[i], sizeof(s->opb[i]), TYPE_OP_BUS, 
DEVICE(s),

+  NULL);


See comment in fsi_opb_init()

Moved it to si_aspeed_apb2opb_realize(),



+    for (i = 0; i < ASPEED_FSI_NUM; i++) {
+    if (!qdev_realize(DEVICE(>fsi[i]), BUS(>opb[i]),
+    errp)) {


this could be a single line.

Removed extra line.


Please remove the comments below, I am not sure they are valid
anymore.

Removed the comment.



+    /*
+ * Avoid endianness issues by mapping each slave's memory 
region
+ * directly. Manually bridging multiple address-spaces 
causes endian

+ * swapping headaches as memory_region_dispatch_read() and
+ * memory_region_dispatch_write() correct the endianness 
based on the
+ * target machine endianness and not relative to the device 
endianness

+ * on either side of the bridge.
+ */
+    /*
+ * XXX: This is a bit hairy and will need to be fixed when I 
sort out
+ * the bus/slave relationship and any changes to the CFAM 
modelling

+ * (multiple slaves, LBUS)
+ */
+    memory_region_add_subregion(>opb[i].mr, 0xa000,
+    >fsi[i].opb2fsi);
+    }
+}

+
+static void fsi_opb_init(Object *o)
+{
+    OPBus *opb = OP_BUS(o);
+
+    memory_region_init_io(>mr, OBJECT(opb), NULL, opb,
+  TYPE_FSI_OPB, UINT32_MAX);


This is better :

memory_region_init(>mr, o, TYPE_OP_BUS, UINT32_MAX);

Changed it as per your suggestion.




+    address_space_init(>as, >mr, TYPE_FSI_OPB);


This routine is problematic. If you run 'make check', you should see
test tests/qtest/device-introspect-test crash in weird way because of
a memory corruption. I didn't dig into the details but I suppose this
a use after free problem.

To solve, we should move qbus_init() done in fsi_aspeed_apb2opb_init()
under fsi_aspeed_apb2opb_realize(), or improve the model a litle more.

It seems we are lacking the OPB/FSI bridge :

typedef struct OPBFSIBridge {
    DeviceState parent;

    OPBus opb;
    FSIMasterState fsi;
    MemoryRegion mr;
    AddressSpace as;
} OPBFSIBridge;

Something like that. It is difficult to understand the design from
the OpenFSI specs. The OPB bus seems overkill. It you could clarify
this aspect, it would be nice.


For now moved qbus_init() to fsi_aspeed_apb2opb_realize(). I will run 
make check.


Thanks for the review.

Regards,

Ninad





Re: [PATCH v15 0/9] rutabaga_gfx + gfxstream

2024-01-25 Thread Gurchetan Singh
On Sat, Jan 20, 2024 at 4:19 AM Alyssa Ross  wrote:

> Gurchetan Singh  writes:
>
> > On Fri, Jan 19, 2024 at 1:13 PM Alyssa Ross  wrote:
> >>
> >> Hi Gurchetan,
> >>
> >> > Thanks for the reminder.  I did make a request to create the release
> >> > tags, but changes were requested by Fedora packaging effort:
> >> >
> >> > https://bugzilla.redhat.com/show_bug.cgi?id=2242058
> >> > https://bugzilla.redhat.com/show_bug.cgi?id=2241701
> >> >
> >> > So the request was canceled, but never re-requested.  I'll fire off
> >> > another request, with:
> >> >
> >> > gfxstream: 23d05703b94035ac045df60823fb1fc4be0fdf1c ("gfxstream:
> >> > manually add debug logic")
> >> > AEMU: dd8b929c247ce9872c775e0e5ddc4300011d0e82 ("aemu: improve
> licensing")
> >> >
> >> > as the commits.  These match the Fedora requests, and the AEMU one has
> >> > been merged into Fedora already it seems.
> >>
> >> These revisions have the problem I mentioned in my previous message:
> >>
> >> >> The gfxstream ref mentioned here isn't compatible with
> >> >> v0.1.2-rutabaga-release, because it no longer provides
> logging_base.pc,
> >>
> >> rutabaga was not fixed to use the new AEMU package names until after the
> >> v0.1.2-rutabaga-release tag, in commit 5dfd74a06.  So will there be a
> >> new Rutabaga release that's compatible with these release versions of
> >> gfxstream and AEMU?
> >
> > Good catch.
> >
> > One possible workaround is to build gfxstream as a shared library.  I
> > think that would avoid rutabaga looking for AEMU package config files.
> >
> > But if another rutabaga release is desired with support for a static
> > library, then we can make that happen too.
>
> We're exclusively building gfxstream as a shared library.
>
> Looking at rutabaga's build.rs, it appears to me like pkg-config is
> always used for gfxstream unless overridden by GFXSTREAM_PATH.
>

Hmm, it seems we should be checking pkg-config --static before looking for
AEMU in build.rs -- oh well.

Would this be a suitable commit for the 0.1.3 release of rutabaga?

https://chromium.googlesource.com/crosvm/crosvm/+/5dfd74a0680d317c6edf44138def886f47cb1c7c

The gfxstream/AEMU commits would remain unchanged.


[PATCH v2 1/3] hw/i2c: core: Add reset

2024-01-25 Thread Joe Komlodi
It's possible for a reset to come in the middle of a transaction, which
causes the bus to be in an old state when a new transaction comes in.

Signed-off-by: Joe Komlodi 
---
 hw/i2c/core.c| 30 +-
 include/hw/i2c/i2c.h |  6 +-
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 4cf30b2c86..def4f134d0 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -23,11 +23,31 @@ static Property i2c_props[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
-static const TypeInfo i2c_bus_info = {
-.name = TYPE_I2C_BUS,
-.parent = TYPE_BUS,
-.instance_size = sizeof(I2CBus),
-};
+static void i2c_bus_enter_reset(Object *obj, ResetType type)
+{
+I2CBus *bus = I2C_BUS(obj);
+I2CNode *node, *next;
+
+bus->broadcast = false;
+QLIST_FOREACH_SAFE(node, >current_devs, next, next) {
+QLIST_REMOVE(node, next);
+g_free(node);
+}
+}
+
+static void i2c_bus_class_init(ObjectClass *klass, void *data)
+{
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+rc->phases.enter = i2c_bus_enter_reset;
+}
+
+ static const TypeInfo i2c_bus_info = {
+ .name = TYPE_I2C_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(I2CBus),
+ .class_size = sizeof(I2CBusClass),
+ .class_init = i2c_bus_class_init,
+ };
 
 static int i2c_bus_pre_save(void *opaque)
 {
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 2a3abacd1b..420868a269 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -64,7 +64,7 @@ struct I2CSlave {
 };
 
 #define TYPE_I2C_BUS "i2c-bus"
-OBJECT_DECLARE_SIMPLE_TYPE(I2CBus, I2C_BUS)
+OBJECT_DECLARE_TYPE(I2CBus, I2CBusClass, I2C_BUS)
 
 typedef struct I2CNode I2CNode;
 
@@ -83,6 +83,10 @@ struct I2CPendingMaster {
 typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList;
 typedef QSIMPLEQ_HEAD(I2CPendingMasters, I2CPendingMaster) I2CPendingMasters;
 
+struct I2CBusClass {
+DeviceClass parent_class;
+};
+
 struct I2CBus {
 BusState qbus;
 I2CNodeList current_devs;
-- 
2.43.0.429.g432eaa2c6b-goog




[PATCH v2 3/3] hw/i2c: smbus_slave: Reset state on reset

2024-01-25 Thread Joe Komlodi
If a reset comes while the SMBus device is not in its idle state, it's
possible for it to get confused on valid transactions post-reset.

Signed-off-by: Joe Komlodi 
---
 hw/i2c/smbus_slave.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
index e24a1ef472..58abde29de 100644
--- a/hw/i2c/smbus_slave.c
+++ b/hw/i2c/smbus_slave.c
@@ -201,10 +201,19 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)
 return 0;
 }
 
+static void smbus_device_enter_reset(Object *obj, ResetType type)
+{
+SMBusDevice *dev = SMBUS_DEVICE(obj);
+dev->mode = SMBUS_IDLE;
+dev->data_len = 0;
+}
+
 static void smbus_device_class_init(ObjectClass *klass, void *data)
 {
 I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
+ResettableClass *rc = RESETTABLE_CLASS(klass);
 
+rc->phases.enter = smbus_device_enter_reset;
 sc->event = smbus_i2c_event;
 sc->recv = smbus_i2c_recv;
 sc->send = smbus_i2c_send;
-- 
2.43.0.429.g432eaa2c6b-goog




[PATCH v2 0/3] hw/i2c: smbus: Reset fixes

2024-01-25 Thread Joe Komlodi
Changelog:

v1 -> v2
- Dropped 4th patch "hw/i2c: smbus: mux: Reset SMBusDevice state
on reset". After more testing and Corey's comment, I realized it
wasn't needed.

Original message:

Hi all,

This series adds some resets for SMBus and for the I2C core. Along with
it, we make SMBus slave error printing a little more helpful.

These reset issues were very infrequent, they would maybe occur in 1 out
of hundreds of resets in our testing, but the way they happen is pretty
straightforward.

Basically as long as a reset happens in the middle of a transaction, the
state of the old transaction would still partially be there after the
reset. Once a new transaction comes in, the partial stale state can
cause the new transaction to incorrectly fail.

Thanks,
Joe

Joe Komlodi (3):
  hw/i2c: core: Add reset
  hw/i2c/smbus_slave: Add object path on error prints
  hw/i2c: smbus_slave: Reset state on reset

 hw/i2c/core.c| 30 +-
 hw/i2c/smbus_slave.c | 17 +++--
 include/hw/i2c/i2c.h |  6 +-
 3 files changed, 45 insertions(+), 8 deletions(-)

-- 
2.43.0.429.g432eaa2c6b-goog




[PATCH v2 2/3] hw/i2c/smbus_slave: Add object path on error prints

2024-01-25 Thread Joe Komlodi
The current logging doesn't tell us which specific smbus device is an
error state.

Signed-off-by: Joe Komlodi 
---
 hw/i2c/smbus_slave.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
index 1300c9ec72..e24a1ef472 100644
--- a/hw/i2c/smbus_slave.c
+++ b/hw/i2c/smbus_slave.c
@@ -25,11 +25,15 @@
 #define DPRINTF(fmt, ...) \
 do { printf("smbus(%02x): " fmt , dev->i2c.address, ## __VA_ARGS__); } while 
(0)
 #define BADF(fmt, ...) \
-do { fprintf(stderr, "smbus: error: " fmt , ## __VA_ARGS__); exit(1);} while 
(0)
+do { fprintf(stderr, "%s: smbus: error: " fmt , \
+ object_get_canonical_path(OBJECT(dev)), ## __VA_ARGS__); \
+ exit(1); } while (0)
 #else
 #define DPRINTF(fmt, ...) do {} while(0)
 #define BADF(fmt, ...) \
-do { fprintf(stderr, "smbus: error: " fmt , ## __VA_ARGS__);} while (0)
+do { fprintf(stderr, "%s: smbus: error: " fmt , \
+ object_get_canonical_path(OBJECT(dev)), ## __VA_ARGS__); \
+ } while (0)
 #endif
 
 enum {
-- 
2.43.0.429.g432eaa2c6b-goog




Re: [PATCH v10 3/9] hw/fsi: Introduce IBM's cfam

2024-01-25 Thread Ninad Palsule

Hello Cedric,



[ clg: - moved object FSIScratchPad under FSICFAMState
    - moved FSIScratchPad code under cfam.c
    - introduced fsi_cfam_instance_init()
    - reworked fsi_cfam_realize() ]


Move the list down before my S-o-b.

Done.




+
+/* Valid, slots, version, type, crc */
+#define CFAM_CONFIG_REG_FSI_SLAVE (ENGINE_CONFIG_NEXT   | \
+ 0x0001   | \
+ 0x5000   | \
+ ENGINE_CONFIG_TYPE_FSI   | \
+    0x000a)
+
+/* Valid, slots, version, type, crc */
+#define CFAM_CONFIG_REG_SCRATCHPAD (ENGINE_CONFIG_NEXT   | \
+ 0x0001   | \
+ 0x1000   | \
+ ENGINE_CONFIG_TYPE_SCRATCHPAD | \
+    0x0007)


I was expecting a macro taking argument to build the config reg value
of each sub engine but that's fine also.


Added single macro.






+
+    memory_region_add_subregion(>mr, 0, >config_iomem);
+    memory_region_add_subregion(>mr, 0x800, >iomem);
+    memory_region_add_subregion(>mr, 0xc00, >lbus.mr);
+
+    /* Add scratchpad engine */
+    if (!qdev_realize(DEVICE(>scratchpad), BUS(>lbus),
+    errp)) {


could be a single line.


Yep, Made it a single line.

Thanks for the review.

Regards,

Ninad





Re: [PATCH v10 2/9] hw/fsi: Introduce IBM's FSI Bus and FSI slave

2024-01-25 Thread Ninad Palsule

Hello Cedric,



The FSI slave: The slave is the terminal point of the FSI bus for
FSI symbols addressed to it. Slaves can be cascaded off of one
another. The slave's configuration registers appear in address space
of the CFAM to which it is attached.


Please add another patch.

Added new patch for FSI-slave.



[ clg: - removed include/hw/fsi/engine-scratchpad.h and
 hw/fsi/engine-scratchpad.c
    - dropped FSI_SCRATCHPAD
    - included FSIBus definition
    - dropped hw/fsi/trace-events changes ]


Move the list down before my S-o-b.

Moved the list.

Thanks for the review.

Regards,

Ninad





Re: [External] Re: [PATCH v2 04/20] So we use multifd to transmit zero pages.

2024-01-25 Thread Hao Xiang
On Thu, Jan 25, 2024 at 3:14 PM Fabiano Rosas  wrote:
>
> Hao Xiang  writes:
>
> > On Mon, Jan 22, 2024 at 8:28 PM Hao Xiang  wrote:
> >>
> >> On Thu, Nov 16, 2023 at 7:14 AM Fabiano Rosas  wrote:
> >> >
> >> > Hao Xiang  writes:
> >> >
> >> > > From: Juan Quintela 
> >> > >
> >> > > Signed-off-by: Juan Quintela 
> >> > > Reviewed-by: Leonardo Bras 
> >> > > ---
> >> > >  migration/multifd.c |  7 ---
> >> > >  migration/options.c | 13 +++--
> >> > >  migration/ram.c | 45 ++---
> >> > >  qapi/migration.json |  1 -
> >> > >  4 files changed, 49 insertions(+), 17 deletions(-)
> >> > >
> >> > > diff --git a/migration/multifd.c b/migration/multifd.c
> >> > > index 1b994790d5..1198ffde9c 100644
> >> > > --- a/migration/multifd.c
> >> > > +++ b/migration/multifd.c
> >> > > @@ -13,6 +13,7 @@
> >> > >  #include "qemu/osdep.h"
> >> > >  #include "qemu/cutils.h"
> >> > >  #include "qemu/rcu.h"
> >> > > +#include "qemu/cutils.h"
> >> > >  #include "exec/target_page.h"
> >> > >  #include "sysemu/sysemu.h"
> >> > >  #include "exec/ramblock.h"
> >> > > @@ -459,7 +460,6 @@ static int multifd_send_pages(QEMUFile *f)
> >> > >  p->packet_num = multifd_send_state->packet_num++;
> >> > >  multifd_send_state->pages = p->pages;
> >> > >  p->pages = pages;
> >> > > -
> >> > >  qemu_mutex_unlock(>mutex);
> >> > >  qemu_sem_post(>sem);
> >> > >
> >> > > @@ -684,7 +684,7 @@ static void *multifd_send_thread(void *opaque)
> >> > >  MigrationThread *thread = NULL;
> >> > >  Error *local_err = NULL;
> >> > >  /* qemu older than 8.2 don't understand zero page on multifd 
> >> > > channel */
> >> > > -bool use_zero_page = !migrate_use_main_zero_page();
> >> > > +bool use_multifd_zero_page = !migrate_use_main_zero_page();
> >> > >  int ret = 0;
> >> > >  bool use_zero_copy_send = migrate_zero_copy_send();
> >> > >
> >> > > @@ -713,6 +713,7 @@ static void *multifd_send_thread(void *opaque)
> >> > >  RAMBlock *rb = p->pages->block;
> >> > >  uint64_t packet_num = p->packet_num;
> >> > >  uint32_t flags;
> >> > > +
> >> > >  p->normal_num = 0;
> >> > >  p->zero_num = 0;
> >> > >
> >> > > @@ -724,7 +725,7 @@ static void *multifd_send_thread(void *opaque)
> >> > >
> >> > >  for (int i = 0; i < p->pages->num; i++) {
> >> > >  uint64_t offset = p->pages->offset[i];
> >> > > -if (use_zero_page &&
> >> > > +if (use_multifd_zero_page &&
> >> >
> >> > We could have a new function in multifd_ops for zero page
> >> > handling. We're already considering an accelerator for the compression
> >> > method in the other series[1] and in this series we're adding an
> >> > accelerator for zero page checking. It's about time we make the
> >> > multifd_ops generic instead of only compression/no compression.
> >>
> >> Sorry I overlooked this email earlier.
> >> I will extend the multifd_ops interface and add a new API for zero
> >> page checking.
> >>
> >> >
> >> > 1- [PATCH v2 0/4] Live Migration Acceleration with IAA Compression
> >> > https://lore.kernel.org/r/20231109154638.488213-1-yuan1@intel.com
> >> >
> >> > >  buffer_is_zero(rb->host + offset, p->page_size)) {
> >> > >  p->zero[p->zero_num] = offset;
> >> > >  p->zero_num++;
> >> > > diff --git a/migration/options.c b/migration/options.c
> >> > > index 00c0c4a0d6..97d121d4d7 100644
> >> > > --- a/migration/options.c
> >> > > +++ b/migration/options.c
> >> > > @@ -195,6 +195,7 @@ Property migration_properties[] = {
> >> > >  DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
> >> > >  DEFINE_PROP_MIG_CAP("x-return-path", 
> >> > > MIGRATION_CAPABILITY_RETURN_PATH),
> >> > >  DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
> >> > > +DEFINE_PROP_MIG_CAP("x-main-zero-page", 
> >> > > MIGRATION_CAPABILITY_MAIN_ZERO_PAGE),
> >> > >  DEFINE_PROP_MIG_CAP("x-background-snapshot",
> >> > >  MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
> >> > >  #ifdef CONFIG_LINUX
> >> > > @@ -288,13 +289,9 @@ bool migrate_multifd(void)
> >> > >
> >> > >  bool migrate_use_main_zero_page(void)
> >> > >  {
> >> > > -//MigrationState *s;
> >> > > -
> >> > > -//s = migrate_get_current();
> >> > > +MigrationState *s = migrate_get_current();
> >> > >
> >> > > -// We will enable this when we add the right code.
> >> > > -// return 
> >> > > s->enabled_capabilities[MIGRATION_CAPABILITY_MAIN_ZERO_PAGE];
> >> > > -return true;
> >> > > +return s->capabilities[MIGRATION_CAPABILITY_MAIN_ZERO_PAGE];
> >> >
> >> > What happens if we disable main-zero-page while multifd is not enabled?
> >>
> >> In ram.c
> >> ...
> >> if (migrate_multifd() && !migrate_use_main_zero_page()) {
> >> migration_ops->ram_save_target_page = ram_save_target_page_multifd;
> >> } else {
> >> 

Re: [PATCH v10 1/9] hw/fsi: Introduce IBM's Local bus and scratchpad

2024-01-25 Thread Ninad Palsule

Hello Cedric,





[ clg: - removed lbus_add_device() bc unused
    - removed lbus_create_device() bc used only once
    - removed "address" property
    - updated meson.build to build fsi dir
    - included an empty hw/fsi/trace-events ]


this list of modifications should be before my S-o-b.

Moved it to correct place.


+
+#define TYPE_FSI_LBUS_DEVICE "fsi.lbus.device"
+OBJECT_DECLARE_TYPE(FSILBusDevice, FSILBusDeviceClass, FSI_LBUS_DEVICE)
+
+#define FSI_LBUS_MEM_REGION_SIZE  (1 * MiB)
+#define FSI_LBUSDEV_IOMEM_START   0xc00 /* 3K used by CFAM config 
etc */


These define are not very useful. Please remove (see comments in
lbus.c)

Removed.




+typedef struct FSILBusDeviceClass {
+    DeviceClass parent;
+
+    uint32_t config;
+} FSILBusDeviceClass;


This class is unused now.

Removed the class. We will add it once we add more devices.




+#include "trace.h"
+
+static void lbus_init(Object *o)


I would prefix the lbus routine and struct with fsi_lbus to be
consistent with the types and macro.

Added prefix fsi_ for all routines.



+{
+    FSILBus *lbus = FSI_LBUS(o);
+
+    memory_region_init(>mr, OBJECT(lbus), TYPE_FSI_LBUS,
+   FSI_LBUS_MEM_REGION_SIZE - 
FSI_LBUSDEV_IOMEM_START);


This is enough :

    memory_region_init(>mr, OBJECT(lbus), TYPE_FSI_LBUS, 1 * MiB);

Changed as per your suggestion.





+
+static void fsi_scratchpad_write(void *opaque, hwaddr addr, uint64_t 
data,

+ unsigned size)
+{
+    FSIScratchPad *s = SCRATCHPAD(opaque);
+
+    trace_fsi_scratchpad_write(addr, size, data);
+
+    if (addr & ~(FSI_SCRATCHPAD_NR_REGS - 1)) {


There is a type confusion. addr is an offset in a memory region and
FSI_SCRATCHPAD_NR_REGS is an index an array.

Fixed.




+    return;
+    }
+
+    s->reg[addr] = data;


same here.

Fixed.




+static void fsi_scratchpad_reset(DeviceState *dev)
+{
+    FSIScratchPad *s = SCRATCHPAD(dev);
+    int i;
+
+    for (i = 0; i < FSI_SCRATCHPAD_NR_REGS; i++) {
+    s->reg[i] = 0;


memset(s->regs, 0, sizeof(s->regs));


Fixed.

Thanks for the review.

Regards,

Ninad





Re: [External] Re: [PATCH v2 04/20] So we use multifd to transmit zero pages.

2024-01-25 Thread Fabiano Rosas
Hao Xiang  writes:

> On Mon, Jan 22, 2024 at 8:28 PM Hao Xiang  wrote:
>>
>> On Thu, Nov 16, 2023 at 7:14 AM Fabiano Rosas  wrote:
>> >
>> > Hao Xiang  writes:
>> >
>> > > From: Juan Quintela 
>> > >
>> > > Signed-off-by: Juan Quintela 
>> > > Reviewed-by: Leonardo Bras 
>> > > ---
>> > >  migration/multifd.c |  7 ---
>> > >  migration/options.c | 13 +++--
>> > >  migration/ram.c | 45 ++---
>> > >  qapi/migration.json |  1 -
>> > >  4 files changed, 49 insertions(+), 17 deletions(-)
>> > >
>> > > diff --git a/migration/multifd.c b/migration/multifd.c
>> > > index 1b994790d5..1198ffde9c 100644
>> > > --- a/migration/multifd.c
>> > > +++ b/migration/multifd.c
>> > > @@ -13,6 +13,7 @@
>> > >  #include "qemu/osdep.h"
>> > >  #include "qemu/cutils.h"
>> > >  #include "qemu/rcu.h"
>> > > +#include "qemu/cutils.h"
>> > >  #include "exec/target_page.h"
>> > >  #include "sysemu/sysemu.h"
>> > >  #include "exec/ramblock.h"
>> > > @@ -459,7 +460,6 @@ static int multifd_send_pages(QEMUFile *f)
>> > >  p->packet_num = multifd_send_state->packet_num++;
>> > >  multifd_send_state->pages = p->pages;
>> > >  p->pages = pages;
>> > > -
>> > >  qemu_mutex_unlock(>mutex);
>> > >  qemu_sem_post(>sem);
>> > >
>> > > @@ -684,7 +684,7 @@ static void *multifd_send_thread(void *opaque)
>> > >  MigrationThread *thread = NULL;
>> > >  Error *local_err = NULL;
>> > >  /* qemu older than 8.2 don't understand zero page on multifd 
>> > > channel */
>> > > -bool use_zero_page = !migrate_use_main_zero_page();
>> > > +bool use_multifd_zero_page = !migrate_use_main_zero_page();
>> > >  int ret = 0;
>> > >  bool use_zero_copy_send = migrate_zero_copy_send();
>> > >
>> > > @@ -713,6 +713,7 @@ static void *multifd_send_thread(void *opaque)
>> > >  RAMBlock *rb = p->pages->block;
>> > >  uint64_t packet_num = p->packet_num;
>> > >  uint32_t flags;
>> > > +
>> > >  p->normal_num = 0;
>> > >  p->zero_num = 0;
>> > >
>> > > @@ -724,7 +725,7 @@ static void *multifd_send_thread(void *opaque)
>> > >
>> > >  for (int i = 0; i < p->pages->num; i++) {
>> > >  uint64_t offset = p->pages->offset[i];
>> > > -if (use_zero_page &&
>> > > +if (use_multifd_zero_page &&
>> >
>> > We could have a new function in multifd_ops for zero page
>> > handling. We're already considering an accelerator for the compression
>> > method in the other series[1] and in this series we're adding an
>> > accelerator for zero page checking. It's about time we make the
>> > multifd_ops generic instead of only compression/no compression.
>>
>> Sorry I overlooked this email earlier.
>> I will extend the multifd_ops interface and add a new API for zero
>> page checking.
>>
>> >
>> > 1- [PATCH v2 0/4] Live Migration Acceleration with IAA Compression
>> > https://lore.kernel.org/r/20231109154638.488213-1-yuan1@intel.com
>> >
>> > >  buffer_is_zero(rb->host + offset, p->page_size)) {
>> > >  p->zero[p->zero_num] = offset;
>> > >  p->zero_num++;
>> > > diff --git a/migration/options.c b/migration/options.c
>> > > index 00c0c4a0d6..97d121d4d7 100644
>> > > --- a/migration/options.c
>> > > +++ b/migration/options.c
>> > > @@ -195,6 +195,7 @@ Property migration_properties[] = {
>> > >  DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
>> > >  DEFINE_PROP_MIG_CAP("x-return-path", 
>> > > MIGRATION_CAPABILITY_RETURN_PATH),
>> > >  DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
>> > > +DEFINE_PROP_MIG_CAP("x-main-zero-page", 
>> > > MIGRATION_CAPABILITY_MAIN_ZERO_PAGE),
>> > >  DEFINE_PROP_MIG_CAP("x-background-snapshot",
>> > >  MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
>> > >  #ifdef CONFIG_LINUX
>> > > @@ -288,13 +289,9 @@ bool migrate_multifd(void)
>> > >
>> > >  bool migrate_use_main_zero_page(void)
>> > >  {
>> > > -//MigrationState *s;
>> > > -
>> > > -//s = migrate_get_current();
>> > > +MigrationState *s = migrate_get_current();
>> > >
>> > > -// We will enable this when we add the right code.
>> > > -// return 
>> > > s->enabled_capabilities[MIGRATION_CAPABILITY_MAIN_ZERO_PAGE];
>> > > -return true;
>> > > +return s->capabilities[MIGRATION_CAPABILITY_MAIN_ZERO_PAGE];
>> >
>> > What happens if we disable main-zero-page while multifd is not enabled?
>>
>> In ram.c
>> ...
>> if (migrate_multifd() && !migrate_use_main_zero_page()) {
>> migration_ops->ram_save_target_page = ram_save_target_page_multifd;
>> } else {
>> migration_ops->ram_save_target_page = ram_save_target_page_legacy;
>> }
>> ...
>>
>> So if main-zero-page is disabled and multifd is also disabled, it will
>> go with the "else" path, which is the legacy path
>> ram_save_target_page_legacy() and do zero page checking from the main
>> thread.
>>
>> >
>> > > 

[PATCH v7 8/9] ppc/pnv: Add a pca9554 I2C device to powernv10-rainier

2024-01-25 Thread Glenn Miles
For powernv10-rainier, the Power Hypervisor code expects to see a
pca9554 device connected to the 3rd PNV I2C engine on port 1 at I2C
address 0x25 (or left-justified address of 0x4A).  This is used by
the hypervisor code to detect if a "Cable Card" is present.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
---

No changes from previous version

 hw/misc/Kconfig | 4 
 hw/misc/meson.build | 1 +
 hw/ppc/Kconfig  | 1 +
 hw/ppc/pnv.c| 6 ++
 4 files changed, 12 insertions(+)

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 4fc6b29b43..83ad849b62 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -34,6 +34,10 @@ config PCA9552
 bool
 depends on I2C
 
+config PCA9554
+bool
+depends on I2C
+
 config I2C_ECHO
 bool
 default y if TEST_DEVICES
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 2ca2ce4b62..8bf7a3b8da 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -4,6 +4,7 @@ system_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: 
files('vmcoreinfo.c'))
 system_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: files('debugexit.c'))
 system_ss.add(when: 'CONFIG_ISA_TESTDEV', if_true: files('pc-testdev.c'))
 system_ss.add(when: 'CONFIG_PCA9552', if_true: files('pca9552.c'))
+system_ss.add(when: 'CONFIG_PCA9554', if_true: files('pca9554.c'))
 system_ss.add(when: 'CONFIG_PCI_TESTDEV', if_true: files('pci-testdev.c'))
 system_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c'))
 system_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c'))
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 8e592e4307..d97743d02f 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -33,6 +33,7 @@ config POWERNV
 select FDT_PPC
 select PCI_POWERNV
 select PCA9552
+select PCA9554
 
 config PPC405
 bool
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 42105211f5..40f6b8fea0 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1913,6 +1913,12 @@ static void pnv_rainier_i2c_init(PnvMachineState *pnv)
 qdev_connect_gpio_out(DEVICE(dev), 2, qdev_get_gpio_in(DEVICE(dev), 
7));
 qdev_connect_gpio_out(DEVICE(dev), 3, qdev_get_gpio_in(DEVICE(dev), 
8));
 qdev_connect_gpio_out(DEVICE(dev), 4, qdev_get_gpio_in(DEVICE(dev), 
9));
+
+/*
+ * Add a PCA9554 I2C device for cable card presence detection
+ * to engine 2, bus 1, address 0x25
+ */
+i2c_slave_create_simple(chip10->i2c[2].busses[1], "pca9554", 0x25);
 }
 }
 
-- 
2.31.1




[PATCH v7 4/9] ppc/pnv: Add pca9552 to powernv10-rainier for PCIe hotplug power control

2024-01-25 Thread Glenn Miles
The Power Hypervisor code expects to see a pca9552 device connected
to the 3rd PNV I2C engine on port 1 at I2C address 0x63 (or left-
justified address of 0xC6).  This is used by hypervisor code to
control PCIe slot power during hotplug events.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
---

No changes from previous version

 hw/ppc/Kconfig   |  1 +
 hw/ppc/pnv.c | 25 +
 include/hw/ppc/pnv.h |  1 +
 3 files changed, 27 insertions(+)

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 44263a58c4..8e592e4307 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -32,6 +32,7 @@ config POWERNV
 select XIVE
 select FDT_PPC
 select PCI_POWERNV
+select PCA9552
 
 config PPC405
 bool
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 08704ce695..d8d19fb065 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -790,6 +790,7 @@ static void pnv_init(MachineState *machine)
 const char *bios_name = machine->firmware ?: FW_FILE_NAME;
 PnvMachineState *pnv = PNV_MACHINE(machine);
 MachineClass *mc = MACHINE_GET_CLASS(machine);
+PnvMachineClass *pmc = PNV_MACHINE_GET_CLASS(machine);
 char *fw_filename;
 long fw_size;
 uint64_t chip_ram_start = 0;
@@ -979,6 +980,13 @@ static void pnv_init(MachineState *machine)
  */
 pnv->powerdown_notifier.notify = pnv_powerdown_notify;
 qemu_register_powerdown_notifier(>powerdown_notifier);
+
+/*
+ * Create/Connect any machine-specific I2C devices
+ */
+if (pmc->i2c_init) {
+pmc->i2c_init(pnv);
+}
 }
 
 /*
@@ -1879,6 +1887,21 @@ static void pnv_chip_power10_realize(DeviceState *dev, 
Error **errp)
   qdev_get_gpio_in(DEVICE(>psi),
PSIHB9_IRQ_SBE_I2C));
 }
+
+}
+
+static void pnv_rainier_i2c_init(PnvMachineState *pnv)
+{
+int i;
+for (i = 0; i < pnv->num_chips; i++) {
+Pnv10Chip *chip10 = PNV10_CHIP(pnv->chips[i]);
+
+/*
+ * Add a PCA9552 I2C device for PCIe hotplug control
+ * to engine 2, bus 1, address 0x63
+ */
+i2c_slave_create_simple(chip10->i2c[2].busses[1], "pca9552", 0x63);
+}
 }
 
 static uint32_t pnv_chip_power10_xscom_pcba(PnvChip *chip, uint64_t addr)
@@ -2286,9 +2309,11 @@ static void pnv_machine_power10_class_init(ObjectClass 
*oc, void *data)
 static void pnv_machine_p10_rainier_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
+PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
 
 pnv_machine_p10_common_class_init(oc, data);
 mc->desc = "IBM PowerNV (Non-Virtualized) POWER10 Rainier";
+pmc->i2c_init = pnv_rainier_i2c_init;
 }
 
 static bool pnv_machine_get_hb(Object *obj, Error **errp)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 7e5fef7c43..110ac9aace 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -76,6 +76,7 @@ struct PnvMachineClass {
 int compat_size;
 
 void (*dt_power_mgt)(PnvMachineState *pnv, void *fdt);
+void (*i2c_init)(PnvMachineState *pnv);
 };
 
 struct PnvMachineState {
-- 
2.31.1




[PATCH v7 3/9] ppc/pnv: New powernv10-rainier machine type

2024-01-25 Thread Glenn Miles
Create a new powernv machine type, powernv10-rainier, that
will contain rainier-specific devices.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
---

No changes from previous version

 hw/ppc/pnv.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 0297871bdd..08704ce695 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -2251,7 +2251,7 @@ static void pnv_machine_power9_class_init(ObjectClass 
*oc, void *data)
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB);
 }
 
-static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
+static void pnv_machine_p10_common_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
 PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
@@ -2263,7 +2263,6 @@ static void pnv_machine_power10_class_init(ObjectClass 
*oc, void *data)
 { TYPE_PNV_PHB_ROOT_PORT, "version", "5" },
 };
 
-mc->desc = "IBM PowerNV (Non-Virtualized) POWER10";
 mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v2.0");
 compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
 
@@ -2276,6 +2275,22 @@ static void pnv_machine_power10_class_init(ObjectClass 
*oc, void *data)
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB);
 }
 
+static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+pnv_machine_p10_common_class_init(oc, data);
+mc->desc = "IBM PowerNV (Non-Virtualized) POWER10";
+}
+
+static void pnv_machine_p10_rainier_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+pnv_machine_p10_common_class_init(oc, data);
+mc->desc = "IBM PowerNV (Non-Virtualized) POWER10 Rainier";
+}
+
 static bool pnv_machine_get_hb(Object *obj, Error **errp)
 {
 PnvMachineState *pnv = PNV_MACHINE(obj);
@@ -2381,6 +2396,11 @@ static void pnv_machine_class_init(ObjectClass *oc, void 
*data)
 }
 
 static const TypeInfo types[] = {
+{
+.name  = MACHINE_TYPE_NAME("powernv10-rainier"),
+.parent= MACHINE_TYPE_NAME("powernv10"),
+.class_init= pnv_machine_p10_rainier_class_init,
+},
 {
 .name  = MACHINE_TYPE_NAME("powernv10"),
 .parent= TYPE_PNV_MACHINE,
-- 
2.31.1




[PATCH v7 2/9] misc/pca9552: Let external devices set pca9552 inputs

2024-01-25 Thread Glenn Miles
Allow external devices to drive pca9552 input pins by adding
input GPIO's to the model.  This allows a device to connect
its output GPIO's to the pca9552 input GPIO's.

In order for an external device to set the state of a pca9552
pin, the pin must first be configured for high impedance (LED
is off).  If the pca9552 pin is configured to drive the pin low
(LED is on), then external input will be ignored.

Here is a table describing the logical state of a pca9552 pin
given the state being driven by the pca9552 and an external device:

   PCA9552
   Configured
   State

  | Hi-Z | Low |
--+--+-+
  External   Hi-Z |  Hi  | Low |
  Device--+--+-+
  State  Low  |  Low | Low |
--+--+-+

Reviewed-by: Andrew Jeffery 
Signed-off-by: Glenn Miles 
---

No changes from previous version

 hw/misc/pca9552.c | 50 +--
 include/hw/misc/pca9552.h |  3 ++-
 2 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index f00a149d61..2ae13af35e 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -44,6 +44,8 @@ DECLARE_CLASS_CHECKERS(PCA955xClass, PCA955X,
 #define PCA9552_LED_OFF  0x1
 #define PCA9552_LED_PWM0 0x2
 #define PCA9552_LED_PWM1 0x3
+#define PCA9552_PIN_LOW  0x0
+#define PCA9552_PIN_HIZ  0x1
 
 static const char *led_state[] = {"on", "off", "pwm0", "pwm1"};
 
@@ -110,22 +112,27 @@ static void pca955x_update_pin_input(PCA955xState *s)
 
 for (i = 0; i < k->pin_count; i++) {
 uint8_t input_reg = PCA9552_INPUT0 + (i / 8);
-uint8_t input_shift = (i % 8);
+uint8_t bit_mask = 1 << (i % 8);
 uint8_t config = pca955x_pin_get_config(s, i);
+uint8_t old_value = s->regs[input_reg] & bit_mask;
+uint8_t new_value;
 
 switch (config) {
 case PCA9552_LED_ON:
 /* Pin is set to 0V to turn on LED */
-qemu_set_irq(s->gpio[i], 0);
-s->regs[input_reg] &= ~(1 << input_shift);
+s->regs[input_reg] &= ~bit_mask;
 break;
 case PCA9552_LED_OFF:
 /*
  * Pin is set to Hi-Z to turn off LED and
- * pullup sets it to a logical 1.
+ * pullup sets it to a logical 1 unless
+ * external device drives it low.
  */
-qemu_set_irq(s->gpio[i], 1);
-s->regs[input_reg] |= 1 << input_shift;
+if (s->ext_state[i] == PCA9552_PIN_LOW) {
+s->regs[input_reg] &= ~bit_mask;
+} else {
+s->regs[input_reg] |=  bit_mask;
+}
 break;
 case PCA9552_LED_PWM0:
 case PCA9552_LED_PWM1:
@@ -133,6 +140,12 @@ static void pca955x_update_pin_input(PCA955xState *s)
 default:
 break;
 }
+
+/* update irq state only if pin state changed */
+new_value = s->regs[input_reg] & bit_mask;
+if (new_value != old_value) {
+qemu_set_irq(s->gpio_out[i], !!new_value);
+}
 }
 }
 
@@ -340,6 +353,7 @@ static const VMStateDescription pca9552_vmstate = {
 VMSTATE_UINT8(len, PCA955xState),
 VMSTATE_UINT8(pointer, PCA955xState),
 VMSTATE_UINT8_ARRAY(regs, PCA955xState, PCA955X_NR_REGS),
+VMSTATE_UINT8_ARRAY(ext_state, PCA955xState, PCA955X_PIN_COUNT_MAX),
 VMSTATE_I2C_SLAVE(i2c, PCA955xState),
 VMSTATE_END_OF_LIST()
 }
@@ -358,6 +372,7 @@ static void pca9552_reset(DeviceState *dev)
 s->regs[PCA9552_LS2] = 0x55;
 s->regs[PCA9552_LS3] = 0x55;
 
+memset(s->ext_state, PCA9552_PIN_HIZ, PCA955X_PIN_COUNT_MAX);
 pca955x_update_pin_input(s);
 
 s->pointer = 0xFF;
@@ -380,6 +395,26 @@ static void pca955x_initfn(Object *obj)
 }
 }
 
+static void pca955x_set_ext_state(PCA955xState *s, int pin, int level)
+{
+if (s->ext_state[pin] != level) {
+uint16_t pins_status = pca955x_pins_get_status(s);
+s->ext_state[pin] = level;
+pca955x_update_pin_input(s);
+pca955x_display_pins_status(s, pins_status);
+}
+}
+
+static void pca955x_gpio_in_handler(void *opaque, int pin, int level)
+{
+
+PCA955xState *s = PCA955X(opaque);
+PCA955xClass *k = PCA955X_GET_CLASS(s);
+
+assert((pin >= 0) && (pin < k->pin_count));
+pca955x_set_ext_state(s, pin, level);
+}
+
 static void pca955x_realize(DeviceState *dev, Error **errp)
 {
 PCA955xClass *k = PCA955X_GET_CLASS(dev);
@@ -389,7 +424,8 @@ static void pca955x_realize(DeviceState *dev, Error **errp)
 s->description = g_strdup("pca-unspecified");
 }
 
-qdev_init_gpio_out(dev, s->gpio, k->pin_count);
+qdev_init_gpio_out(dev, s->gpio_out, k->pin_count);
+qdev_init_gpio_in(dev, pca955x_gpio_in_handler, k->pin_count);
 }
 
 static Property pca955x_properties[] = {
diff --git a/include/hw/misc/pca9552.h 

[PATCH v7 9/9] ppc/pnv: Test pnv i2c master and connected devices

2024-01-25 Thread Glenn Miles
Tests the following for both P9 and P10:
  - I2C master POR status
  - I2C master status after immediate reset

Tests the following for powernv10-ranier only:
  - Config pca9552 hotplug device pins as inputs then
Read the INPUT0/1 registers to verify all pins are high
  - Connected GPIO pin tests of P10 PCA9552 device.  Tests
output of pins 0-4 affect input of pins 5-9 respectively.
  - PCA9554 GPIO pins test.  Tests input and ouput functionality.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
---

Changes from previous version:
  - Moved PNV I2C register definitions from pnv-host-i2c-test.c and
pnv_i2c.c into pnv_i2c_regs.h.
  - Moved PNV XSCOM definitions from pnv-host-i2c-test.c and
pnv-xscom-test.c into pnv-xscom.h.
  - Renamed pnv_i2c_dev_t to PnvI2cDev.
  - Added PnvI2cCtlr structure for conveniece in passing parameters.

 hw/ppc/pnv_i2c.c| 131 +
 include/hw/i2c/pnv_i2c_regs.h   | 143 ++
 tests/qtest/meson.build |   1 +
 tests/qtest/pnv-host-i2c-test.c | 491 
 tests/qtest/pnv-xscom-test.c|  61 +---
 tests/qtest/pnv-xscom.h |  80 ++
 6 files changed, 717 insertions(+), 190 deletions(-)
 create mode 100644 include/hw/i2c/pnv_i2c_regs.h
 create mode 100644 tests/qtest/pnv-host-i2c-test.c
 create mode 100644 tests/qtest/pnv-xscom.h

diff --git a/hw/ppc/pnv_i2c.c b/hw/ppc/pnv_i2c.c
index 774946d6b2..4581cc5e5d 100644
--- a/hw/ppc/pnv_i2c.c
+++ b/hw/ppc/pnv_i2c.c
@@ -22,136 +22,7 @@
 
 #include 
 
-/* I2C FIFO register */
-#define I2C_FIFO_REG0x4
-#define I2C_FIFOPPC_BITMASK(0, 7)
-
-/* I2C command register */
-#define I2C_CMD_REG 0x5
-#define I2C_CMD_WITH_START  PPC_BIT(0)
-#define I2C_CMD_WITH_ADDR   PPC_BIT(1)
-#define I2C_CMD_READ_CONT   PPC_BIT(2)
-#define I2C_CMD_WITH_STOP   PPC_BIT(3)
-#define I2C_CMD_INTR_STEERING   PPC_BITMASK(6, 7) /* P9 */
-#define   I2C_CMD_INTR_STEER_HOST   1
-#define   I2C_CMD_INTR_STEER_OCC2
-#define I2C_CMD_DEV_ADDRPPC_BITMASK(8, 14)
-#define I2C_CMD_READ_NOT_WRITE  PPC_BIT(15)
-#define I2C_CMD_LEN_BYTES   PPC_BITMASK(16, 31)
-#define I2C_MAX_TFR_LEN 0xfff0ull
-
-/* I2C mode register */
-#define I2C_MODE_REG0x6
-#define I2C_MODE_BIT_RATE_DIV   PPC_BITMASK(0, 15)
-#define I2C_MODE_PORT_NUM   PPC_BITMASK(16, 21)
-#define I2C_MODE_ENHANCED   PPC_BIT(28)
-#define I2C_MODE_DIAGNOSTIC PPC_BIT(29)
-#define I2C_MODE_PACING_ALLOW   PPC_BIT(30)
-#define I2C_MODE_WRAP   PPC_BIT(31)
-
-/* I2C watermark register */
-#define I2C_WATERMARK_REG   0x7
-#define I2C_WATERMARK_HIGH  PPC_BITMASK(16, 19)
-#define I2C_WATERMARK_LOW   PPC_BITMASK(24, 27)
-
-/*
- * I2C interrupt mask and condition registers
- *
- * NB: The function of 0x9 and 0xa changes depending on whether you're reading
- * or writing to them. When read they return the interrupt condition bits
- * and on writes they update the interrupt mask register.
- *
- *  The bit definitions are the same for all the interrupt registers.
- */
-#define I2C_INTR_MASK_REG   0x8
-
-#define I2C_INTR_RAW_COND_REG   0x9 /* read */
-#define I2C_INTR_MASK_OR_REG0x9 /* write*/
-
-#define I2C_INTR_COND_REG   0xa /* read */
-#define I2C_INTR_MASK_AND_REG   0xa /* write */
-
-#define I2C_INTR_ALLPPC_BITMASK(16, 31)
-#define I2C_INTR_INVALID_CMDPPC_BIT(16)
-#define I2C_INTR_LBUS_PARITY_ERRPPC_BIT(17)
-#define I2C_INTR_BKEND_OVERRUN_ERR  PPC_BIT(18)
-#define I2C_INTR_BKEND_ACCESS_ERR   PPC_BIT(19)
-#define I2C_INTR_ARBT_LOST_ERR  PPC_BIT(20)
-#define I2C_INTR_NACK_RCVD_ERR  PPC_BIT(21)
-#define I2C_INTR_DATA_REQ   PPC_BIT(22)
-#define I2C_INTR_CMD_COMP   PPC_BIT(23)
-#define I2C_INTR_STOP_ERR   PPC_BIT(24)
-#define I2C_INTR_I2C_BUSY   PPC_BIT(25)
-#define I2C_INTR_NOT_I2C_BUSY   PPC_BIT(26)
-#define I2C_INTR_SCL_EQ_1   PPC_BIT(28)
-#define I2C_INTR_SCL_EQ_0   PPC_BIT(29)
-#define I2C_INTR_SDA_EQ_1   PPC_BIT(30)
-#define I2C_INTR_SDA_EQ_0   PPC_BIT(31)
-
-/* I2C status register */
-#define I2C_RESET_I2C_REG   0xb /* write */
-#define I2C_RESET_ERRORS0xc
-#define I2C_STAT_REG0xb /* read */
-#define I2C_STAT_INVALID_CMDPPC_BIT(0)
-#define I2C_STAT_LBUS_PARITY_ERRPPC_BIT(1)
-#define I2C_STAT_BKEND_OVERRUN_ERR  PPC_BIT(2)
-#define I2C_STAT_BKEND_ACCESS_ERR   PPC_BIT(3)
-#define I2C_STAT_ARBT_LOST_ERR  PPC_BIT(4)
-#define I2C_STAT_NACK_RCVD_ERR  PPC_BIT(5)
-#define I2C_STAT_DATA_REQ   PPC_BIT(6)
-#define 

[PATCH v7 7/9] misc: Add a pca9554 GPIO device model

2024-01-25 Thread Glenn Miles
Specs are available here:

https://www.nxp.com/docs/en/data-sheet/PCA9554_9554A.pdf

This is a simple model supporting the basic registers for GPIO
mode.  The device also supports an interrupt output line but the
model does not yet support this.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
---

No changes from previous version

 MAINTAINERS|  10 +-
 hw/misc/pca9554.c  | 328 +
 include/hw/misc/pca9554.h  |  36 
 include/hw/misc/pca9554_regs.h |  19 ++
 4 files changed, 391 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/pca9554.c
 create mode 100644 include/hw/misc/pca9554.h
 create mode 100644 include/hw/misc/pca9554_regs.h

diff --git a/MAINTAINERS b/MAINTAINERS
index dfaca8323e..51861e3c7d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1169,9 +1169,7 @@ R: Joel Stanley 
 L: qemu-...@nongnu.org
 S: Maintained
 F: hw/*/*aspeed*
-F: hw/misc/pca9552.c
 F: include/hw/*/*aspeed*
-F: include/hw/misc/pca9552*.h
 F: hw/net/ftgmac100.c
 F: include/hw/net/ftgmac100.h
 F: docs/system/arm/aspeed.rst
@@ -1540,6 +1538,14 @@ F: include/hw/pci-host/pnv*
 F: pc-bios/skiboot.lid
 F: tests/qtest/pnv*
 
+pca955x
+M: Glenn Miles 
+L: qemu-...@nongnu.org
+L: qemu-...@nongnu.org
+S: Odd Fixes
+F: hw/misc/pca955*.c
+F: include/hw/misc/pca955*.h
+
 virtex_ml507
 M: Edgar E. Iglesias 
 L: qemu-...@nongnu.org
diff --git a/hw/misc/pca9554.c b/hw/misc/pca9554.c
new file mode 100644
index 00..778b32e443
--- /dev/null
+++ b/hw/misc/pca9554.c
@@ -0,0 +1,328 @@
+/*
+ * PCA9554 I/O port
+ *
+ * Copyright (c) 2023, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/bitops.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/pca9554.h"
+#include "hw/misc/pca9554_regs.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "trace.h"
+#include "qom/object.h"
+
+struct PCA9554Class {
+/*< private >*/
+I2CSlaveClass parent_class;
+/*< public >*/
+};
+typedef struct PCA9554Class PCA9554Class;
+
+DECLARE_CLASS_CHECKERS(PCA9554Class, PCA9554,
+   TYPE_PCA9554)
+
+#define PCA9554_PIN_LOW  0x0
+#define PCA9554_PIN_HIZ  0x1
+
+static const char *pin_state[] = {"low", "high"};
+
+static void pca9554_update_pin_input(PCA9554State *s)
+{
+int i;
+uint8_t config = s->regs[PCA9554_CONFIG];
+uint8_t output = s->regs[PCA9554_OUTPUT];
+uint8_t internal_state = config | output;
+
+for (i = 0; i < PCA9554_PIN_COUNT; i++) {
+uint8_t bit_mask = 1 << i;
+uint8_t internal_pin_state = (internal_state >> i) & 0x1;
+uint8_t old_value = s->regs[PCA9554_INPUT] & bit_mask;
+uint8_t new_value;
+
+switch (internal_pin_state) {
+case PCA9554_PIN_LOW:
+s->regs[PCA9554_INPUT] &= ~bit_mask;
+break;
+case PCA9554_PIN_HIZ:
+/*
+ * pullup sets it to a logical 1 unless
+ * external device drives it low.
+ */
+if (s->ext_state[i] == PCA9554_PIN_LOW) {
+s->regs[PCA9554_INPUT] &= ~bit_mask;
+} else {
+s->regs[PCA9554_INPUT] |=  bit_mask;
+}
+break;
+default:
+break;
+}
+
+/* update irq state only if pin state changed */
+new_value = s->regs[PCA9554_INPUT] & bit_mask;
+if (new_value != old_value) {
+if (new_value) {
+/* changed from 0 to 1 */
+qemu_set_irq(s->gpio_out[i], 1);
+} else {
+/* changed from 1 to 0 */
+qemu_set_irq(s->gpio_out[i], 0);
+}
+}
+}
+}
+
+static uint8_t pca9554_read(PCA9554State *s, uint8_t reg)
+{
+switch (reg) {
+case PCA9554_INPUT:
+return s->regs[PCA9554_INPUT] ^ s->regs[PCA9554_POLARITY];
+case PCA9554_OUTPUT:
+case PCA9554_POLARITY:
+case PCA9554_CONFIG:
+return s->regs[reg];
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected read to register %d\n",
+  __func__, reg);
+return 0xFF;
+}
+}
+
+static void pca9554_write(PCA9554State *s, uint8_t reg, uint8_t data)
+{
+switch (reg) {
+case PCA9554_OUTPUT:
+case PCA9554_CONFIG:
+s->regs[reg] = data;
+pca9554_update_pin_input(s);
+break;
+case PCA9554_POLARITY:
+s->regs[reg] = data;
+break;
+case PCA9554_INPUT:
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected write to register %d\n",
+  __func__, reg);
+}
+}
+
+static uint8_t pca9554_recv(I2CSlave *i2c)
+{
+PCA9554State *s = PCA9554(i2c);
+uint8_t ret;
+
+ret = pca9554_read(s, s->pointer & 0x3);
+
+return ret;
+}
+
+static int pca9554_send(I2CSlave *i2c, uint8_t 

[PATCH v7 1/9] misc/pca9552: Fix inverted input status

2024-01-25 Thread Glenn Miles
The pca9552 INPUT0 and INPUT1 registers are supposed to
hold the logical values of the LED pins.  A logical 0
should be seen in the INPUT0/1 registers for a pin when
its corresponding LSn bits are set to 0, which is also
the state needed for turning on an LED in a typical
usage scenario.  Existing code was doing the opposite
and setting INPUT0/1 bit to a 1 when the LSn bit was
set to 0, so this commit fixes that.

Reviewed-by: Andrew Jeffery 
Signed-off-by: Glenn Miles 
---

No changes from previous version

 hw/misc/pca9552.c  | 18 +-
 tests/qtest/pca9552-test.c |  6 +++---
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index 72b653463f..f00a149d61 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -36,7 +36,10 @@ typedef struct PCA955xClass PCA955xClass;
 
 DECLARE_CLASS_CHECKERS(PCA955xClass, PCA955X,
TYPE_PCA955X)
-
+/*
+ * Note:  The LED_ON and LED_OFF configuration values for the PCA955X
+ *chips are the reverse of the PCA953X family of chips.
+ */
 #define PCA9552_LED_ON   0x0
 #define PCA9552_LED_OFF  0x1
 #define PCA9552_LED_PWM0 0x2
@@ -112,13 +115,18 @@ static void pca955x_update_pin_input(PCA955xState *s)
 
 switch (config) {
 case PCA9552_LED_ON:
-qemu_set_irq(s->gpio[i], 1);
-s->regs[input_reg] |= 1 << input_shift;
-break;
-case PCA9552_LED_OFF:
+/* Pin is set to 0V to turn on LED */
 qemu_set_irq(s->gpio[i], 0);
 s->regs[input_reg] &= ~(1 << input_shift);
 break;
+case PCA9552_LED_OFF:
+/*
+ * Pin is set to Hi-Z to turn off LED and
+ * pullup sets it to a logical 1.
+ */
+qemu_set_irq(s->gpio[i], 1);
+s->regs[input_reg] |= 1 << input_shift;
+break;
 case PCA9552_LED_PWM0:
 case PCA9552_LED_PWM1:
 /* TODO */
diff --git a/tests/qtest/pca9552-test.c b/tests/qtest/pca9552-test.c
index d80ed93cd3..ccca2b3d91 100644
--- a/tests/qtest/pca9552-test.c
+++ b/tests/qtest/pca9552-test.c
@@ -60,7 +60,7 @@ static void send_and_receive(void *obj, void *data, 
QGuestAllocator *alloc)
 g_assert_cmphex(value, ==, 0x55);
 
 value = i2c_get8(i2cdev, PCA9552_INPUT0);
-g_assert_cmphex(value, ==, 0x0);
+g_assert_cmphex(value, ==, 0xFF);
 
 pca9552_init(i2cdev);
 
@@ -68,13 +68,13 @@ static void send_and_receive(void *obj, void *data, 
QGuestAllocator *alloc)
 g_assert_cmphex(value, ==, 0x54);
 
 value = i2c_get8(i2cdev, PCA9552_INPUT0);
-g_assert_cmphex(value, ==, 0x01);
+g_assert_cmphex(value, ==, 0xFE);
 
 value = i2c_get8(i2cdev, PCA9552_LS3);
 g_assert_cmphex(value, ==, 0x54);
 
 value = i2c_get8(i2cdev, PCA9552_INPUT1);
-g_assert_cmphex(value, ==, 0x10);
+g_assert_cmphex(value, ==, 0xEF);
 }
 
 static void pca9552_register_nodes(void)
-- 
2.31.1




[PATCH v7 5/9] ppc/pnv: Wire up pca9552 GPIO pins for PCIe hotplug power control

2024-01-25 Thread Glenn Miles
For power10-rainier, a pca9552 device is used for PCIe slot hotplug
power control by the Power Hypervisor code.  The code expects that
some time after it enables power to a PCIe slot by asserting one of
the pca9552 GPIO pins 0-4, it should see a "power good" signal asserted
on one of pca9552 GPIO pins 5-9.

To simulate this behavior, we simply connect the GPIO outputs for
pins 0-4 to the GPIO inputs for pins 5-9.

Each PCIe slot is assigned 3 GPIO pins on the pca9552 device, for
control of up to 5 PCIe slots.  The per-slot signal names are:

   SLOTx_EN...PHYP uses this as an output to enable
  slot power.  We connect this to the
  SLOTx_PG pin to simulate a PGOOD signal.
   SLOTx_PG...PHYP uses this as in input to detect
  PGOOD for the slot.  For our purposes
  we just connect this to the SLOTx_EN
  output.
   SLOTx_Control..PHYP uses this as an output to prevent
  a race condition in the real hotplug
  circuitry, but we can ignore this output
  for simulation.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
---

No changes from previous version

 hw/ppc/pnv.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d8d19fb065..42105211f5 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1900,7 +1900,19 @@ static void pnv_rainier_i2c_init(PnvMachineState *pnv)
  * Add a PCA9552 I2C device for PCIe hotplug control
  * to engine 2, bus 1, address 0x63
  */
-i2c_slave_create_simple(chip10->i2c[2].busses[1], "pca9552", 0x63);
+I2CSlave *dev = i2c_slave_create_simple(chip10->i2c[2].busses[1],
+"pca9552", 0x63);
+
+/*
+ * Connect PCA9552 GPIO pins 0-4 (SLOTx_EN) outputs to GPIO pins 5-9
+ * (SLOTx_PG) inputs in order to fake the pgood state of PCIe slots
+ * after hypervisor code sets a SLOTx_EN pin high.
+ */
+qdev_connect_gpio_out(DEVICE(dev), 0, qdev_get_gpio_in(DEVICE(dev), 
5));
+qdev_connect_gpio_out(DEVICE(dev), 1, qdev_get_gpio_in(DEVICE(dev), 
6));
+qdev_connect_gpio_out(DEVICE(dev), 2, qdev_get_gpio_in(DEVICE(dev), 
7));
+qdev_connect_gpio_out(DEVICE(dev), 3, qdev_get_gpio_in(DEVICE(dev), 
8));
+qdev_connect_gpio_out(DEVICE(dev), 4, qdev_get_gpio_in(DEVICE(dev), 
9));
 }
 }
 
-- 
2.31.1




[PATCH v7 6/9] ppc/pnv: Use resettable interface to reset child I2C buses

2024-01-25 Thread Glenn Miles
The QEMU I2C buses and devices use the resettable
interface for resetting while the PNV I2C controller
and parent buses and devices have not yet transitioned
to this new interface and use the old reset strategy.
This was preventing the I2C buses and devices wired
to the PNV I2C controller from being reset.

The short term fix for this is to have the PNV I2C
Controller's reset function explicitly call the resettable
interface function, bus_cold_reset(), on all child
I2C buses.

The long term fix should be to transition all PNV parent
devices and buses to use the resettable interface so that
all child buses and devices are automatically reset.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
---

No changes from previous version

 hw/ppc/pnv_i2c.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv_i2c.c b/hw/ppc/pnv_i2c.c
index 656a48eebe..774946d6b2 100644
--- a/hw/ppc/pnv_i2c.c
+++ b/hw/ppc/pnv_i2c.c
@@ -629,6 +629,19 @@ static int pnv_i2c_dt_xscom(PnvXScomInterface *dev, void 
*fdt,
 return 0;
 }
 
+static void pnv_i2c_sys_reset(void *dev)
+{
+int port;
+PnvI2C *i2c = PNV_I2C(dev);
+
+pnv_i2c_reset(dev);
+
+/* reset all buses connected to this i2c controller */
+for (port = 0; port < i2c->num_busses; port++) {
+bus_cold_reset(BUS(i2c->busses[port]));
+}
+}
+
 static void pnv_i2c_realize(DeviceState *dev, Error **errp)
 {
 PnvI2C *i2c = PNV_I2C(dev);
@@ -654,7 +667,7 @@ static void pnv_i2c_realize(DeviceState *dev, Error **errp)
 
 fifo8_create(>fifo, PNV_I2C_FIFO_SIZE);
 
-qemu_register_reset(pnv_i2c_reset, dev);
+qemu_register_reset(pnv_i2c_sys_reset, dev);
 
 qdev_init_gpio_out(DEVICE(dev), >psi_irq, 1);
 }
-- 
2.31.1




[PATCH v7 0/9] Add powernv10 I2C devices and tests

2024-01-25 Thread Glenn Miles
This series of patches includes support, tests and fixes for
adding PCA9552 and PCA9554 I2C devices to the powernv10 chip.

The PCA9552 device is used for PCIe slot hotplug power control
and monitoring, while the PCA9554 device is used for presence
detection of IBM CableCard devices.  Both devices are required
by the Power Hypervisor Firmware on the Power10 Ranier platform.

Changes from previous version:
  - Made several changes to commit 9/9 to address comments from
Cédric.
  - Added new PnvI2cCtlr struct to commit 9/9 for convenience in
passing parameters.

Glenn Miles (9):
  misc/pca9552: Fix inverted input status
  misc/pca9552: Let external devices set pca9552 inputs
  ppc/pnv: New powernv10-rainier machine type
  ppc/pnv: Add pca9552 to powernv10-rainier for PCIe hotplug power
control
  ppc/pnv: Wire up pca9552 GPIO pins for PCIe hotplug power control
  ppc/pnv: Use resettable interface to reset child I2C buses
  misc: Add a pca9554 GPIO device model
  ppc/pnv: Add a pca9554 I2C device to powernv10-rainier
  ppc/pnv: Test pnv i2c master and connected devices

 MAINTAINERS |  10 +-
 hw/misc/Kconfig |   4 +
 hw/misc/meson.build |   1 +
 hw/misc/pca9552.c   |  58 +++-
 hw/misc/pca9554.c   | 328 +
 hw/ppc/Kconfig  |   2 +
 hw/ppc/pnv.c|  67 -
 hw/ppc/pnv_i2c.c| 146 +-
 include/hw/i2c/pnv_i2c_regs.h   | 143 ++
 include/hw/misc/pca9552.h   |   3 +-
 include/hw/misc/pca9554.h   |  36 +++
 include/hw/misc/pca9554_regs.h  |  19 ++
 include/hw/ppc/pnv.h|   1 +
 tests/qtest/meson.build |   1 +
 tests/qtest/pca9552-test.c  |   6 +-
 tests/qtest/pnv-host-i2c-test.c | 491 
 tests/qtest/pnv-xscom-test.c|  61 +---
 tests/qtest/pnv-xscom.h |  80 ++
 18 files changed, 1251 insertions(+), 206 deletions(-)
 create mode 100644 hw/misc/pca9554.c
 create mode 100644 include/hw/i2c/pnv_i2c_regs.h
 create mode 100644 include/hw/misc/pca9554.h
 create mode 100644 include/hw/misc/pca9554_regs.h
 create mode 100644 tests/qtest/pnv-host-i2c-test.c
 create mode 100644 tests/qtest/pnv-xscom.h

-- 
2.31.1




[PATCH trivial 1/2] close_all_open_fd(): move to oslib-posix.c

2024-01-25 Thread Michael Tokarev
Initially in async-teardown.c, but the same construct is used
elsewhere too.

Signed-off-by: Michael Tokarev 
---
 include/sysemu/os-posix.h |  1 +
 system/async-teardown.c   | 37 +
 util/oslib-posix.c| 36 
 3 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index dff32ae185..4c91d03f44 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -53,6 +53,7 @@ bool os_set_runas(const char *user_id);
 void os_set_chroot(const char *path);
 void os_setup_post(void);
 int os_mlock(void);
+void os_close_all_open_fd(int minfd);
 
 /**
  * qemu_alloc_stack:
diff --git a/system/async-teardown.c b/system/async-teardown.c
index 396963c091..41d3d94935 100644
--- a/system/async-teardown.c
+++ b/system/async-teardown.c
@@ -26,40 +26,6 @@
 
 static pid_t the_ppid;
 
-/*
- * Close all open file descriptors.
- */
-static void close_all_open_fd(void)
-{
-struct dirent *de;
-int fd, dfd;
-DIR *dir;
-
-#ifdef CONFIG_CLOSE_RANGE
-int r = close_range(0, ~0U, 0);
-if (!r) {
-/* Success, no need to try other ways. */
-return;
-}
-#endif
-
-dir = opendir("/proc/self/fd");
-if (!dir) {
-/* If /proc is not mounted, there is nothing that can be done. */
-return;
-}
-/* Avoid closing the directory. */
-dfd = dirfd(dir);
-
-for (de = readdir(dir); de; de = readdir(dir)) {
-fd = atoi(de->d_name);
-if (fd != dfd) {
-close(fd);
-}
-}
-closedir(dir);
-}
-
 static void hup_handler(int signal)
 {
 /* Check every second if this process has been reparented. */
@@ -85,9 +51,8 @@ static int async_teardown_fn(void *arg)
 /*
  * Close all file descriptors that might have been inherited from the
  * main qemu process when doing clone, needed to make libvirt happy.
- * Not using close_range for increased compatibility with older kernels.
  */
-close_all_open_fd();
+os_close_all_open_fd(0);
 
 /* Set up a handler for SIGHUP and unblock SIGHUP. */
 sigaction(SIGHUP, , NULL);
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 7c297003b9..09d0ce4da6 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -27,6 +27,7 @@
  */
 
 #include "qemu/osdep.h"
+#include 
 #include 
 
 #include 
@@ -106,6 +107,41 @@ int qemu_get_thread_id(void)
 #endif
 }
 
+/*
+ * Close all open file descriptors starting with minfd and up.
+ * Not using close_range for increased compatibility with older kernels.
+ */
+void os_close_all_open_fd(int minfd)
+{
+struct dirent *de;
+int fd, dfd;
+DIR *dir;
+
+#ifdef CONFIG_CLOSE_RANGE
+int r = close_range(minfd, ~0U, 0);
+if (!r) {
+/* Success, no need to try other ways. */
+return;
+}
+#endif
+
+dir = opendir("/proc/self/fd");
+if (!dir) {
+/* If /proc is not mounted, there is nothing that can be done. */
+return;
+}
+/* Avoid closing the directory. */
+dfd = dirfd(dir);
+
+for (de = readdir(dir); de; de = readdir(dir)) {
+fd = atoi(de->d_name);
+if (fd >= minfd && fd != dfd) {
+close(fd);
+}
+}
+closedir(dir);
+}
+
 int qemu_daemon(int nochdir, int noclose)
 {
 return daemon(nochdir, noclose);
-- 
2.39.2




[PATCH trivial 2/2] net/tap: use os_close_all_open_fd() instead of open-coding it

2024-01-25 Thread Michael Tokarev
Current code loops over every file descriptor up to SC_OPEN_MAX/RLIMIT_NOFILE
which might be huge and the loop might be slow.  But we already have
os_close_all_open_fd() which is fast.  Use it.

Signed-off-by: Michael Tokarev 
---
 net/tap.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/net/tap.c b/net/tap.c
index c698b70475..11c85c50dc 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -459,13 +459,7 @@ static void launch_script(const char *setup_script, const 
char *ifname,
 return;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
-
-for (i = 3; i < open_max; i++) {
-if (i != fd) {
-close(i);
-}
-}
+os_close_all_open_fd(3);
 parg = args;
 *parg++ = (char *)setup_script;
 *parg++ = (char *)ifname;
@@ -549,16 +543,11 @@ static int net_bridge_run_helper(const char *helper, 
const char *bridge,
 return -1;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
 char *fd_buf = NULL;
 char *br_buf = NULL;
 char *helper_cmd = NULL;
 
-for (i = 3; i < open_max; i++) {
-if (i != sv[1]) {
-close(i);
-}
-}
+os_close_all_open_fd(3);
 
 fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
 
-- 
2.39.2




[PATCH trivial 0/2] split out os_close_all_open_fd and use it in net/tap.c too

2024-01-25 Thread Michael Tokarev
We have at least two places in qemu where we're closing all possible file
descriptors, - in async-teardown.c and in net/tap.c.  While async-teardown
one uses either close_range() or readdir(/proc/self/fd), the two calls in
net/tap.c loops from 3 to RLIMIT_NOFILE, which might be quite slow, and
it actually *is* slow on some systems (eg, just qemu-system-x86_64 startup
with a tap device is very slow on alpine linux).

While for net/tap.c, maybe the better fix is to get rid of this closing
entirely and use O_CLOEXEC instead, this needs to be prepared at first,
while we alredy have almost ready-to-be-used implementation which only
needs to be moved into a common place.

Michael Tokarev (2):
  close_all_open_fd(): move to oslib-posix.c
  net/tap: use os_close_all_open_fd() instead of open-coding it

 include/sysemu/os-posix.h |  1 +
 net/tap.c | 15 ++-
 system/async-teardown.c   | 37 +
 util/oslib-posix.c| 36 
 4 files changed, 40 insertions(+), 49 deletions(-)

-- 
2.39.2




Re: [External] Re: [PATCH v2 04/20] So we use multifd to transmit zero pages.

2024-01-25 Thread Hao Xiang
On Mon, Jan 22, 2024 at 8:28 PM Hao Xiang  wrote:
>
> On Thu, Nov 16, 2023 at 7:14 AM Fabiano Rosas  wrote:
> >
> > Hao Xiang  writes:
> >
> > > From: Juan Quintela 
> > >
> > > Signed-off-by: Juan Quintela 
> > > Reviewed-by: Leonardo Bras 
> > > ---
> > >  migration/multifd.c |  7 ---
> > >  migration/options.c | 13 +++--
> > >  migration/ram.c | 45 ++---
> > >  qapi/migration.json |  1 -
> > >  4 files changed, 49 insertions(+), 17 deletions(-)
> > >
> > > diff --git a/migration/multifd.c b/migration/multifd.c
> > > index 1b994790d5..1198ffde9c 100644
> > > --- a/migration/multifd.c
> > > +++ b/migration/multifd.c
> > > @@ -13,6 +13,7 @@
> > >  #include "qemu/osdep.h"
> > >  #include "qemu/cutils.h"
> > >  #include "qemu/rcu.h"
> > > +#include "qemu/cutils.h"
> > >  #include "exec/target_page.h"
> > >  #include "sysemu/sysemu.h"
> > >  #include "exec/ramblock.h"
> > > @@ -459,7 +460,6 @@ static int multifd_send_pages(QEMUFile *f)
> > >  p->packet_num = multifd_send_state->packet_num++;
> > >  multifd_send_state->pages = p->pages;
> > >  p->pages = pages;
> > > -
> > >  qemu_mutex_unlock(>mutex);
> > >  qemu_sem_post(>sem);
> > >
> > > @@ -684,7 +684,7 @@ static void *multifd_send_thread(void *opaque)
> > >  MigrationThread *thread = NULL;
> > >  Error *local_err = NULL;
> > >  /* qemu older than 8.2 don't understand zero page on multifd channel 
> > > */
> > > -bool use_zero_page = !migrate_use_main_zero_page();
> > > +bool use_multifd_zero_page = !migrate_use_main_zero_page();
> > >  int ret = 0;
> > >  bool use_zero_copy_send = migrate_zero_copy_send();
> > >
> > > @@ -713,6 +713,7 @@ static void *multifd_send_thread(void *opaque)
> > >  RAMBlock *rb = p->pages->block;
> > >  uint64_t packet_num = p->packet_num;
> > >  uint32_t flags;
> > > +
> > >  p->normal_num = 0;
> > >  p->zero_num = 0;
> > >
> > > @@ -724,7 +725,7 @@ static void *multifd_send_thread(void *opaque)
> > >
> > >  for (int i = 0; i < p->pages->num; i++) {
> > >  uint64_t offset = p->pages->offset[i];
> > > -if (use_zero_page &&
> > > +if (use_multifd_zero_page &&
> >
> > We could have a new function in multifd_ops for zero page
> > handling. We're already considering an accelerator for the compression
> > method in the other series[1] and in this series we're adding an
> > accelerator for zero page checking. It's about time we make the
> > multifd_ops generic instead of only compression/no compression.
>
> Sorry I overlooked this email earlier.
> I will extend the multifd_ops interface and add a new API for zero
> page checking.
>
> >
> > 1- [PATCH v2 0/4] Live Migration Acceleration with IAA Compression
> > https://lore.kernel.org/r/20231109154638.488213-1-yuan1@intel.com
> >
> > >  buffer_is_zero(rb->host + offset, p->page_size)) {
> > >  p->zero[p->zero_num] = offset;
> > >  p->zero_num++;
> > > diff --git a/migration/options.c b/migration/options.c
> > > index 00c0c4a0d6..97d121d4d7 100644
> > > --- a/migration/options.c
> > > +++ b/migration/options.c
> > > @@ -195,6 +195,7 @@ Property migration_properties[] = {
> > >  DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK),
> > >  DEFINE_PROP_MIG_CAP("x-return-path", 
> > > MIGRATION_CAPABILITY_RETURN_PATH),
> > >  DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
> > > +DEFINE_PROP_MIG_CAP("x-main-zero-page", 
> > > MIGRATION_CAPABILITY_MAIN_ZERO_PAGE),
> > >  DEFINE_PROP_MIG_CAP("x-background-snapshot",
> > >  MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
> > >  #ifdef CONFIG_LINUX
> > > @@ -288,13 +289,9 @@ bool migrate_multifd(void)
> > >
> > >  bool migrate_use_main_zero_page(void)
> > >  {
> > > -//MigrationState *s;
> > > -
> > > -//s = migrate_get_current();
> > > +MigrationState *s = migrate_get_current();
> > >
> > > -// We will enable this when we add the right code.
> > > -// return 
> > > s->enabled_capabilities[MIGRATION_CAPABILITY_MAIN_ZERO_PAGE];
> > > -return true;
> > > +return s->capabilities[MIGRATION_CAPABILITY_MAIN_ZERO_PAGE];
> >
> > What happens if we disable main-zero-page while multifd is not enabled?
>
> In ram.c
> ...
> if (migrate_multifd() && !migrate_use_main_zero_page()) {
> migration_ops->ram_save_target_page = ram_save_target_page_multifd;
> } else {
> migration_ops->ram_save_target_page = ram_save_target_page_legacy;
> }
> ...
>
> So if main-zero-page is disabled and multifd is also disabled, it will
> go with the "else" path, which is the legacy path
> ram_save_target_page_legacy() and do zero page checking from the main
> thread.
>
> >
> > >  }
> > >
> > >  bool migrate_pause_before_switchover(void)
> > > @@ -457,6 +454,7 @@ 
> > > 

Re: [PATCH v2] target/i386/host-cpu: Use iommu phys_bits with VFIO assigned devices on Intel h/w

2024-01-25 Thread Alex Williamson
On Thu, 25 Jan 2024 09:18:02 +0100
Eric Auger  wrote:

> Hi Vivek,
> 
> On 1/18/24 20:20, Vivek Kasireddy wrote:
> > Recent updates in OVMF and Seabios have resulted in MMIO regions
> > being placed at the upper end of the physical address space. As a
> > result, when a Host device is assigned to the Guest via VFIO, the
> > following mapping failures occur when VFIO tries to map the MMIO
> > regions of the device:
> > VFIO_MAP_DMA failed: Invalid argument
> > vfio_dma_map(0x557b2f2736d0, 0x3800, 0x100, 0x7f98ac40) = 
> > -22 (Invalid argument)
> > 
> > The above failures are mainly seen on some Intel platforms where
> > the physical address width is larger than the Host's IOMMU
> > address width. In these cases, VFIO fails to map the MMIO regions
> > because the IOVAs would be larger than the IOMMU aperture regions.
> > 
> > Therefore, one way to solve this problem would be to ensure that
> > cpu->phys_bits = 
> > This can be done by parsing the IOMMU caps value from sysfs and
> > extracting the address width and using it to override the
> > phys_bits value as shown in this patch.
> > 
> > Previous attempt at solving this issue in OVMF:
> > https://edk2.groups.io/g/devel/topic/102359124
> > 
> > Cc: Gerd Hoffmann 
> > Cc: Philippe Mathieu-Daudé 
> > Cc: Alex Williamson 
> > Cc: Cédric Le Goater 
> > Cc: Laszlo Ersek 
> > Cc: Dongwon Kim 
> > Acked-by: Gerd Hoffmann 
> > Tested-by: Yanghang Liu 
> > Signed-off-by: Vivek Kasireddy 
> > 
> > ---
> > v2:
> > - Replace the term passthrough with assigned (Laszlo)
> > - Update the commit message to note that both OVMF and Seabios
> >   guests are affected (Cédric)
> > - Update the subject to indicate what is done in the patch
> > ---
> >  target/i386/host-cpu.c | 61 +-
> >  1 file changed, 60 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c
> > index 92ecb7254b..5c9fcd7dc2 100644
> > --- a/target/i386/host-cpu.c
> > +++ b/target/i386/host-cpu.c
> > @@ -12,6 +12,8 @@
> >  #include "host-cpu.h"
> >  #include "qapi/error.h"
> >  #include "qemu/error-report.h"
> > +#include "qemu/config-file.h"
> > +#include "qemu/option.h"
> >  #include "sysemu/sysemu.h"
> >  
> >  /* Note: Only safe for use on x86(-64) hosts */
> > @@ -51,11 +53,58 @@ static void host_cpu_enable_cpu_pm(X86CPU *cpu)
> >  env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
> >  }
> >  
> > +static int intel_iommu_check(void *opaque, QemuOpts *opts, Error **errp)
> > +{
> > +g_autofree char *dev_path = NULL, *iommu_path = NULL, *caps = NULL;
> > +const char *driver = qemu_opt_get(opts, "driver");
> > +const char *device = qemu_opt_get(opts, "host");
> > +uint32_t *iommu_phys_bits = opaque;
> > +struct stat st;
> > +uint64_t iommu_caps;
> > +
> > +/*
> > + * Check if the user requested VFIO device assignment. We don't have
> > + * to limit phys_bits if there are no valid assigned devices.
> > + */
> > +if (g_strcmp0(driver, "vfio-pci") || !device) {
> > +return 0;
> > +}
> > +
> > +dev_path = g_strdup_printf("/sys/bus/pci/devices/%s", device);
> > +if (stat(dev_path, ) < 0) {
> > +return 0;
> > +}
> > +
> > +iommu_path = g_strdup_printf("%s/iommu/intel-iommu/cap", dev_path);
> > +if (stat(iommu_path, ) < 0) {
> > +return 0;
> > +}
> > +
> > +if (g_file_get_contents(iommu_path, , NULL, NULL)) {
> > +if (sscanf(caps, "%lx", _caps) != 1) {
> > +return 0;
> > +}
> > +*iommu_phys_bits = ((iommu_caps >> 16) & 0x3f) + 1;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +static uint32_t host_iommu_phys_bits(void)
> > +{
> > +uint32_t iommu_phys_bits = 0;
> > +
> > +qemu_opts_foreach(qemu_find_opts("device"),
> > +  intel_iommu_check, _phys_bits, NULL);
> > +return iommu_phys_bits;
> > +}
> > +
> >  static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu)
> >  {
> >  uint32_t host_phys_bits = host_cpu_phys_bits();
> > +uint32_t iommu_phys_bits = host_iommu_phys_bits();
> >  uint32_t phys_bits = cpu->phys_bits;
> > -static bool warned;
> > +static bool warned, warned2;
> >  
> >  /*
> >   * Print a warning if the user set it to a value that's not the
> > @@ -78,6 +127,16 @@ static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu)
> >  }
> >  }
> >  
> > +if (iommu_phys_bits && phys_bits > iommu_phys_bits) {
> > +phys_bits = iommu_phys_bits;  
> are you allowed to change the host cpu characteristics without taking
> care of compats for migration?

Not only is migration an issue, but so is hotplug.  Anything that
aligns the VM configuration to the host is going to have migration
issues and anything that does so conditionally based on the current set
of attached devices will have hotplug issues.

It'd be more prudent to find the least common denominator under

Re: [PATCH 04/17] migration/multifd: Set p->running = true in the right place

2024-01-25 Thread Fabiano Rosas
Avihai Horon  writes:

> The commit in the fixes line moved multifd thread creation to a
> different location, but forgot to move the p->running = true assignment
> as well. Thus, p->running is set to true before multifd thread is
> actually created.
>
> p->running is used in multifd_save_cleanup() to decide whether to join
> the multifd thread or not.
>
> With TLS, an error in multifd_tls_channel_connect() can lead to a
> segmentation fault because p->running is true but p->thread is never
> initialized, so multifd_save_cleanup() tries to join an uninitialized
> thread.
>
> Fix it by moving p->running = true assignment right after multifd thread
> creation. Also move qio_channel_set_delay() to there, as this is where
> it used to be originally.
>
> Fixes: 29647140157a ("migration/tls: add support for multifd tls-handshake")
> Signed-off-by: Avihai Horon 

Just for context, I haven't looked at this patch yet, but we were
planning to remove p->running altogether:

https://lore.kernel.org/r/20231110200241.20679-1-faro...@suse.de



Re: [PATCH] iotests: don't run tests requiring cached writes in '-nocache' mode

2024-01-25 Thread Eric Blake
On Mon, Dec 11, 2023 at 03:32:23PM +0200, Andrey Drobyshev wrote:
> There're tests whose logic implies running without O_DIRECT set,
> otherwise they fail when running iotests in '-nocache' mode.  For these
> tests let's add _require_no_o_direct() helper which can be put in the
> preabmle and which makes sure '-nocache' isn't set.  Use it to skip

preamble

> running the following tests:
> 
>   * 271: creates files with unaligned sizes, thus producing multiple
> errors like:
> 
> qemu-io: can't open device /path/to/t.qcow2.raw: Cannot get 'write'
> permission without 'resize': Image size is not a multiple of request alignment

I wonder if we can instead tweak the test to use larger sizes such
that all accesses ARE aligned even with O_DIRECT.

/me goes and reads the test...

# Note that the image size is not a multiple of the cluster size
_reset_img 2083k

Ah - we really DO have a test that depends on odd sizing; where
changing it to be more nicely aligned will break other assumptions in
the test.

> 
>   * 308, file-io-error: use fuse exports.  Though fuse does have
> 'direct-io' mode (see https://docs.kernel.org/filesystems/fuse-io.html)
> we aren't using it yet, thus getting errors like:
> 
> qemu-io: can't open device /path/to/t.qcow2.fuse: Could not open
> '/path/to/t.qcow2.fuse': filesystem does not support O_DIRECT

And I agree that this one is beyond our control, so adding skip
support makes sense.

> 
> Signed-off-by: Andrey Drobyshev 
> ---
>  tests/qemu-iotests/271 | 1 +
>  tests/qemu-iotests/308 | 2 ++
>  tests/qemu-iotests/common.rc   | 7 +++
>  tests/qemu-iotests/tests/file-io-error | 1 +
>  4 files changed, 11 insertions(+)

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org




Re: [PATCH] iotests/264: Use iotests.sock_dir for socket creation

2024-01-25 Thread Eric Blake
On Thu, Jan 25, 2024 at 03:52:37PM +0200, Andrey Drobyshev wrote:
> If socket path is too long (longer than 108 bytes), socket can't be
> opened.  This might lead to failure when test dir path is long enough.
> Make sure socket is created in iotests.sock_dir to avoid such a case.
> 
> This commit basically aligns iotests/264 with the rest of iotests.
> 
> Signed-off-by: Andrey Drobyshev 
> ---
>  tests/qemu-iotests/264 | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Eric Blake 

> 
> diff --git a/tests/qemu-iotests/264 b/tests/qemu-iotests/264
> index c532ccd809..c6ba2754e2 100755
> --- a/tests/qemu-iotests/264
> +++ b/tests/qemu-iotests/264
> @@ -25,7 +25,8 @@ import os
>  import iotests
>  from iotests import qemu_img_create, file_path, qemu_nbd_popen
>  
> -disk_a, disk_b, nbd_sock = file_path('disk_a', 'disk_b', 'nbd-sock')
> +disk_a, disk_b = file_path('disk_a', 'disk_b')
> +nbd_sock = file_path('nbd-sock', base_dir=iotests.sock_dir)
>  nbd_uri = 'nbd+unix:///?socket=' + nbd_sock
>  wait_limit = 3.0
>  wait_step = 0.2
> -- 
> 2.39.3
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org




Re: [PATCH] vfio/pci: Clear MSI-X IRQ index always

2024-01-25 Thread Alex Williamson
On Thu, 25 Jan 2024 15:42:20 +0100
Cédric Le Goater  wrote:

> When doing device assignment of a physical device, MSI-X can be
> enabled with no vectors enabled and this sets the IRQ index to
> VFIO_PCI_MSIX_IRQ_INDEX. However, when MSI-X is disabled, the IRQ
> index is left untouched if no vectors are in use. Then, when INTx
> is enabled, the IRQ index value is considered incompatible (set to
> MSI-X) and VFIO_DEVICE_SET_IRQS fails. QEMU complains with :
> 
> qemu-system-x86_64: vfio :08:00.0: Failed to set up TRIGGER eventfd 
> signaling for interrupt INTX-0: VFIO_DEVICE_SET_IRQS failure: Invalid argument
> 
> To avoid that, unconditionaly clear the IRQ index when MSI-X is
> disabled.
> 
> Buglink: https://issues.redhat.com/browse/RHEL-21293
> Fixes: 5ebffa4e87e7 ("vfio/pci: use an invalid fd to enable MSI-X")
> Cc: Jing Liu 
> Cc: Alex Williamson 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/vfio/pci.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 
> d7fe06715c4b9cde66a68c31aaf405315921b0d6..4fa387f0430d62ca2ba1b5ae5b7037f8f06b33f9
>  100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -826,9 +826,11 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev)
>  }
>  }
>  
> -if (vdev->nr_vectors) {
> -vfio_disable_irqindex(>vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
> -}
> +/*
> + * Always clear MSI-X IRQ index. A PF device could have enabled
> + * MSI-X with no vectors. See vfio_msix_enable().
> + */
> +vfio_disable_irqindex(>vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
>  
>  vfio_msi_disable_common(vdev);
>  vfio_intx_enable(vdev, );

LGTM, at worst the SET_IRQS ioctl return an errno if we try to disable
an unconfigured interrupt index, so seems safe to call unconditionally
here.

Reviewed-by: Alex Williamson 




Re: [PATCH v2] hw/arm: add PCIe to Freescale i.MX6

2024-01-25 Thread Nikita Ostrenkov
Ping
https://patchew.org/QEMU/20240108140325.1291-1-n.ostren...@gmail.com/

пн, 8 янв. 2024 г., 17:03 Nikita Ostrenkov :

> Signed-off-by: Nikita Ostrenkov 
> ---
>  hw/arm/Kconfig|  2 ++
>  hw/arm/fsl-imx6.c | 25 ++
>  include/hw/arm/fsl-imx6.h | 44 ---
>  3 files changed, 50 insertions(+), 21 deletions(-)
>
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 660f49db49..2559d1317b 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -530,6 +530,7 @@ config FSL_IMX31
>
>  config FSL_IMX6
>  bool
> +imply PCIE_DEVICES
>  imply I2C_DEVICES
>  select A9MPCORE
>  select IMX
> @@ -537,6 +538,7 @@ config FSL_IMX6
>  select IMX_I2C
>  select IMX_USBPHY
>  select WDT_IMX2
> +select PCI_EXPRESS_DESIGNWARE
>  select SDHCI
>
>  config ASPEED_SOC
> diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
> index b2153022c0..27702b6d6d 100644
> --- a/hw/arm/fsl-imx6.c
> +++ b/hw/arm/fsl-imx6.c
> @@ -22,6 +22,7 @@
>  #include "qemu/osdep.h"
>  #include "qapi/error.h"
>  #include "hw/arm/fsl-imx6.h"
> +#include "hw/misc/unimp.h"
>  #include "hw/usb/imx-usb-phy.h"
>  #include "hw/boards.h"
>  #include "hw/qdev-properties.h"
> @@ -102,6 +103,8 @@ static void fsl_imx6_init(Object *obj)
>
>
>  object_initialize_child(obj, "eth", >eth, TYPE_IMX_ENET);
> +
> +object_initialize_child(obj, "pcie", >pcie,
> TYPE_DESIGNWARE_PCIE_HOST);
>  }
>
>  static void fsl_imx6_realize(DeviceState *dev, Error **errp)
> @@ -109,6 +112,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error
> **errp)
>  MachineState *ms = MACHINE(qdev_get_machine());
>  FslIMX6State *s = FSL_IMX6(dev);
>  uint16_t i;
> +qemu_irq irq;
>  unsigned int smp_cpus = ms->smp.cpus;
>
>  if (smp_cpus > FSL_IMX6_NUM_CPUS) {
> @@ -421,6 +425,27 @@ static void fsl_imx6_realize(DeviceState *dev, Error
> **errp)
>  FSL_IMX6_WDOGn_IRQ[i]));
>  }
>
> +/*
> + * PCIe
> + */
> +sysbus_realize(SYS_BUS_DEVICE(>pcie), _abort);
> +sysbus_mmio_map(SYS_BUS_DEVICE(>pcie), 0, FSL_IMX6_PCIe_REG_ADDR);
> +
> +irq = qdev_get_gpio_in(DEVICE(>a9mpcore), FSL_IMX6_PCIE1_IRQ);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>pcie), 0, irq);
> +irq = qdev_get_gpio_in(DEVICE(>a9mpcore), FSL_IMX6_PCIE2_IRQ);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>pcie), 1, irq);
> +irq = qdev_get_gpio_in(DEVICE(>a9mpcore), FSL_IMX6_PCIE3_IRQ);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>pcie), 2, irq);
> +irq = qdev_get_gpio_in(DEVICE(>a9mpcore), FSL_IMX6_PCIE4_IRQ);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>pcie), 3, irq);
> +
> +/*
> + * PCIe PHY
> + */
> +create_unimplemented_device("pcie-phy", FSL_IMX6_PCIe_ADDR,
> +FSL_IMX6_PCIe_SIZE);
> +
>  /* ROM memory */
>  if (!memory_region_init_rom(>rom, OBJECT(dev), "imx6.rom",
>  FSL_IMX6_ROM_SIZE, errp)) {
> diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
> index 519b871014..61c593ffd2 100644
> --- a/include/hw/arm/fsl-imx6.h
> +++ b/include/hw/arm/fsl-imx6.h
> @@ -32,6 +32,7 @@
>  #include "hw/net/imx_fec.h"
>  #include "hw/usb/chipidea.h"
>  #include "hw/usb/imx-usb-phy.h"
> +#include "hw/pci-host/designware.h"
>  #include "exec/memory.h"
>  #include "cpu.h"
>  #include "qom/object.h"
> @@ -55,27 +56,28 @@ struct FslIMX6State {
>  DeviceState parent_obj;
>
>  /*< public >*/
> -ARMCPU cpu[FSL_IMX6_NUM_CPUS];
> -A9MPPrivState  a9mpcore;
> -IMX6CCMState   ccm;
> -IMX6SRCState   src;
> -IMX7SNVSState  snvs;
> -IMXSerialState uart[FSL_IMX6_NUM_UARTS];
> -IMXGPTStategpt;
> -IMXEPITState   epit[FSL_IMX6_NUM_EPITS];
> -IMXI2CStatei2c[FSL_IMX6_NUM_I2CS];
> -IMXGPIOState   gpio[FSL_IMX6_NUM_GPIOS];
> -SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS];
> -IMXSPIStatespi[FSL_IMX6_NUM_ECSPIS];
> -IMX2WdtState   wdt[FSL_IMX6_NUM_WDTS];
> -IMXUSBPHYState usbphy[FSL_IMX6_NUM_USB_PHYS];
> -ChipideaState  usb[FSL_IMX6_NUM_USBS];
> -IMXFECStateeth;
> -MemoryRegion   rom;
> -MemoryRegion   caam;
> -MemoryRegion   ocram;
> -MemoryRegion   ocram_alias;
> -uint32_t   phy_num;
> +ARMCPU cpu[FSL_IMX6_NUM_CPUS];
> +A9MPPrivState  a9mpcore;
> +IMX6CCMState   ccm;
> +IMX6SRCState   src;
> +IMX7SNVSState  snvs;
> +IMXSerialState uart[FSL_IMX6_NUM_UARTS];
> +IMXGPTStategpt;
> +IMXEPITState   epit[FSL_IMX6_NUM_EPITS];
> +IMXI2CStatei2c[FSL_IMX6_NUM_I2CS];
> +IMXGPIOState   gpio[FSL_IMX6_NUM_GPIOS];
> +SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS];
> +IMXSPIStatespi[FSL_IMX6_NUM_ECSPIS];
> +IMX2WdtState   wdt[FSL_IMX6_NUM_WDTS];
> +IMXUSBPHYState usbphy[FSL_IMX6_NUM_USB_PHYS];
> +ChipideaState  usb[FSL_IMX6_NUM_USBS];
> 

[PATCH] {linux, bsd}-user: Fail mmap() if size doesn't fit into host's size_t

2024-01-25 Thread Ilya Leoshkevich
s390x's branch-relative-long test fails with the following error
message on 32-bit hosts:

qemu-s390x: ../accel/tcg/user-exec.c:493: page_set_flags: Assertion `last 
<= GUEST_ADDR_MAX' failed.

The root cause is that the size passed to mmap() by this test does not
fit into 32 bits and gets truncated. Since there is no chance for such
mmap() to succeed, detect this condition and fail the mmap() right away.

Signed-off-by: Ilya Leoshkevich 
---
 bsd-user/mmap.c   | 4 
 linux-user/mmap.c | 4 
 2 files changed, 8 insertions(+)

diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 3ef11b28079..5dc327d0ad3 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -256,6 +256,10 @@ static abi_ulong mmap_find_vma_aligned(abi_ulong start, 
abi_ulong size,
 
 size = HOST_PAGE_ALIGN(size);
 
+if (size != (size_t)size) {
+return (abi_ulong)(-1);
+}
+
 if (reserved_va) {
 return mmap_find_vma_reserved(start, size,
 (alignment != 0 ? 1 << alignment :
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 96c9433e271..ae59d70fb67 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -389,6 +389,10 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, 
abi_ulong align)
 
 size = HOST_PAGE_ALIGN(size);
 
+if (size != (size_t)size) {
+return (abi_ulong)(-1);
+}
+
 if (reserved_va) {
 return mmap_find_vma_reserved(start, size, align);
 }
-- 
2.43.0




Re: [PATCH v3] hw/usb: fix xhci port notify

2024-01-25 Thread Nikita Ostrenkov
ping
https://patchew.org/QEMU/20231117173916.3658-1-n.ostren...@gmail.com/

пн, 18 дек. 2023 г., 13:40 Nikita Ostrenkov :

> ping
> https://patchew.org/QEMU/20231117173916.3658-1-n.ostren...@gmail.com/
>
> пт, 17 нояб. 2023 г., 20:39 Nikita Ostrenkov :
>
>> From MCF5253 Reference manual
>> https://www.nxp.com/docs/en/reference-manual/MCF5253RM.pdf
>>
>> Host mode: Port Change Detect. The controller sets this bit to a one when
>> on any port a Connect Status occurs, a PortEnable/Disable Change occurs, an
>> Over Current Change occurs, or the Force Port Resume bit is set as
>> theresult of a J-K transition on the suspended port.
>>
>> Signed-off-by: Nikita Ostrenkov 
>> ---
>>  hw/usb/hcd-xhci.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
>> index 4b60114207..1b2f4ac721 100644
>> --- a/hw/usb/hcd-xhci.c
>> +++ b/hw/usb/hcd-xhci.c
>> @@ -2627,6 +2627,7 @@ static void xhci_port_notify(XHCIPort *port,
>> uint32_t bits)
>>  if (!xhci_running(port->xhci)) {
>>  return;
>>  }
>> +port->xhci->usbsts |= USBSTS_PCD;
>>  xhci_event(port->xhci, , 0);
>>  }
>>
>> --
>> 2.34.1
>>
>>


[PATCH 6/6] target/riscv: Promote svade to a normal extension

2024-01-25 Thread Daniel Henrique Barboza
From: Andrew Jones 

Named features are extensions which don't make sense for users to
control and are therefore not exposed on the command line. However,
svade is an extension which makes sense for users to control, so treat
it like a "normal" extension. The default is false, since QEMU has
always implemented hardware A/D PTE bit updating, so users must opt into
svade (or get it from a CPU type which enables it by default).

Signed-off-by: Andrew Jones 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a56c2ff91d..4ddde25412 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1421,6 +1421,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
 
 MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
 MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
+MULTI_EXT_CFG_BOOL("svade", ext_svade, false),
 MULTI_EXT_CFG_BOOL("svadu", ext_svadu, true),
 MULTI_EXT_CFG_BOOL("svinval", ext_svinval, false),
 MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false),
@@ -1528,7 +1529,6 @@ const RISCVCPUMultiExtConfig 
riscv_cpu_experimental_exts[] = {
  * and priv_ver like regular extensions.
  */
 const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
-MULTI_EXT_CFG_BOOL("svade", ext_svade, true),
 MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
 
 /*
@@ -2175,8 +2175,6 @@ static RISCVCPUProfile RVA22U64 = {
  * Other named features that we already implement: Sstvecd, Sstvala,
  * Sscounterenw
  *
- * Named features that we need to enable: svade
- *
  * The remaining features/extensions comes from RVA22U64.
  */
 static RISCVCPUProfile RVA22S64 = {
@@ -2188,11 +2186,11 @@ static RISCVCPUProfile RVA22S64 = {
 .ext_offsets = {
 /* rva22s64 exts */
 CPU_CFG_OFFSET(ext_zifencei), CPU_CFG_OFFSET(ext_svpbmt),
-CPU_CFG_OFFSET(ext_svinval),
+CPU_CFG_OFFSET(ext_svinval), CPU_CFG_OFFSET(ext_svade),
 
 /* rva22s64 named features */
 CPU_CFG_OFFSET(ext_sstvecd), CPU_CFG_OFFSET(ext_sstvala),
-CPU_CFG_OFFSET(ext_sscounterenw), CPU_CFG_OFFSET(ext_svade),
+CPU_CFG_OFFSET(ext_sscounterenw),
 
 RISCV_PROFILE_EXT_LIST_END
 }
-- 
2.43.0




[PATCH 5/6] target/riscv: Gate hardware A/D PTE bit updating

2024-01-25 Thread Daniel Henrique Barboza
From: Andrew Jones 

Gate hardware A/D PTE bit updating on {m,h}envcfg.ADUE and only
enable menvcfg.ADUE on reset if svade has not been selected. Now
that we also consider svade, we have four possible configurations:

 1) !svade && !svadu
use hardware updating and there's no way to disable it
(the default, which maintains past behavior. Maintaining
 the default, even with !svadu is a change that fixes [1])

 2) !svade && svadu
use hardware updating, but also provide {m,h}envcfg.ADUE,
allowing software to switch to exception mode
(being able to switch is a change which fixes [1])

 3) svade && !svadu
use exception mode and there's no way to switch to hardware
updating
(this behavior change fixes [2])

 4) svade && svadu
use exception mode, but also provide {m,h}envcfg.ADUE,
allowing software to switch to hardware updating
(this behavior change fixes [2])

Fixes: 0af3f115e68e ("target/riscv: Add *envcfg.HADE related check in address 
translation") [1]
Fixes: 48531f5adb2a ("target/riscv: implement svade") [2]
Signed-off-by: Andrew Jones 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c |  2 +-
 target/riscv/cpu_helper.c  | 18 ++
 target/riscv/tcg/tcg-cpu.c | 16 +---
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7fd433daee..a56c2ff91d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -960,7 +960,7 @@ static void riscv_cpu_reset_hold(Object *obj)
 env->two_stage_lookup = false;
 
 env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
-   (cpu->cfg.ext_svadu ? MENVCFG_ADUE : 0);
+   (!cpu->cfg.ext_svade && cpu->cfg.ext_svadu ? MENVCFG_ADUE : 
0);
 env->henvcfg = 0;
 
 /* Initialized default priorities of local interrupts. */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 8da9104da4..9da9758cb4 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -907,7 +907,9 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 }
 
 bool pbmte = env->menvcfg & MENVCFG_PBMTE;
-bool adue = env->menvcfg & MENVCFG_ADUE;
+bool svade = riscv_cpu_cfg(env)->ext_svade;
+bool svadu = riscv_cpu_cfg(env)->ext_svadu;
+bool adue = svadu ? env->menvcfg & MENVCFG_ADUE : !svade;
 
 if (first_stage && two_stage && env->virt_enabled) {
 pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
@@ -1082,9 +1084,17 @@ restart:
 return TRANSLATE_FAIL;
 }
 
-/* If necessary, set accessed and dirty bits. */
-target_ulong updated_pte = pte | PTE_A |
-(access_type == MMU_DATA_STORE ? PTE_D : 0);
+target_ulong updated_pte = pte;
+
+/*
+ * If ADUE is enabled, set accessed and dirty bits.
+ * Otherwise raise an exception if necessary.
+ */
+if (adue) {
+updated_pte |= PTE_A | (access_type == MMU_DATA_STORE ? PTE_D : 0);
+} else if (!(pte & PTE_A) || (access_type == MMU_DATA_STORE && !(pte & 
PTE_D))) {
+return TRANSLATE_FAIL;
+}
 
 /* Page table updates need to be atomic with MTTCG enabled */
 if (updated_pte != pte && !is_debug) {
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 6d5028cf84..bc3c45b117 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -196,18 +196,14 @@ static bool cpu_cfg_offset_is_named_feat(uint32_t 
ext_offset)
 
 static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset)
 {
-switch (feat_offset) {
-case CPU_CFG_OFFSET(ext_zic64b):
+ /*
+  * All other named features are already enabled
+  * in riscv_tcg_cpu_instance_init().
+  */
+if (feat_offset == CPU_CFG_OFFSET(ext_zic64b)) {
 cpu->cfg.cbom_blocksize = 64;
 cpu->cfg.cbop_blocksize = 64;
 cpu->cfg.cboz_blocksize = 64;
-break;
-case CPU_CFG_OFFSET(ext_svade):
-cpu->cfg.ext_svadu = false;
-break;
-default:
-/* Named feature already enabled in riscv_tcg_cpu_instance_init */
-return;
 }
 }
 
@@ -349,8 +345,6 @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu)
 cpu->cfg.ext_zic64b = cpu->cfg.cbom_blocksize == 64 &&
   cpu->cfg.cbop_blocksize == 64 &&
   cpu->cfg.cboz_blocksize == 64;
-
-cpu->cfg.ext_svade = !cpu->cfg.ext_svadu;
 }
 
 static void riscv_cpu_validate_g(RISCVCPU *cpu)
-- 
2.43.0




[PATCH 3/6] target/riscv: add remaining named features

2024-01-25 Thread Daniel Henrique Barboza
The RVA22U64 and RVA22S64 profiles mandates certain extensions that,
until now, we were implying that they were available.

We can't do this anymore since named features also has a riscv,isa
entry.  Let's add them to riscv_cpu_named_features[].

They will also need to be explicitly enabled in both profile
descriptions. TCG will enable the named features it already implements,
other accelerators are free to handle it as they like.

After this patch, here's the riscv,isa from a buildroot using the
'rva22s64' CPU:

 # cat /proc/device-tree/cpus/cpu@0/riscv,isa
rv64imafdc_zic64b_zicbom_zicbop_zicboz_ziccamoa_ziccif_zicclsm_ziccrse_
zicntr_zicsr_zifencei_zihintpause_zihpm_za64rs_zfhmin_zca_zcd_zba_zbb_
zbs_zkt_sscounterenw_sstvala_sstvecd_svade_svinval_svpbmt#

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 41 +-
 target/riscv/cpu_cfg.h |  9 +
 target/riscv/tcg/tcg-cpu.c | 19 +-
 3 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 28d3cfa8ce..1ecd8a57ed 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -101,6 +101,10 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
 ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
 ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
+ISA_EXT_DATA_ENTRY(ziccamoa, PRIV_VERSION_1_11_0, ext_ziccamoa),
+ISA_EXT_DATA_ENTRY(ziccif, PRIV_VERSION_1_11_0, ext_ziccif),
+ISA_EXT_DATA_ENTRY(zicclsm, PRIV_VERSION_1_11_0, ext_zicclsm),
+ISA_EXT_DATA_ENTRY(ziccrse, PRIV_VERSION_1_11_0, ext_ziccrse),
 ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
 ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
 ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr),
@@ -109,6 +113,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
 ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
 ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
+ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, ext_za64rs),
 ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
 ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
 ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
@@ -170,8 +175,12 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
 ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
 ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
+ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, ext_ssccptr),
 ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
+ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, ext_sscounterenw),
 ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
+ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, ext_sstvala),
+ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, ext_sstvecd),
 ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
 ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
 ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
@@ -1523,6 +1532,22 @@ const RISCVCPUMultiExtConfig riscv_cpu_named_features[] 
= {
 MULTI_EXT_CFG_BOOL("svade", ext_svade, true),
 MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
 
+/*
+ * cache-related extensions that are always enabled
+ * since QEMU RISC-V does not have a cache model.
+ */
+MULTI_EXT_CFG_BOOL("za64rs", ext_za64rs, true),
+MULTI_EXT_CFG_BOOL("ziccif", ext_ziccif, true),
+MULTI_EXT_CFG_BOOL("ziccrse", ext_ziccrse, true),
+MULTI_EXT_CFG_BOOL("ziccamoa", ext_ziccamoa, true),
+MULTI_EXT_CFG_BOOL("zicclsm", ext_zicclsm, true),
+MULTI_EXT_CFG_BOOL("ssccptr", ext_ssccptr, true),
+
+/* Other named features that QEMU TCG always implements */
+MULTI_EXT_CFG_BOOL("sstvecd", ext_sstvecd, true),
+MULTI_EXT_CFG_BOOL("sstvala", ext_sstvala, true),
+MULTI_EXT_CFG_BOOL("sscounterenw", ext_sscounterenw, true),
+
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2116,13 +2141,8 @@ static const PropertyInfo prop_marchid = {
 };
 
 /*
- * RVA22U64 defines some 'named features' or 'synthetic extensions'
- * that are cache related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa
- * and Zicclsm. We do not implement caching in QEMU so we'll consider
- * all these named features as always enabled.
- *
- * There's no riscv,isa update for them (nor for zic64b, despite it
- * having a cfg offset) at this moment.
+ * RVA22U64 defines some cache related extensions: Za64rs,
+ * Ziccif, Ziccrse, Ziccamoa and Zicclsm.
  */
 static RISCVCPUProfile RVA22U64 = {
 .parent = NULL,
@@ -2139,7 +2159,9 @@ static RISCVCPUProfile RVA22U64 = {
 CPU_CFG_OFFSET(ext_zicbop), CPU_CFG_OFFSET(ext_zicboz),
 
 /* mandatory named features 

[PATCH 1/6] target/riscv/tcg: set 'mmu' with 'satp' in cpu_set_profile()

2024-01-25 Thread Daniel Henrique Barboza
Recent changes in options handling removed the 'mmu' default the bare
CPUs had, meaning that we must enable 'mmu' by hand when using the
rva22s64 profile CPU.

Given that this profile is setting a satp mode, it already implies that
we need a 'mmu'. Enable the 'mmu' in this case.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/tcg/tcg-cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index da437975b4..88f92d1c7d 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1107,6 +1107,7 @@ static void cpu_set_profile(Object *obj, Visitor *v, 
const char *name,
 
 #ifndef CONFIG_USER_ONLY
 if (profile->satp_mode != RISCV_PROFILE_ATTR_UNUSED) {
+object_property_set_bool(obj, "mmu", true, NULL);
 const char *satp_prop = satp_mode_str(profile->satp_mode,
   riscv_cpu_is_32bit(cpu));
 object_property_set_bool(obj, satp_prop, profile->enabled, NULL);
-- 
2.43.0




[PATCH 2/6] target/riscv: add riscv,isa to named features

2024-01-25 Thread Daniel Henrique Barboza
Further discussions after the introduction of rva22 support in QEMU
revealed that what we've been calling 'named features' are actually
regular extensions, with their respective riscv,isa DTs. This is
clarified in [1]. [2] is a bug tracker asking for the profile spec to be
less cryptic about it.

As far as QEMU goes we understand extensions as something that the user
can enable/disable in the command line. This isn't the case for named
features, so we'll have to reach a middle ground.

We'll keep our existing nomenclature 'named features' to refer to any
extension that the user can't control in the command line. We'll also do
the following:

- 'svade' and 'zic64b' flags are renamed to 'ext_svade' and
  'ext_zic64b'. 'ext_svade' and 'ext_zic64b' now have riscv,isa strings and
  priv_spec versions;

- skip name feature check in cpu_bump_multi_ext_priv_ver(). Now that
  named features have a riscv,isa and an entry in isa_edata_arr[] we
  don't need to gate the call to cpu_cfg_ext_get_min_version() anymore.

[1] https://github.com/riscv/riscv-profiles/issues/121
[2] https://github.com/riscv/riscv-profiles/issues/142

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 17 +
 target/riscv/cpu_cfg.h |  6 --
 target/riscv/tcg/tcg-cpu.c | 16 ++--
 3 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 88e8cc8681..28d3cfa8ce 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -97,6 +97,7 @@ bool riscv_cpu_option_set(const char *optname)
  * instead.
  */
 const RISCVIsaExtData isa_edata_arr[] = {
+ISA_EXT_DATA_ENTRY(zic64b, PRIV_VERSION_1_12_0, ext_zic64b),
 ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
 ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
 ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
@@ -171,6 +172,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
 ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
 ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
+ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
 ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
 ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
 ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
@@ -1510,9 +1512,16 @@ const RISCVCPUMultiExtConfig 
riscv_cpu_experimental_exts[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+/*
+ * 'Named features' is the name we give to extensions that we
+ * don't want to expose to users. They are either immutable
+ * (always enabled/disable) or they'll vary depending on
+ * the resulting CPU state. They have riscv,isa strings
+ * and priv_ver like regular extensions.
+ */
 const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
-MULTI_EXT_CFG_BOOL("svade", svade, true),
-MULTI_EXT_CFG_BOOL("zic64b", zic64b, true),
+MULTI_EXT_CFG_BOOL("svade", ext_svade, true),
+MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
 
 DEFINE_PROP_END_OF_LIST(),
 };
@@ -2130,7 +2139,7 @@ static RISCVCPUProfile RVA22U64 = {
 CPU_CFG_OFFSET(ext_zicbop), CPU_CFG_OFFSET(ext_zicboz),
 
 /* mandatory named features for this profile */
-CPU_CFG_OFFSET(zic64b),
+CPU_CFG_OFFSET(ext_zic64b),
 
 RISCV_PROFILE_EXT_LIST_END
 }
@@ -2161,7 +2170,7 @@ static RISCVCPUProfile RVA22S64 = {
 CPU_CFG_OFFSET(ext_svinval),
 
 /* rva22s64 named features */
-CPU_CFG_OFFSET(svade),
+CPU_CFG_OFFSET(ext_svade),
 
 RISCV_PROFILE_EXT_LIST_END
 }
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index e241922f89..698f926ab1 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -117,13 +117,15 @@ struct RISCVCPUConfig {
 bool ext_smepmp;
 bool rvv_ta_all_1s;
 bool rvv_ma_all_1s;
-bool svade;
-bool zic64b;
 
 uint32_t mvendorid;
 uint64_t marchid;
 uint64_t mimpid;
 
+/* Named features  */
+bool ext_svade;
+bool ext_zic64b;
+
 /* Vendor-specific custom extensions */
 bool ext_xtheadba;
 bool ext_xtheadbb;
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 88f92d1c7d..90861cc065 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -197,12 +197,12 @@ static bool cpu_cfg_offset_is_named_feat(uint32_t 
ext_offset)
 static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset)
 {
 switch (feat_offset) {
-case CPU_CFG_OFFSET(zic64b):
+case CPU_CFG_OFFSET(ext_zic64b):
 cpu->cfg.cbom_blocksize = 64;
 cpu->cfg.cbop_blocksize = 64;
 cpu->cfg.cboz_blocksize = 64;
 break;
-case CPU_CFG_OFFSET(svade):
+case CPU_CFG_OFFSET(ext_svade):
 cpu->cfg.ext_svadu = false;
 break;
 default:
@@ -219,10 +219,6 @@ static void 

[PATCH 0/6] riscv: named features riscv,isa, 'svade' rework

2024-01-25 Thread Daniel Henrique Barboza
Hi,

This is a bundle of fixes based on discoveries that were made in the
last week or so:

- what we call "named features" are actually real extensions, which are
  considered to be ratified by the profile spec that defines them. This
  means that we need to add riscv,isa strings for them. More info can be
  found on the commit msg of patch 2;

- the design behind 'svade' and 'svadu' is wrong. 'svade' does not mean
  'we do not have svadu'. In fact they can coexist. Patch 5 gives more
  details about it.


After this series, 'svade' is promoted to a regular extension and all
the named features QEMU implements are now being displayed in riscv,isa.


Andrew Jones (3):
  target/riscv: Reset henvcfg to zero
  target/riscv: Gate hardware A/D PTE bit updating
  target/riscv: Promote svade to a normal extension

Daniel Henrique Barboza (3):
  target/riscv/tcg: set 'mmu' with 'satp' in cpu_set_profile()
  target/riscv: add riscv,isa to named features
  target/riscv: add remaining named features

 target/riscv/cpu.c | 63 --
 target/riscv/cpu_cfg.h | 15 +++--
 target/riscv/cpu_helper.c  | 18 ---
 target/riscv/csr.c |  2 +-
 target/riscv/tcg/tcg-cpu.c | 42 +++--
 5 files changed, 99 insertions(+), 41 deletions(-)

-- 
2.43.0




[PATCH 4/6] target/riscv: Reset henvcfg to zero

2024-01-25 Thread Daniel Henrique Barboza
From: Andrew Jones 

The hypervisor should decide what it wants to enable. Zero all
configuration enable bits on reset.

Also, commit ed67d63798f2 ("target/riscv: Update CSR bits name for
svadu extension") missed one reference to 'hade'. Change it now.

Fixes: 0af3f115e68e ("target/riscv: Add *envcfg.HADE related check in address 
translation")
Fixes: ed67d63798f2 ("target/riscv: Update CSR bits name for svadu extension")
Signed-off-by: Andrew Jones 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 3 +--
 target/riscv/csr.c | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1ecd8a57ed..7fd433daee 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -961,8 +961,7 @@ static void riscv_cpu_reset_hold(Object *obj)
 
 env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
(cpu->cfg.ext_svadu ? MENVCFG_ADUE : 0);
-env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) |
-   (cpu->cfg.ext_svadu ? HENVCFG_ADUE : 0);
+env->henvcfg = 0;
 
 /* Initialized default priorities of local interrupts. */
 for (i = 0; i < ARRAY_SIZE(env->miprio); i++) {
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d9a010387f..93f7bc2cb4 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2115,7 +2115,7 @@ static RISCVException read_henvcfg(CPURISCVState *env, 
int csrno,
 /*
  * henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
  * henvcfg.stce is read_only 0 when menvcfg.stce = 0
- * henvcfg.hade is read_only 0 when menvcfg.hade = 0
+ * henvcfg.adue is read_only 0 when menvcfg.adue = 0
  */
 *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
env->menvcfg);
-- 
2.43.0




[PATCH 1/3] tests/vm: Set UseDNS=no in the sshd configuration

2024-01-25 Thread Ilya Leoshkevich
make vm-build-freebsd sometimes fails with "Connection timed out during
banner exchange". The client strace shows:

13:59:30 write(3, "SSH-2.0-OpenSSH_9.3\r\n", 21) = 21
13:59:30 getpid()   = 252655
13:59:30 poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, 
revents=POLLIN}])
13:59:32 read(3, "S", 1)= 1
13:59:32 poll([{fd=3, events=POLLIN}], 1, 3625) = 1 ([{fd=3, 
revents=POLLIN}])
13:59:32 read(3, "S", 1)= 1
13:59:32 poll([{fd=3, events=POLLIN}], 1, 3625) = 1 ([{fd=3, 
revents=POLLIN}])
13:59:32 read(3, "H", 1)= 1

There is a 2s delay during connection, and ConnectTimeout is set to 1.
Raising it makes the issue go away, but we can do better. The server
truss shows:

888: 27.811414714 socket(PF_INET,SOCK_DGRAM|SOCK_CLOEXEC,0) = 5 (0x5)
888: 27.811765030 connect(5,{ AF_INET 10.0.2.3:53 },16) = 0 (0x0)
888: 27.812166941 sendto(5,"\^Z/\^A\0\0\^A\0\0\0\0\0\0\^A2"...,39,0,NULL,0) 
= 39 (0x27)
888: 29.363970743 poll({ 5/POLLRDNORM },1,5000) = 1 (0x1)

So the delay is due to a DNS query. Disable DNS queries in the server
config.

Signed-off-by: Ilya Leoshkevich 
---
 tests/vm/basevm.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 61725b83254..c0d62c08031 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -423,6 +423,8 @@ def console_ssh_init(self, prompt, user, pw):
 def console_sshd_config(self, prompt):
 self.console_wait(prompt)
 self.console_send("echo 'PermitRootLogin yes' >> 
/etc/ssh/sshd_config\n")
+self.console_wait(prompt)
+self.console_send("echo 'UseDNS no' >> /etc/ssh/sshd_config\n")
 for var in self.envvars:
 self.console_wait(prompt)
 self.console_send("echo 'AcceptEnv %s' >> /etc/ssh/sshd_config\n" 
% var)
-- 
2.43.0




[PATCH 2/3] tests/vm/freebsd: Reload the sshd configuration

2024-01-25 Thread Ilya Leoshkevich
After console_sshd_config(), the SSH server needs to be nudged to pick
up the new configs. The scripts for the other BSD flavors already do
this with a reboot, but a simple reload is sufficient.

Signed-off-by: Ilya Leoshkevich 
---
 tests/vm/freebsd | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index b581bd17fb7..9971bc1f2b2 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -108,6 +108,8 @@ class FreeBSDVM(basevm.BaseVM):
 prompt = "root@freebsd:~ #"
 self.console_ssh_init(prompt, "root", self._config["root_pass"])
 self.console_sshd_config(prompt)
+self.console_wait(prompt)
+self.console_send("service sshd reload\n")
 
 # setup virtio-blk #1 (tarfile)
 self.console_wait(prompt)
-- 
2.43.0




Re: [PATCH 0/7] qapi qmp: Documentation fixes

2024-01-25 Thread Eric Blake
On Sat, Jan 20, 2024 at 10:53:20AM +0100, Markus Armbruster wrote:
> Markus Armbruster (7):
>   docs/devel/qapi-code-gen: Fix missing ':' in tagged section docs
>   docs: Replace dangling references to docs/interop/qmp-intro.txt
>   qapi: Fix dangling references to docs/devel/qapi-code-gen.txt
>   docs/interop/bitmaps: Clean up a reference to qemu-qmp-ref
>   qapi: Fix mangled "Returns" sections in documentation
>   qapi: Indent tagged doc comment sections properly
>   qapi: Fix malformed "Since:" section tags (again)

For the series:
Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org




[PATCH 3/3] meson: Disable CONFIG_NOTIFY1 on FreeBSD

2024-01-25 Thread Ilya Leoshkevich
make vm-build-freebsd fails with:

ld: error: undefined symbol: inotify_init1
>>> referenced by filemonitor-inotify.c:183 
(../src/util/filemonitor-inotify.c:183)
>>>   util_filemonitor-inotify.c.o:(qemu_file_monitor_new) in 
archive libqemuutil.a

On FreeBSD inotify functions are defined in libinotify.so, so it might
be tempting to add it to the dependencies. Doing so, however, reveals
that this library handles rename events differently from Linux:

$ FILEMONITOR_DEBUG=1 build/tests/unit/test-util-filemonitor
Rename /tmp/test-util-filemonitor-K13LI2/fish/one.txt -> 
/tmp/test-util-filemonitor-K13LI2/two.txt
Event id=2 event=2 file=one.txt
Queue event id 2 event 2 file one.txt
Queue event id 1 event 2 file two.txt
Queue event id 10002 event 2 file two.txt
Queue event id 1 event 0 file two.txt
Queue event id 10002 event 0 file two.txt
Event id=1 event=0 file=two.txt
Expected event 0 but got 2

FreeBSD itself disables this functionality in the respective port [1].
So do it upstream too.

[1] 
https://cgit.freebsd.org/ports/tree/emulators/qemu-devel/files/patch-util_meson.build?id=984366c18f1bc54e38751afc29be08c596b83696

Signed-off-by: Ilya Leoshkevich 
---
 meson.build | 1 +
 1 file changed, 1 insertion(+)

diff --git a/meson.build b/meson.build
index d0329966f1b..3d67d78b522 100644
--- a/meson.build
+++ b/meson.build
@@ -2403,6 +2403,7 @@ config_host_data.set('CONFIG_GETRANDOM',
 config_host_data.set('CONFIG_INOTIFY',
  cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
 config_host_data.set('CONFIG_INOTIFY1',
+ host_os != 'freebsd' and
  cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
  cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
-- 
2.43.0




[PATCH 0/3] make vm-build-freebsd fixes

2024-01-25 Thread Ilya Leoshkevich
Hi,

I needed to verify that my qemu-user changes didn't break BSD, and
Daniel Berrange suggested vm-build-freebsd on IRC. I had several
problems with it, which this series resolves.

Best regards,
Ilya

Ilya Leoshkevich (3):
  tests/vm: Set UseDNS=no in the sshd configuration
  tests/vm/freebsd: Reload the sshd configuration
  meson: Disable CONFIG_NOTIFY1 on FreeBSD

 meson.build| 1 +
 tests/vm/basevm.py | 2 ++
 tests/vm/freebsd   | 2 ++
 3 files changed, 5 insertions(+)

-- 
2.43.0




[PATCH v15 8/9] hw/net: GMAC Tx Implementation

2024-01-25 Thread Nabih Estefan
From: Nabih Estefan Diaz 

- Implementation of Transmit function for packets
- Implementation for reading and writing from and to descriptors in
  memory for Tx

Added relevant trace-events

NOTE: This function implements the steps detailed in the datasheet for
transmitting messages from the GMAC.

Change-Id: Icf14f9fcc6cc7808a41acd872bca67c9832087e6
Signed-off-by: Nabih Estefan 
Reviewed-by: Tyrone Ting 
---
 hw/net/npcm_gmac.c  | 203 
 hw/net/trace-events |   2 +
 2 files changed, 205 insertions(+)

diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
index b2b9314f5e..a0b1cd9356 100644
--- a/hw/net/npcm_gmac.c
+++ b/hw/net/npcm_gmac.c
@@ -235,6 +235,37 @@ static int gmac_write_rx_desc(dma_addr_t addr, struct 
NPCMGMACRxDesc *desc)
 return 0;
 }
 
+static int gmac_read_tx_desc(dma_addr_t addr, struct NPCMGMACTxDesc *desc)
+{
+if (dma_memory_read(_space_memory, addr, desc,
+sizeof(*desc), MEMTXATTRS_UNSPECIFIED)) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
+  HWADDR_PRIx "\n", __func__, addr);
+return -1;
+}
+desc->tdes0 = le32_to_cpu(desc->tdes0);
+desc->tdes1 = le32_to_cpu(desc->tdes1);
+desc->tdes2 = le32_to_cpu(desc->tdes2);
+desc->tdes3 = le32_to_cpu(desc->tdes3);
+return 0;
+}
+
+static int gmac_write_tx_desc(dma_addr_t addr, struct NPCMGMACTxDesc *desc)
+{
+struct NPCMGMACTxDesc le_desc;
+le_desc.tdes0 = cpu_to_le32(desc->tdes0);
+le_desc.tdes1 = cpu_to_le32(desc->tdes1);
+le_desc.tdes2 = cpu_to_le32(desc->tdes2);
+le_desc.tdes3 = cpu_to_le32(desc->tdes3);
+if (dma_memory_write(_space_memory, addr, _desc,
+sizeof(le_desc), MEMTXATTRS_UNSPECIFIED)) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
+  HWADDR_PRIx "\n", __func__, addr);
+return -1;
+}
+return 0;
+}
+
 static int gmac_rx_transfer_frame_to_buffer(uint32_t rx_buf_len,
 uint32_t *left_frame,
 uint32_t rx_buf_addr,
@@ -456,6 +487,155 @@ static ssize_t gmac_receive(NetClientState *nc, const 
uint8_t *buf, size_t len)
 return len;
 }
 
+static int gmac_tx_get_csum(uint32_t tdes1)
+{
+uint32_t mask = TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(tdes1);
+int csum = 0;
+
+if (likely(mask > 0)) {
+csum |= CSUM_IP;
+}
+if (likely(mask > 1)) {
+csum |= CSUM_TCP | CSUM_UDP;
+}
+
+return csum;
+}
+
+static void gmac_try_send_next_packet(NPCMGMACState *gmac)
+{
+/*
+ * Comments about steps refer to steps for
+ * transmitting in page 384 of datasheet
+ */
+uint16_t tx_buffer_size = 2048;
+g_autofree uint8_t *tx_send_buffer = g_malloc(tx_buffer_size);
+uint32_t desc_addr;
+struct NPCMGMACTxDesc tx_desc;
+uint32_t tx_buf_addr, tx_buf_len;
+uint16_t length = 0;
+uint8_t *buf = tx_send_buffer;
+uint32_t prev_buf_size = 0;
+int csum = 0;
+
+/* steps 1&2 */
+if (!gmac->regs[R_NPCM_DMA_HOST_TX_DESC]) {
+gmac->regs[R_NPCM_DMA_HOST_TX_DESC] =
+NPCM_DMA_HOST_TX_DESC_MASK(gmac->regs[R_NPCM_DMA_TX_BASE_ADDR]);
+}
+desc_addr = gmac->regs[R_NPCM_DMA_HOST_TX_DESC];
+
+while (true) {
+gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
+NPCM_DMA_STATUS_TX_RUNNING_FETCHING_STATE);
+if (gmac_read_tx_desc(desc_addr, _desc)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "TX Descriptor @ 0x%x can't be read\n",
+  desc_addr);
+return;
+}
+/* step 3 */
+
+trace_npcm_gmac_packet_desc_read(DEVICE(gmac)->canonical_path,
+desc_addr);
+trace_npcm_gmac_debug_desc_data(DEVICE(gmac)->canonical_path, _desc,
+tx_desc.tdes0, tx_desc.tdes1, tx_desc.tdes2, tx_desc.tdes3);
+
+/* 1 = DMA Owned, 0 = Software Owned */
+if (!(tx_desc.tdes0 & TX_DESC_TDES0_OWN)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "TX Descriptor @ 0x%x is owned by software\n",
+  desc_addr);
+gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_TU;
+gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
+NPCM_DMA_STATUS_TX_SUSPENDED_STATE);
+gmac_update_irq(gmac);
+return;
+}
+
+gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
+NPCM_DMA_STATUS_TX_RUNNING_READ_STATE);
+/* Give the descriptor back regardless of what happens. */
+tx_desc.tdes0 &= ~TX_DESC_TDES0_OWN;
+
+if (tx_desc.tdes1 & TX_DESC_TDES1_FIRST_SEG_MASK) {
+csum = gmac_tx_get_csum(tx_desc.tdes1);
+}
+
+/* step 4 */
+tx_buf_addr = tx_desc.tdes2;
+

[PATCH v15 4/9] hw/net: Add NPCMXXX GMAC device

2024-01-25 Thread Nabih Estefan
From: Hao Wu 

This patch implements the basic registers of GMAC device and sets
registers for networking functionalities.
Squashed IRQ Implementation patch into this one for compliation.
Tested:
The following message shows up with the change:
Broadcom BCM54612E stmmac-0:00: attached PHY driver [Broadcom BCM54612E] 
(mii_bus:phy_addr=stmmac-0:00, irq=POLL)
stmmaceth f0802000.eth eth0: Link is Up - 1Gbps/Full - flow control rx/tx

Change-Id: If71c6d486b95edcccba109ba454870714d7e0940
Signed-off-by: Hao Wu 
Signed-off-by: Nabih Estefan Diaz 
Reviewed-by: Tyrone Ting 
---
 hw/net/meson.build |   2 +-
 hw/net/npcm_gmac.c | 464 +
 hw/net/trace-events|  12 +
 include/hw/net/npcm_gmac.h | 340 +++
 4 files changed, 817 insertions(+), 1 deletion(-)
 create mode 100644 hw/net/npcm_gmac.c
 create mode 100644 include/hw/net/npcm_gmac.h

diff --git a/hw/net/meson.build b/hw/net/meson.build
index 9afceb0619..d4e1dc9838 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -38,7 +38,7 @@ system_ss.add(when: 'CONFIG_I82596_COMMON', if_true: 
files('i82596.c'))
 system_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
 system_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
 system_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
-system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
+system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c', 
'npcm_gmac.c'))
 
 system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
 system_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
new file mode 100644
index 00..f434530930
--- /dev/null
+++ b/hw/net/npcm_gmac.c
@@ -0,0 +1,464 @@
+/*
+ * Nuvoton NPCM7xx/8xx GMAC Module
+ *
+ * Copyright 2024 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * Unsupported/unimplemented features:
+ * - MII is not implemented, MII_ADDR.BUSY and MII_DATA always return zero
+ * - Precision timestamp (PTP) is not implemented.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/registerfields.h"
+#include "hw/net/mii.h"
+#include "hw/net/npcm_gmac.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/units.h"
+#include "sysemu/dma.h"
+#include "trace.h"
+
+REG32(NPCM_DMA_BUS_MODE, 0x1000)
+REG32(NPCM_DMA_XMT_POLL_DEMAND, 0x1004)
+REG32(NPCM_DMA_RCV_POLL_DEMAND, 0x1008)
+REG32(NPCM_DMA_RX_BASE_ADDR, 0x100c)
+REG32(NPCM_DMA_TX_BASE_ADDR, 0x1010)
+REG32(NPCM_DMA_STATUS, 0x1014)
+REG32(NPCM_DMA_CONTROL, 0x1018)
+REG32(NPCM_DMA_INTR_ENA, 0x101c)
+REG32(NPCM_DMA_MISSED_FRAME_CTR, 0x1020)
+REG32(NPCM_DMA_HOST_TX_DESC, 0x1048)
+REG32(NPCM_DMA_HOST_RX_DESC, 0x104c)
+REG32(NPCM_DMA_CUR_TX_BUF_ADDR, 0x1050)
+REG32(NPCM_DMA_CUR_RX_BUF_ADDR, 0x1054)
+REG32(NPCM_DMA_HW_FEATURE, 0x1058)
+
+REG32(NPCM_GMAC_MAC_CONFIG, 0x0)
+REG32(NPCM_GMAC_FRAME_FILTER, 0x4)
+REG32(NPCM_GMAC_HASH_HIGH, 0x8)
+REG32(NPCM_GMAC_HASH_LOW, 0xc)
+REG32(NPCM_GMAC_MII_ADDR, 0x10)
+REG32(NPCM_GMAC_MII_DATA, 0x14)
+REG32(NPCM_GMAC_FLOW_CTRL, 0x18)
+REG32(NPCM_GMAC_VLAN_FLAG, 0x1c)
+REG32(NPCM_GMAC_VERSION, 0x20)
+REG32(NPCM_GMAC_WAKEUP_FILTER, 0x28)
+REG32(NPCM_GMAC_PMT, 0x2c)
+REG32(NPCM_GMAC_LPI_CTRL, 0x30)
+REG32(NPCM_GMAC_TIMER_CTRL, 0x34)
+REG32(NPCM_GMAC_INT_STATUS, 0x38)
+REG32(NPCM_GMAC_INT_MASK, 0x3c)
+REG32(NPCM_GMAC_MAC0_ADDR_HI, 0x40)
+REG32(NPCM_GMAC_MAC0_ADDR_LO, 0x44)
+REG32(NPCM_GMAC_MAC1_ADDR_HI, 0x48)
+REG32(NPCM_GMAC_MAC1_ADDR_LO, 0x4c)
+REG32(NPCM_GMAC_MAC2_ADDR_HI, 0x50)
+REG32(NPCM_GMAC_MAC2_ADDR_LO, 0x54)
+REG32(NPCM_GMAC_MAC3_ADDR_HI, 0x58)
+REG32(NPCM_GMAC_MAC3_ADDR_LO, 0x5c)
+REG32(NPCM_GMAC_RGMII_STATUS, 0xd8)
+REG32(NPCM_GMAC_WATCHDOG, 0xdc)
+REG32(NPCM_GMAC_PTP_TCR, 0x700)
+REG32(NPCM_GMAC_PTP_SSIR, 0x704)
+REG32(NPCM_GMAC_PTP_STSR, 0x708)
+REG32(NPCM_GMAC_PTP_STNSR, 0x70c)
+REG32(NPCM_GMAC_PTP_STSUR, 0x710)
+REG32(NPCM_GMAC_PTP_STNSUR, 0x714)
+REG32(NPCM_GMAC_PTP_TAR, 0x718)
+REG32(NPCM_GMAC_PTP_TTSR, 0x71c)
+
+/* Register Fields */
+#define NPCM_GMAC_MII_ADDR_BUSY BIT(0)
+#define NPCM_GMAC_MII_ADDR_WRITEBIT(1)
+#define NPCM_GMAC_MII_ADDR_GR(rv)   extract16((rv), 6, 5)
+#define NPCM_GMAC_MII_ADDR_PA(rv)   extract16((rv), 11, 5)
+
+#define NPCM_GMAC_INT_MASK_LPIIMBIT(10)
+#define NPCM_GMAC_INT_MASK_PMTM BIT(3)
+#define NPCM_GMAC_INT_MASK_RGIM BIT(0)
+
+#define NPCM_DMA_BUS_MODE_SWR   BIT(0)
+
+static const uint32_t 

[PATCH v15 6/9] tests/qtest: Creating qtest for GMAC Module

2024-01-25 Thread Nabih Estefan
From: Nabih Estefan Diaz 

 - Created qtest to check initialization of registers in GMAC Module.
 - Implemented test into Build File.

Change-Id: I8b2fe152d3987a7eec4cf6a1d25ba92e75a5391d
Signed-off-by: Nabih Estefan 
Reviewed-by: Tyrone Ting 
---
 tests/qtest/meson.build  |   1 +
 tests/qtest/npcm_gmac-test.c | 209 +++
 2 files changed, 210 insertions(+)
 create mode 100644 tests/qtest/npcm_gmac-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 101f9c219e..e6025ee92a 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -229,6 +229,7 @@ qtests_aarch64 = \
   (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) +  \
   (config_all_accel.has_key('CONFIG_TCG') and  
  \
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : 
[]) + \
+  (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
   ['arm-cpu-features',
'numa-test',
'boot-serial-test',
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
new file mode 100644
index 00..6914ac92f1
--- /dev/null
+++ b/tests/qtest/npcm_gmac-test.c
@@ -0,0 +1,209 @@
+/*
+ * QTests for Nuvoton NPCM7xx/8xx GMAC Modules.
+ *
+ * Copyright 2024 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "libqos/libqos.h"
+
+/* Name of the GMAC Device */
+#define TYPE_NPCM_GMAC "npcm-gmac"
+
+typedef struct GMACModule {
+int irq;
+uint64_t base_addr;
+} GMACModule;
+
+typedef struct TestData {
+const GMACModule *module;
+} TestData;
+
+/* Values extracted from hw/arm/npcm8xx.c */
+static const GMACModule gmac_module_list[] = {
+{
+.irq= 14,
+.base_addr  = 0xf0802000
+},
+{
+.irq= 15,
+.base_addr  = 0xf0804000
+},
+{
+.irq= 16,
+.base_addr  = 0xf0806000
+},
+{
+.irq= 17,
+.base_addr  = 0xf0808000
+}
+};
+
+/* Returns the index of the GMAC module. */
+static int gmac_module_index(const GMACModule *mod)
+{
+ptrdiff_t diff = mod - gmac_module_list;
+
+g_assert_true(diff >= 0 && diff < ARRAY_SIZE(gmac_module_list));
+
+return diff;
+}
+
+/* 32-bit register indices. Taken from npcm_gmac.c */
+typedef enum NPCMRegister {
+/* DMA Registers */
+NPCM_DMA_BUS_MODE = 0x1000,
+NPCM_DMA_XMT_POLL_DEMAND = 0x1004,
+NPCM_DMA_RCV_POLL_DEMAND = 0x1008,
+NPCM_DMA_RCV_BASE_ADDR = 0x100c,
+NPCM_DMA_TX_BASE_ADDR = 0x1010,
+NPCM_DMA_STATUS = 0x1014,
+NPCM_DMA_CONTROL = 0x1018,
+NPCM_DMA_INTR_ENA = 0x101c,
+NPCM_DMA_MISSED_FRAME_CTR = 0x1020,
+NPCM_DMA_HOST_TX_DESC = 0x1048,
+NPCM_DMA_HOST_RX_DESC = 0x104c,
+NPCM_DMA_CUR_TX_BUF_ADDR = 0x1050,
+NPCM_DMA_CUR_RX_BUF_ADDR = 0x1054,
+NPCM_DMA_HW_FEATURE = 0x1058,
+
+/* GMAC Registers */
+NPCM_GMAC_MAC_CONFIG = 0x0,
+NPCM_GMAC_FRAME_FILTER = 0x4,
+NPCM_GMAC_HASH_HIGH = 0x8,
+NPCM_GMAC_HASH_LOW = 0xc,
+NPCM_GMAC_MII_ADDR = 0x10,
+NPCM_GMAC_MII_DATA = 0x14,
+NPCM_GMAC_FLOW_CTRL = 0x18,
+NPCM_GMAC_VLAN_FLAG = 0x1c,
+NPCM_GMAC_VERSION = 0x20,
+NPCM_GMAC_WAKEUP_FILTER = 0x28,
+NPCM_GMAC_PMT = 0x2c,
+NPCM_GMAC_LPI_CTRL = 0x30,
+NPCM_GMAC_TIMER_CTRL = 0x34,
+NPCM_GMAC_INT_STATUS = 0x38,
+NPCM_GMAC_INT_MASK = 0x3c,
+NPCM_GMAC_MAC0_ADDR_HI = 0x40,
+NPCM_GMAC_MAC0_ADDR_LO = 0x44,
+NPCM_GMAC_MAC1_ADDR_HI = 0x48,
+NPCM_GMAC_MAC1_ADDR_LO = 0x4c,
+NPCM_GMAC_MAC2_ADDR_HI = 0x50,
+NPCM_GMAC_MAC2_ADDR_LO = 0x54,
+NPCM_GMAC_MAC3_ADDR_HI = 0x58,
+NPCM_GMAC_MAC3_ADDR_LO = 0x5c,
+NPCM_GMAC_RGMII_STATUS = 0xd8,
+NPCM_GMAC_WATCHDOG = 0xdc,
+NPCM_GMAC_PTP_TCR = 0x700,
+NPCM_GMAC_PTP_SSIR = 0x704,
+NPCM_GMAC_PTP_STSR = 0x708,
+NPCM_GMAC_PTP_STNSR = 0x70c,
+NPCM_GMAC_PTP_STSUR = 0x710,
+NPCM_GMAC_PTP_STNSUR = 0x714,
+NPCM_GMAC_PTP_TAR = 0x718,
+NPCM_GMAC_PTP_TTSR = 0x71c,
+} NPCMRegister;
+
+static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
+  NPCMRegister regno)
+{
+return qtest_readl(qts, mod->base_addr + regno);
+}
+
+/* Check that GMAC registers are reset to default value */
+static void test_init(gconstpointer test_data)
+{
+const TestData *td = test_data;
+const GMACModule *mod = td->module;
+QTestState *qts = qtest_init("-machine npcm845-evb");
+
+#define 

[PATCH v15 5/9] hw/arm: Add GMAC devices to NPCM7XX SoC

2024-01-25 Thread Nabih Estefan
From: Hao Wu 

Change-Id: Id8a3461fb5042adc4c3fd6f4fbd1ca0d33e22565
Signed-off-by: Hao Wu 
Signed-off-by: Nabih Estefan 
Reviewed-by: Tyrone Ting 
---
 hw/arm/npcm7xx.c | 36 ++--
 include/hw/arm/npcm7xx.h |  2 ++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index c9e87162cb..12e11250e1 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -91,6 +91,7 @@ enum NPCM7xxInterrupt {
 NPCM7XX_GMAC1_IRQ   = 14,
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
+NPCM7XX_GMAC2_IRQ,
 NPCM7XX_MMC_IRQ = 26,
 NPCM7XX_PSPI2_IRQ   = 28,
 NPCM7XX_PSPI1_IRQ   = 31,
@@ -234,6 +235,12 @@ static const hwaddr npcm7xx_pspi_addr[] = {
 0xf0201000,
 };
 
+/* Register base address for each GMAC Module */
+static const hwaddr npcm7xx_gmac_addr[] = {
+0xf0802000,
+0xf0804000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -462,6 +469,10 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "pspi[*]", >pspi[i], TYPE_NPCM_PSPI);
 }
 
+for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
+object_initialize_child(obj, "gmac[*]", >gmac[i], TYPE_NPCM_GMAC);
+}
+
 object_initialize_child(obj, "pci-mbox", >pci_mbox,
 TYPE_NPCM7XX_PCI_MBOX);
 object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
@@ -695,6 +706,29 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
 }
 
+/*
+ * GMAC Modules. Cannot fail.
+ */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_gmac_addr) != ARRAY_SIZE(s->gmac));
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->gmac) != 2);
+for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
+SysBusDevice *sbd = SYS_BUS_DEVICE(>gmac[i]);
+
+/*
+ * The device exists regardless of whether it's connected to a QEMU
+ * netdev backend. So always instantiate it even if there is no
+ * backend.
+ */
+sysbus_realize(sbd, _abort);
+sysbus_mmio_map(sbd, 0, npcm7xx_gmac_addr[i]);
+int irq = i == 0 ? NPCM7XX_GMAC1_IRQ : NPCM7XX_GMAC2_IRQ;
+/*
+ * N.B. The values for the second argument sysbus_connect_irq are
+ * chosen to match the registration order in npcm7xx_emc_realize.
+ */
+sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
+}
+
 /*
  * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
  * specified, but this is a programming error.
@@ -765,8 +799,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.siox[2]",  0xf0102000,   4 * KiB);
 create_unimplemented_device("npcm7xx.ahbpci",   0xf040,   1 * MiB);
 create_unimplemented_device("npcm7xx.mcphy",0xf05f,  64 * KiB);
-create_unimplemented_device("npcm7xx.gmac1",0xf0802000,   8 * KiB);
-create_unimplemented_device("npcm7xx.gmac2",0xf0804000,   8 * KiB);
 create_unimplemented_device("npcm7xx.vcd",  0xf081,  64 * KiB);
 create_unimplemented_device("npcm7xx.ece",  0xf082,   8 * KiB);
 create_unimplemented_device("npcm7xx.vdma", 0xf0822000,   8 * KiB);
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index cec3792a2e..9e5cf639a2 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -30,6 +30,7 @@
 #include "hw/misc/npcm7xx_pwm.h"
 #include "hw/misc/npcm7xx_rng.h"
 #include "hw/net/npcm7xx_emc.h"
+#include "hw/net/npcm_gmac.h"
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "hw/ssi/npcm7xx_fiu.h"
@@ -105,6 +106,7 @@ struct NPCM7xxState {
 OHCISysBusState ohci;
 NPCM7xxFIUState fiu[2];
 NPCM7xxEMCState emc[2];
+NPCMGMACState   gmac[2];
 NPCM7xxPCIMBoxState pci_mbox;
 NPCM7xxSDHCIState   mmc;
 NPCMPSPIState   pspi[2];
-- 
2.43.0.429.g432eaa2c6b-goog




  1   2   3   >