Re: [PATCH v12 00/10] migration: Modify 'migrate' and 'migrate-incoming' QAPI commands for migration

2023-10-09 Thread Het Gala


On 10/10/2023 2:34 AM, Fabiano Rosas wrote:

Het Gala  writes:


This is v12 patchset of modified 'migrate' and 'migrate-incoming' QAPI design
for upstream review.

Would like to thank all the maintainers that actively participated in the v11
patchset discussion and gave insightful suggestions to improve the patches.

Link to previous upstream community patchset links:
v1:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2022-2D12_msg04339.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=OXhp-cq93AZ1ZRIwKL5wXhx5-8ei7RfBdmmbU9KNDfg=  
v2:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D02_msg02106.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=r7SYaB2fxLcEP2DiHslsbEyaY7ZPrXxageSBRtRZ7TA=  
v3:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D02_msg02473.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=fnGhJw56ypUavnslnUL6JeK4OLi7xwh7TGsafaSSZvw=  
v4:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D05_msg03064.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=SA4q18GEE4q3Eh7sy5nhQ8OZO5KM8kfapiBkSPZYDxE=  
v5:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D05_msg04845.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=QRW_aAGHmTBajBnu1a4jcxQFZ1lf1N3RCyLgOt82Ji4=  
v6:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D06_msg01251.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=7Dmgm47UdQ0h0Y9-XffsUW_ZdeQ-eCCVzhUkigTMKbc=  
v7:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D07_msg02027.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=8a3tAfIJ-6st1tlYkbjsRWEv-JvEFxokXzanf0WCqzw=  
v8:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D07_msg02770.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=4q_F05ZPdhWsPJ0fa850gHS90AsVX7MbsaIHi-3OsMI=  
v9:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D07_msg04216.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=1wNhJSfSvAoadG06F2JKFHZ2mA4QWSgqvYpt1zRX9qw=  
v10:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D07_msg05022.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=guEm3FuFn7jutT4ZB4RlgwttD4IMSBJy1MNh2zp3tYY=  
v11:https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2023-2D10_msg00740.html=DwIFaQ=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=s4FkORPOMqBTxCrkaYO6frUTsbcGM6c3K4FCdGaNAKeCIZ2GS9VaQxJGytQv0mGv=W7rbQhebtuWtT2ydMuG21OOkbqlh9KxMi1ZM5yZP6Ig=  


v11 -> v12 changelog:
---
- Resolved double-freeing when using g_autoptr in structures that are
   nested into another.
- Overwriting of pointers to an existing allocated memory is solved at
   various places.
- Use of g_autoptr caused make check errors in non-error path while going
   out of scope inside function. Added g_steal_pointer() in the non-error
   paths wherever required.

Please run make check before sending:
▶ 242/355 qcow2 181  FAIL

You can also push your code to your gitlab and run a pipeline with the
branch.


I tested on my setup, and it passed all the checks.

[root@06f1b38a5d6a build]# make check
/rpmbuild/SOURCES/qemu/build/pyvenv/bin/meson test  --no-rebuild -t 0  
--num-processes 1 --print-errorlogs
  1/348 qemu:qtest+qtest-x86_64 / 
qtest-x86_64/qom-test    OK 14.00s   8 subtests passed
  2/348 qemu:qtest+qtest-x86_64 / 
qtest-x86_64/migration-test  OK 82.28s   13 subtests passed
  3/348 qemu:qtest+qtest-x86_64 / 
qtest-x86_64/bios-tables-test    OK 79.38s   51 subtests passed
  4/348 qemu:qtest+qtest-x86_64 / 
qtest-x86_64/test-hmp    OK 5.67s   9 subtests passed
  5/348 qemu:qtest+qtest-x86_64 / 
qtest-x86_64/ahci-test 

Re: [PATCH v2 08/58] i386/tdx: Adjust the supported CPUID based on TDX restrictions

2023-10-09 Thread Xiaoyao Li

On 10/10/2023 9:02 AM, Tina Zhang wrote:

Hi,

On 8/18/23 17:49, Xiaoyao Li wrote:

According to Chapter "CPUID Virtualization" in TDX module spec, CPUID
bits of TD can be classified into 6 types:


1 | As configured | configurable by VMM, independent of native value;

2 | As configured | configurable by VMM if the bit is supported natively
 (if native)   | Otherwise it equals as native(0).

3 | Fixed | fixed to 0/1

4 | Native    | reflect the native value

5 | Calculated    | calculated by TDX module.

6 | Inducing #VE  | get #VE exception


Note:
1. All the configurable XFAM related features and TD attributes related
    features fall into type #2. And fixed0/1 bits of XFAM and TD
    attributes fall into type #3.

2. For CPUID leaves not listed in "CPUID virtualization Overview" table
    in TDX module spec, TDX module injects #VE to TDs when those are
    queried. For this case, TDs can request CPUID emulation from VMM via
    TDVMCALL and the values are fully controlled by VMM.

Due to TDX module has its own virtualization policy on CPUID bits, it 
leads

to what reported via KVM_GET_SUPPORTED_CPUID diverges from the supported
CPUID bits for TDs. In order to keep a consistent CPUID configuration
between VMM and TDs. Adjust supported CPUID for TDs based on TDX
restrictions.

Currently only focus on the CPUID leaves recognized by QEMU's
feature_word_info[] that are indexed by a FeatureWord.

Introduce a TDX CPUID lookup table, which maintains 1 entry for each
FeatureWord. Each entry has below fields:

  - tdx_fixed0/1: The bits that are fixed as 0/1;

  - vmm_fixup:   The bits that are configurable from the view of TDX 
module.
 But they requires emulation of VMM when they are 
configured

    as enabled. For those, they are not supported if VMM doesn't
    report them as supported. So they need be fixed up by
    checking if VMM supports them.

  - inducing_ve: TD gets #VE when querying this CPUID leaf. The result is
 totally configurable by VMM.

  - supported_on_ve: It's valid only when @inducing_ve is true. It 
represents

    the maximum feature set supported that be emulated
    for TDs.

By applying TDX CPUID lookup table and TDX capabilities reported from
TDX module, the supported CPUID for TDs can be obtained from following
steps:

- get the base of VMM supported feature set;

- if the leaf is not a FeatureWord just return VMM's value without
   modification;

- if the leaf is an inducing_ve type, applying supported_on_ve mask and
   return;

- include all native bits, it covers type #2, #4, and parts of type #1.
   (it also includes some unsupported bits. The following step will
    correct it.)

- apply fixed0/1 to it (it covers #3, and rectifies the previous step);

- add configurable bits (it covers the other part of type #1);

- fix the ones in vmm_fixup;

- filter the one has valid .supported field;

(Calculated type is ignored since it's determined at runtime).

Co-developed-by: Chenyi Qiang 
Signed-off-by: Chenyi Qiang 
Signed-off-by: Xiaoyao Li 
---
  target/i386/cpu.h |  16 +++
  target/i386/kvm/kvm.c |   4 +
  target/i386/kvm/tdx.c | 254 ++
  target/i386/kvm/tdx.h |   2 +
  4 files changed, 276 insertions(+)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e0771a10433b..c93dcd274531 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -780,6 +780,8 @@ uint64_t 
x86_cpu_get_supported_feature_word(FeatureWord w,

  /* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */
  #define CPUID_7_0_EBX_FSGSBASE  (1U << 0)
+/* Support for TSC adjustment MSR 0x3B */
+#define CPUID_7_0_EBX_TSC_ADJUST    (1U << 1)
  /* Support SGX */
  #define CPUID_7_0_EBX_SGX   (1U << 2)
  /* 1st Group of Advanced Bit Manipulation Extensions */
@@ -798,8 +800,12 @@ uint64_t 
x86_cpu_get_supported_feature_word(FeatureWord w,

  #define CPUID_7_0_EBX_INVPCID   (1U << 10)
  /* Restricted Transactional Memory */
  #define CPUID_7_0_EBX_RTM   (1U << 11)
+/* Cache QoS Monitoring */
+#define CPUID_7_0_EBX_PQM   (1U << 12)
  /* Memory Protection Extension */
  #define CPUID_7_0_EBX_MPX   (1U << 14)
+/* Resource Director Technology Allocation */
+#define CPUID_7_0_EBX_RDT_A (1U << 15)
  /* AVX-512 Foundation */
  #define CPUID_7_0_EBX_AVX512F   (1U << 16)
  /* AVX-512 Doubleword & Quadword Instruction */
@@ 

Re: [PATCH v2 3/3] target/hexagon: avoid shadowing globals

2023-10-09 Thread Philippe Mathieu-Daudé

On 9/10/23 22:53, Brian Cain wrote:

On 9/10/23 08:09, Philippe Mathieu-Daudé wrote:

On 6/10/23 00:22, Brian Cain wrote:

The typedef `vaddr` is shadowed by `vaddr` identifiers, so we rename the
identifiers to avoid shadowing the type name.


This one surprises me, since we have other occurences:

include/exec/memory.h:751:bool memory_get_xlat_addr(IOMMUTLBEntry
*iotlb, void **vaddr,
  include/qemu/plugin.h:199:void qemu_plugin_vcpu_mem_cb(CPUState
*cpu, uint64_t vaddr,
target/arm/internals.h:643:G_NORETURN void
arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
target/i386/tcg/helper-tcg.h:70:G_NORETURN void
handle_unaligned_access(CPUX86State *env, vaddr vaddr,
...

$ git grep -w vaddr, | wc -l
   207

What is the error/warning like?


OK I could reproduce, I suppose you are building with Clang which
doesn't support shadow-local so you get global warnings too (as
mentioned in this patch subject...):


No -- I generally build with gcc and only double-check the clang results to 
make sure I don't see any new failures there.

But I've not tested "-Wshadow" with clang yet.  I found these by adding "-Wshadow=global" 
to "-Wshadow=local".  I thought it might be useful to address these too while we're here.


In file included from ../../gdbstub/trace.h:1,
   from ../../gdbstub/softmmu.c:30:
trace/trace-gdbstub.h: In function '_nocheck__trace_gdbstub_hit_watchpoint':
trace/trace-gdbstub.h:903:106: error: declaration of 'vaddr' shadows a
global declaration [-Werror=shadow]
903 | static inline void _nocheck__trace_gdbstub_hit_watchpoint(const
char * type, int cpu_gdb_index, uint64_t vaddr)
|
  ~^
In file included from include/sysemu/accel-ops.h:13,
   from include/sysemu/cpus.h:4,
   from ../../gdbstub/softmmu.c:21:
include/exec/cpu-common.h:21:18: note: shadowed declaration is here
 21 | typedef uint64_t vaddr;
|  ^
trace/trace-gdbstub.h: In function 'trace_gdbstub_hit_watchpoint':
trace/trace-gdbstub.h:923:96: error: declaration of 'vaddr' shadows a
global declaration [-Werror=shadow]
923 | static inline void trace_gdbstub_hit_watchpoint(const char *
type, int cpu_gdb_index, uint64_t vaddr)
|
~^
include/exec/cpu-common.h:21:18: note: shadowed declaration is here
 21 | typedef uint64_t vaddr;
|  ^


If we have to clean that for -Wshadow=global, I'm tempted to rename
the typedef as 'vaddr_t' and keep the 'vaddr' variable names.

Richard, Anton, what do you think?


Clang users got confused by this, IIUC Markus and Thomas idea is
to only enable these warnings for GCC, enforcing them for Clang
users via CI (until Clang get this option supported). Personally
I'd rather enable the warning once for all, waiting for Clang
support (or clean/enable global shadowing for GCC too).


Hopefully it's helpful or at least benign if we address the shadowed globals under 
target/hexagon/ for now, even if "-Wshadow=global" is not enabled.


See this thread:
https://lore.kernel.org/qemu-devel/11abc551-188e-85c0-fe55-
b2b58d351...@redhat.com/

Regards,

Phil.





Re: [PATCH v11 09/10] migration: Implement MigrateChannelList to hmp migration flow.

2023-10-09 Thread Het Gala


On 10/9/2023 8:05 PM, Fabiano Rosas wrote:

Het Gala  writes:


On 10/4/2023 8:55 PM, Fabiano Rosas wrote:

Het Gala   writes:


Integrate MigrateChannelList with all transport backends
(socket, exec and rdma) for both src and dest migration
endpoints for hmp migration.

Suggested-by: Aravind Retnakaran
Signed-off-by: Het Gala
Reviewed-by: Daniel P. Berrangé
---
   migration/migration-hmp-cmds.c | 15 +--
   migration/migration.c  |  5 ++---
   migration/migration.h  |  3 ++-
   3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
index a2e6a5c51e..a1657f3d37 100644
--- a/migration/migration-hmp-cmds.c
+++ b/migration/migration-hmp-cmds.c
@@ -441,9 +441,14 @@ void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
   {
   Error *err = NULL;
   const char *uri = qdict_get_str(qdict, "uri");
+MigrationChannelList *caps = NULL;
+g_autoptr(MigrationChannel) channel = g_new0(MigrationChannel, 1);

Just the pointer here. If I remember correctly the g_autoptr here would
cause a double free when freeing the caps.

Yes, we'll just have 'g_autoptr(MigrationChannel) channel = NULL'.

Is it because inside QAPI_LIST_PREPEND, caps will be refrencing to the
same memory as 'channel', we don't need to free channel ?

Slightly different scenario here. Here the issue is that we will free
the caps with qapi_free_MigrationChannel() before returning. Then, at
function exit the g_autoptr will try to free 'channel', which has
already been freed along with 'caps'. That's a double free, I think it
hits an assert inside glib, if I remember correctly.


I am still not
sure what is the right place to use g_steal_pointer(), is this a right
place to use (non-error paths) ?

It doesn't look like we need it here. As long as the qapi list has a
reference and we're freeing the caps, then channel should be freed by
that function already.
Ack. Yes, with the discussion in earlier patches, I also don't think we 
need g_autoptr too here. Normal pointer is enough as we are freeing the 
memory after the function is returned.
   
-qmp_migrate_incoming(uri, false, NULL, );

+migrate_uri_parse(uri, , );
+QAPI_LIST_PREPEND(caps, channel);
   
+qmp_migrate_incoming(NULL, true, caps, );

+qapi_free_MigrationChannelList(caps);
   hmp_handle_error(mon, err);
   }
   
@@ -730,9 +735,15 @@ 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(MigrationChannel) channel = g_new0(MigrationChannel, 1);

Same here. We free the channel via caps and we attribute it below, no
need to allocate.

Ack.
   
-qmp_migrate(uri, false, NULL, !!blk, blk, !!inc, inc,

+migrate_uri_parse(uri, , );
+QAPI_LIST_PREPEND(caps, channel);
+
+qmp_migrate(NULL, true, caps, !!blk, blk, !!inc, inc,
false, false, true, resume, );
+qapi_free_MigrationChannelList(caps);
   if (hmp_handle_error(mon, err)) {

Regards,
Het Gala

Regards,
Het Gala

Re: [PATCH v11 08/10] migration: Implement MigrateChannelList to qmp migration flow.

2023-10-09 Thread Het Gala


On 10/9/2023 7:59 PM, Fabiano Rosas wrote:

Het Gala  writes:


On 10/4/2023 8:51 PM, Fabiano Rosas wrote:

Het Gala   writes:


Integrate MigrateChannelList with all transport backends
(socket, exec and rdma) for both src and dest migration
endpoints for qmp migration.

For current series, limit the size of MigrateChannelList
to single element (single interface) as runtime check.

Suggested-by: Aravind Retnakaran
Signed-off-by: Het Gala
Reviewed-by: Daniel P. Berrangé
---
   migration/migration.c | 95 +++
   1 file changed, 52 insertions(+), 43 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 6f948988ec..3eae32e616 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -432,9 +432,10 @@ void migrate_add_address(SocketAddress *address)
   }
   
   static bool migrate_uri_parse(const char *uri,

-  MigrationAddress **channel,
+  MigrationChannel **channel,
 Error **errp)
   {
+g_autoptr(MigrationChannel) val = g_new0(MigrationChannel, 1);

Here val is passed out of scope so it shouldn't be g_autoptr.

I guess, same as for 'addr' we need to go with adding
g_steal_pointer() here too ?

Yes, you cannot give the same pointer to *channel because this one is
already being tracked by g_autoptr and it will free the memory when it
gets the chance. So we need to steal it from g_autoptr, so to speak.

Yes true. Ack.

   g_autoptr(MigrationAddress) addr = g_new0(MigrationAddress, 1);
   SocketAddress *saddr = >u.socket;
   InetSocketAddress *isock = >u.rdma;
@@ -471,7 +472,9 @@ static bool migrate_uri_parse(const char *uri,
   return false;
   }
   
-*channel = addr;

+val->channel_type = MIGRATION_CHANNEL_TYPE_MAIN;
+val->addr = addr;
+*channel = val;
   return true;
   }
   
@@ -479,41 +482,44 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels,

 MigrationChannelList *channels,
 Error **errp)
   {
-g_autoptr(MigrationAddress) channel = g_new0(MigrationAddress, 1);
+g_autoptr(MigrationChannel) channel = g_new0(MigrationChannel, 1);
+g_autoptr(MigrationAddress) addr = g_new0(MigrationAddress, 1);

Here we want just the pointer, no allocation, no freeing. For both
channel and addr.

Ack, same as channel in patch 2.

This is actually one of the cases where we need to think about how we
are going to free that memory. You need to make sure no one is using the
'addr' after you call into the *_incoming_migration functions. All users
should either use the value and return or make a copy if they intend to
pass it forward. If you determine that no one is using 'addr' and
'channel', then we could bring the channel g_autoptr back.
Honestly, I think g_autoptr would work here because no one uses addr or 
channel after *_incoming_migration or *_outgoing_migration functions. 
But not sure. But that does not make the checks pass, so I have gone 
forward with simple pointers to pass make checks.


   
   /*

* Having preliminary checks for uri and channel
*/
-if (has_channels) {
-error_setg(errp, "'channels' argument should not be set yet.");
-return;
-}
-
   if (uri && has_channels) {
   error_setg(errp, "'uri' and 'channels' arguments are mutually "
  "exclusive; exactly one of the two should be present in "
  "'migrate-incoming' qmp command ");
   return;
-}
-
-if (!uri && !has_channels) {
+} else if (channels) {
+/* To verify that Migrate channel list has only item */
+if (channels->next) {
+error_setg(errp, "Channel list has more than one entries");
+return;
+}
+channel = channels->value;
+} else if (uri) {
+/* caller uses the old URI syntax */
+if (!migrate_uri_parse(uri, , errp)) {
+return;
+}
+} else {
   error_setg(errp, "neither 'uri' or 'channels' argument are "
  "specified in 'migrate-incoming' qmp command ");
   return;
   }
-
-if (uri && !migrate_uri_parse(uri, , errp)) {
-return;
-}
+addr = channel->addr;
   
   /* transport mechanism not suitable for migration? */

-if (!migration_channels_and_transport_compatible(channel, errp)) {
+if (!migration_channels_and_transport_compatible(addr, errp)) {
   return;
   }
   
   qapi_event_send_migration(MIGRATION_STATUS_SETUP);

-if (channel->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
-SocketAddress *saddr = >u.socket;
+if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
+SocketAddress *saddr = >u.socket;
   if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
   saddr->type == 

Re: [PATCH] hw/loongarch: remove global loaderparams variable

2023-10-09 Thread Philippe Mathieu-Daudé

Hi Thomas,

On 9/10/23 23:00, Thomas Weißschuh wrote:

Passing the struct around explicitly makes the control-flow more
obvious.

Signed-off-by: Thomas Weißschuh 
---
  hw/loongarch/virt.c | 50 -
  1 file changed, 27 insertions(+), 23 deletions(-)




-static void loongarch_direct_kernel_boot(LoongArchMachineState *lams)
+static void loongarch_direct_kernel_boot(LoongArchMachineState *lams,
+ const struct loaderparams 
*loaderparams)
  {
  MachineState *machine = MACHINE(lams);
  int64_t kernel_addr = 0;
  LoongArchCPU *lacpu;
  int i;
  
-kernel_addr = load_kernel_info();

+kernel_addr = load_kernel_info(loaderparams);
  if (!machine->firmware) {
  for (i = 0; i < machine->smp.cpus; i++) {
  lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
@@ -793,6 +796,7 @@ static void loongarch_init(MachineState *machine)
  MachineClass *mc = MACHINE_GET_CLASS(machine);
  CPUState *cpu;
  char *ramName = NULL;
+struct loaderparams loaderparams;


Please zero-initialize with '= { }', otherwise great!

Reviewed-by: Philippe Mathieu-Daudé 

  
  if (!cpu_model) {

  cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
@@ -898,9 +902,9 @@ static void loongarch_init(MachineState *machine)
  /* load the kernel. */
  if (loaderparams.kernel_filename) {
  if (lams->bios_loaded) {
-loongarch_firmware_boot(lams);
+loongarch_firmware_boot(lams, );
  } else {
-loongarch_direct_kernel_boot(lams);
+loongarch_direct_kernel_boot(lams, );
  }
  }
  fdt_add_flash_node(lams);

base-commit: 2f3913f4b2ad74baeb5a6f1d36efbd9ecdf1057d





[PATCH] hw/ufs: Fix incorrect register fields

2023-10-09 Thread Jeuk Kim
From: Jeuk Kim 

This patch fixes invalid ufs register fields.
This fixes an issue reported by Bin Meng that
caused ufs to fail over riscv.

Signed-off-by: Jeuk Kim 
---
 include/block/ufs.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/block/ufs.h b/include/block/ufs.h
index fd884eb8ce..7631a5af10 100644
--- a/include/block/ufs.h
+++ b/include/block/ufs.h
@@ -111,14 +111,14 @@ REG32(UECT, offsetof(UfsReg, uect))
 REG32(UECDME, offsetof(UfsReg, uecdme))
 REG32(UTRIACR, offsetof(UfsReg, utriacr))
 REG32(UTRLBA, offsetof(UfsReg, utrlba))
-FIELD(UTRLBA, UTRLBA, 9, 22)
+FIELD(UTRLBA, UTRLBA, 10, 22)
 REG32(UTRLBAU, offsetof(UfsReg, utrlbau))
 REG32(UTRLDBR, offsetof(UfsReg, utrldbr))
 REG32(UTRLCLR, offsetof(UfsReg, utrlclr))
 REG32(UTRLRSR, offsetof(UfsReg, utrlrsr))
 REG32(UTRLCNR, offsetof(UfsReg, utrlcnr))
 REG32(UTMRLBA, offsetof(UfsReg, utmrlba))
-FIELD(UTMRLBA, UTMRLBA, 9, 22)
+FIELD(UTMRLBA, UTMRLBA, 10, 22)
 REG32(UTMRLBAU, offsetof(UfsReg, utmrlbau))
 REG32(UTMRLDBR, offsetof(UfsReg, utmrldbr))
 REG32(UTMRLCLR, offsetof(UfsReg, utmrlclr))
-- 
2.34.1




Re: [PATCH v2 3/3] target/hexagon: avoid shadowing globals

2023-10-09 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> On 9/10/23 08:09, Philippe Mathieu-Daudé wrote:
>> Hi Brian,
>> On 6/10/23 00:22, Brian Cain wrote:
>>> The typedef `vaddr` is shadowed by `vaddr` identifiers, so we rename the
>>> identifiers to avoid shadowing the type name.
>> This one surprises me, since we have other occurences:
>> include/exec/memory.h:751:bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, 
>> void **vaddr,
>>  include/qemu/plugin.h:199:void qemu_plugin_vcpu_mem_cb(CPUState *cpu, 
>> uint64_t vaddr,
>> target/arm/internals.h:643:G_NORETURN void 
>> arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
>> target/i386/tcg/helper-tcg.h:70:G_NORETURN void 
>> handle_unaligned_access(CPUX86State *env, vaddr vaddr,
>> ...
>> $ git grep -w vaddr, | wc -l
>>   207
>> What is the error/warning like?
>
> OK I could reproduce, I suppose you are building with Clang which
> doesn't support shadow-local so you get global warnings too (as
> mentioned in this patch subject...):
>
> In file included from ../../gdbstub/trace.h:1,
>  from ../../gdbstub/softmmu.c:30:
> trace/trace-gdbstub.h: In function '_nocheck__trace_gdbstub_hit_watchpoint':
> trace/trace-gdbstub.h:903:106: error: declaration of 'vaddr' shadows a global 
> declaration [-Werror=shadow]
>   903 | static inline void _nocheck__trace_gdbstub_hit_watchpoint(const char 
> * type, int cpu_gdb_index, uint64_t vaddr)
>   |  ~^
> In file included from include/sysemu/accel-ops.h:13,
>  from include/sysemu/cpus.h:4,
>  from ../../gdbstub/softmmu.c:21:
> include/exec/cpu-common.h:21:18: note: shadowed declaration is here
>21 | typedef uint64_t vaddr;
>   |  ^
> trace/trace-gdbstub.h: In function 'trace_gdbstub_hit_watchpoint':
> trace/trace-gdbstub.h:923:96: error: declaration of 'vaddr' shadows a global 
> declaration [-Werror=shadow]
>   923 | static inline void trace_gdbstub_hit_watchpoint(const char * type, 
> int cpu_gdb_index, uint64_t vaddr)
>   |~^
> include/exec/cpu-common.h:21:18: note: shadowed declaration is here
>21 | typedef uint64_t vaddr;
>   |  ^
>
> Clang users got confused by this, IIUC Markus and Thomas idea is
> to only enable these warnings for GCC, enforcing them for Clang
> users via CI (until Clang get this option supported). Personally
> I'd rather enable the warning once for all, waiting for Clang
> support (or clean/enable global shadowing for GCC too).
>
> See this thread:
> https://lore.kernel.org/qemu-devel/11abc551-188e-85c0-fe55-b2b58d351...@redhat.com/

The idea to enable some variation of -Wshadow goes back to this thread:

Subject: Re: [RFC PATCH] docs/style: permit inline loop variables
Date: Thu, 24 Aug 2023 14:18:53 +0100
Message-ID: 


https://lore.kernel.org/qemu-devel/cafeaca8wobo5f16vyhbqcjeadfn5zwx5cq7l4vq3fh8c_6n...@mail.gmail.com/

I've been aiming at -Wshadow=local because (1) it seemed more practical
(a lot less cleanup needed before we can enable the warning), and (2)
local shadowing is basically always foolish and fully our own fault.

No objection to additional -Wshadow work as long as I'm not the one
doing it :)




Re: [Virtio-fs] (no subject)

2023-10-09 Thread Yajun Wu



On 10/9/2023 5:13 PM, Hanna Czenczek wrote:

External email: Use caution opening links or attachments


On 09.10.23 11:07, Hanna Czenczek wrote:

On 09.10.23 10:21, Hanna Czenczek wrote:

On 07.10.23 04:22, Yajun Wu wrote:

[...]


The main motivation of adding VHOST_USER_SET_STATUS is to let
backend DPDK know
when DRIVER_OK bit is valid. It's an indication of all VQ
configuration has sent,
otherwise DPDK has to rely on first queue pair is ready, then
receiving/applying
VQ configuration one by one.

During live migration, configuring VQ one by one is very time
consuming.

One question I have here is why it wasn’t then introduced in the live
migration code, but in the general VM stop/cont code instead. It does
seem time-consuming to do this every time the VM is paused and resumed.


Yes, VM stop/cont will call vhost_net_stop/vhost_net_start. Maybe 
because there's no device level stop/cont vhost message?





For VIRTIO
net vDPA, HW needs to know how many VQs are enabled to set
RSS(Receive-Side Scaling).

If you don’t want SET_STATUS message, backend can remove protocol
feature bit
VHOST_USER_PROTOCOL_F_STATUS.

The problem isn’t back-ends that don’t want the message, the problem
is that qemu uses the message wrongly, which prevents well-behaving
back-ends from implementing the message.


DPDK is ignoring SET_STATUS 0, but using GET_VRING_BASE to do device
close/reset.

So the right thing to do for back-ends is to announce STATUS support
and then not implement it correctly?

GET_VRING_BASE should not reset the close or reset the device, by the
way.  It should stop that one vring, not more.  We have a
RESET_DEVICE command for resetting.
I believe dpdk uses GET_VRING_BASE long before qemu has RESET_DEVICE? 
It's a compatible issue. For new backend implements, we can have better 
solution, right?

I'm not involved in discussion about adding SET_STATUS in Vhost
protocol. This feature
is essential for vDPA(same as vhost-vdpa implements
VHOST_VDPA_SET_STATUS).

So from what I gather from your response is that there is only a
single use for SET_STATUS, which is the DRIVER_OK bit.  If so,
documenting that all other bits are to be ignored by both back-end
and front-end would be fine by me.

I’m not fully serious about that suggestion, but I hear the strong
implication that nothing but DRIVER_OK was of any concern, and this
is really important to note when we talk about the status of the
STATUS feature in vhost today.  It seems to me now that it was not
intended to be the virtio-level status byte, but just a DRIVER_OK
signalling path from front-end to back-end.  That makes it a
vhost-level protocol feature to me.

On second thought, it just is a pure vhost-level protocol feature, and
has nothing to do with the virtio status byte as-is.  The only stated
purpose is for the front-end to send DRIVER_OK after migration, but
migration is transparent to the guest, so the guest would never change
the status byte during migration.  Therefore, if this feature is
essential, we will never be able to have a status byte that is
transparently shared between guest and back-end device, i.e. the
virtio status byte.

On third thought, scratch that.  The guest wouldn’t set it, but
naturally, after migration, the front-end will need to restore the
status byte from the source, so the front-end will always need to set
it, even if it were otherwise used controlled only by the guest and the
back-end device.  So technically, this doesn’t prevent such a use case.
(In practice, it isn’t controlled by the guest right now, but that could
be fixed.)
I only tested the feature with DPDK(the only backend use it today?). Max 
defined the protocol and added the corresponding code in DPDK before I 
added QEMU support. If other backend or different device type want to 
use this, we can have further discussion?

Cc-ing Alex on this mail, because to me, this seems like an important
detail when he plans on using the byte in the future. If we need a
virtio status byte, I can’t see how we could use the existing F_STATUS
for it.

Hanna




[PATCH v1 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext

2023-10-09 Thread Song Gao
Hi, All.

This series adds save/restore sigcontext. 

We use extctx_flags to choces which sigcontext need save/restore.

The extctx_flags default value is EXTCTX_FLAGS_FPU, we need
save/restore fpu context.

After a LSX/LASX instruction is execed, extctx_flags value change to
EXTCTX_FLAGS_LSX/LASX, we always need save/restore lsx/lasx context.


The test_signal.c is a simple test.

The default vreg len is 64. After execed a LSX instruction, the vreg len is 
128, and then we exec a FPU instruction, the vreg len is also 128. After
execed a LASX instruction, the vreg len is 256, and then we exec a FPU
instruction, the vreg len is also 256.

test_signal.c:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

static sigjmp_buf jmpbuf;

struct _ctx_layout {
struct sctx_info *addr;
unsigned int size;
};

struct extctx_layout {
unsigned long size;
unsigned int flags;
struct _ctx_layout fpu;
struct _ctx_layout lsx;
struct _ctx_layout lasx;
struct _ctx_layout end;
};
static int parse_extcontext(struct sigcontext *sc, struct extctx_layout *extctx)
{
uint32_t magic, size;
struct sctx_info *info = (struct sctx_info *)>sc_extcontext;

while(1) {
magic = (uint32_t)info->magic;
size =  (uint32_t)info->size;

printf("magic is %lx\n", magic);
printf("size is %lx\n", size);
switch (magic) {
case 0: /* END*/
return 0;
case FPU_CTX_MAGIC:
if (size < (sizeof(struct sctx_info) +
sizeof(struct fpu_context))) {
return -1;
}
extctx->fpu.addr = info;
break;
case LSX_CTX_MAGIC:
if (size < (sizeof(struct sctx_info) +
sizeof(struct lsx_context))) {
return -1;
}
extctx->lsx.addr = info;
break;
case LASX_CTX_MAGIC:
if (size < (sizeof(struct sctx_info) +
sizeof(struct lasx_context))) {
return -1;
}
extctx->lasx.addr = info;
break;
default:
return -1;
}
info = (struct sctx_info *)((char *)info +size);
}
return 0;
}

static int n = 0;

static void do_signal(int sig, siginfo_t *info, void *ucontext)
{
int i;
struct ucontext *uc = (struct ucontext *)ucontext;
struct extctx_layout extctx;

memset(, 0, sizeof(struct extctx_layout));

printf("pc: %016lx\n", uc->uc_mcontext.sc_pc);

parse_extcontext(>uc_mcontext, );

if (n < 5) {
printf("extctx.lasx.addr is %lx\n", extctx.lasx.addr);
printf("extctx.lsx.addr  is %lx\n", extctx.lsx.addr);
printf("extctx.fpu.addr  is %lx\n", extctx.fpu.addr);

if (extctx.lasx.addr) {
struct sctx_info *info = extctx.lasx.addr;
struct lasx_context *lasx_ctx = (struct lasx_context *)((char 
*)info +
sizeof(struct sctx_info));
printf("vl: %016lx\n", 256);
} else if (extctx.lsx.addr) {
struct sctx_info *info = extctx.lsx.addr;
struct lsx_context *lsx_ctx = (struct lsx_context *)((char *)info +
  sizeof(struct sctx_info));
printf("vl: %016lx\n", 128);
} else if (extctx.fpu.addr) {
struct sctx_info *info = extctx.fpu.addr;
struct fpu_context *fpu_ctx = (struct fpu_context *)((char *)info +
  sizeof(struct sctx_info));
printf("vl: %016lx\n", 64);
}
}
n++;

printf("n is -- %d\n", n);
if (n == 1) {
// vaddwev.w.hu$vr27, $vr22, $vr29
asm volatile(".word 0x702ef6db");
printf("After execed LSX instructons  vaddwev.w.hu\n");
}

if (n == 2) {
// 0101395efadd.d  $fs6, $ft2, $ft6
asm volatile(".word 0x0101395e");
printf("After execed FPU instructions fadd\n");
}

if (n == 3) {
// xvextrins.d $xr13, $xr15, 0x59
asm volatile(".word 0x778165ed");
printf("After execed LASX instructions xvextrins.d\n");
}

if (n == 4) {
// 0101395efadd.d  $fs6, $ft2, $ft6
asm volatile(".word 0x0101395e");
printf("After execed FPU instructions fadd\n");
}

if (n == 5) {
exit(0);
}

siglongjmp(jmpbuf, 1);
}

static int setup_signal(int sig, void (*fn) (int, siginfo_t *, void *))
{
struct sigaction my_act;
int ret;

my_act.sa_sigaction = fn;
my_act.sa_flags = SA_SIGINFO;
sigemptyset(_act.sa_mask);

ret = sigaction(sig, _act, NULL);
if (ret != 0) {
printf("FAIL: signal %d\n", sig);
return SIG_ERR;
}
}

int main()
{
setup_signal(SIGSEGV, do_signal);


[PATCH v1 5/6] linux-user/loongarch64: Add LSX sigcontext save/restore

2023-10-09 Thread Song Gao
Signed-off-by: Song Gao 
---
 linux-user/loongarch64/signal.c | 107 ++--
 1 file changed, 87 insertions(+), 20 deletions(-)

diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index 277e9f5757..4b09e50a5f 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -33,6 +33,14 @@ struct target_fpu_context {
 uint32_t fcsr;
 } QEMU_ALIGNED(FPU_CTX_ALIGN);
 
+#define LSX_CTX_MAGIC   0x53580001
+#define LSX_CTX_ALIGN   16
+struct target_lsx_context {
+uint64_t regs[2 * 32];
+uint64_t fcc;
+uint32_t fcsr;
+} QEMU_ALIGNED(LSX_CTX_ALIGN);
+
 #define CONTEXT_INFO_ALIGN  16
 struct target_sctx_info {
 uint32_t magic;
@@ -66,9 +74,10 @@ struct ctx_layout {
 };
 
 struct extctx_layout {
-unsigned int size;
+unsigned long size;
 unsigned int flags;
 struct ctx_layout fpu;
+struct ctx_layout lsx;
 struct ctx_layout end;
 };
 
@@ -90,7 +99,8 @@ static abi_ptr extframe_alloc(struct extctx_layout *extctx,
 return sp;
 }
 
-static abi_ptr setup_extcontext(struct extctx_layout *extctx, abi_ptr sp)
+static abi_ptr setup_extcontext(CPULoongArchState *env,
+struct extctx_layout *extctx, abi_ptr sp)
 {
 memset(extctx, 0, sizeof(struct extctx_layout));
 
@@ -99,8 +109,15 @@ static abi_ptr setup_extcontext(struct extctx_layout 
*extctx, abi_ptr sp)
 
 /* For qemu, there is no lazy fp context switch, so fp always present. */
 extctx->flags = SC_USED_FP;
-sp = extframe_alloc(extctx, >fpu,
+
+if (env->extctx_flags & EXTCTX_FLAGS_LSX) {
+sp = extframe_alloc(extctx, >lsx,
+sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp);
+
+} else if (env->extctx_flags & EXTCTX_FLAGS_FPU) {
+sp = extframe_alloc(extctx, >fpu,
 sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
+}
 
 return sp;
 }
@@ -110,7 +127,6 @@ static void setup_sigframe(CPULoongArchState *env,
struct extctx_layout *extctx)
 {
 struct target_sctx_info *info;
-struct target_fpu_context *fpu_ctx;
 int i;
 
 __put_user(extctx->flags, >sc_flags);
@@ -121,18 +137,39 @@ static void setup_sigframe(CPULoongArchState *env,
 }
 
 /*
- * Set fpu context
+ * Set extension context
  */
-info = extctx->fpu.haddr;
-__put_user(FPU_CTX_MAGIC, >magic);
-__put_user(extctx->fpu.size, >size);
 
-fpu_ctx = (struct target_fpu_context *)(info + 1);
-for (i = 0; i < 32; ++i) {
-__put_user(env->fpr[i].vreg.D(0), _ctx->regs[i]);
+if (env->extctx_flags & EXTCTX_FLAGS_LSX) {
+struct target_lsx_context *lsx_ctx;
+info = extctx->lsx.haddr;
+
+__put_user(LSX_CTX_MAGIC, >magic);
+__put_user(extctx->lsx.size, >size);
+
+lsx_ctx = (struct target_lsx_context *)(info + 1);
+
+for (i = 0; i < 32; ++i) {
+__put_user(env->fpr[i].vreg.UD(0), _ctx->regs[2 * i]);
+__put_user(env->fpr[i].vreg.UD(1), _ctx->regs[2 * i + 1]);
+}
+__put_user(read_fcc(env), _ctx->fcc);
+__put_user(env->fcsr0, _ctx->fcsr);
+} else if (env->extctx_flags & EXTCTX_FLAGS_FPU) {
+struct target_fpu_context *fpu_ctx;
+info = extctx->fpu.haddr;
+
+__put_user(FPU_CTX_MAGIC, >magic);
+__put_user(extctx->fpu.size, >size);
+
+fpu_ctx = (struct target_fpu_context *)(info + 1);
+
+for (i = 0; i < 32; ++i) {
+__put_user(env->fpr[i].vreg.UD(0), _ctx->regs[i]);
+}
+__put_user(read_fcc(env), _ctx->fcc);
+__put_user(env->fcsr0, _ctx->fcsr);
 }
-__put_user(read_fcc(env), _ctx->fcc);
-__put_user(env->fcsr0, _ctx->fcsr);
 
 /*
  * Set end context
@@ -169,6 +206,15 @@ static bool parse_extcontext(struct extctx_layout *extctx, 
abi_ptr frame)
 extctx->fpu.size = size;
 extctx->size += size;
 break;
+case LSX_CTX_MAGIC:
+if (size < (sizeof(struct target_sctx_info) +
+sizeof(struct target_lsx_context))) {
+return false;
+}
+extctx->lsx.gaddr = frame;
+extctx->lsx.size = size;
+extctx->size += size;
+break;
 default:
 return false;
 }
@@ -182,19 +228,31 @@ static void restore_sigframe(CPULoongArchState *env,
  struct extctx_layout *extctx)
 {
 int i;
+uint64_t fcc;
 
 __get_user(env->pc, >sc_pc);
 for (i = 1; i < 32; ++i) {
 __get_user(env->gpr[i], >sc_regs[i]);
 }
 
-if (extctx->fpu.haddr) {
+if (extctx->lsx.haddr) {
+struct target_lsx_context *lsx_ctx =
+extctx->lsx.haddr + sizeof(struct target_sctx_info);
+
+for (i = 0; i < 32; ++i) {
+__get_user(env->fpr[i].vreg.UD(0), _ctx->regs[2 * i]);
+

[PATCH v1 2/6] target/loongarch: Add set_vec_extctx to set LSX/LASX instructions extctx_flags

2023-10-09 Thread Song Gao
Signed-off-by: Song Gao 
---
 target/loongarch/insn_trans/trans_vec.c.inc | 12 
 target/loongarch/internals.h|  2 ++
 2 files changed, 14 insertions(+)

diff --git a/target/loongarch/insn_trans/trans_vec.c.inc 
b/target/loongarch/insn_trans/trans_vec.c.inc
index 98f856bb29..aef16ef44a 100644
--- a/target/loongarch/insn_trans/trans_vec.c.inc
+++ b/target/loongarch/insn_trans/trans_vec.c.inc
@@ -23,8 +23,20 @@ static bool check_vec(DisasContext *ctx, uint32_t oprsz)
 
 #else
 
+static void set_vec_extctx(DisasContext *ctx, uint32_t oprsz)
+{
+if (oprsz == 16) {
+ctx->extctx_flags |= EXTCTX_FLAGS_LSX;
+}
+
+if (oprsz == 32) {
+ctx->extctx_flags |= EXTCTX_FLAGS_LASX;
+}
+}
+
 static bool check_vec(DisasContext *ctx, uint32_t oprsz)
 {
+set_vec_extctx(ctx, oprsz);
 return true;
 }
 
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index 01d98ac2fc..2efba9b859 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -22,6 +22,8 @@
 #define LOONGARCH_HGLOBAL_SHIFT 12
 
 #define EXTCTX_FLAGS_FPU  0b01
+#define EXTCTX_FLAGS_LSX  0b10
+#define EXTCTX_FLAGS_LASX 0b100
 
 void loongarch_translate_init(void);
 
-- 
2.25.1




[PATCH v1 4/6] linux-user/loongarch64: setup_sigframe() set 'end' context size 0

2023-10-09 Thread Song Gao
See:
  https://github.com/torvalds/linux/blob/master/arch/loongarch/kernel/signal.c

The kernel setup_sigcontext() set end context size 0.

Signed-off-by: Song Gao 
---
 linux-user/loongarch64/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index d97aa7db7f..277e9f5757 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -139,7 +139,7 @@ static void setup_sigframe(CPULoongArchState *env,
  */
 info = extctx->end.haddr;
 __put_user(0, >magic);
-__put_user(extctx->end.size, >size);
+__put_user(0, >size);
 }
 
 static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
-- 
2.25.1




[PATCH v1 3/6] linux-user/loongarch64: Fix setup_extcontext alloc wrong fpu_context size

2023-10-09 Thread Song Gao
See:
 https://github.com/torvalds/linux/blob/master/arch/loongarch/kernel/signal.c

The alloc size is sizeof(struct target_fpu_context).

Signed-off-by: Song Gao 
---
 linux-user/loongarch64/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index 39572c1190..d97aa7db7f 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -100,7 +100,7 @@ static abi_ptr setup_extcontext(struct extctx_layout 
*extctx, abi_ptr sp)
 /* For qemu, there is no lazy fp context switch, so fp always present. */
 extctx->flags = SC_USED_FP;
 sp = extframe_alloc(extctx, >fpu,
-sizeof(struct target_rt_sigframe), FPU_CTX_ALIGN, sp);
+sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
 
 return sp;
 }
-- 
2.25.1




[PATCH v1 1/6] target/loongarch: Add env->extctx_flags for user-mode setup extcontext

2023-10-09 Thread Song Gao
extctx_flags only for user-mode,  and the default value is
EXTCTX_FLAGS_FPU, We only need save/restore fpu context,
After a LSX or LASX instruction is execed, the value change to
EXTCTX_FLAGS_LSX/LASX, and we need save/restore lsx/lasx
context. So if the binary no LSX/LASX instruction We only need
save/restore fpu context.

Signed-off-by: Song Gao 
---
 target/loongarch/cpu.c   | 2 ++
 target/loongarch/cpu.h   | 2 ++
 target/loongarch/internals.h | 2 ++
 target/loongarch/translate.c | 3 +++
 target/loongarch/translate.h | 1 +
 5 files changed, 10 insertions(+)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 2bea7ca5d5..32dd1b624b 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -546,6 +546,8 @@ static void loongarch_cpu_reset_hold(Object *obj)
 memset(env->tlb, 0, sizeof(env->tlb));
 #endif
 
+env->extctx_flags = EXTCTX_FLAGS_FPU;
+
 restore_fp_status(env);
 cs->exception_index = -1;
 }
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 40e70a8119..7a94963e5f 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -295,6 +295,8 @@ typedef struct CPUArchState {
 uint64_t lladdr; /* LL virtual address compared against SC */
 uint64_t llval;
 
+uint64_t extctx_flags; /* Use for user-mode setup extcontext */
+
 /* LoongArch CSRs */
 uint64_t CSR_CRMD;
 uint64_t CSR_PRMD;
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index c492863cc5..01d98ac2fc 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -21,6 +21,8 @@
 /* Global bit for huge page */
 #define LOONGARCH_HGLOBAL_SHIFT 12
 
+#define EXTCTX_FLAGS_FPU  0b01
+
 void loongarch_translate_init(void);
 
 void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 21f4db6fbd..9b82295542 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -147,6 +147,8 @@ static void 
loongarch_tr_init_disas_context(DisasContextBase *dcbase,
 
 ctx->cpucfg1 = env->cpucfg[1];
 ctx->cpucfg2 = env->cpucfg[2];
+
+ctx->extctx_flags = env->extctx_flags;
 }
 
 static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
@@ -294,6 +296,7 @@ static void loongarch_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
 generate_exception(ctx, EXCCODE_INE);
 }
 
+env->extctx_flags |= ctx->extctx_flags;
 ctx->base.pc_next += 4;
 
 if (ctx->va32) {
diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 195f53573a..3bf1a1df86 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -40,6 +40,7 @@ typedef enum {
 typedef struct DisasContext {
 DisasContextBase base;
 target_ulong page_start;
+uint64_t extctx_flags;
 uint32_t opcode;
 uint16_t mem_idx;
 uint16_t plv;
-- 
2.25.1




[PATCH v1 6/6] linux-user/loongarch64: Add LASX sigcontext save/restore

2023-10-09 Thread Song Gao
Signed-off-by: Song Gao 
---
 linux-user/loongarch64/signal.c | 67 ++---
 1 file changed, 62 insertions(+), 5 deletions(-)

diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index 4b09e50a5f..e5b7688a2e 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -41,6 +41,14 @@ struct target_lsx_context {
 uint32_t fcsr;
 } QEMU_ALIGNED(LSX_CTX_ALIGN);
 
+#define LASX_CTX_MAGIC  0x41535801
+#define LASX_CTX_ALIGN  32
+struct target_lasx_context {
+uint64_t regs[4 * 32];
+uint64_t fcc;
+uint32_t fcsr;
+} QEMU_ALIGNED(LASX_CTX_ALIGN);
+
 #define CONTEXT_INFO_ALIGN  16
 struct target_sctx_info {
 uint32_t magic;
@@ -78,6 +86,7 @@ struct extctx_layout {
 unsigned int flags;
 struct ctx_layout fpu;
 struct ctx_layout lsx;
+struct ctx_layout lasx;
 struct ctx_layout end;
 };
 
@@ -110,7 +119,10 @@ static abi_ptr setup_extcontext(CPULoongArchState *env,
 /* For qemu, there is no lazy fp context switch, so fp always present. */
 extctx->flags = SC_USED_FP;
 
-if (env->extctx_flags & EXTCTX_FLAGS_LSX) {
+if (env->extctx_flags & EXTCTX_FLAGS_LASX) {
+sp = extframe_alloc(extctx, >lasx,
+sizeof(struct target_lasx_context), LASX_CTX_ALIGN, 
sp);
+} else if (env->extctx_flags & EXTCTX_FLAGS_LSX) {
 sp = extframe_alloc(extctx, >lsx,
 sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp);
 
@@ -140,7 +152,24 @@ static void setup_sigframe(CPULoongArchState *env,
  * Set extension context
  */
 
-if (env->extctx_flags & EXTCTX_FLAGS_LSX) {
+if (env->extctx_flags & EXTCTX_FLAGS_LASX) {
+struct target_lasx_context *lasx_ctx;
+info = extctx->lasx.haddr;
+
+__put_user(LASX_CTX_MAGIC, >magic);
+__put_user(extctx->lasx.size, >size);
+
+lasx_ctx = (struct target_lasx_context *)(info + 1);
+
+for (i = 0; i < 32; ++i) {
+__put_user(env->fpr[i].vreg.UD(0), _ctx->regs[4 * i]);
+__put_user(env->fpr[i].vreg.UD(1), _ctx->regs[4 * i + 1]);
+__put_user(env->fpr[i].vreg.UD(2), _ctx->regs[4 * i + 2]);
+__put_user(env->fpr[i].vreg.UD(3), _ctx->regs[4 * i + 3]);
+}
+__put_user(read_fcc(env), _ctx->fcc);
+__put_user(env->fcsr0, _ctx->fcsr);
+} else if (env->extctx_flags & EXTCTX_FLAGS_LSX) {
 struct target_lsx_context *lsx_ctx;
 info = extctx->lsx.haddr;
 
@@ -215,6 +244,15 @@ static bool parse_extcontext(struct extctx_layout *extctx, 
abi_ptr frame)
 extctx->lsx.size = size;
 extctx->size += size;
 break;
+case LASX_CTX_MAGIC:
+if (size < (sizeof(struct target_sctx_info) +
+sizeof(struct target_lasx_context))) {
+return false;
+}
+extctx->lasx.gaddr = frame;
+extctx->lasx.size = size;
+extctx->size += size;
+break;
 default:
 return false;
 }
@@ -235,7 +273,21 @@ static void restore_sigframe(CPULoongArchState *env,
 __get_user(env->gpr[i], >sc_regs[i]);
 }
 
-if (extctx->lsx.haddr) {
+if (extctx->lasx.haddr) {
+struct target_lasx_context *lasx_ctx =
+extctx->lasx.haddr + sizeof(struct target_sctx_info);
+
+for (i = 0; i < 32; ++i) {
+__get_user(env->fpr[i].vreg.UD(0), _ctx->regs[4 * i]);
+__get_user(env->fpr[i].vreg.UD(1), _ctx->regs[4 * i + 1]);
+__get_user(env->fpr[i].vreg.UD(2), _ctx->regs[4 * i + 2]);
+__get_user(env->fpr[i].vreg.UD(3), _ctx->regs[4 * i + 3]);
+}
+__get_user(fcc, _ctx->fcc);
+write_fcc(env, fcc);
+__get_user(env->fcsr0, _ctx->fcsr);
+restore_fp_status(env);
+} else if (extctx->lsx.haddr) {
 struct target_lsx_context *lsx_ctx =
 extctx->lsx.haddr + sizeof(struct target_sctx_info);
 
@@ -299,7 +351,10 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 return;
 }
 
-if (env->extctx_flags & EXTCTX_FLAGS_LSX) {
+if (env->extctx_flags & EXTCTX_FLAGS_LASX) {
+extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr);
+extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
+} else if (env->extctx_flags & EXTCTX_FLAGS_LSX) {
 extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
 extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
 } else if (env->extctx_flags & EXTCTX_FLAGS_FPU) {
@@ -349,7 +404,9 @@ long do_rt_sigreturn(CPULoongArchState *env)
 goto badframe;
 }
 
-if (extctx.lsx.gaddr) {
+if (extctx.lasx.gaddr) {
+extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr);
+} else if (extctx.lsx.gaddr) {
 extctx.lsx.haddr = (void *)frame + 

Re: [Virtio-fs] (no subject)

2023-10-09 Thread Yajun Wu



On 10/9/2023 6:28 PM, German Maglione wrote:

External email: Use caution opening links or attachments


On Sat, Oct 7, 2023 at 4:23 AM Yajun Wu  wrote:


On 10/6/2023 6:34 PM, Michael S. Tsirkin wrote:

External email: Use caution opening links or attachments


On Fri, Oct 06, 2023 at 11:47:55AM +0200, Hanna Czenczek wrote:

On 06.10.23 11:26, Michael S. Tsirkin wrote:

On Fri, Oct 06, 2023 at 11:15:55AM +0200, Hanna Czenczek wrote:

On 06.10.23 10:45, Michael S. Tsirkin wrote:

On Fri, Oct 06, 2023 at 09:48:14AM +0200, Hanna Czenczek wrote:

On 05.10.23 19:15, Michael S. Tsirkin wrote:

On Thu, Oct 05, 2023 at 01:08:52PM -0400, Stefan Hajnoczi wrote:

On Wed, Oct 04, 2023 at 02:58:57PM +0200, Hanna Czenczek wrote:

There is no clearly defined purpose for the virtio status byte in
vhost-user: For resetting, we already have RESET_DEVICE; and for virtio
feature negotiation, we have [GS]ET_FEATURES.  With the REPLY_ACK
protocol extension, it is possible for SET_FEATURES to return errors
(SET_PROTOCOL_FEATURES may be called before SET_FEATURES).

As for implementations, SET_STATUS is not widely implemented.  dpdk does
implement it, but only uses it to signal feature negotiation failure.
While it does log reset requests (SET_STATUS 0) as such, it effectively
ignores them, in contrast to RESET_OWNER (which is deprecated, and today
means the same thing as RESET_DEVICE).

While qemu superficially has support for [GS]ET_STATUS, it does not
forward the guest-set status byte, but instead just makes it up
internally, and actually completely ignores what the back-end returns,
only using it as the template for a subsequent SET_STATUS to add single
bits to it.  Notably, after setting FEATURES_OK, it never reads it back
to see whether the flag is still set, which is the only way in which
dpdk uses the status byte.

As-is, no front-end or back-end can rely on the other side handling this
field in a useful manner, and it also provides no practical use over
other mechanisms the vhost-user protocol has, which are more clearly
defined.  Deprecate it.

Suggested-by: Stefan Hajnoczi 
Signed-off-by: Hanna Czenczek 
---
  docs/interop/vhost-user.rst | 28 +---
  1 file changed, 21 insertions(+), 7 deletions(-)

Reviewed-by: Stefan Hajnoczi 

SET_STATUS is the only way to signal failure to acknowledge FEATURES_OK.
The fact current backends never check errors does not mean they never
will. So no, not applying this.

Can this not be done with REPLY_ACK?  I.e., with the following message
order:

1. GET_FEATURES to find out whether VHOST_USER_F_PROTOCOL_FEATURES is
present
2. GET_PROTOCOL_FEATURES to hopefully get VHOST_USER_PROTOCOL_F_REPLY_ACK
3. SET_PROTOCOL_FEATURES to set VHOST_USER_PROTOCOL_F_REPLY_ACK
4. SET_FEATURES with need_reply

If not, the problem is that qemu has sent SET_STATUS 0 for a while when the
vCPUs are stopped, which generally seems to request a device reset.  If we
don’t state at least that SET_STATUS 0 is to be ignored, back-ends that will
implement SET_STATUS later may break with at least these qemu versions.  But
documenting that a particular use of the status byte is to be ignored would
be really strange.

Hanna

Hmm I guess. Though just following virtio spec seems cleaner to me...
vhost-user reconfigures the state fully on start.

Not the internal device state, though.  virtiofsd has internal state, and
other devices like vhost-gpu back-ends would probably, too.

Stefan has recently sent a series
(https://lists.nongnu.org/archive/html/qemu-devel/2023-10/msg00709.html) to
put the reset (RESET_DEVICE) into virtio_reset() (when we really need a
reset).

I really don’t like our current approach with the status byte. Following the
virtio specification to me would mean that the guest directly controls this
byte, which it does not.  qemu makes up values as it deems appropriate, and
this includes sending a SET_STATUS 0 when the guest is just paused, i.e.
when the guest really doesn’t want a device reset.

That means that qemu does not treat this as a virtio device field (because
that would mean exposing it to the guest driver), but instead treats it as
part of the vhost(-user) protocol.  It doesn’t feel right to me that we use
a virtio-defined feature for communication on the vhost level, i.e. between
front-end and back-end, and not between guest driver and device.  I think
all vhost-level protocol features should be fully defined in the vhost-user
specification, which REPLY_ACK is.

Hmm that makes sense. Maybe we should have done what stefan's patch
is doing.

Do look at the original commit that introduced it to understand why
it was added.

I don’t understand why this was added to the stop/cont code, though.  If it
is time consuming to make these changes, why are they done every time the VM
is paused
and resumed?  It makes sense that this would be done for the initial
configuration (where a reset also wouldn’t hurt), but here it seems wrong.

(To be clear, a reset in the 

[PATCH v2 5/7] virtio-net: Return an error when vhost cannot enable RSS

2023-10-09 Thread Akihiko Odaki
vhost requires eBPF for RSS. Even when eBPF is not available, virtio-net
reported RSS availability, and raised a warning only after the
guest requested RSS, and the guest could not know that RSS is not
available.

Check RSS availability during device realization and return an error
if RSS is requested but not available. Assert RSS availability when
the guest actually requests the feature.

Signed-off-by: Akihiko Odaki 
---
 ebpf/ebpf_rss.h  |   2 +-
 ebpf/ebpf_rss-stub.c |   4 +-
 ebpf/ebpf_rss.c  |  68 +-
 hw/net/virtio-net.c  | 114 +--
 4 files changed, 82 insertions(+), 106 deletions(-)

diff --git a/ebpf/ebpf_rss.h b/ebpf/ebpf_rss.h
index bf3f2572c7..1128173572 100644
--- a/ebpf/ebpf_rss.h
+++ b/ebpf/ebpf_rss.h
@@ -36,7 +36,7 @@ bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx);
 
 bool ebpf_rss_load(struct EBPFRSSContext *ctx);
 
-bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
+void ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
   uint16_t *indirections_table, uint8_t *toeplitz_key);
 
 void ebpf_rss_unload(struct EBPFRSSContext *ctx);
diff --git a/ebpf/ebpf_rss-stub.c b/ebpf/ebpf_rss-stub.c
index e71e229190..525b358597 100644
--- a/ebpf/ebpf_rss-stub.c
+++ b/ebpf/ebpf_rss-stub.c
@@ -28,10 +28,10 @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
 return false;
 }
 
-bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
+void ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
   uint16_t *indirections_table, uint8_t *toeplitz_key)
 {
-return false;
+g_assert_not_reached();
 }
 
 void ebpf_rss_unload(struct EBPFRSSContext *ctx)
diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
index cee658c158..6cdf82d059 100644
--- a/ebpf/ebpf_rss.c
+++ b/ebpf/ebpf_rss.c
@@ -74,42 +74,32 @@ error:
 return false;
 }
 
-static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
+static void ebpf_rss_set_config(struct EBPFRSSContext *ctx,
 struct EBPFRSSConfig *config)
 {
 uint32_t map_key = 0;
 
-if (!ebpf_rss_is_loaded(ctx)) {
-return false;
-}
-if (bpf_map_update_elem(ctx->map_configuration,
-_key, config, 0) < 0) {
-return false;
-}
-return true;
+assert(ebpf_rss_is_loaded(ctx));
+assert(!bpf_map_update_elem(ctx->map_configuration, _key, config, 0));
 }
 
-static bool ebpf_rss_set_indirections_table(struct EBPFRSSContext *ctx,
+static void ebpf_rss_set_indirections_table(struct EBPFRSSContext *ctx,
 uint16_t *indirections_table,
 size_t len)
 {
 uint32_t i = 0;
 
-if (!ebpf_rss_is_loaded(ctx) || indirections_table == NULL ||
-   len > VIRTIO_NET_RSS_MAX_TABLE_LEN) {
-return false;
-}
+assert(ebpf_rss_is_loaded(ctx));
+assert(indirections_table);
+assert(len <= VIRTIO_NET_RSS_MAX_TABLE_LEN);
 
 for (; i < len; ++i) {
-if (bpf_map_update_elem(ctx->map_indirections_table, ,
-indirections_table + i, 0) < 0) {
-return false;
-}
+assert(!bpf_map_update_elem(ctx->map_indirections_table, ,
+indirections_table + i, 0));
 }
-return true;
 }
 
-static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
+static void ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
  uint8_t *toeplitz_key)
 {
 uint32_t map_key = 0;
@@ -117,41 +107,29 @@ static bool ebpf_rss_set_toepliz_key(struct 
EBPFRSSContext *ctx,
 /* prepare toeplitz key */
 uint8_t toe[VIRTIO_NET_RSS_MAX_KEY_SIZE] = {};
 
-if (!ebpf_rss_is_loaded(ctx) || toeplitz_key == NULL) {
-return false;
-}
+assert(ebpf_rss_is_loaded(ctx));
+assert(toeplitz_key);
+
 memcpy(toe, toeplitz_key, VIRTIO_NET_RSS_MAX_KEY_SIZE);
 *(uint32_t *)toe = ntohl(*(uint32_t *)toe);
 
-if (bpf_map_update_elem(ctx->map_toeplitz_key, _key, toe,
-0) < 0) {
-return false;
-}
-return true;
+assert(!bpf_map_update_elem(ctx->map_toeplitz_key, _key, toe, 0));
 }
 
-bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
+void ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
   uint16_t *indirections_table, uint8_t *toeplitz_key)
 {
-if (!ebpf_rss_is_loaded(ctx) || config == NULL ||
-indirections_table == NULL || toeplitz_key == NULL) {
-return false;
-}
-
-if (!ebpf_rss_set_config(ctx, config)) {
-return false;
-}
+assert(ebpf_rss_is_loaded(ctx));
+assert(config);
+assert(indirections_table);
+assert(toeplitz_key);
 
-if (!ebpf_rss_set_indirections_table(ctx, 

[PATCH v2 7/7] ebpf: Fix RSS error handling

2023-10-09 Thread Akihiko Odaki
calculate_rss_hash() was using hash value 0 to tell if it calculated
a hash, but the hash value may be 0 on a rare occasion. Have a
distinct bool value for correctness.

Fixes: f3fa412de2 ("ebpf: Added eBPF RSS program.")
Signed-off-by: Akihiko Odaki 
---
 tools/ebpf/rss.bpf.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/tools/ebpf/rss.bpf.c b/tools/ebpf/rss.bpf.c
index 20f227e2ac..667ea6899e 100644
--- a/tools/ebpf/rss.bpf.c
+++ b/tools/ebpf/rss.bpf.c
@@ -377,18 +377,19 @@ error:
 return err;
 }
 
-static inline __u32 calculate_rss_hash(struct __sk_buff *skb,
-struct rss_config_t *config, struct toeplitz_key_data_t *toe)
+static inline bool calculate_rss_hash(struct __sk_buff *skb,
+  struct rss_config_t *config,
+  struct toeplitz_key_data_t *toe,
+  __u32 *result)
 {
 __u8 rss_input[HASH_CALCULATION_BUFFER_SIZE] = {};
 size_t bytes_written = 0;
-__u32 result = 0;
 int err = 0;
 struct packet_hash_info_t packet_info = {};
 
 err = parse_packet(skb, _info);
 if (err) {
-return 0;
+return false;
 }
 
 if (packet_info.is_ipv4) {
@@ -521,11 +522,13 @@ static inline __u32 calculate_rss_hash(struct __sk_buff 
*skb,
 }
 }
 
-if (bytes_written) {
-net_toeplitz_add(, rss_input, bytes_written, toe);
+if (!bytes_written) {
+return false;
 }
 
-return result;
+net_toeplitz_add(result, rss_input, bytes_written, toe);
+
+return true;
 }
 
 SEC("tun_rss_steering")
@@ -546,8 +549,7 @@ int tun_rss_steering_prog(struct __sk_buff *skb)
 return config->default_queue;
 }
 
-hash = calculate_rss_hash(skb, config, toe);
-if (hash) {
+if (calculate_rss_hash(skb, config, toe, )) {
 __u32 table_idx = hash % config->indirections_len;
 __u16 *queue = 0;
 
-- 
2.42.0




[PATCH v2 0/7] virtio-net RSS/hash report fixes

2023-10-09 Thread Akihiko Odaki
This series contains fixes and improvements for virtio-net RSS and hash
reporting feature.

V1 -> V2:
  Added patch "ebpf: Fix RSS error handling".

Akihiko Odaki (7):
  tap: Fix virtio-net header buffer size
  virtio-net: Copy header only when necessary
  virtio-net: Disable RSS on reset
  virtio-net: Unify the logic to update NIC state for RSS
  virtio-net: Return an error when vhost cannot enable RSS
  virtio-net: Do not clear VIRTIO_NET_F_RSS
  ebpf: Fix RSS error handling

 ebpf/ebpf_rss.h  |   2 +-
 ebpf/ebpf_rss-stub.c |   4 +-
 ebpf/ebpf_rss.c  |  68 ---
 hw/net/virtio-net.c  | 277 ---
 net/tap.c|   4 +-
 tools/ebpf/rss.bpf.c |  20 ++--
 6 files changed, 166 insertions(+), 209 deletions(-)

-- 
2.42.0




[PATCH v2 3/7] virtio-net: Disable RSS on reset

2023-10-09 Thread Akihiko Odaki
RSS is disabled by default.

Fixes: 590790297c ("virtio-net: implement RSS configuration command")
Signed-off-by: Akihiko Odaki 
---
 hw/net/virtio-net.c | 70 +++--
 1 file changed, 36 insertions(+), 34 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 1ba748c964..83bac9a98a 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -601,40 +601,6 @@ static void virtio_net_queue_enable(VirtIODevice *vdev, 
uint32_t queue_index)
 }
 }
 
-static void virtio_net_reset(VirtIODevice *vdev)
-{
-VirtIONet *n = VIRTIO_NET(vdev);
-int i;
-
-/* Reset back to compatibility mode */
-n->promisc = 1;
-n->allmulti = 0;
-n->alluni = 0;
-n->nomulti = 0;
-n->nouni = 0;
-n->nobcast = 0;
-/* multiqueue is disabled by default */
-n->curr_queue_pairs = 1;
-timer_del(n->announce_timer.tm);
-n->announce_timer.round = 0;
-n->status &= ~VIRTIO_NET_S_ANNOUNCE;
-
-/* Flush any MAC and VLAN filter table state */
-n->mac_table.in_use = 0;
-n->mac_table.first_multi = 0;
-n->mac_table.multi_overflow = 0;
-n->mac_table.uni_overflow = 0;
-memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
-memcpy(>mac[0], >nic->conf->macaddr, sizeof(n->mac));
-qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
-memset(n->vlans, 0, MAX_VLAN >> 3);
-
-/* Flush any async TX */
-for (i = 0;  i < n->max_queue_pairs; i++) {
-flush_or_purge_queued_packets(qemu_get_subqueue(n->nic, i));
-}
-}
-
 static void peer_test_vnet_hdr(VirtIONet *n)
 {
 NetClientState *nc = qemu_get_queue(n->nic);
@@ -3789,6 +3755,42 @@ static void virtio_net_device_unrealize(DeviceState *dev)
 virtio_cleanup(vdev);
 }
 
+static void virtio_net_reset(VirtIODevice *vdev)
+{
+VirtIONet *n = VIRTIO_NET(vdev);
+int i;
+
+/* Reset back to compatibility mode */
+n->promisc = 1;
+n->allmulti = 0;
+n->alluni = 0;
+n->nomulti = 0;
+n->nouni = 0;
+n->nobcast = 0;
+/* multiqueue is disabled by default */
+n->curr_queue_pairs = 1;
+timer_del(n->announce_timer.tm);
+n->announce_timer.round = 0;
+n->status &= ~VIRTIO_NET_S_ANNOUNCE;
+
+/* Flush any MAC and VLAN filter table state */
+n->mac_table.in_use = 0;
+n->mac_table.first_multi = 0;
+n->mac_table.multi_overflow = 0;
+n->mac_table.uni_overflow = 0;
+memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
+memcpy(>mac[0], >nic->conf->macaddr, sizeof(n->mac));
+qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
+memset(n->vlans, 0, MAX_VLAN >> 3);
+
+/* Flush any async TX */
+for (i = 0;  i < n->max_queue_pairs; i++) {
+flush_or_purge_queued_packets(qemu_get_subqueue(n->nic, i));
+}
+
+virtio_net_disable_rss(n);
+}
+
 static void virtio_net_instance_init(Object *obj)
 {
 VirtIONet *n = VIRTIO_NET(obj);
-- 
2.42.0




[PATCH v2 1/7] tap: Fix virtio-net header buffer size

2023-10-09 Thread Akihiko Odaki
The largest possible virtio-net header is struct virtio_net_hdr_v1_hash.

Fixes: fbbdbddec0 ("tap: allow extended virtio header with hash info")
Signed-off-by: Akihiko Odaki 
---
 net/tap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/tap.c b/net/tap.c
index c6639d9f20..ea46feeaa8 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -118,7 +118,7 @@ static ssize_t tap_receive_iov(NetClientState *nc, const 
struct iovec *iov,
 TAPState *s = DO_UPCAST(TAPState, nc, nc);
 const struct iovec *iovp = iov;
 struct iovec iov_copy[iovcnt + 1];
-struct virtio_net_hdr_mrg_rxbuf hdr = { };
+struct virtio_net_hdr_v1_hash hdr = { };
 
 if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
 iov_copy[0].iov_base = 
@@ -136,7 +136,7 @@ static ssize_t tap_receive_raw(NetClientState *nc, const 
uint8_t *buf, size_t si
 TAPState *s = DO_UPCAST(TAPState, nc, nc);
 struct iovec iov[2];
 int iovcnt = 0;
-struct virtio_net_hdr_mrg_rxbuf hdr = { };
+struct virtio_net_hdr_v1_hash hdr = { };
 
 if (s->host_vnet_hdr_len) {
 iov[iovcnt].iov_base = 
-- 
2.42.0




[PATCH v2 4/7] virtio-net: Unify the logic to update NIC state for RSS

2023-10-09 Thread Akihiko Odaki
The code to attach or detach the eBPF program to RSS were duplicated so
unify them into one function to save some code.

Signed-off-by: Akihiko Odaki 
---
 hw/net/virtio-net.c | 90 ++---
 1 file changed, 36 insertions(+), 54 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 83bac9a98a..3c3440ab72 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1212,18 +1212,6 @@ static int virtio_net_handle_announce(VirtIONet *n, 
uint8_t cmd,
 }
 }
 
-static void virtio_net_detach_epbf_rss(VirtIONet *n);
-
-static void virtio_net_disable_rss(VirtIONet *n)
-{
-if (n->rss_data.enabled) {
-trace_virtio_net_rss_disable();
-}
-n->rss_data.enabled = false;
-
-virtio_net_detach_epbf_rss(n);
-}
-
 static bool virtio_net_attach_ebpf_to_backend(NICState *nic, int prog_fd)
 {
 NetClientState *nc = qemu_get_peer(qemu_get_queue(nic), 0);
@@ -1271,6 +1259,40 @@ static void virtio_net_detach_epbf_rss(VirtIONet *n)
 virtio_net_attach_ebpf_to_backend(n->nic, -1);
 }
 
+static void virtio_net_commit_rss_config(VirtIONet *n)
+{
+if (n->rss_data.enabled) {
+n->rss_data.enabled_software_rss = n->rss_data.populate_hash;
+if (n->rss_data.populate_hash) {
+virtio_net_detach_epbf_rss(n);
+} else if (!virtio_net_attach_epbf_rss(n)) {
+if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
+warn_report("Can't use eBPF RSS for vhost");
+} else {
+warn_report("Can't use eBPF RSS - fallback to software RSS");
+n->rss_data.enabled_software_rss = true;
+}
+}
+
+trace_virtio_net_rss_enable(n->rss_data.hash_types,
+n->rss_data.indirections_len,
+sizeof(n->rss_data.key));
+} else {
+virtio_net_detach_epbf_rss(n);
+trace_virtio_net_rss_disable();
+}
+}
+
+static void virtio_net_disable_rss(VirtIONet *n)
+{
+if (!n->rss_data.enabled) {
+return;
+}
+
+n->rss_data.enabled = false;
+virtio_net_commit_rss_config(n);
+}
+
 static bool virtio_net_load_ebpf(VirtIONet *n)
 {
 if (!virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
@@ -1399,28 +1421,7 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
 goto error;
 }
 n->rss_data.enabled = true;
-
-if (!n->rss_data.populate_hash) {
-if (!virtio_net_attach_epbf_rss(n)) {
-/* EBPF must be loaded for vhost */
-if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
-warn_report("Can't load eBPF RSS for vhost");
-goto error;
-}
-/* fallback to software RSS */
-warn_report("Can't load eBPF RSS - fallback to software RSS");
-n->rss_data.enabled_software_rss = true;
-}
-} else {
-/* use software RSS for hash populating */
-/* and detach eBPF if was loaded before */
-virtio_net_detach_epbf_rss(n);
-n->rss_data.enabled_software_rss = true;
-}
-
-trace_virtio_net_rss_enable(n->rss_data.hash_types,
-n->rss_data.indirections_len,
-temp.b);
+virtio_net_commit_rss_config(n);
 return queue_pairs;
 error:
 trace_virtio_net_rss_error(err_msg, err_value);
@@ -3016,26 +3017,7 @@ static int virtio_net_post_load_device(void *opaque, int 
version_id)
 }
 }
 
-if (n->rss_data.enabled) {
-n->rss_data.enabled_software_rss = n->rss_data.populate_hash;
-if (!n->rss_data.populate_hash) {
-if (!virtio_net_attach_epbf_rss(n)) {
-if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
-warn_report("Can't post-load eBPF RSS for vhost");
-} else {
-warn_report("Can't post-load eBPF RSS - "
-"fallback to software RSS");
-n->rss_data.enabled_software_rss = true;
-}
-}
-}
-
-trace_virtio_net_rss_enable(n->rss_data.hash_types,
-n->rss_data.indirections_len,
-sizeof(n->rss_data.key));
-} else {
-trace_virtio_net_rss_disable();
-}
+virtio_net_commit_rss_config(n);
 return 0;
 }
 
-- 
2.42.0




[PATCH v2 2/7] virtio-net: Copy header only when necessary

2023-10-09 Thread Akihiko Odaki
It is necessary to copy the header only for byte swapping. Worse, when
byte swapping is not needed, the header can be larger than the buffer
due to VIRTIO_NET_F_HASH_REPORT, which results in buffer overflow.

Copy the header only when byte swapping is needed.

Fixes: e22f0603fb ("virtio-net: reference implementation of hash report")
Signed-off-by: Akihiko Odaki 
---
 hw/net/virtio-net.c | 26 --
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9a93a2df01..1ba748c964 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -361,7 +361,8 @@ static void virtio_net_vnet_endian_status(VirtIONet *n, 
uint8_t status)
  * can't do it, we fallback onto fixing the headers in the core
  * virtio-net code.
  */
-n->needs_vnet_hdr_swap = virtio_net_set_vnet_endian(vdev, n->nic->ncs,
+n->needs_vnet_hdr_swap = n->has_vnet_hdr &&
+ virtio_net_set_vnet_endian(vdev, n->nic->ncs,
 queue_pairs, true);
 } else if (virtio_net_started(n, vdev->status)) {
 /* After using the device, we need to reset the network backend to
@@ -2690,7 +2691,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
 return -EINVAL;
 }
 
-if (n->has_vnet_hdr) {
+if (n->needs_vnet_hdr_swap) {
 if (iov_to_buf(out_sg, out_num, 0, , n->guest_hdr_len) <
 n->guest_hdr_len) {
 virtio_error(vdev, "virtio-net header incorrect");
@@ -2698,19 +2699,16 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
 g_free(elem);
 return -EINVAL;
 }
-if (n->needs_vnet_hdr_swap) {
-virtio_net_hdr_swap(vdev, (void *) );
-sg2[0].iov_base = 
-sg2[0].iov_len = n->guest_hdr_len;
-out_num = iov_copy([1], ARRAY_SIZE(sg2) - 1,
-   out_sg, out_num,
-   n->guest_hdr_len, -1);
-if (out_num == VIRTQUEUE_MAX_SIZE) {
-goto drop;
-}
-out_num += 1;
-out_sg = sg2;
+virtio_net_hdr_swap(vdev, (void *) );
+sg2[0].iov_base = 
+sg2[0].iov_len = n->guest_hdr_len;
+out_num = iov_copy([1], ARRAY_SIZE(sg2) - 1, out_sg, out_num,
+   n->guest_hdr_len, -1);
+if (out_num == VIRTQUEUE_MAX_SIZE) {
+goto drop;
 }
+out_num += 1;
+out_sg = sg2;
 }
 /*
  * If host wants to see the guest header as is, we can
-- 
2.42.0




[PATCH v2 6/7] virtio-net: Do not clear VIRTIO_NET_F_RSS

2023-10-09 Thread Akihiko Odaki
Even if eBPF is not available, virtio-net can perform RSS on the
user-space if vhost is disabled although such a configuration results in
a warning. If vhost is enabled, the configuration will be rejected when
realizing the device. Therefore, VIRTIO_NET_F_RSS should not be cleared
even if eBPF is not loaded.

Signed-off-by: Akihiko Odaki 
---
 hw/net/virtio-net.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 05f9abdbcd..3bb4bf136d 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -775,9 +775,6 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, 
uint64_t features,
 return features;
 }
 
-if (!ebpf_rss_is_loaded(>ebpf_rss)) {
-virtio_clear_feature(, VIRTIO_NET_F_RSS);
-}
 features = vhost_net_get_features(get_vhost_net(nc->peer), features);
 vdev->backend_features = features;
 
-- 
2.42.0




Re: [PULL v2 0/6] vfio queue

2023-10-09 Thread Stefan Hajnoczi
Applied, thanks.

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


signature.asc
Description: PGP signature


Re: [PULL v2 00/25] Audio, source reorg, HVF changes for 2023-10-06

2023-10-09 Thread Stefan Hajnoczi
Applied, thanks.

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


signature.asc
Description: PGP signature


Re: [PULL 00/20] Q800 for 8.2 patches

2023-10-09 Thread Stefan Hajnoczi
Applied, thanks.

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


signature.asc
Description: PGP signature


Re: [PULL 00/15] NBD patches through 2023-10-05

2023-10-09 Thread Stefan Hajnoczi
Applied, thanks.

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


signature.asc
Description: PGP signature


Re: [PULL 00/32] -Wshadow=local patches patches for 2023-10-06

2023-10-09 Thread Stefan Hajnoczi
Applied, thanks.

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


signature.asc
Description: PGP signature


Re: qemu direct kernel boot on LoongArch

2023-10-09 Thread maobibo

Thomas,

Thanks for reporting this issue.

It is the problem of QEMU for LoongArch system, QEMU does not support 
booting vmlinux with elf format without UEFI bios now. We will add 
support to boot vmlinux directly on QEMU LoongArch side.


Regards
Bibo Mao

在 2023/10/10 上午4:13, Thomas Weißschuh 写道:

Hi,

I'm trying to boot a LoongArch Linux via the direct kernel mode of qemu.
( qemu -kernel vmlinux -append "verbose" )
This doesn't work so well.

A few problems I encoutered:

* Linux reads the cmdline from $a1 during boot, but qemu doesn't place it there.
* Qemu puts a FDT at 1MiB but Linux doesn't use it.
* Qemu does not put the cmdline into the FDT.
* Linux panics in memory_present() because memblock_init() in
   arch/loongarch/kernel/mem.c did not set up any memblocks.
* Qemu has no support for initrds in direct kernel mode on LoongArch.

(All observations based on current git versions)

For the other architectures I'm using Linux/qemu with the direct kernel
mode works nicely including cmdline and initrds.

Are these restrictions by design/intentional or is it just for somebody
to do the necessary legwork?

The direct kernel mode is nice because it does not require the
installation of the additional EFI binary.


Thanks,
Thomas






[PULL 2/2] migration/dirtyrate: use QEMU_CLOCK_HOST to report start-time

2023-10-09 Thread Hyman Huang
From: Andrei Gudkov 

Currently query-dirty-rate uses QEMU_CLOCK_REALTIME as
the source for start-time field. This translates to
clock_gettime(CLOCK_MONOTONIC), i.e. number of seconds
since host boot. This is not very useful. The only
reasonable use case of start-time I can imagine is to
check whether previously completed measurements are
too old or not. But this makes sense only if start-time
is reported as host wall-clock time.

This patch replaces source of start-time from
QEMU_CLOCK_REALTIME to QEMU_CLOCK_HOST.

Signed-off-by: Andrei Gudkov 
Reviewed-by: Hyman Huang 
Message-Id: 
<399861531e3b24a1ecea2ba453fb2c3d129fb03a.1693905328.git.gudkov.and...@huawei.com>
Signed-off-by: Hyman Huang 
---
 migration/dirtyrate.c | 15 ++-
 qapi/migration.json   |  4 ++--
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index a461b28bb5..036ac017fc 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -293,11 +293,10 @@ query_dirty_rate_info(TimeUnit calc_time_unit)
 return info;
 }
 
-static void init_dirtyrate_stat(int64_t start_time,
-struct DirtyRateConfig config)
+static void init_dirtyrate_stat(struct DirtyRateConfig config)
 {
 DirtyStat.dirty_rate = -1;
-DirtyStat.start_time = start_time;
+DirtyStat.start_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
 DirtyStat.calc_time_ms = config.calc_time_ms;
 DirtyStat.sample_pages = config.sample_pages_per_gigabytes;
 
@@ -633,7 +632,7 @@ static void calculate_dirtyrate_dirty_bitmap(struct 
DirtyRateConfig config)
 record_dirtypages_bitmap(_pages, true);
 
 start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
-DirtyStat.start_time = start_time / 1000;
+DirtyStat.start_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
 
 DirtyStat.calc_time_ms = dirty_stat_wait(config.calc_time_ms, start_time);
 
@@ -659,7 +658,7 @@ static void calculate_dirtyrate_dirty_ring(struct 
DirtyRateConfig config)
 /* start log sync */
 global_dirty_log_change(GLOBAL_DIRTY_DIRTY_RATE, true);
 
-DirtyStat.start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
+DirtyStat.start_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
 
 /* calculate vcpu dirtyrate */
 DirtyStat.calc_time_ms = vcpu_calculate_dirtyrate(config.calc_time_ms,
@@ -685,6 +684,7 @@ static void calculate_dirtyrate_sample_vm(struct 
DirtyRateConfig config)
 
 rcu_read_lock();
 initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+DirtyStat.start_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
 if (!record_ramblock_hash_info(_dinfo, config, _count)) {
 goto out;
 }
@@ -692,7 +692,6 @@ static void calculate_dirtyrate_sample_vm(struct 
DirtyRateConfig config)
 
 DirtyStat.calc_time_ms = dirty_stat_wait(config.calc_time_ms,
  initial_time);
-DirtyStat.start_time = initial_time / 1000;
 
 rcu_read_lock();
 if (!compare_page_hash_info(block_dinfo, block_count)) {
@@ -756,7 +755,6 @@ void qmp_calc_dirty_rate(int64_t calc_time,
 static struct DirtyRateConfig config;
 QemuThread thread;
 int ret;
-int64_t start_time;
 
 /*
  * If the dirty rate is already being measured, don't attempt to start.
@@ -833,8 +831,7 @@ void qmp_calc_dirty_rate(int64_t calc_time,
  **/
 dirtyrate_mode = mode;
 
-start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
-init_dirtyrate_stat(start_time, config);
+init_dirtyrate_stat(config);
 
 qemu_thread_create(, "get_dirtyrate", get_dirtyrate_thread,
(void *), QEMU_THREAD_DETACHED);
diff --git a/qapi/migration.json b/qapi/migration.json
index 1717aa4bbd..d8f3bbd7b0 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1974,13 +1974,13 @@
 # 1. Measurement is in progress:
 #
 # <- {"status": "measuring", "sample-pages": 512,
-# "mode": "page-sampling", "start-time": 3665220, "calc-time": 10,
+# "mode": "page-sampling", "start-time": 1693900454, "calc-time": 10,
 # "calc-time-unit": "second"}
 #
 # 2. Measurement has been completed:
 #
 # <- {"status": "measured", "sample-pages": 512, "dirty-rate": 108,
-# "mode": "page-sampling", "start-time": 3665220, "calc-time": 10,
+# "mode": "page-sampling", "start-time": 1693900454, "calc-time": 10,
 # "calc-time-unit": "second"}
 ##
 { 'command': 'query-dirty-rate', 'data': {'*calc-time-unit': 'TimeUnit' },
-- 
2.39.1




[PULL 0/2] Dirty page rate and dirty page limit 20231010 patches

2023-10-09 Thread Hyman Huang
The following changes since commit 2f3913f4b2ad74baeb5a6f1d36efbd9ecdf1057d:

  Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu 
into staging (2023-10-05 09:01:01 -0400)

are available in the Git repository at:

  https://github.com/newfriday/qemu.git 
tags/dirtylimit-dirtyrate-pull-request-20231010

for you to fetch changes up to 320a6ccc769dc09ae7ad0b4838e322018f334bf4:

  migration/dirtyrate: use QEMU_CLOCK_HOST to report start-time (2023-10-10 
08:04:12 +0800)


Dirtylimit and dirtyrate 20231010 patches PULL request

Dirty page rate measurement optimization.
Please apply, thanks, Yong.


Andrei Gudkov (2):
  migration/calc-dirty-rate: millisecond-granularity period
  migration/dirtyrate: use QEMU_CLOCK_HOST to report start-time

 migration/dirtyrate.c | 122 +++---
 migration/dirtyrate.h |  12 +++--
 qapi/migration.json   |  58 
 3 files changed, 134 insertions(+), 58 deletions(-)

-- 
2.39.1




[PULL 1/2] migration/calc-dirty-rate: millisecond-granularity period

2023-10-09 Thread Hyman Huang
From: Andrei Gudkov 

This patch allows to measure dirty page rate for
sub-second intervals of time. An optional argument is
introduced -- calc-time-unit. For example:
{"execute": "calc-dirty-rate", "arguments":
  {"calc-time": 500, "calc-time-unit": "millisecond"} }

Millisecond granularity allows to make predictions whether
migration will succeed or not. To do this, calculate dirty
rate with calc-time set to max allowed downtime (e.g. 300ms),
convert measured rate into volume of dirtied memory,
and divide by network throughput. If the value is lower
than max allowed downtime, then migration will converge.

Measurement results for single thread randomly writing to
a 1/4/24GiB memory region:

++---+
| calc-time  |dirty rate MiB/s   |
| (milliseconds) ++---+--+
|| theoretical| page-sampling | dirty-bitmap |
|| (at 3M wr/sec) |   |  |
+++---+--+
|   1GiB |
+++---+--+
|100 |   6996 |  7100 | 3192 |
|200 |   4606 |  4660 | 2655 |
|300 |   3305 |  3280 | 2371 |
|400 |   2534 |  2525 | 2154 |
|500 |   2041 |  2044 | 1871 |
|750 |   1365 |  1341 | 1358 |
|   1000 |   1024 |  1052 | 1025 |
|   1500 |683 |   678 |  684 |
|   2000 |512 |   507 |  513 |
+++---+--+
|   4GiB |
+++---+--+
|100 |  10232 |  8880 | 4070 |
|200 |   8954 |  8049 | 3195 |
|300 |   7889 |  7193 | 2881 |
|400 |   6996 |  6530 | 2700 |
|500 |   6245 |  5772 | 2312 |
|750 |   4829 |  4586 | 2465 |
|   1000 |   3865 |  3780 | 2178 |
|   1500 |   2694 |  2633 | 2004 |
|   2000 |   2041 |  2031 | 1789 |
+++---+--+
|   24GiB|
+++---+--+
|100 |  11495 |  8640 | 5597 |
|200 |  11226 |  8616 | 3527 |
|300 |  10965 |  8386 | 2355 |
|400 |  10713 |  8370 | 2179 |
|500 |  10469 |  8196 | 2098 |
|750 |   9890 |  7885 | 2556 |
|   1000 |   9354 |  7506 | 2084 |
|   1500 |   8397 |  6944 | 2075 |
|   2000 |   7574 |  6402 | 2062 |
+++---+--+

Theoretical values are computed according to the following formula:
size * (1 - (1-(4096/size))^(time*wps)) / (time * 2^20),
where size is in bytes, time is in seconds, and wps is number of
writes per second.

Signed-off-by: Andrei Gudkov 
Reviewed-by: Hyman Huang 
Message-Id: 

Signed-off-by: Hyman Huang 
---
 migration/dirtyrate.c | 107 +-
 migration/dirtyrate.h |  12 +++--
 qapi/migration.json   |  58 ++-
 3 files changed, 128 insertions(+), 49 deletions(-)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index bccb3515e3..a461b28bb5 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -189,10 +189,9 @@ retry:
 return duration;
 }
 
-static bool is_sample_period_valid(int64_t sec)
+static bool is_calc_time_valid(int64_t msec)
 {
-if (sec < MIN_FETCH_DIRTYRATE_TIME_SEC ||
-sec > MAX_FETCH_DIRTYRATE_TIME_SEC) {
+if ((msec < MIN_CALC_TIME_MS) || (msec > MAX_CALC_TIME_MS)) {
 return false;
 }
 
@@ -216,7 +215,39 @@ static int dirtyrate_set_state(int *state, int old_state, 
int new_state)
 }
 }
 
-static struct DirtyRateInfo *query_dirty_rate_info(void)
+/* Decimal power of given time unit relative to one second */
+static int time_unit_to_power(TimeUnit time_unit)
+{
+switch (time_unit) {
+case TIME_UNIT_SECOND:
+return 0;
+case TIME_UNIT_MILLISECOND:
+return -3;
+default:
+assert(false); /* 

Re: [QEMU][PATCH v1 2/7] xen: add pseudo RAM region for grant mappings

2023-10-09 Thread Stefano Stabellini
On Mon, 9 Oct 2023, Stefano Stabellini wrote:
> On Thu, 5 Oct 2023, Vikram Garhwal wrote:
> > From: Juergen Gross 
> > 
> > Add a memory region which can be used to automatically map granted
> > memory. It is starting at 0x8000ULL in order to be able to
> > distinguish it from normal RAM.
> > 
> > For this reason the xen.ram memory region is expanded, which has no
> > further impact as it is used just as a container of the real RAM
> > regions and now the grant region.
> > 
> > Signed-off-by: Juergen Gross 
> > Signed-off-by: Vikram Garhwal 
> 
> This patch doesn't apply to staging anymore
> 
> 
> > ---
> >  hw/i386/xen/xen-hvm.c   |  3 ++
> >  hw/xen/xen-hvm-common.c |  4 +--
> >  hw/xen/xen-mapcache.c   | 27 ++
> >  include/exec/ram_addr.h |  1 +
> >  include/hw/xen/xen-hvm-common.h |  2 ++
> >  include/hw/xen/xen_pvdev.h  |  3 ++
> >  include/sysemu/xen-mapcache.h   |  3 ++
> >  softmmu/physmem.c   | 62 +
> >  8 files changed, 80 insertions(+), 25 deletions(-)
> > 
> > diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> > index f42621e674..67a8a6 100644
> > --- a/hw/i386/xen/xen-hvm.c
> > +++ b/hw/i386/xen/xen-hvm.c
> > @@ -172,6 +172,9 @@ static void xen_ram_init(PCMachineState *pcms,
> >   x86ms->above_4g_mem_size);
> >  memory_region_add_subregion(sysmem, 0x1ULL, _hi);
> >  }
> > +
> > +/* Add grant mappings as a pseudo RAM region. */
> > +ram_grants = *xen_init_grant_ram();
> >  }
> >  
> >  static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
> > diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
> > index 565dc39c8f..b7255977a5 100644
> > --- a/hw/xen/xen-hvm-common.c
> > +++ b/hw/xen/xen-hvm-common.c
> > @@ -9,7 +9,7 @@
> >  #include "hw/boards.h"
> >  #include "hw/xen/arch_hvm.h"
> >  
> > -MemoryRegion ram_memory;
> > +MemoryRegion ram_memory, ram_grants;
> >  
> >  void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
> > Error **errp)
> > @@ -26,7 +26,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, 
> > MemoryRegion *mr,
> >  return;
> >  }
> >  
> > -if (mr == _memory) {
> > +if (mr == _memory || mr == _grants) {
> >  return;
> >  }
> >  
> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > index f7d974677d..8115c44c00 100644
> > --- a/hw/xen/xen-mapcache.c
> > +++ b/hw/xen/xen-mapcache.c
> > @@ -14,7 +14,9 @@
> >  
> >  #include 
> >  
> > +#include "hw/xen/xen-hvm-common.h"
> >  #include "hw/xen/xen_native.h"
> > +#include "hw/xen/xen_pvdev.h"
> >  #include "qemu/bitmap.h"
> >  
> >  #include "sysemu/runstate.h"
> > @@ -597,3 +599,28 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> >  mapcache_unlock();
> >  return p;
> >  }
> > +
> > +MemoryRegion *xen_init_grant_ram(void)
> > +{
> > +RAMBlock *block;
> > +
> > +memory_region_init(_grants, NULL, "xen.grants",
> > +   XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE);
> > +block = g_malloc0(sizeof(*block));
> > +block->mr = _grants;
> > +block->used_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE;
> > +block->max_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE;
> > +block->fd = -1;
> > +block->page_size = XC_PAGE_SIZE;
> > +block->host = (void *)XEN_GRANT_ADDR_OFF;
> > +block->offset = XEN_GRANT_ADDR_OFF;
> > +block->flags = RAM_PREALLOC;
> > +ram_grants.ram_block = block;
> > +ram_grants.ram = true;
> > +ram_grants.terminates = true;
> > +ram_block_add_list(block);
> > +memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF,
> > +_grants);
> > +
> > +return _grants;
> 
> It doesn't look like xen_init_grant_ram has anything to do with the
> mapcache. It should be in another file. Maybe ./hw/xen/xen-hvm-common.c
> or ./hw/i386/xen/xen-hvm.c (but this is x86 specific and we need grants
> on ARM too)

Now having seen all the other patches, it might be OK to keep this here.
I am OK with this patch once it is rebased on the latest staging. I
would still advise to split the physdev.c changes to a separate patch.



Re: [QEMU][PATCH v1 7/7] hw: arm: Add grant mapping.

2023-10-09 Thread Stefano Stabellini
On Thu, 5 Oct 2023, Vikram Garhwal wrote:
> Enable grant ram mapping support for Xenpvh machine on ARM.
> 
> Signed-off-by: Vikram Garhwal 

Reviewed-by: Stefano Stabellini 


> ---
>  hw/arm/xen_arm.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
> index f83b983ec5..553c289720 100644
> --- a/hw/arm/xen_arm.c
> +++ b/hw/arm/xen_arm.c
> @@ -125,6 +125,9 @@ static void xen_init_ram(MachineState *machine)
>  DPRINTF("Initialized region xen.ram.hi: base 0x%llx size 0x%lx\n",
>  GUEST_RAM1_BASE, ram_size[1]);
>  }
> +
> +DPRINTF("init grant ram mapping for XEN\n");
> +ram_grants = *xen_init_grant_ram();
>  }
>  
>  void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
> -- 
> 2.17.1
> 



Re: [QEMU][PATCH v1 6/7] xen: add map and unmap callbacks for grant region

2023-10-09 Thread Stefano Stabellini
On Thu, 5 Oct 2023, Vikram Garhwal wrote:
> From: Juergen Gross 
> 
> Add the callbacks for mapping/unmapping guest memory via grants to the
> special grant memory region.
> 
> Signed-off-by: Juergen Gross 
> Signed-off-by: Vikram Garhwal 

This looks good. We need to add a check to make sure we don't exceed
XEN_MAX_VIRTIO_GRANTS.



> ---
>  hw/xen/xen-mapcache.c | 167 +-
>  softmmu/physmem.c |  11 ++-
>  2 files changed, 173 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> index 8a61c7dde6..52844a6a9d 100644
> --- a/hw/xen/xen-mapcache.c
> +++ b/hw/xen/xen-mapcache.c
> @@ -9,6 +9,8 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/queue.h"
> +#include "qemu/thread.h"
>  #include "qemu/units.h"
>  #include "qemu/error-report.h"
>  
> @@ -23,6 +25,8 @@
>  #include "sysemu/xen-mapcache.h"
>  #include "trace.h"
>  
> +#include 
> +#include 
>  
>  //#define MAPCACHE_DEBUG
>  
> @@ -385,7 +389,7 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
>  return p;
>  }
>  
> -ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
> +static ram_addr_t xen_ram_addr_from_mapcache_try(void *ptr)
>  {
>  MapCacheEntry *entry = NULL;
>  MapCacheRev *reventry;
> @@ -594,10 +598,170 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
>  return p;
>  }
>  
> +struct XENMappedGrantRegion {
> +void *addr;
> +unsigned int pages;
> +unsigned int refs;
> +unsigned int prot;
> +uint32_t idx;
> +QLIST_ENTRY(XENMappedGrantRegion) list;
> +};
> +
> +static xengnttab_handle *xen_region_gnttabdev;
> +static QLIST_HEAD(GrantRegionList, XENMappedGrantRegion) xen_grant_mappings =
> +QLIST_HEAD_INITIALIZER(xen_grant_mappings);
> +static QemuMutex xen_map_mutex;
> +
> +static void *xen_map_grant_dyn(MemoryRegion **mr, hwaddr addr, hwaddr *plen,
> +   bool is_write, MemTxAttrs attrs)
> +{
> +unsigned int page_off = addr & (XC_PAGE_SIZE - 1);
> +unsigned int i;
> +unsigned int nrefs = (page_off + *plen + XC_PAGE_SIZE - 1) >> 
> XC_PAGE_SHIFT;
> +uint32_t ref = (addr - XEN_GRANT_ADDR_OFF) >> XC_PAGE_SHIFT;
> +uint32_t *refs = NULL;
> +unsigned int prot = PROT_READ;
> +struct XENMappedGrantRegion *mgr = NULL;
> +
> +if (is_write) {
> +prot |= PROT_WRITE;
> +}
> +
> +qemu_mutex_lock(_map_mutex);
> +
> +QLIST_FOREACH(mgr, _grant_mappings, list) {
> +if (mgr->idx == ref &&
> +mgr->pages == nrefs &&
> +(mgr->prot & prot) == prot) {
> +break;
> +}
> +}
> +if (!mgr) {
> +mgr = g_new(struct XENMappedGrantRegion, 1);
> +
> +if (nrefs == 1) {
> +refs = 
> +} else {
> +refs = g_new(uint32_t, nrefs);
> +for (i = 0; i < nrefs; i++) {
> +refs[i] = ref + i;
> +}
> +}
> +mgr->addr = xengnttab_map_domain_grant_refs(xen_region_gnttabdev, 
> nrefs,
> +xen_domid, refs, prot);
> +if (mgr->addr) {
> +mgr->pages = nrefs;
> +mgr->refs = 1;
> +mgr->prot = prot;
> +mgr->idx = ref;
> +
> +QLIST_INSERT_HEAD(_grant_mappings, mgr, list);
> +} else {
> +g_free(mgr);
> +mgr = NULL;
> +}
> +} else {
> +mgr->refs++;
> +}
> +
> +qemu_mutex_unlock(_map_mutex);
> +
> +if (nrefs > 1) {
> +g_free(refs);
> +}
> +
> +return mgr ? mgr->addr + page_off : NULL;
> +}
> +
> +static void xen_unmap_grant_dyn(MemoryRegion *mr, void *buffer, ram_addr_t 
> addr,
> +hwaddr len, bool is_write, hwaddr access_len)
> +{
> +unsigned int page_off = (unsigned long)buffer & (XC_PAGE_SIZE - 1);
> +unsigned int nrefs = (page_off + len + XC_PAGE_SIZE - 1) >> 
> XC_PAGE_SHIFT;
> +unsigned int prot = PROT_READ;
> +struct XENMappedGrantRegion *mgr = NULL;
> +
> +if (is_write) {
> +prot |= PROT_WRITE;
> +}
> +
> +qemu_mutex_lock(_map_mutex);
> +
> +QLIST_FOREACH(mgr, _grant_mappings, list) {
> +if (mgr->addr == buffer - page_off &&
> +mgr->pages == nrefs &&
> +(mgr->prot & prot) == prot) {
> +break;
> +}
> +}
> +if (mgr) {
> +mgr->refs--;
> +if (!mgr->refs) {
> +xengnttab_unmap(xen_region_gnttabdev, mgr->addr, nrefs);
> +
> +QLIST_REMOVE(mgr, list);
> +g_free(mgr);
> +}
> +} else {
> +error_report("xen_unmap_grant_dyn() trying to unmap unknown buffer");
> +}
> +
> +qemu_mutex_unlock(_map_mutex);
> +}
> +
> +static ram_addr_t xen_ram_addr_from_grant_cache(void *ptr)
> +{
> +unsigned int page_off = (unsigned long)ptr & (XC_PAGE_SIZE - 1);
> +struct XENMappedGrantRegion *mgr = NULL;
> +ram_addr_t raddr = 

Re: [QEMU][PATCH v1 5/7] memory: add MemoryRegion map and unmap callbacks

2023-10-09 Thread Stefano Stabellini
On Thu, 5 Oct 2023, Vikram Garhwal wrote:
> From: Juergen Gross 
> 
> In order to support mapping and unmapping guest memory dynamically to
> and from qemu during address_space_[un]map() operations add the map()
> and unmap() callbacks to MemoryRegionOps.
> 
> Those will be used e.g. for Xen grant mappings when performing guest
> I/Os.
> 
> Signed-off-by: Juergen Gross 
> Signed-off-by: Vikram Garhwal 

Can't we just use the existing Xen hooks in qemu_ram_ptr_length and
xen_invalidate_map_cache_entry? Do we really need new ones?


> ---
>  include/exec/memory.h | 21 ++
>  softmmu/physmem.c | 50 +--
>  2 files changed, 60 insertions(+), 11 deletions(-)
> 
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index c99842d2fc..f3c62d2883 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -280,6 +280,27 @@ struct MemoryRegionOps {
>  unsigned size,
>  MemTxAttrs attrs);
>  
> +/*
> + * Dynamically create mapping. @addr is the guest address to map; @plen
> + * is the pointer to the usable length of the buffer.
> + * @mr contents can be changed in case a new memory region is created for
> + * the mapping.
> + * Returns the buffer address for accessing the data.
> + */
> +void *(*map)(MemoryRegion **mr,
> + hwaddr addr,
> + hwaddr *plen,
> + bool is_write,
> + MemTxAttrs attrs);
> +
> +/* Unmap an area obtained via map() before. */
> +void (*unmap)(MemoryRegion *mr,
> +  void *buffer,
> +  ram_addr_t addr,
> +  hwaddr len,
> +  bool is_write,
> +  hwaddr access_len);
> +
>  enum device_endian endianness;
>  /* Guest-visible constraints: */
>  struct {
> diff --git a/softmmu/physmem.c b/softmmu/physmem.c
> index 6e5e379dd0..5f425bea1c 100644
> --- a/softmmu/physmem.c
> +++ b/softmmu/physmem.c
> @@ -3135,6 +3135,7 @@ void *address_space_map(AddressSpace *as,
>  hwaddr len = *plen;
>  hwaddr l, xlat;
>  MemoryRegion *mr;
> +void *ptr = NULL;
>  FlatView *fv;
>  
>  if (len == 0) {
> @@ -3168,12 +3169,20 @@ void *address_space_map(AddressSpace *as,
>  return bounce.buffer;
>  }
>  
> -
>  memory_region_ref(mr);
> +
> +if (mr->ops && mr->ops->map) {
> +ptr = mr->ops->map(, addr, plen, is_write, attrs);
> +}
> +
>  *plen = flatview_extend_translation(fv, addr, len, mr, xlat,
>  l, is_write, attrs);
>  fuzz_dma_read_cb(addr, *plen, mr);
> -return qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
> +if (ptr == NULL) {
> +ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
> +}
> +
> +return ptr;
>  }
>  
>  /* Unmaps a memory region previously mapped by address_space_map().
> @@ -3189,11 +3198,16 @@ void address_space_unmap(AddressSpace *as, void 
> *buffer, hwaddr len,
>  
>  mr = memory_region_from_host(buffer, );
>  assert(mr != NULL);
> -if (is_write) {
> -invalidate_and_set_dirty(mr, addr1, access_len);
> -}
> -if (xen_enabled()) {
> -xen_invalidate_map_cache_entry(buffer);
> +
> +if (mr->ops && mr->ops->unmap) {
> +mr->ops->unmap(mr, buffer, addr1, len, is_write, access_len);
> +} else {
> +if (is_write) {
> +invalidate_and_set_dirty(mr, addr1, access_len);
> +}
> +if (xen_enabled()) {
> +xen_invalidate_map_cache_entry(buffer);
> +}
>  }
>  memory_region_unref(mr);
>  return;
> @@ -3266,10 +3280,18 @@ int64_t address_space_cache_init(MemoryRegionCache 
> *cache,
>   * doing this if we found actual RAM, which behaves the same
>   * regardless of attributes; so UNSPECIFIED is fine.
>   */
> +if (mr->ops && mr->ops->map) {
> +cache->ptr = mr->ops->map(, addr, , is_write,
> +  MEMTXATTRS_UNSPECIFIED);
> +}
> +
>  l = flatview_extend_translation(cache->fv, addr, len, mr,
>  cache->xlat, l, is_write,
>  MEMTXATTRS_UNSPECIFIED);
> -cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, , 
> true);
> +if (!cache->ptr) {
> +cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, ,
> + true);
> +}
>  } else {
>  cache->ptr = NULL;
>  }
> @@ -3291,14 +3313,20 @@ void address_space_cache_invalidate(MemoryRegionCache 
> *cache,
>  
>  void address_space_cache_destroy(MemoryRegionCache *cache)
>  {
> -if (!cache->mrs.mr) {
> +MemoryRegion *mr = cache->mrs.mr;
> 

Re: [QEMU][PATCH v1 4/7] xen: let xen_ram_addr_from_mapcache() return -1 in case of not found entry

2023-10-09 Thread Stefano Stabellini
On Thu, 5 Oct 2023, Vikram Garhwal wrote:
> From: Juergen Gross 
> 
> Today xen_ram_addr_from_mapcache() will either abort() or return 0 in
> case it can't find a matching entry for a pointer value. Both cases
> are bad, so change that to return an invalid address instead.
> 
> Signed-off-by: Juergen Gross 

Reviewed-by: Stefano Stabellini 


> ---
>  hw/xen/xen-mapcache.c | 12 +++-
>  1 file changed, 3 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> index 8115c44c00..8a61c7dde6 100644
> --- a/hw/xen/xen-mapcache.c
> +++ b/hw/xen/xen-mapcache.c
> @@ -404,13 +404,8 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
>  }
>  }
>  if (!found) {
> -fprintf(stderr, "%s, could not find %p\n", __func__, ptr);
> -QTAILQ_FOREACH(reventry, >locked_entries, next) {
> -DPRINTF("   "HWADDR_FMT_plx" -> %p is present\n", 
> reventry->paddr_index,
> -reventry->vaddr_req);
> -}
> -abort();
> -return 0;
> +mapcache_unlock();
> +return RAM_ADDR_INVALID;
>  }
>  
>  entry = >entry[paddr_index % mapcache->nr_buckets];
> @@ -418,8 +413,7 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
>  entry = entry->next;
>  }
>  if (!entry) {
> -DPRINTF("Trying to find address %p that is not in the mapcache!\n", 
> ptr);
> -raddr = 0;
> +raddr = RAM_ADDR_INVALID;
>  } else {
>  raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
>   ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
> -- 
> 2.17.1
> 



Re: [QEMU][PATCH v1 3/7] softmmu: let qemu_map_ram_ptr() use qemu_ram_ptr_length()

2023-10-09 Thread Stefano Stabellini
On Thu, 5 Oct 2023, Vikram Garhwal wrote:
> From: Juergen Gross 
> 
> qemu_map_ram_ptr() and qemu_ram_ptr_length() share quite some code, so
> modify qemu_ram_ptr_length() a little bit and use it for
> qemu_map_ram_ptr(), too.
> 
> Signed-off-by: Juergen Gross 
> Signed-off-by: Vikram Garhwal 

This patch also doesn't apply due to code movement.

Other than that, the patch looks good to me


> ---
>  softmmu/physmem.c | 58 +++
>  1 file changed, 23 insertions(+), 35 deletions(-)
> 
> diff --git a/softmmu/physmem.c b/softmmu/physmem.c
> index e182a2fa07..6e5e379dd0 100644
> --- a/softmmu/physmem.c
> +++ b/softmmu/physmem.c
> @@ -2163,38 +2163,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
>  }
>  #endif /* !_WIN32 */
>  
> -/* Return a host pointer to ram allocated with qemu_ram_alloc.
> - * This should not be used for general purpose DMA.  Use address_space_map
> - * or address_space_rw instead. For local memory (e.g. video ram) that the
> - * device owns, use memory_region_get_ram_ptr.
> - *
> - * Called within RCU critical section.
> - */
> -void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
> -{
> -RAMBlock *block = ram_block;
> -
> -if (block == NULL) {
> -block = qemu_get_ram_block(addr);
> -addr -= block->offset;
> -}
> -
> -if (xen_enabled() && block->host == NULL) {
> -/* We need to check if the requested address is in the RAM
> - * because we don't want to map the entire memory in QEMU.
> - * In that case just map until the end of the page.
> - */
> -if (block->offset == 0) {
> -return xen_map_cache(addr, 0, 0, false);
> -}
> -
> -block->host = xen_map_cache(block->offset, block->max_length, 1, 
> false);
> -}
> -return ramblock_ptr(block, addr);
> -}
> -
> -/* Return a host pointer to guest's ram. Similar to qemu_map_ram_ptr
> - * but takes a size argument.
> +/*
> + * Return a host pointer to guest's ram.
>   *
>   * Called within RCU critical section.
>   */
> @@ -2202,7 +2172,9 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, 
> ram_addr_t addr,
>   hwaddr *size, bool lock)
>  {
>  RAMBlock *block = ram_block;
> -if (*size == 0) {
> +hwaddr len = 0;
> +
> +if (size && *size == 0) {
>  return NULL;
>  }
>  
> @@ -2210,7 +2182,10 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, 
> ram_addr_t addr,
>  block = qemu_get_ram_block(addr);
>  addr -= block->offset;
>  }
> -*size = MIN(*size, block->max_length - addr);
> +if (size) {
> +*size = MIN(*size, block->max_length - addr);
> +len = *size;
> +}
>  
>  if (xen_enabled() && block->host == NULL) {
>  /* We need to check if the requested address is in the RAM
> @@ -2218,7 +2193,7 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, 
> ram_addr_t addr,
>   * In that case just map the requested area.
>   */
>  if (block->offset == 0) {
> -return xen_map_cache(addr, *size, lock, lock);
> +return xen_map_cache(addr, len, lock, lock);
>  }
>  
>  block->host = xen_map_cache(block->offset, block->max_length, 1, 
> lock);
> @@ -2227,6 +2202,19 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, 
> ram_addr_t addr,
>  return ramblock_ptr(block, addr);
>  }
>  
> +/*
> + * Return a host pointer to ram allocated with qemu_ram_alloc.
> + * This should not be used for general purpose DMA.  Use address_space_map
> + * or address_space_rw instead. For local memory (e.g. video ram) that the
> + * device owns, use memory_region_get_ram_ptr.
> + *
> + * Called within RCU critical section.
> + */
> +void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
> +{
> +return qemu_ram_ptr_length(ram_block, addr, NULL, false);
> +}
> +
>  /* Return the offset of a hostpointer within a ramblock */
>  ram_addr_t qemu_ram_block_host_offset(RAMBlock *rb, void *host)
>  {
> -- 
> 2.17.1
> 



Re: [PATCH v17 6/9] gfxstream + rutabaga: add initial support for gfxstream

2023-10-09 Thread Gurchetan Singh
On Mon, Oct 9, 2023 at 12:11 AM Marc-André Lureau <
marcandre.lur...@redhat.com> wrote:

> On Fri, Oct 6, 2023 at 5:09 AM Gurchetan Singh
>  wrote:
> >
> > This adds initial support for gfxstream and cross-domain.  Both
> > features rely on virtio-gpu blob resources and context types, which
> > are also implemented in this patch.
> >
> > gfxstream has a long and illustrious history in Android graphics
> > paravirtualization.  It has been powering graphics in the Android
> > Studio Emulator for more than a decade, which is the main developer
> > platform.
> >
> > Originally conceived by Jesse Hall, it was first known as "EmuGL" [a].
> > The key design characteristic was a 1:1 threading model and
> > auto-generation, which fit nicely with the OpenGLES spec.  It also
> > allowed easy layering with ANGLE on the host, which provides the GLES
> > implementations on Windows or MacOS enviroments.
> >
> > gfxstream has traditionally been maintained by a single engineer, and
> > between 2015 to 2021, the goldfish throne passed to Frank Yang.
> > Historians often remark this glorious reign ("pax gfxstreama" is the
> > academic term) was comparable to that of Augustus and both Queen
> > Elizabeths.  Just to name a few accomplishments in a resplendent
> > panoply: higher versions of GLES, address space graphics, snapshot
> > support and CTS compliant Vulkan [b].
> >
> > One major drawback was the use of out-of-tree goldfish drivers.
> > Android engineers didn't know much about DRM/KMS and especially TTM so
> > a simple guest to host pipe was conceived.
> >
> > Luckily, virtio-gpu 3D started to emerge in 2016 due to the work of
> > the Mesa/virglrenderer communities.  In 2018, the initial virtio-gpu
> > port of gfxstream was done by Cuttlefish enthusiast Alistair Delva.
> > It was a symbol compatible replacement of virglrenderer [c] and named
> > "AVDVirglrenderer".  This implementation forms the basis of the
> > current gfxstream host implementation still in use today.
> >
> > cross-domain support follows a similar arc.  Originally conceived by
> > Wayland aficionado David Reveman and crosvm enjoyer Zach Reizner in
> > 2018, it initially relied on the downstream "virtio-wl" device.
> >
> > In 2020 and 2021, virtio-gpu was extended to include blob resources
> > and multiple timelines by yours truly, features gfxstream/cross-domain
> > both require to function correctly.
> >
> > Right now, we stand at the precipice of a truly fantastic possibility:
> > the Android Emulator powered by upstream QEMU and upstream Linux
> > kernel.  gfxstream will then be packaged properfully, and app
> > developers can even fix gfxstream bugs on their own if they encounter
> > them.
> >
> > It's been quite the ride, my friends.  Where will gfxstream head next,
> > nobody really knows.  I wouldn't be surprised if it's around for
> > another decade, maintained by a new generation of Android graphics
> > enthusiasts.
> >
> > Technical details:
> >   - Very simple initial display integration: just used Pixman
> >   - Largely, 1:1 mapping of virtio-gpu hypercalls to rutabaga function
> > calls
> >
> > Next steps for Android VMs:
> >   - The next step would be improving display integration and UI
> interfaces
> > with the goal of the QEMU upstream graphics being in an emulator
> > release [d].
> >
> > Next steps for Linux VMs for display virtualization:
> >   - For widespread distribution, someone needs to package Sommelier or
> the
> > wayland-proxy-virtwl [e] ideally into Debian main. In addition, newer
> > versions of the Linux kernel come with DRM_VIRTIO_GPU_KMS option,
> > which allows disabling KMS hypercalls.  If anyone cares enough, it'll
> > probably be possible to build a custom VM variant that uses this
> display
> > virtualization strategy.
> >
> > [a]
> https://android-review.googlesource.com/c/platform/development/+/34470
> > [b]
> https://android-review.googlesource.com/q/topic:%22vulkan-hostconnection-start%22
> > [c]
> https://android-review.googlesource.com/c/device/generic/goldfish-opengl/+/761927
> > [d] https://developer.android.com/studio/releases/emulator
> > [e] https://github.com/talex5/wayland-proxy-virtwl
> >
> > Signed-off-by: Gurchetan Singh 
> > Tested-by: Alyssa Ross 
> > Tested-by: Emmanouil Pitsidianakis 
> > Tested-by: Akihiko Odaki 
> > Reviewed-by: Emmanouil Pitsidianakis 
> > Reviewed-by: Antonio Caggiano 
> > Reviewed-by: Akihiko Odaki 
> > ---
> >  hw/display/virtio-gpu-pci-rutabaga.c |   47 ++
> >  hw/display/virtio-gpu-rutabaga.c | 1113 ++
> >  hw/display/virtio-vga-rutabaga.c |   50 ++
> >  3 files changed, 1210 insertions(+)
> >  create mode 100644 hw/display/virtio-gpu-pci-rutabaga.c
> >  create mode 100644 hw/display/virtio-gpu-rutabaga.c
> >  create mode 100644 hw/display/virtio-vga-rutabaga.c
> >
> > diff --git a/hw/display/virtio-gpu-pci-rutabaga.c
> b/hw/display/virtio-gpu-pci-rutabaga.c
> > new file mode 100644
> > index 

Re: [QEMU][PATCH v1 2/7] xen: add pseudo RAM region for grant mappings

2023-10-09 Thread Stefano Stabellini
On Thu, 5 Oct 2023, Vikram Garhwal wrote:
> From: Juergen Gross 
> 
> Add a memory region which can be used to automatically map granted
> memory. It is starting at 0x8000ULL in order to be able to
> distinguish it from normal RAM.
> 
> For this reason the xen.ram memory region is expanded, which has no
> further impact as it is used just as a container of the real RAM
> regions and now the grant region.
> 
> Signed-off-by: Juergen Gross 
> Signed-off-by: Vikram Garhwal 

This patch doesn't apply to staging anymore


> ---
>  hw/i386/xen/xen-hvm.c   |  3 ++
>  hw/xen/xen-hvm-common.c |  4 +--
>  hw/xen/xen-mapcache.c   | 27 ++
>  include/exec/ram_addr.h |  1 +
>  include/hw/xen/xen-hvm-common.h |  2 ++
>  include/hw/xen/xen_pvdev.h  |  3 ++
>  include/sysemu/xen-mapcache.h   |  3 ++
>  softmmu/physmem.c   | 62 +
>  8 files changed, 80 insertions(+), 25 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index f42621e674..67a8a6 100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -172,6 +172,9 @@ static void xen_ram_init(PCMachineState *pcms,
>   x86ms->above_4g_mem_size);
>  memory_region_add_subregion(sysmem, 0x1ULL, _hi);
>  }
> +
> +/* Add grant mappings as a pseudo RAM region. */
> +ram_grants = *xen_init_grant_ram();
>  }
>  
>  static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
> diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
> index 565dc39c8f..b7255977a5 100644
> --- a/hw/xen/xen-hvm-common.c
> +++ b/hw/xen/xen-hvm-common.c
> @@ -9,7 +9,7 @@
>  #include "hw/boards.h"
>  #include "hw/xen/arch_hvm.h"
>  
> -MemoryRegion ram_memory;
> +MemoryRegion ram_memory, ram_grants;
>  
>  void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
> Error **errp)
> @@ -26,7 +26,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, 
> MemoryRegion *mr,
>  return;
>  }
>  
> -if (mr == _memory) {
> +if (mr == _memory || mr == _grants) {
>  return;
>  }
>  
> diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> index f7d974677d..8115c44c00 100644
> --- a/hw/xen/xen-mapcache.c
> +++ b/hw/xen/xen-mapcache.c
> @@ -14,7 +14,9 @@
>  
>  #include 
>  
> +#include "hw/xen/xen-hvm-common.h"
>  #include "hw/xen/xen_native.h"
> +#include "hw/xen/xen_pvdev.h"
>  #include "qemu/bitmap.h"
>  
>  #include "sysemu/runstate.h"
> @@ -597,3 +599,28 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
>  mapcache_unlock();
>  return p;
>  }
> +
> +MemoryRegion *xen_init_grant_ram(void)
> +{
> +RAMBlock *block;
> +
> +memory_region_init(_grants, NULL, "xen.grants",
> +   XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE);
> +block = g_malloc0(sizeof(*block));
> +block->mr = _grants;
> +block->used_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE;
> +block->max_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE;
> +block->fd = -1;
> +block->page_size = XC_PAGE_SIZE;
> +block->host = (void *)XEN_GRANT_ADDR_OFF;
> +block->offset = XEN_GRANT_ADDR_OFF;
> +block->flags = RAM_PREALLOC;
> +ram_grants.ram_block = block;
> +ram_grants.ram = true;
> +ram_grants.terminates = true;
> +ram_block_add_list(block);
> +memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF,
> +_grants);
> +
> +return _grants;

It doesn't look like xen_init_grant_ram has anything to do with the
mapcache. It should be in another file. Maybe ./hw/xen/xen-hvm-common.c
or ./hw/i386/xen/xen-hvm.c (but this is x86 specific and we need grants
on ARM too)


> +}
> diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
> index 90676093f5..c0b5f9a7d0 100644
> --- a/include/exec/ram_addr.h
> +++ b/include/exec/ram_addr.h
> @@ -139,6 +139,7 @@ void qemu_ram_free(RAMBlock *block);
>  int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
>  
>  void qemu_ram_msync(RAMBlock *block, ram_addr_t start, ram_addr_t length);
> +void ram_block_add_list(RAMBlock *new_block);
>  
>  /* Clear whole block of mem */
>  static inline void qemu_ram_block_writeback(RAMBlock *block)
> diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h
> index 4e9904f1a6..0d300ba898 100644
> --- a/include/hw/xen/xen-hvm-common.h
> +++ b/include/hw/xen/xen-hvm-common.h
> @@ -17,6 +17,8 @@
>  #include 
>  
>  extern MemoryRegion ram_memory;
> +
> +extern MemoryRegion ram_grants;
>  extern MemoryListener xen_io_listener;
>  extern DeviceListener xen_device_listener;
>  
> diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h
> index ddad4b9f36..0f1b5edfa9 100644
> --- a/include/hw/xen/xen_pvdev.h
> +++ b/include/hw/xen/xen_pvdev.h
> @@ -80,4 +80,7 @@ int xen_pv_send_notify(struct XenLegacyDevice 

Re: [PATCH 1/3] via-ide: Fix legacy mode emulation

2023-10-09 Thread BALATON Zoltan

On Mon, 9 Oct 2023, Mark Cave-Ayland wrote:

On 09/10/2023 23:23, BALATON Zoltan wrote:

On Mon, 9 Oct 2023, Mark Cave-Ayland wrote:

On 08/10/2023 12:08, BALATON Zoltan wrote:


On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The initial value for BARs were set in reset method for emulating
legacy mode at start but this does not work because PCI code resets
BARs after calling device reset method.


This is certainly something I've noticed when testing previous versions 
of the VIA patches. Perhaps it's worth a separate thread to the PCI 
devs?


I think I brought up this back then but was told current PCI code won't 
change and since that could break everything else that makes sense so 
this is something that we should take as given and accomodate that.


I don't remember the details of that thread, but that's not too much of an 
issue here as the values won't be used.



Additionally the values
written to BARs were also wrong.


I don't believe this is correct: according to the datasheet the values 
on reset are the ones given in the current reset code, so even if the 
reset function is overridden at a later data during PCI bus reset, I 
would leave these for now since it is a different issue.


Those values are missing the IO space bit for one so they can't be 
correct as a BAR value no matter what the datasheet says. And since they 
are ineffective now I think it's best to remove them to avoid confusion.


Maybe, or perhaps just fix up the missing IO space bit and add a comment 
pointing out these are the defaults, but currently they are erased on PCI 
bus reset? I have found it useful to have the values around to save having 
to reference the datasheet.


The data sheet does not list the io space bits so fixing that would lead to 
values not matching data sheet any more. Also the defaults in the data 
sheet don't make much sense even with io space but as some of them match 
legacy ports while others don't. I can either drop this hunk leaving the 
current values there or add a FIXME comment saying they are ineffective but 
because they are overwritten (either by PCI code now or firmware/guest 
later) I think it's best to remove them any maybe only bring them back if 
we find they would be needed for any guest and what would be the correct 
default valuss here. I don't trust the data sheet on that and getting it 
from real hardware is also not really possible because the firmware could 
have overwritten them by the time you can get them. So I don't think 
keeping these here would help anybody, just cause confusion.


We can check the values on real hardware given the Forth in my previous reply 
which will then tell us the correct values for once and for all. My guess is 
that since the address is a separate field to the BAR type in the datasheet, 
the IO bit was simply missed.


I only have device tree dump from real pegasos2 but it has BARs so you 
can see here:


package 0xFC5CE70 /pci/ide:
parent=0xFC58E08
children=0xFC5D418
link=0xFC5D948
dict=0xFC5CEA0:
open  func[0x11F4]
close func[0x11F5]
dma-alloc func[0x11F6]
dma-free  func[0x11F7]
decode-unit   func[0x11F8]
encode-unit   func[0x11F9]
selftest  func[0x11FA]
props=0xFC5CEB8:
vendor-id 0x1106 (4358)
device-id 0x571 (1393)
revision-id   0x6 (6)
class-code0x1018F (65935)
subsystem-id  0x0 (0)
subsystem-vendor-id   0x0 (0)
.vendor-name  "VIA"
.part-number  "VT82C586/596/686"
.description  "PCI IDE Controller"
interrupts0x1 (1)
devsel-speed  0x1 (1)
fast-back-to-back
min-grant 0x0 (0)
max-latency   0x0 (0)
name  "ide"
reg   C,1:0
  iC,1,10,0:8
  iC,1,14,0:4
  iC,1,18,0:8
  iC,1,1C,0:4
  iC,1,20,0:10
device_type   "spi"
assigned-addressesiC,1,10,FE001000:8
  iC,1,14,FE00100C:4
  iC,1,18,FE001010:8
  iC,1,1C,FE00101C:4
  iC,1,20,FE001020:10

That means by the time you could run your Forth the firmware already set 
the IDE device up se we get the same values as in Linux. If you want to 
see how the firmware progrems it you can find out with the emulated 
pegasos2 using -bios pegasos2.rom and enabling pci traces, but we can't 
find out what are the default values on real machine before this without 
replacing firmware that likely nobody dares to try. So just let it go and 
accept that whatever defaults are 

Re: [QEMU][PATCH v1 1/7] xen: when unplugging emulated devices skip virtio devices

2023-10-09 Thread Stefano Stabellini
On Thu, 5 Oct 2023, Vikram Garhwal wrote:
> From: Juergen Gross 
> 
> Virtio devices should never be unplugged at boot time, as they are
> similar to pci passthrough devices.
> 
> Signed-off-by: Juergen Gross 
> Signed-off-by: Vikram Garhwal 
> ---
>  hw/i386/xen/xen_platform.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
> index 17457ff3de..3560eaf8c8 100644
> --- a/hw/i386/xen/xen_platform.c
> +++ b/hw/i386/xen/xen_platform.c
> @@ -28,6 +28,7 @@
>  #include "hw/ide/pci.h"
>  #include "hw/pci/pci.h"
>  #include "migration/vmstate.h"
> +#include "hw/virtio/virtio-bus.h"
>  #include "net/net.h"
>  #include "trace.h"
>  #include "sysemu/xen.h"
> @@ -132,7 +133,8 @@ static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
>  /* We have to ignore passthrough devices */
>  if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
>  PCI_CLASS_NETWORK_ETHERNET
> -&& !pci_device_is_passthrough(d)) {
> +&& !pci_device_is_passthrough(d)
> +&& !qdev_get_child_bus(>qdev, TYPE_VIRTIO_BUS)) {

Please update the in-code comment above to say "ignore passthrough
devices and virtio devices"


>  object_unparent(OBJECT(d));
>  }
>  }
> @@ -208,6 +210,10 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void 
> *opaque)
>  /* We have to ignore passthrough devices */
>  if (pci_device_is_passthrough(d))
>  return;
> +/* Ignore virtio devices */
> +if (qdev_get_child_bus(>qdev, TYPE_VIRTIO_BUS)) {
> +return;
> +}
>  
>  switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) {
>  case PCI_CLASS_STORAGE_IDE:
> -- 
> 2.17.1
> 



Re: [PATCH 1/3] via-ide: Fix legacy mode emulation

2023-10-09 Thread Mark Cave-Ayland

On 09/10/2023 23:23, BALATON Zoltan wrote:


On Mon, 9 Oct 2023, Mark Cave-Ayland wrote:

On 08/10/2023 12:08, BALATON Zoltan wrote:


On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The initial value for BARs were set in reset method for emulating
legacy mode at start but this does not work because PCI code resets
BARs after calling device reset method.


This is certainly something I've noticed when testing previous versions of the 
VIA patches. Perhaps it's worth a separate thread to the PCI devs?


I think I brought up this back then but was told current PCI code won't change and 
since that could break everything else that makes sense so this is something that 
we should take as given and accomodate that.


I don't remember the details of that thread, but that's not too much of an issue 
here as the values won't be used.



Additionally the values
written to BARs were also wrong.


I don't believe this is correct: according to the datasheet the values on reset 
are the ones given in the current reset code, so even if the reset function is 
overridden at a later data during PCI bus reset, I would leave these for now 
since it is a different issue.


Those values are missing the IO space bit for one so they can't be correct as a 
BAR value no matter what the datasheet says. And since they are ineffective now I 
think it's best to remove them to avoid confusion.


Maybe, or perhaps just fix up the missing IO space bit and add a comment pointing 
out these are the defaults, but currently they are erased on PCI bus reset? I have 
found it useful to have the values around to save having to reference the datasheet.


The data sheet does not list the io space bits so fixing that would lead to values 
not matching data sheet any more. Also the defaults in the data sheet don't make much 
sense even with io space but as some of them match legacy ports while others don't. I 
can either drop this hunk leaving the current values there or add a FIXME comment 
saying they are ineffective but because they are overwritten (either by PCI code now 
or firmware/guest later) I think it's best to remove them any maybe only bring them 
back if we find they would be needed for any guest and what would be the correct 
default valuss here. I don't trust the data sheet on that and getting it from real 
hardware is also not really possible because the firmware could have overwritten them 
by the time you can get them. So I don't think keeping these here would help anybody, 
just cause confusion.


We can check the values on real hardware given the Forth in my previous reply which 
will then tell us the correct values for once and for all. My guess is that since the 
address is a separate field to the BAR type in the datasheet, the IO bit was simply 
missed.



Move setting the BARs to a callback on writing the PCI config regsiter
that sets the compatibility mode (which firmwares needing this mode
seem to do) and fix their values to program it to use legacy port
numbers. As noted in a comment, we only do this when the BARs were
unset before, because logs from real machine show this is how real
chip works, even if it contradicts the data sheet which is not very
clear about this.

Signed-off-by: BALATON Zoltan 
---
  hw/ide/via.c | 35 ++-
  1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index fff23803a6..8186190207 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -132,11 +132,6 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
   PCI_STATUS_DEVSEL_MEDIUM);
  -    pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, 0x01f0);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_1, 0x03f4);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x0170);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x0374);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0xcc01); /* BMIBA: 20-23h 
*/
  pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x010e);
    /* IDE chip enable, IDE configuration 1/2, IDE FIFO Configuration*/
@@ -159,6 +154,35 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_long(pci_conf + 0xc0, 0x00020001);
  }
  +static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr,
+  uint32_t val, int len)
+{
+    pci_default_write_config(pd, addr, val, len);
+    /*
+ * Only set BARs if they are unset. Logs from real hardware show that
+ * writing class_prog to enable compatibility mode after BARs were set
+ * (possibly by firmware) it will use ports set by BARs not ISA ports
+ * (e.g. pegasos2 Linux does this and calls it non-100% native mode).


Can you remind me again where the references are to non-100% native mode? The 
only thing I can find in Linux is 
https://github.com/torvalds/linux/blob/master/arch/powerpc/platforms/chrp/pci.c#L360 but that simply forces a switch to 

Re: [PATCH 2/3] hw/pci-host: Add emulation of Mai Logic Articia S

2023-10-09 Thread BALATON Zoltan

On Mon, 9 Oct 2023, Mark Cave-Ayland wrote:

On 09/10/2023 22:57, BALATON Zoltan wrote:

On Mon, 9 Oct 2023, Mark Cave-Ayland wrote:

On 08/10/2023 19:08, BALATON Zoltan wrote:

On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The Articia S is a generic chipset supporting several different CPUs
that were used on some PPC boards. This is a minimal emulation of the
parts needed for emulating the AmigaOne board.

Signed-off-by: BALATON Zoltan 
---
  hw/pci-host/Kconfig   |   5 +
  hw/pci-host/articia.c | 266 
++

  hw/pci-host/meson.build   |   2 +
  include/hw/pci-host/articia.h |  17 +++
  4 files changed, 290 insertions(+)
  create mode 100644 hw/pci-host/articia.c
  create mode 100644 include/hw/pci-host/articia.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index a07070eddf..33014c80a4 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -73,6 +73,11 @@ config SH_PCI
  bool
  select PCI
  +config ARTICIA
+    bool
+    select PCI
+    select I8259
+
  config MV64361
  bool
  select PCI
diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
new file mode 100644
index 00..80558e1c47
--- /dev/null
+++ b/hw/pci-host/articia.c
@@ -0,0 +1,266 @@
+/*
+ * Mai Logic Articia S emulation
+ *
+ * Copyright (c) 2023 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/pci/pci_device.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/i2c/bitbang_i2c.h"
+#include "hw/intc/i8259.h"
+#include "hw/pci-host/articia.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaState, ARTICIA)
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaHostState, ARTICIA_PCI_HOST)
+struct ArticiaHostState {
+    PCIDevice parent_obj;
+
+    ArticiaState *as;
+};
+
+/* TYPE_ARTICIA */
+
+struct ArticiaState {
+    PCIHostState parent_obj;
+
+    qemu_irq irq[PCI_NUM_PINS];
+    MemoryRegion io;
+    MemoryRegion mem;
+    MemoryRegion reg;
+
+    bitbang_i2c_interface smbus;
+    uint32_t gpio; /* bits 0-7 in, 8-15 out, 16-23 direction (0 in, 1 
out) */

+    hwaddr gpio_base;
+    MemoryRegion gpio_reg;
+};


These types above should be in the header file and not in the C file, as 
per our current QOM guidelines.


I don't think there's such a guideline, at least I did not find any 
mention of it in style and qom docs. It was necessary to move some type 
declarations to headers for types that are embedded in other objects 
because C needs the struct size for that, but I don't think that should 
be a general thing when it's not needed.


The reason for that is that moving these to the header exposes internal 
object structure to users that should not need to know that so it breaks 
object encapsulation and also needs moving a bunch of includes to the 
header which then makes the users of this type also include those headers 
when they don't really need them but only need the type defines to 
instantiate the object and that's all they should have access to. So I 
think declaring types in the header should only be done for types that 
aren't full devices and are meant to be embedded as part of another 
device or a SoC but otherwise it's better to keep implementation closed 
and local to the object and not expose it unless really needed, that's 
why these are here.


If you insist I can move these but I don't think there's really such 
recommendation and I don't think that's a good idea because of the above.


Maybe it was something that was missed out of the recent documentation 
updates, but you can clearly see this has been the standard pattern for 
some time, including for recent devices such as the xlnx-versal. If there 
are any devices that don't follow this pattern then it is likely because 
they are based on older code.


If you disagree with this, then start a new thread on qemu-devel with a 
new proposal and if everyone is agreement then that will be become the new 
standard.


I think you should start a thread with a patch to style or qom docs about 
this to document this standard and if that's accepted then I also accept it 
as a real recommendation as my understanding of it was as above that it was 
needed for some deviecs to allow embedding them but not a general 
recommendation for all devices and I don't think it should be beacuse of 
braeaking encapsulation and introduces a lot of unneded includes so I'd 
keep it to those devices where it'e really needed which is what the docs 
currently say.


Oh is there already a mention of this somewhere in the docs? Can you provide 
a link so we can check the wording? Certainly that's the way my own patches 
(and other people's patches) have been reviewed historically over the years.


The only mention I could find is in docs/devel/qom.rst, section "Standard 
type declaration and definition macros" which says: "In types which 

Re: [PATCH 2/3] hw/pci-host: Add emulation of Mai Logic Articia S

2023-10-09 Thread Mark Cave-Ayland

On 09/10/2023 22:57, BALATON Zoltan wrote:


On Mon, 9 Oct 2023, Mark Cave-Ayland wrote:

On 08/10/2023 19:08, BALATON Zoltan wrote:

On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The Articia S is a generic chipset supporting several different CPUs
that were used on some PPC boards. This is a minimal emulation of the
parts needed for emulating the AmigaOne board.

Signed-off-by: BALATON Zoltan 
---
  hw/pci-host/Kconfig   |   5 +
  hw/pci-host/articia.c | 266 ++
  hw/pci-host/meson.build   |   2 +
  include/hw/pci-host/articia.h |  17 +++
  4 files changed, 290 insertions(+)
  create mode 100644 hw/pci-host/articia.c
  create mode 100644 include/hw/pci-host/articia.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index a07070eddf..33014c80a4 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -73,6 +73,11 @@ config SH_PCI
  bool
  select PCI
  +config ARTICIA
+    bool
+    select PCI
+    select I8259
+
  config MV64361
  bool
  select PCI
diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
new file mode 100644
index 00..80558e1c47
--- /dev/null
+++ b/hw/pci-host/articia.c
@@ -0,0 +1,266 @@
+/*
+ * Mai Logic Articia S emulation
+ *
+ * Copyright (c) 2023 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/pci/pci_device.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/i2c/bitbang_i2c.h"
+#include "hw/intc/i8259.h"
+#include "hw/pci-host/articia.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaState, ARTICIA)
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaHostState, ARTICIA_PCI_HOST)
+struct ArticiaHostState {
+    PCIDevice parent_obj;
+
+    ArticiaState *as;
+};
+
+/* TYPE_ARTICIA */
+
+struct ArticiaState {
+    PCIHostState parent_obj;
+
+    qemu_irq irq[PCI_NUM_PINS];
+    MemoryRegion io;
+    MemoryRegion mem;
+    MemoryRegion reg;
+
+    bitbang_i2c_interface smbus;
+    uint32_t gpio; /* bits 0-7 in, 8-15 out, 16-23 direction (0 in, 1 out) */
+    hwaddr gpio_base;
+    MemoryRegion gpio_reg;
+};


These types above should be in the header file and not in the C file, as per our 
current QOM guidelines.


I don't think there's such a guideline, at least I did not find any mention of it 
in style and qom docs. It was necessary to move some type declarations to headers 
for types that are embedded in other objects because C needs the struct size for 
that, but I don't think that should be a general thing when it's not needed.


The reason for that is that moving these to the header exposes internal object 
structure to users that should not need to know that so it breaks object 
encapsulation and also needs moving a bunch of includes to the header which then 
makes the users of this type also include those headers when they don't really 
need them but only need the type defines to instantiate the object and that's all 
they should have access to. So I think declaring types in the header should only 
be done for types that aren't full devices and are meant to be embedded as part of 
another device or a SoC but otherwise it's better to keep implementation closed 
and local to the object and not expose it unless really needed, that's why these 
are here.


If you insist I can move these but I don't think there's really such 
recommendation and I don't think that's a good idea because of the above.


Maybe it was something that was missed out of the recent documentation updates, but 
you can clearly see this has been the standard pattern for some time, including for 
recent devices such as the xlnx-versal. If there are any devices that don't follow 
this pattern then it is likely because they are based on older code.


If you disagree with this, then start a new thread on qemu-devel with a new 
proposal and if everyone is agreement then that will be become the new standard.


I think you should start a thread with a patch to style or qom docs about this to 
document this standard and if that's accepted then I also accept it as a real 
recommendation as my understanding of it was as above that it was needed for some 
deviecs to allow embedding them but not a general recommendation for all devices and 
I don't think it should be beacuse of braeaking encapsulation and introduces a lot of 
unneded includes so I'd keep it to those devices where it'e really needed which is 
what the docs currently say.


Oh is there already a mention of this somewhere in the docs? Can you provide a link 
so we can check the wording? Certainly that's the way my own patches (and other 
people's patches) have been reviewed historically over the years.


But I also said I can change this if you insist as for just this devices only used 
once it does not matter much so I take that as you still want this chnage so I can 
send another version but wait 

Re: [PATCH 1/3] via-ide: Fix legacy mode emulation

2023-10-09 Thread BALATON Zoltan

On Mon, 9 Oct 2023, Mark Cave-Ayland wrote:

On 08/10/2023 12:08, BALATON Zoltan wrote:


On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The initial value for BARs were set in reset method for emulating
legacy mode at start but this does not work because PCI code resets
BARs after calling device reset method.


This is certainly something I've noticed when testing previous versions of 
the VIA patches. Perhaps it's worth a separate thread to the PCI devs?


I think I brought up this back then but was told current PCI code won't 
change and since that could break everything else that makes sense so this 
is something that we should take as given and accomodate that.


I don't remember the details of that thread, but that's not too much of an 
issue here as the values won't be used.



Additionally the values
written to BARs were also wrong.


I don't believe this is correct: according to the datasheet the values on 
reset are the ones given in the current reset code, so even if the reset 
function is overridden at a later data during PCI bus reset, I would leave 
these for now since it is a different issue.


Those values are missing the IO space bit for one so they can't be correct 
as a BAR value no matter what the datasheet says. And since they are 
ineffective now I think it's best to remove them to avoid confusion.


Maybe, or perhaps just fix up the missing IO space bit and add a comment 
pointing out these are the defaults, but currently they are erased on PCI bus 
reset? I have found it useful to have the values around to save having to 
reference the datasheet.


The data sheet does not list the io space bits so fixing that would lead 
to values not matching data sheet any more. Also the defaults in the data 
sheet don't make much sense even with io space but as some of them match 
legacy ports while others don't. I can either drop this hunk leaving the 
current values there or add a FIXME comment saying they are ineffective 
but because they are overwritten (either by PCI code now or firmware/guest 
later) I think it's best to remove them any maybe only bring them back if 
we find they would be needed for any guest and what would be the correct 
default valuss here. I don't trust the data sheet on that and getting it 
from real hardware is also not really possible because the firmware could 
have overwritten them by the time you can get them. So I don't think 
keeping these here would help anybody, just cause confusion.



Move setting the BARs to a callback on writing the PCI config regsiter
that sets the compatibility mode (which firmwares needing this mode
seem to do) and fix their values to program it to use legacy port
numbers. As noted in a comment, we only do this when the BARs were
unset before, because logs from real machine show this is how real
chip works, even if it contradicts the data sheet which is not very
clear about this.

Signed-off-by: BALATON Zoltan 
---
  hw/ide/via.c | 35 ++-
  1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index fff23803a6..8186190207 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -132,11 +132,6 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
   PCI_STATUS_DEVSEL_MEDIUM);
  -    pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, 0x01f0);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_1, 0x03f4);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x0170);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x0374);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0xcc01); /* BMIBA: 
20-23h */

  pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x010e);
    /* IDE chip enable, IDE configuration 1/2, IDE FIFO 
Configuration*/

@@ -159,6 +154,35 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_long(pci_conf + 0xc0, 0x00020001);
  }
  +static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr,
+  uint32_t val, int len)
+{
+    pci_default_write_config(pd, addr, val, len);
+    /*
+ * Only set BARs if they are unset. Logs from real hardware show 
that
+ * writing class_prog to enable compatibility mode after BARs were 
set
+ * (possibly by firmware) it will use ports set by BARs not ISA 
ports
+ * (e.g. pegasos2 Linux does this and calls it non-100% native 
mode).


Can you remind me again where the references are to non-100% native mode? 
The only thing I can find in Linux is 
https://github.com/torvalds/linux/blob/master/arch/powerpc/platforms/chrp/pci.c#L360 
but that simply forces a switch to legacy mode, with no mention of 
"non-100% native mode".


It was discussed somewhere in the via-ide thread we had when this was last 
touched for pegasos2 in March 2020. Basically the non-100% native mode is 
when ports are set by BARs but IRQs are still hard coded to 14-15. Linux 
can work with all 3 

Re: [PATCH v4 03/10] hw/fsi: Introduce IBM's cfam,fsi-slave

2023-10-09 Thread Ninad Palsule

Hello Cedric,

Thanks for the review.

On 9/11/23 07:19, Cédric Le Goater wrote:

On 9/9/23 00:28, Ninad Palsule wrote:

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.

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 
---
v2:
- Incorporated Joel's review comments.
v3:
- Incorporated Thomas Huth's review comments.
---
  hw/fsi/Kconfig |   9 ++
  hw/fsi/cfam.c  | 238 +
  hw/fsi/fsi-slave.c | 109 +
  hw/fsi/meson.build |   2 +
  hw/fsi/trace-events    |   5 +
  include/hw/fsi/cfam.h  |  61 ++
  include/hw/fsi/fsi-slave.h |  29 +
  7 files changed, 453 insertions(+)
  create mode 100644 hw/fsi/cfam.c
  create mode 100644 hw/fsi/fsi-slave.c
  create mode 100644 hw/fsi/trace-events
  create mode 100644 include/hw/fsi/cfam.h
  create mode 100644 include/hw/fsi/fsi-slave.h

diff --git a/hw/fsi/Kconfig b/hw/fsi/Kconfig
index 2a9c49f2c9..087980be22 100644
--- a/hw/fsi/Kconfig
+++ b/hw/fsi/Kconfig
@@ -1,3 +1,12 @@
+config CFAM
+    bool
+    select FSI
+    select SCRATCHPAD
+    select LBUS
+
+config FSI
+    bool
+
  config SCRATCHPAD
  bool
  select LBUS
diff --git a/hw/fsi/cfam.c b/hw/fsi/cfam.c
new file mode 100644
index 00..9a9e65d33f
--- /dev/null
+++ b/hw/fsi/cfam.c
@@ -0,0 +1,238 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2023 IBM Corp.
+ *
+ * IBM Common FRU Access Macro
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "trace.h"
+
+#include "hw/fsi/bits.h"
+#include "hw/fsi/cfam.h"
+#include "hw/fsi/engine-scratchpad.h"
+
+#include "hw/qdev-properties.h"
+
+#define TO_REG(x)  ((x) >> 2)
+
+#define CFAM_ENGINE_CONFIG  TO_REG(0x04)
+
+#define CFAM_CONFIG_CHIP_ID    TO_REG(0x00)
+#define CFAM_CONFIG_CHIP_ID_P9 0xc0022d15
+#define   CFAM_CONFIG_CHIP_ID_BREAK    0xc0de
+
+static uint64_t cfam_config_read(void *opaque, hwaddr addr, unsigned 
size)

+{
+    CFAMConfig *config;
+    CFAMState *cfam;
+    LBusNode *node;
+    int i;
+
+    config = CFAM_CONFIG(opaque);
+    cfam = container_of(config, CFAMState, config);
+
+    trace_cfam_config_read(addr, size);
+
+    assert(size == 4);
+    assert(!(addr & 3));



These checks are useless if the MemoryRegionOps is defined accordingly.
Good suggestion. Updated MemoryRegionOps registration and removed these 
asserts.



+
+    switch (addr) {
+    case 0x00:
+    return CFAM_CONFIG_CHIP_ID_P9;
+    case 0x04:
+    return ENGINE_CONFIG_NEXT
+    | 0x0001    /* slots */
+    | 0x1000    /* version */
+    | ENGINE_CONFIG_TYPE_PEEK   /* type */
+    | 0x000c;   /* crc */
+    case 0x08:
+    return ENGINE_CONFIG_NEXT
+    | 0x0001    /* slots */
+    | 0x5000    /* version */
+    | ENGINE_CONFIG_TYPE_FSI    /* type */
+    | 0x000a;   /* crc */
+    break;
+    default:
+    /* FIXME: Improve this */


This looks hacky. What is it suppose to do ?
Yes, This is kind of work in progress. Looks like it is expecting 
address 0xc onwards devices and if we find any device then it will 
return config data for that device otherwise its a bad things and sends 
a break to reset.




+    i = 0xc;
+    QLIST_FOREACH(node, >lbus.devices, next) {
+    if (i == addr) {
+    return LBUS_DEVICE_GET_CLASS(node->ldev)->config;
+    }
+    i += size;
+    }
+
+    if (i == addr) {
+    return 0;
+    }
+
+    /*
+ * As per FSI specification, This is a magic value at 
address 0 of
+ * given FSI port. This causes FSI master to send BREAK 
command for

+ * initialization and recovery.
+ */
+    return 0xc0de;


we could use a definition.

Fixed



+    }
+}
+
+static void cfam_config_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned size)
+{
+    CFAMConfig *s = CFAM_CONFIG(opaque);
+
+    trace_cfam_config_write(addr, size, data);
+
+    assert(size == 4);
+    assert(!(addr & 3));


These checks are useless if the MemoryRegionOps is defined accordingly.

Removed.




Re: [PATCH 2/3] hw/pci-host: Add emulation of Mai Logic Articia S

2023-10-09 Thread BALATON Zoltan

On Mon, 9 Oct 2023, Mark Cave-Ayland wrote:

On 08/10/2023 19:08, BALATON Zoltan wrote:

On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The Articia S is a generic chipset supporting several different CPUs
that were used on some PPC boards. This is a minimal emulation of the
parts needed for emulating the AmigaOne board.

Signed-off-by: BALATON Zoltan 
---
  hw/pci-host/Kconfig   |   5 +
  hw/pci-host/articia.c | 266 ++
  hw/pci-host/meson.build   |   2 +
  include/hw/pci-host/articia.h |  17 +++
  4 files changed, 290 insertions(+)
  create mode 100644 hw/pci-host/articia.c
  create mode 100644 include/hw/pci-host/articia.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index a07070eddf..33014c80a4 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -73,6 +73,11 @@ config SH_PCI
  bool
  select PCI
  +config ARTICIA
+    bool
+    select PCI
+    select I8259
+
  config MV64361
  bool
  select PCI
diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
new file mode 100644
index 00..80558e1c47
--- /dev/null
+++ b/hw/pci-host/articia.c
@@ -0,0 +1,266 @@
+/*
+ * Mai Logic Articia S emulation
+ *
+ * Copyright (c) 2023 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/pci/pci_device.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/i2c/bitbang_i2c.h"
+#include "hw/intc/i8259.h"
+#include "hw/pci-host/articia.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaState, ARTICIA)
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaHostState, ARTICIA_PCI_HOST)
+struct ArticiaHostState {
+    PCIDevice parent_obj;
+
+    ArticiaState *as;
+};
+
+/* TYPE_ARTICIA */
+
+struct ArticiaState {
+    PCIHostState parent_obj;
+
+    qemu_irq irq[PCI_NUM_PINS];
+    MemoryRegion io;
+    MemoryRegion mem;
+    MemoryRegion reg;
+
+    bitbang_i2c_interface smbus;
+    uint32_t gpio; /* bits 0-7 in, 8-15 out, 16-23 direction (0 in, 1 
out) */

+    hwaddr gpio_base;
+    MemoryRegion gpio_reg;
+};


These types above should be in the header file and not in the C file, as 
per our current QOM guidelines.


I don't think there's such a guideline, at least I did not find any mention 
of it in style and qom docs. It was necessary to move some type 
declarations to headers for types that are embedded in other objects 
because C needs the struct size for that, but I don't think that should be 
a general thing when it's not needed.


The reason for that is that moving these to the header exposes internal 
object structure to users that should not need to know that so it breaks 
object encapsulation and also needs moving a bunch of includes to the 
header which then makes the users of this type also include those headers 
when they don't really need them but only need the type defines to 
instantiate the object and that's all they should have access to. So I 
think declaring types in the header should only be done for types that 
aren't full devices and are meant to be embedded as part of another device 
or a SoC but otherwise it's better to keep implementation closed and local 
to the object and not expose it unless really needed, that's why these are 
here.


If you insist I can move these but I don't think there's really such 
recommendation and I don't think that's a good idea because of the above.


Maybe it was something that was missed out of the recent documentation 
updates, but you can clearly see this has been the standard pattern for some 
time, including for recent devices such as the xlnx-versal. If there are any 
devices that don't follow this pattern then it is likely because they are 
based on older code.


If you disagree with this, then start a new thread on qemu-devel with a new 
proposal and if everyone is agreement then that will be become the new 
standard.


I think you should start a thread with a patch to style or qom docs about 
this to document this standard and if that's accepted then I also accept 
it as a real recommendation as my understanding of it was as above that it 
was needed for some deviecs to allow embedding them but not a general 
recommendation for all devices and I don't think it should be beacuse of 
braeaking encapsulation and introduces a lot of unneded includes so I'd 
keep it to those devices where it'e really needed which is what the docs 
currently say.


But I also said I can change this if you insist as for just this devices 
only used once it does not matter much so I take that as you still want 
this chnage so I can send another version but wait for the opinion of the 
maintainers if they want anything else changed so I cah do all remaining 
changes in next version.


Regards,
BALATON Zoltan

Re: [PATCH] target/sparc: Clean up global variable shadowing

2023-10-09 Thread Mark Cave-Ayland

On 09/10/2023 10:24, Philippe Mathieu-Daudé wrote:


Fix:

   target/sparc/translate.c:2823:66: error: declaration shadows a variable in 
the global scope [-Werror,-Wshadow]
   static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env tcg_env)
^
   include/tcg/tcg.h:579:17: note: previous declaration is here
   extern TCGv_env tcg_env;
   ^

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

diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index f92ff80ac8..26ed371109 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2820,19 +2820,19 @@ static void gen_fmovq(DisasContext *dc, DisasCompare 
*cmp, int rd, int rs)
  }
  
  #ifndef CONFIG_USER_ONLY

-static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env tcg_env)
+static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env env)
  {
  TCGv_i32 r_tl = tcg_temp_new_i32();
  
  /* load env->tl into r_tl */

-tcg_gen_ld_i32(r_tl, tcg_env, offsetof(CPUSPARCState, tl));
+tcg_gen_ld_i32(r_tl, env, offsetof(CPUSPARCState, tl));
  
  /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */

  tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
  
  /* calculate offset to current trap state from env->ts, reuse r_tl */

  tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
-tcg_gen_addi_ptr(r_tsptr, tcg_env, offsetof(CPUSPARCState, ts));
+tcg_gen_addi_ptr(r_tsptr, env, offsetof(CPUSPARCState, ts));
  
  /* tsptr = env->ts[env->tl & MAXTL_MASK] */

  {


Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.




Re: [PATCH 2/3] hw/pci-host: Add emulation of Mai Logic Articia S

2023-10-09 Thread Mark Cave-Ayland

On 08/10/2023 19:08, BALATON Zoltan wrote:


On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The Articia S is a generic chipset supporting several different CPUs
that were used on some PPC boards. This is a minimal emulation of the
parts needed for emulating the AmigaOne board.

Signed-off-by: BALATON Zoltan 
---
  hw/pci-host/Kconfig   |   5 +
  hw/pci-host/articia.c | 266 ++
  hw/pci-host/meson.build   |   2 +
  include/hw/pci-host/articia.h |  17 +++
  4 files changed, 290 insertions(+)
  create mode 100644 hw/pci-host/articia.c
  create mode 100644 include/hw/pci-host/articia.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index a07070eddf..33014c80a4 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -73,6 +73,11 @@ config SH_PCI
  bool
  select PCI
  +config ARTICIA
+    bool
+    select PCI
+    select I8259
+
  config MV64361
  bool
  select PCI
diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
new file mode 100644
index 00..80558e1c47
--- /dev/null
+++ b/hw/pci-host/articia.c
@@ -0,0 +1,266 @@
+/*
+ * Mai Logic Articia S emulation
+ *
+ * Copyright (c) 2023 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/pci/pci_device.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/i2c/bitbang_i2c.h"
+#include "hw/intc/i8259.h"
+#include "hw/pci-host/articia.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaState, ARTICIA)
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaHostState, ARTICIA_PCI_HOST)
+struct ArticiaHostState {
+    PCIDevice parent_obj;
+
+    ArticiaState *as;
+};
+
+/* TYPE_ARTICIA */
+
+struct ArticiaState {
+    PCIHostState parent_obj;
+
+    qemu_irq irq[PCI_NUM_PINS];
+    MemoryRegion io;
+    MemoryRegion mem;
+    MemoryRegion reg;
+
+    bitbang_i2c_interface smbus;
+    uint32_t gpio; /* bits 0-7 in, 8-15 out, 16-23 direction (0 in, 1 out) */
+    hwaddr gpio_base;
+    MemoryRegion gpio_reg;
+};


These types above should be in the header file and not in the C file, as per our 
current QOM guidelines.


I don't think there's such a guideline, at least I did not find any mention of it in 
style and qom docs. It was necessary to move some type declarations to headers for 
types that are embedded in other objects because C needs the struct size for that, 
but I don't think that should be a general thing when it's not needed.


The reason for that is that moving these to the header exposes internal object 
structure to users that should not need to know that so it breaks object 
encapsulation and also needs moving a bunch of includes to the header which then 
makes the users of this type also include those headers when they don't really need 
them but only need the type defines to instantiate the object and that's all they 
should have access to. So I think declaring types in the header should only be done 
for types that aren't full devices and are meant to be embedded as part of another 
device or a SoC but otherwise it's better to keep implementation closed and local to 
the object and not expose it unless really needed, that's why these are here.


If you insist I can move these but I don't think there's really such recommendation 
and I don't think that's a good idea because of the above.


Maybe it was something that was missed out of the recent documentation updates, but 
you can clearly see this has been the standard pattern for some time, including for 
recent devices such as the xlnx-versal. If there are any devices that don't follow 
this pattern then it is likely because they are based on older code.


If you disagree with this, then start a new thread on qemu-devel with a new proposal 
and if everyone is agreement then that will be become the new standard.



ATB,

Mark.




Re: [PATCH 1/3] via-ide: Fix legacy mode emulation

2023-10-09 Thread Mark Cave-Ayland

On 08/10/2023 12:08, BALATON Zoltan wrote:


On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The initial value for BARs were set in reset method for emulating
legacy mode at start but this does not work because PCI code resets
BARs after calling device reset method.


This is certainly something I've noticed when testing previous versions of the VIA 
patches. Perhaps it's worth a separate thread to the PCI devs?


I think I brought up this back then but was told current PCI code won't change and 
since that could break everything else that makes sense so this is something that we 
should take as given and accomodate that.


I don't remember the details of that thread, but that's not too much of an issue here 
as the values won't be used.



Additionally the values
written to BARs were also wrong.


I don't believe this is correct: according to the datasheet the values on reset are 
the ones given in the current reset code, so even if the reset function is 
overridden at a later data during PCI bus reset, I would leave these for now since 
it is a different issue.


Those values are missing the IO space bit for one so they can't be correct as a BAR 
value no matter what the datasheet says. And since they are ineffective now I think 
it's best to remove them to avoid confusion.


Maybe, or perhaps just fix up the missing IO space bit and add a comment pointing out 
these are the defaults, but currently they are erased on PCI bus reset? I have found 
it useful to have the values around to save having to reference the datasheet.



Move setting the BARs to a callback on writing the PCI config regsiter
that sets the compatibility mode (which firmwares needing this mode
seem to do) and fix their values to program it to use legacy port
numbers. As noted in a comment, we only do this when the BARs were
unset before, because logs from real machine show this is how real
chip works, even if it contradicts the data sheet which is not very
clear about this.

Signed-off-by: BALATON Zoltan 
---
  hw/ide/via.c | 35 ++-
  1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index fff23803a6..8186190207 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -132,11 +132,6 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
   PCI_STATUS_DEVSEL_MEDIUM);
  -    pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, 0x01f0);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_1, 0x03f4);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x0170);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x0374);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0xcc01); /* BMIBA: 20-23h 
*/
  pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x010e);
    /* IDE chip enable, IDE configuration 1/2, IDE FIFO Configuration*/
@@ -159,6 +154,35 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_long(pci_conf + 0xc0, 0x00020001);
  }
  +static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr,
+  uint32_t val, int len)
+{
+    pci_default_write_config(pd, addr, val, len);
+    /*
+ * Only set BARs if they are unset. Logs from real hardware show that
+ * writing class_prog to enable compatibility mode after BARs were set
+ * (possibly by firmware) it will use ports set by BARs not ISA ports
+ * (e.g. pegasos2 Linux does this and calls it non-100% native mode).


Can you remind me again where the references are to non-100% native mode? The only 
thing I can find in Linux is 
https://github.com/torvalds/linux/blob/master/arch/powerpc/platforms/chrp/pci.c#L360 but that simply forces a switch to legacy mode, with no mention of "non-100% native mode".


It was discussed somewhere in the via-ide thread we had when this was last touched 
for pegasos2 in March 2020. Basically the non-100% native mode is when ports are set 
by BARs but IRQs are still hard coded to 14-15. Linux can work with all 3 possible 
modes: legacy (both ports and IRQs are hard coded to ISA values), native (using BARs 
and PCI config 0x3c for a single interrupt for both channels, vt82c686 data sheet 
does not document this but vt8231 has a comment saying native mode only) and non-100% 
native mode where BARs are effective to set port addresses but IRQs don't respect 
0x3c but use 14-15 as in legacy mode. Some machines only work in non-100% native mode 
such as pegasos2 and Linux has some quirks for this. Other OSes running on this 
machine work with what the firmware has set up and can't work with anything else so 
we need to emulate what those OSes want (which matches real hardware) because Linux 
can usually cope anyway. On pegasso2 MorphOS uses BARs but expects IRQ 14-15 which is 
what the firmware also sets up by setting mode to native in the PCI config of the IDE 
func yet IRQs are fixed at 14-15. Linux forces its driver to use legacy 

Re: [PATCH v2 3/3] qom: Link multiple numa nodes to device using a new object

2023-10-09 Thread Alex Williamson
On Mon, 9 Oct 2023 13:30:48 +0100
Jonathan Cameron  wrote:

> On Sun, 8 Oct 2023 01:47:40 +0530
>  wrote:
> 
> > From: Ankit Agrawal 
> > 
> > NVIDIA GPU's support MIG (Mult-Instance GPUs) feature [1], which allows
> > partitioning of the GPU device resources (including device memory) into
> > several (upto 8) isolated instances. Each of the partitioned memory needs
> > a dedicated NUMA node to operate. The partitions are not fixed and they
> > can be created/deleted at runtime.
> > 
> > Unfortunately Linux OS does not provide a means to dynamically 
> > create/destroy
> > NUMA nodes and such feature implementation is not expected to be trivial. 
> > The
> > nodes that OS discovers at the boot time while parsing SRAT remains fixed. 
> > So
> > we utilize the GI Affinity structures that allows association between nodes
> > and devices. Multiple GI structures per BDF is possible, allowing creation 
> > of
> > multiple nodes by exposing unique PXM in each of these structures.
> > 
> > Introducing a new nvidia-acpi-generic-initiator object, which inherits from
> > the generic acpi-generic-initiator object to allow a BDF to be associated 
> > with
> > more than 1 nodes.
> > 
> > An admin can provide the range of nodes using numa-node-start and
> > numa-node-count and link it to a device by providing its id. The following
> > sample creates 8 nodes and link them to the device dev0:
> > 
> > -numa node,nodeid=2 \
> > -numa node,nodeid=3 \
> > -numa node,nodeid=4 \
> > -numa node,nodeid=5 \
> > -numa node,nodeid=6 \
> > -numa node,nodeid=7 \
> > -numa node,nodeid=8 \
> > -numa node,nodeid=9 \
> > -device 
> > vfio-pci-nohotplug,host=0009:01:00.0,bus=pcie.0,addr=04.0,rombar=0,id=dev0 \
> > -object 
> > nvidia-acpi-generic-initiator,id=gi0,device=dev0,numa-node-start=2,numa-node-count=8
> >  \  
> 
> If you go this way, use an array of references to the numa nodes instead of a 
> start and number.
> There is no obvious reason why they should be contiguous that I can see.

Yup, I was looking for other places we allow a list syntax, I only
found fds=a:b:...:z, which is also used for vhostfds=.  I didn't find a
property beyond the string type to hold this though.

> I think it is simpler the other way around though - so have the numa nodes 
> point at the
> vfio-pci-nohotplug device. 

Do you have a syntax you'd propose for this?  I'm having trouble seeing
how it makes things simpler.  Thanks,

Alex

> > [1] https://www.nvidia.com/en-in/technologies/multi-instance-gpu
> > 
> > Signed-off-by: Ankit Agrawal 
> > ---
> >  hw/acpi/acpi-generic-initiator.c | 61 
> >  include/hw/acpi/acpi-generic-initiator.h | 12 +
> >  qapi/qom.json| 24 +-
> >  3 files changed, 95 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/acpi/acpi-generic-initiator.c 
> > b/hw/acpi/acpi-generic-initiator.c
> > index 1ae79639be..8ef887c3a4 100644
> > --- a/hw/acpi/acpi-generic-initiator.c
> > +++ b/hw/acpi/acpi-generic-initiator.c
> > @@ -150,3 +150,64 @@ void build_srat_generic_initiator(GArray *table_data)
> >  }
> >  g_slist_free(list);
> >  }
> > +
> > +static void
> > +nvidia_acpi_generic_initiator_set_node_start(Object *obj, Visitor *v,
> > + const char *name, void 
> > *opaque,
> > + Error **errp)
> > +{
> > +AcpiGenericInitiator *gi = ACPI_GENERIC_INITIATOR(obj);
> > +uint32_t value;
> > +
> > +if (!visit_type_uint32(v, name, , errp)) {
> > +return;
> > +}
> > +
> > +if (value >= MAX_NODES) {
> > +return;
> > +}
> > +
> > +gi->node = value;
> > +}
> > +
> > +static void
> > +nvidia_acpi_generic_initiator_set_node_count(Object *obj, Visitor *v,
> > + const char *name, void 
> > *opaque,
> > + Error **errp)
> > +{
> > +AcpiGenericInitiator *gi = ACPI_GENERIC_INITIATOR(obj);
> > +uint32_t value;
> > +
> > +if (!visit_type_uint32(v, name, , errp)) {
> > +return;
> > +}
> > +
> > +gi->node_count = value;
> > +}
> > +
> > +static void nvidia_acpi_generic_initiator_class_init(ObjectClass *oc, void 
> > *data)
> > +{
> > +object_class_property_add(oc, 
> > NVIDIA_ACPI_GENERIC_INITIATOR_NODE_START_PROP,
> > +  "uint32", NULL,
> > +  nvidia_acpi_generic_initiator_set_node_start,
> > +  NULL, NULL);
> > +object_class_property_add(oc, 
> > NVIDIA_ACPI_GENERIC_INITIATOR_NODE_COUNT_PROP,
> > +  "uint32", NULL,
> > +  nvidia_acpi_generic_initiator_set_node_count,
> > +  NULL, NULL);
> > +}
> > +
> > +static const TypeInfo nvidia_acpi_generic_initiator_info = {
> > +.parent 

Re: [PATCH v12 09/10] migration: Implement MigrateChannelList to hmp migration flow.

2023-10-09 Thread Fabiano Rosas
Het Gala  writes:

> Integrate MigrateChannelList with all transport backends
> (socket, exec and rdma) for both src and dest migration
> endpoints for hmp migration.
>
> Suggested-by: Aravind Retnakaran 
> Signed-off-by: Het Gala 
> ---
>  migration/migration-hmp-cmds.c | 15 +--
>  migration/migration.c  |  5 ++---
>  migration/migration.h  |  3 ++-
>  3 files changed, 17 insertions(+), 6 deletions(-)
>
> diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
> index a2e6a5c51e..21b57f7ed8 100644
> --- a/migration/migration-hmp-cmds.c
> +++ b/migration/migration-hmp-cmds.c
> @@ -441,9 +441,14 @@ void hmp_migrate_incoming(Monitor *mon, const QDict 
> *qdict)
>  {
>  Error *err = NULL;
>  const char *uri = qdict_get_str(qdict, "uri");
> +MigrationChannelList *caps = NULL;
> +g_autoptr(MigrationChannel) channel = NULL;

No g_autoptr here because the list code will already free the channel.

>  
> -qmp_migrate_incoming(uri, false, NULL, );
> +migrate_uri_parse(uri, , );

Need to check the return value of this function.

$ (echo "migrate -d unix:") | ./qemu-system-x86_64 -monitor stdio -display none
QEMU 8.1.50 monitor - type 'help' for more information
(qemu) migrate -d unix:
Segmentation fault (core dumped)

> +QAPI_LIST_PREPEND(caps, channel);
>  
> +qmp_migrate_incoming(NULL, true, caps, );
> +qapi_free_MigrationChannelList(caps);
>  hmp_handle_error(mon, err);
>  }
>  
> @@ -730,9 +735,15 @@ 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(MigrationChannel) channel = NULL;
>  
> -qmp_migrate(uri, false, NULL, !!blk, blk, !!inc, inc,
> +migrate_uri_parse(uri, , );
> +QAPI_LIST_PREPEND(caps, channel);
> +
> +qmp_migrate(NULL, true, caps, !!blk, blk, !!inc, inc,
>   false, false, true, resume, );
> +qapi_free_MigrationChannelList(caps);
>  if (hmp_handle_error(mon, err)) {
>  return;
>  }



Re: [PATCH v2] misc/pca9552: Fix for pca9552 not getting reset

2023-10-09 Thread Cédric Le Goater

Hello Glenn,

On 10/5/23 23:10, Glenn Miles wrote:

Testing of the pca9552 device on the powernv platform
showed that the reset method was not being called when
an instance of the device was realized.  This was causing
the INPUT0/INPUT1 POR values to be incorrect.

Fixed by overriding the parent pca955x_realize method with a
new pca9552_realize method which first calls
the parent pca955x_realize method followed by the
pca9552_reset function.

Signed-off-by: Glenn Miles 
---
  hw/misc/pca9552.c | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index fff19e369a..bc12dced7f 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -384,6 +384,12 @@ static void pca955x_realize(DeviceState *dev, Error **errp)
  qdev_init_gpio_out(dev, s->gpio, k->pin_count);
  }
  
+static void pca9552_realize(DeviceState *dev, Error **errp)

+{
+pca955x_realize(dev, errp);
+pca9552_reset(dev);
+}


This looks wrong. You need both handlers, a realize and a reset.

Thanks,

C.




+
  static Property pca955x_properties[] = {
  DEFINE_PROP_STRING("description", PCA955xState, description),
  DEFINE_PROP_END_OF_LIST(),
@@ -416,7 +422,7 @@ static void pca9552_class_init(ObjectClass *oc, void *data)
  DeviceClass *dc = DEVICE_CLASS(oc);
  PCA955xClass *pc = PCA955X_CLASS(oc);
  
-dc->reset = pca9552_reset;

+dc->realize = pca9552_realize;
  dc->vmsd = _vmstate;
  pc->max_reg = PCA9552_LS3;
  pc->pin_count = 16;





Re: [PATCH v12 00/10] migration: Modify 'migrate' and 'migrate-incoming' QAPI commands for migration

2023-10-09 Thread Fabiano Rosas
Het Gala  writes:

> This is v12 patchset of modified 'migrate' and 'migrate-incoming' QAPI design
> for upstream review.
>
> Would like to thank all the maintainers that actively participated in the v11
> patchset discussion and gave insightful suggestions to improve the patches.
>
> Link to previous upstream community patchset links:
> v1: https://lists.gnu.org/archive/html/qemu-devel/2022-12/msg04339.html
> v2: https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg02106.html
> v3: https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg02473.html
> v4: https://lists.gnu.org/archive/html/qemu-devel/2023-05/msg03064.html
> v5: https://lists.gnu.org/archive/html/qemu-devel/2023-05/msg04845.html
> v6: https://lists.gnu.org/archive/html/qemu-devel/2023-06/msg01251.html
> v7: https://lists.gnu.org/archive/html/qemu-devel/2023-07/msg02027.html
> v8: https://lists.gnu.org/archive/html/qemu-devel/2023-07/msg02770.html
> v9: https://lists.gnu.org/archive/html/qemu-devel/2023-07/msg04216.html
> v10: https://lists.gnu.org/archive/html/qemu-devel/2023-07/msg05022.html
> v11: https://lists.gnu.org/archive/html/qemu-devel/2023-10/msg00740.html
>
> v11 -> v12 changelog:
> ---
> - Resolved double-freeing when using g_autoptr in structures that are
>   nested into another.
> - Overwriting of pointers to an existing allocated memory is solved at
>   various places.
> - Use of g_autoptr caused make check errors in non-error path while going
>   out of scope inside function. Added g_steal_pointer() in the non-error
>   paths wherever required.

Please run make check before sending:
▶ 242/355 qcow2 181  FAIL

You can also push your code to your gitlab and run a pipeline with the
branch.



[PATCH] hw/loongarch: remove global loaderparams variable

2023-10-09 Thread Thomas Weißschuh
Passing the struct around explicitly makes the control-flow more
obvious.

Signed-off-by: Thomas Weißschuh 
---
 hw/loongarch/virt.c | 50 -
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 2629128aeda4..ea7eb408c071 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -47,6 +47,13 @@
 #include "qemu/error-report.h"
 
 
+struct loaderparams {
+uint64_t ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+};
+
 static void virt_flash_create(LoongArchMachineState *lams)
 {
 DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01);
@@ -411,24 +418,17 @@ static const MemoryRegionOps loongarch_virt_pm_ops = {
 }
 };
 
-static struct _loaderparams {
-uint64_t ram_size;
-const char *kernel_filename;
-const char *kernel_cmdline;
-const char *initrd_filename;
-} loaderparams;
-
 static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
 {
 return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
 }
 
-static int64_t load_kernel_info(void)
+static int64_t load_kernel_info(const struct loaderparams *loaderparams)
 {
 uint64_t kernel_entry, kernel_low, kernel_high;
 ssize_t kernel_size;
 
-kernel_size = load_elf(loaderparams.kernel_filename, NULL,
+kernel_size = load_elf(loaderparams->kernel_filename, NULL,
cpu_loongarch_virt_to_phys, NULL,
_entry, _low,
_high, NULL, 0,
@@ -436,7 +436,7 @@ static int64_t load_kernel_info(void)
 
 if (kernel_size < 0) {
 error_report("could not load kernel '%s': %s",
- loaderparams.kernel_filename,
+ loaderparams->kernel_filename,
  load_elf_strerror(kernel_size));
 exit(1);
 }
@@ -728,7 +728,8 @@ static void reset_load_elf(void *opaque)
 }
 }
 
-static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg)
+static void fw_cfg_add_kernel_info(const struct loaderparams *loaderparams,
+   FWCfgState *fw_cfg)
 {
 /*
  * Expose the kernel, the command line, and the initrd in fw_cfg.
@@ -737,36 +738,38 @@ static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg)
  */
 load_image_to_fw_cfg(fw_cfg,
  FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
- loaderparams.kernel_filename,
+ loaderparams->kernel_filename,
  false);
 
-if (loaderparams.initrd_filename) {
+if (loaderparams->initrd_filename) {
 load_image_to_fw_cfg(fw_cfg,
  FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
- loaderparams.initrd_filename, false);
+ loaderparams->initrd_filename, false);
 }
 
-if (loaderparams.kernel_cmdline) {
+if (loaderparams->kernel_cmdline) {
 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
-   strlen(loaderparams.kernel_cmdline) + 1);
+   strlen(loaderparams->kernel_cmdline) + 1);
 fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
-  loaderparams.kernel_cmdline);
+  loaderparams->kernel_cmdline);
 }
 }
 
-static void loongarch_firmware_boot(LoongArchMachineState *lams)
+static void loongarch_firmware_boot(LoongArchMachineState *lams,
+const struct loaderparams *loaderparams)
 {
-fw_cfg_add_kernel_info(lams->fw_cfg);
+fw_cfg_add_kernel_info(loaderparams, lams->fw_cfg);
 }
 
-static void loongarch_direct_kernel_boot(LoongArchMachineState *lams)
+static void loongarch_direct_kernel_boot(LoongArchMachineState *lams,
+ const struct loaderparams 
*loaderparams)
 {
 MachineState *machine = MACHINE(lams);
 int64_t kernel_addr = 0;
 LoongArchCPU *lacpu;
 int i;
 
-kernel_addr = load_kernel_info();
+kernel_addr = load_kernel_info(loaderparams);
 if (!machine->firmware) {
 for (i = 0; i < machine->smp.cpus; i++) {
 lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
@@ -793,6 +796,7 @@ static void loongarch_init(MachineState *machine)
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 CPUState *cpu;
 char *ramName = NULL;
+struct loaderparams loaderparams;
 
 if (!cpu_model) {
 cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
@@ -898,9 +902,9 @@ static void loongarch_init(MachineState *machine)
 /* load the kernel. */
 if (loaderparams.kernel_filename) {
 if (lams->bios_loaded) {
-loongarch_firmware_boot(lams);
+loongarch_firmware_boot(lams, );
 } else {
-loongarch_direct_kernel_boot(lams);
+loongarch_direct_kernel_boot(lams, );
 }
 }
 fdt_add_flash_node(lams);


RE: [PATCH V4 10/10] target/arm/kvm: Write CPU state back to KVM on reset

2023-10-09 Thread Salil Mehta via
Hello,
Perhaps I need to drop this patch from this patch-set as it is ARM specific.
I pulled this from RFC V2 of Virtual CPU Hotplug Support on ARMv8 and is
not required by other architectures trying to implement Virtual CPU Hotplug
Support.

https://lore.kernel.org/qemu-devel/20230926103654.34424-2-salil.me...@huawei.com/

I will retain the Reviewed-by's collected here in the RFC V3 patch-set.

Sorry, for the noise.

Thanks
Salil.

> From: Salil Mehta 
> Sent: Monday, October 9, 2023 9:36 PM
> To: qemu-devel@nongnu.org; qemu-...@nongnu.org
> Cc: Salil Mehta ; m...@kernel.org; jean-
> phili...@linaro.org; Jonathan Cameron ;
> lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; imamm...@redhat.com; andrew.jo...@linux.dev;
> da...@redhat.com; phi...@linaro.org; eric.au...@redhat.com;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> w...@kernel.org; gs...@redhat.com; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: [PATCH V4 10/10] target/arm/kvm: Write CPU state back to KVM on
> reset
> 
> From: Jean-Philippe Brucker 
> 
> When a KVM vCPU is reset following a PSCI CPU_ON call, its power state
> is not synchronized with KVM at the moment. Because the vCPU is not
> marked dirty, we miss the call to kvm_arch_put_registers() that writes
> to KVM's MP_STATE. Force mp_state synchronization.
> 
> Signed-off-by: Jean-Philippe Brucker 
> Signed-off-by: Salil Mehta 
> Reviewed-by: Alex Bennée 
> Reviewed-by: Gavin Shan 
> ---
>  target/arm/kvm.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index b66b936a95..8cb70b9e7c 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -642,11 +642,12 @@ void kvm_arm_cpu_post_load(ARMCPU *cpu)
>  void kvm_arm_reset_vcpu(ARMCPU *cpu)
>  {
>  int ret;
> +CPUState *cs = CPU(cpu);
> 
>  /* Re-init VCPU so that all registers are set to
>   * their respective reset values.
>   */
> -ret = kvm_arm_vcpu_init(CPU(cpu));
> +ret = kvm_arm_vcpu_init(cs);
>  if (ret < 0) {
>  fprintf(stderr, "kvm_arm_vcpu_init failed: %s\n", strerror(-ret));
>  abort();
> @@ -663,6 +664,11 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu)
>   * for the same reason we do so in kvm_arch_get_registers().
>   */
>  write_list_to_cpustate(cpu);
> +/*
> + * Ensure we call kvm_arch_put_registers(). The vCPU isn't marked
> dirty if
> + * it was parked in KVM and is now booting from a PSCI CPU_ON call.
> + */
> +cs->vcpu_dirty = true;
>  }
> 
>  /*
> --
> 2.34.1



Re: [PATCH 3/3] vfio/ccw: Remove redundant definition of TYPE_VFIO_CCW

2023-10-09 Thread Cédric Le Goater

On 10/9/23 20:58, Eric Farman wrote:

On Mon, 2023-10-09 at 10:20 +0800, Zhenzhong Duan wrote:

No functional changes.

Signed-off-by: Zhenzhong Duan 


I see Cedric has already queued this, but FWIW:

Reviewed-by: Eric Farman 


I will take the new tags when I rebase.

Thanks,

C.





---
  include/hw/s390x/vfio-ccw.h | 2 --
  1 file changed, 2 deletions(-)

diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-
ccw.h
index 63a909eb7e..4209d27657 100644
--- a/include/hw/s390x/vfio-ccw.h
+++ b/include/hw/s390x/vfio-ccw.h
@@ -22,6 +22,4 @@
  #define TYPE_VFIO_CCW "vfio-ccw"
  OBJECT_DECLARE_SIMPLE_TYPE(VFIOCCWDevice, VFIO_CCW)
  
-#define TYPE_VFIO_CCW "vfio-ccw"

-
  #endif







RE: [PATCH v2 3/3] target/hexagon: avoid shadowing globals

2023-10-09 Thread Brian Cain


> -Original Message-
> From: Philippe Mathieu-Daudé 
> Sent: Monday, October 9, 2023 1:43 AM
> To: Brian Cain ; qemu-devel@nongnu.org
> Cc: arm...@redhat.com; richard.hender...@linaro.org;
> peter.mayd...@linaro.org; Matheus Bernardino (QUIC)
> ; stefa...@redhat.com; a...@rev.ng;
> a...@rev.ng; Marco Liebel (QUIC) ;
> ltaylorsimp...@gmail.com; Thomas Huth ; Daniel P.
> Berrangé 
> Subject: Re: [PATCH v2 3/3] target/hexagon: avoid shadowing globals
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> On 9/10/23 08:09, Philippe Mathieu-Daudé wrote:
> > Hi Brian,
> >
> > On 6/10/23 00:22, Brian Cain wrote:
> >> The typedef `vaddr` is shadowed by `vaddr` identifiers, so we rename the
> >> identifiers to avoid shadowing the type name.
> >
> > This one surprises me, since we have other occurences:
> >
> > include/exec/memory.h:751:bool memory_get_xlat_addr(IOMMUTLBEntry
> > *iotlb, void **vaddr,
> >  include/qemu/plugin.h:199:void qemu_plugin_vcpu_mem_cb(CPUState
> > *cpu, uint64_t vaddr,
> > target/arm/internals.h:643:G_NORETURN void
> > arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
> > target/i386/tcg/helper-tcg.h:70:G_NORETURN void
> > handle_unaligned_access(CPUX86State *env, vaddr vaddr,
> > ...
> >
> > $ git grep -w vaddr, | wc -l
> >   207
> >
> > What is the error/warning like?
> 
> OK I could reproduce, I suppose you are building with Clang which
> doesn't support shadow-local so you get global warnings too (as
> mentioned in this patch subject...):

No -- I generally build with gcc and only double-check the clang results to 
make sure I don't see any new failures there.

But I've not tested "-Wshadow" with clang yet.  I found these by adding 
"-Wshadow=global" to "-Wshadow=local".  I thought it might be useful to address 
these too while we're here.

> In file included from ../../gdbstub/trace.h:1,
>   from ../../gdbstub/softmmu.c:30:
> trace/trace-gdbstub.h: In function '_nocheck__trace_gdbstub_hit_watchpoint':
> trace/trace-gdbstub.h:903:106: error: declaration of 'vaddr' shadows a
> global declaration [-Werror=shadow]
>903 | static inline void _nocheck__trace_gdbstub_hit_watchpoint(const
> char * type, int cpu_gdb_index, uint64_t vaddr)
>|
>  ~^
> In file included from include/sysemu/accel-ops.h:13,
>   from include/sysemu/cpus.h:4,
>   from ../../gdbstub/softmmu.c:21:
> include/exec/cpu-common.h:21:18: note: shadowed declaration is here
> 21 | typedef uint64_t vaddr;
>|  ^
> trace/trace-gdbstub.h: In function 'trace_gdbstub_hit_watchpoint':
> trace/trace-gdbstub.h:923:96: error: declaration of 'vaddr' shadows a
> global declaration [-Werror=shadow]
>923 | static inline void trace_gdbstub_hit_watchpoint(const char *
> type, int cpu_gdb_index, uint64_t vaddr)
>|
>~^
> include/exec/cpu-common.h:21:18: note: shadowed declaration is here
> 21 | typedef uint64_t vaddr;
>|  ^
> 
> Clang users got confused by this, IIUC Markus and Thomas idea is
> to only enable these warnings for GCC, enforcing them for Clang
> users via CI (until Clang get this option supported). Personally
> I'd rather enable the warning once for all, waiting for Clang
> support (or clean/enable global shadowing for GCC too).

Hopefully it's helpful or at least benign if we address the shadowed globals 
under target/hexagon/ for now, even if "-Wshadow=global" is not enabled.

> See this thread:
> https://lore.kernel.org/qemu-devel/11abc551-188e-85c0-fe55-
> b2b58d351...@redhat.com/
> 
> Regards,
> 
> Phil.


Re: [PATCH] ppc/pnv: Add an I2C master controller model

2023-10-09 Thread Cédric Le Goater

Hello Glenn,

On 10/9/23 20:05, Glenn Miles wrote:

From: Cédric Le Goater 

Not supported :

  . 10 bit addresses
  . multimaster
  . slave

Signed-off-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
[milesg: fixed formatting warning]



Overall it looks good ;)

Some suggestions for the respin :

* Please split the model implementation from the wiring in the board.
  Adding a cover letter would be nice.

* In the commit log, please add more details on the unit being modeled,
  how this I2C unit interacts with the rest of the machine, what is
  modeled, what is not, etc. A simple intro in short.

* Add a SPDX-License-Identifier tag in new files.

Thanks,

C.

PS: I am not getting your emails for some (corporate) reasons.



---
  hw/ppc/meson.build |   1 +
  hw/ppc/pnv.c   |  26 ++
  hw/ppc/pnv_i2c.c   | 678 +
  include/hw/ppc/pnv_chip.h  |   4 +
  include/hw/ppc/pnv_i2c.h   |  39 +++
  include/hw/ppc/pnv_xscom.h |   3 +
  6 files changed, 751 insertions(+)
  create mode 100644 hw/ppc/pnv_i2c.c
  create mode 100644 include/hw/ppc/pnv_i2c.h

diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 7c2c52434a..87b756a701 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -43,6 +43,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files(
'pnv.c',
'pnv_xscom.c',
'pnv_core.c',
+  'pnv_i2c.c',
'pnv_lpc.c',
'pnv_psi.c',
'pnv_occ.c',
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index eb54f93986..32b6d9889d 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1438,6 +1438,10 @@ static void pnv_chip_power9_instance_init(Object *obj)
  object_initialize_child(obj, "pec[*]", >pecs[i],
  TYPE_PNV_PHB4_PEC);
  }
+
+for (i = 0; i < PNV9_CHIP_MAX_I2C; i++) {
+object_initialize_child(obj, "i2c[*]", >i2c[i], TYPE_PNV_I2C);
+}
  }
  
  static void pnv_chip_quad_realize_one(PnvChip *chip, PnvQuad *eq,

@@ -1510,6 +1514,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, 
Error **errp)
  PnvChip *chip = PNV_CHIP(dev);
  Pnv9Psi *psi9 = >psi;
  Error *local_err = NULL;
+int i;
  
  /* XSCOM bridge is first */

  pnv_xscom_realize(chip, PNV9_XSCOM_SIZE, _err);
@@ -1613,6 +1618,27 @@ static void pnv_chip_power9_realize(DeviceState *dev, 
Error **errp)
  error_propagate(errp, local_err);
  return;
  }
+
+/*
+ * I2C
+ * TODO: The number of busses is specific to each platform
+ */
+for (i = 0; i < PNV9_CHIP_MAX_I2C; i++) {
+Object *obj =  OBJECT(>i2c[i]);
+
+object_property_set_int(obj, "engine", i + 1, _fatal);
+object_property_set_int(obj, "num-busses", 1, _fatal);
+object_property_set_link(obj, "chip", OBJECT(chip), _abort);
+if (!qdev_realize(DEVICE(obj), NULL, errp)) {
+return;
+}
+pnv_xscom_add_subregion(chip, PNV9_XSCOM_I2CM_BASE +
+   chip9->i2c[i].engine * PNV9_XSCOM_I2CM_SIZE,
+>i2c[i].xscom_regs);
+qdev_connect_gpio_out(DEVICE(>i2c[i]), 0,
+  qdev_get_gpio_in(DEVICE(>psi),
+   PSIHB9_IRQ_SBE_I2C));
+}
  }
  
  static uint32_t pnv_chip_power9_xscom_pcba(PnvChip *chip, uint64_t addr)

diff --git a/hw/ppc/pnv_i2c.c b/hw/ppc/pnv_i2c.c
new file mode 100644
index 00..8c191912bf
--- /dev/null
+++ b/hw/ppc/pnv_i2c.c
@@ -0,0 +1,678 @@
+/*
+ * QEMU PowerPC PowerNV Processor I2C model
+ *
+ * Copyright (c) 2019-2021, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "sysemu/reset.h"
+
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_chip.h"
+#include "hw/ppc/pnv_i2c.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/fdt.h"
+
+#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  

[PATCH V4 10/10] target/arm/kvm: Write CPU state back to KVM on reset

2023-10-09 Thread Salil Mehta via
From: Jean-Philippe Brucker 

When a KVM vCPU is reset following a PSCI CPU_ON call, its power state
is not synchronized with KVM at the moment. Because the vCPU is not
marked dirty, we miss the call to kvm_arch_put_registers() that writes
to KVM's MP_STATE. Force mp_state synchronization.

Signed-off-by: Jean-Philippe Brucker 
Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Gavin Shan 
---
 target/arm/kvm.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index b66b936a95..8cb70b9e7c 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -642,11 +642,12 @@ void kvm_arm_cpu_post_load(ARMCPU *cpu)
 void kvm_arm_reset_vcpu(ARMCPU *cpu)
 {
 int ret;
+CPUState *cs = CPU(cpu);
 
 /* Re-init VCPU so that all registers are set to
  * their respective reset values.
  */
-ret = kvm_arm_vcpu_init(CPU(cpu));
+ret = kvm_arm_vcpu_init(cs);
 if (ret < 0) {
 fprintf(stderr, "kvm_arm_vcpu_init failed: %s\n", strerror(-ret));
 abort();
@@ -663,6 +664,11 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu)
  * for the same reason we do so in kvm_arch_get_registers().
  */
 write_list_to_cpustate(cpu);
+/*
+ * Ensure we call kvm_arch_put_registers(). The vCPU isn't marked dirty if
+ * it was parked in KVM and is now booting from a PSCI CPU_ON call.
+ */
+cs->vcpu_dirty = true;
 }
 
 /*
-- 
2.34.1




[PATCH V4 09/10] gdbstub: Add helper function to unregister GDB register space

2023-10-09 Thread Salil Mehta via
Add common function to help unregister the GDB Register Space. This shall be
done in context to the CPU unrealization.

Signed-off-by: Salil Mehta 
---
 gdbstub/gdbstub.c  | 15 +++
 include/exec/gdbstub.h |  5 +
 2 files changed, 20 insertions(+)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 349d348c7b..97b89e2d00 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -491,6 +491,21 @@ void gdb_register_coprocessor(CPUState *cpu,
 }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+GDBRegisterState *s, *p;
+
+p = cpu->gdb_regs;
+while (p) {
+s = p;
+p = p->next;
+/* s->xml is static const char so isn't freed */
+g_free(s);
+}
+cpu->gdb_regs = NULL;
+cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
 CPUState *cpu = gdb_get_first_cpu_in_process(p);
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 16a139043f..7d1368d377 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -27,6 +27,11 @@ typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t 
*buf, int reg);
 void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   int num_regs, const char *xml, int g_pos);
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
 
 /**
  * gdbserver_start: start the gdb server
-- 
2.34.1




[PATCH V4 08/10] physmem: Add helper function to destroy CPU AddressSpace

2023-10-09 Thread Salil Mehta via
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
involves destruction of the CPU AddressSpace. Add common function to help
destroy the CPU AddressSpace.

Signed-off-by: Salil Mehta 
---
 include/exec/cpu-common.h |  8 
 include/hw/core/cpu.h |  1 +
 softmmu/physmem.c | 25 +
 3 files changed, 34 insertions(+)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 41788c0bdd..eb56a228a2 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -120,6 +120,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
 const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
 hwaddr len, bool is_write);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 648b5b3586..65d2ae4581 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -355,6 +355,7 @@ struct CPUState {
 QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
 CPUAddressSpace *cpu_ases;
+int cpu_ases_count;
 int num_ases;
 AddressSpace *as;
 MemoryRegion *memory;
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 4f6ca653b3..4dfa0ca66f 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -761,6 +761,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
 if (!cpu->cpu_ases) {
 cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+cpu->cpu_ases_count = cpu->num_ases;
 }
 
 newas = >cpu_ases[asidx];
@@ -774,6 +775,30 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+CPUAddressSpace *cpuas;
+
+assert(asidx < cpu->num_ases);
+assert(asidx == 0 || !kvm_enabled());
+assert(cpu->cpu_ases);
+
+cpuas = >cpu_ases[asidx];
+if (tcg_enabled()) {
+memory_listener_unregister(>tcg_as_listener);
+}
+
+address_space_destroy(cpuas->as);
+g_free_rcu(cpuas->as, rcu);
+
+if (cpu->cpu_ases_count == 1) {
+g_free(cpu->cpu_ases);
+cpu->cpu_ases = NULL;
+}
+
+cpu->cpu_ases_count--;
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
 /* Return the AddressSpace corresponding to the specified index */
-- 
2.34.1




[PATCH V4 07/10] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2023-10-09 Thread Salil Mehta via
ACPI GED shall be used to convey to the guest kernel about any CPU hot-(un)plug
events. Therefore, existing ACPI GED framework inside QEMU needs to be enhanced
to support CPU hotplug state and events.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
---
 hw/acpi/generic_event_device.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 62d504d231..0d5f0140e5 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -239,6 +240,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else {
 acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
 }
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -253,6 +256,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
 acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -266,6 +271,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_unplug_cb(>memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -277,6 +284,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
ACPIOSTInfoList ***list)
 AcpiGedState *s = ACPI_GED(adev);
 
 acpi_memory_ospm_status(>memhp_state, list);
+acpi_cpu_ospm_status(>cpuhp_state, list);
 }
 
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
@@ -291,6 +299,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 sel = ACPI_GED_PWR_DOWN_EVT;
 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+sel = ACPI_GED_CPU_HOTPLUG_EVT;
 } else {
 /* Unknown event. Return without generating interrupt. */
 warn_report("GED: Unsupported event %d. No irq injected", ev);
-- 
2.34.1




[PATCH V4 06/10] hw/acpi: Update GED _EVT method AML with CPU scan

2023-10-09 Thread Salil Mehta via
OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually
results in start of the CPU scan. Scan figures out the CPU and the kind of
event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT
method with the call to \\_SB.CPUS.CSCN

Also, macro CPU_SCAN_METHOD might be referred in other places like during GED
intialization so it makes sense to have its definition placed in some common
header file like cpu_hotplug.h. But doing this can cause compilation break
because of the conflicting macro definitions present in cpu.c and cpu_hotplug.c
and because both these files get compiled due to historic reasons of x86 world
i.e. decision to use legacy(GPE.2)/modern(GED) CPU hotplug interface happens
during runtime [1]. To mitigate above, for now, declare a new common macro
ACPI_CPU_SCAN_METHOD for CPU scan method instead.
(This needs a separate discussion later on for clean-up)

Reference:
[1] 
https://lore.kernel.org/qemu-devel/1463496205-251412-24-git-send-email-imamm...@redhat.com/

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
---
 hw/acpi/cpu.c  | 2 +-
 hw/acpi/generic_event_device.c | 4 
 include/hw/acpi/cpu_hotplug.h  | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 66a71660ec..d7d7b5b8d2 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -322,7 +322,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPUHP_RES_DEVICE  "PRES"
 #define CPU_LOCK  "CPLK"
 #define CPU_STS_METHOD"CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
+#define CPU_SCAN_METHOD   ACPI_CPU_SCAN_METHOD
 #define CPU_NOTIFY_METHOD "CTFY"
 #define CPU_EJECT_METHOD  "CEJ0"
 #define CPU_OST_METHOD"COST"
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index d2fa1d0e4a..62d504d231 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -108,6 +108,10 @@ void build_ged_aml(Aml *table, const char *name, 
HotplugHandler *hotplug_dev,
 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
  MEMORY_SLOT_SCAN_METHOD));
 break;
+case ACPI_GED_CPU_HOTPLUG_EVT:
+aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "."
+ ACPI_CPU_SCAN_METHOD));
+break;
 case ACPI_GED_PWR_DOWN_EVT:
 aml_append(if_ctx,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 48b291e45e..ef631750b4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,8 @@
 #include "hw/acpi/cpu.h"
 
 #define ACPI_CPU_HOTPLUG_REG_LEN 12
+#define ACPI_CPU_SCAN_METHOD "CSCN"
+#define ACPI_CPU_CONTAINER "\\_SB.CPUS"
 
 typedef struct AcpiCpuHotplug {
 Object *device;
-- 
2.34.1




[PATCH V4 05/10] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2023-10-09 Thread Salil Mehta via
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is based on
PCI and is IO port based and hence existing CPUs AML code assumes _CRS objects
would evaluate to a system resource which describes IO Port address. But on ARM
arch CPUs control device(\\_SB.PRES) register interface is memory-mapped hence
_CRS object should evaluate to system resource which describes memory-mapped
base address. Update build CPUs AML function to accept both IO/MEMORY region
spaces and accordingly update the _CRS object.

Legacy CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event handler to
notify OSPM about any CPU hot(un)plug events. GED framework uses new register
interface for cpu-(ctrl)dev. Make AML for GPE.2 event handler conditional.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
---
 hw/acpi/cpu.c | 23 ---
 hw/i386/acpi-build.c  |  2 +-
 include/hw/acpi/cpu.h |  5 +++--
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 45defdc0e2..66a71660ec 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -338,9 +338,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-hwaddr io_base,
+hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method)
+const char *event_handler_method,
+AmlRegionSpace rs)
 {
 Aml *ifctx;
 Aml *field;
@@ -367,13 +368,19 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
 crs = aml_resource_template();
-aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+if (rs == AML_SYSTEM_IO) {
+aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
ACPI_CPU_HOTPLUG_REG_LEN));
+} else {
+aml_append(crs, aml_memory32_fixed(base_addr,
+   ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+}
+
 aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
 /* declare CPU hotplug MMIO region with related access fields */
 aml_append(cpu_ctrl_dev,
-aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+aml_operation_region("PRST", rs, aml_int(base_addr),
  ACPI_CPU_HOTPLUG_REG_LEN));
 
 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -699,9 +706,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(sb_scope, cpus_dev);
 aml_append(table, sb_scope);
 
-method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-aml_append(table, method);
+if (event_handler_method) {
+method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
+aml_append(table, method);
+}
 
 g_free(cphp_res_path);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4d2d40bab5..611d3d044d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1550,7 +1550,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
 };
 build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
-   "\\_SB.PCI0", "\\_GPE._E02");
+   "\\_SB.PCI0", "\\_GPE._E02", AML_SYSTEM_IO);
 }
 
 if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index 999caaf510..b87ebfdf4b 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -56,9 +56,10 @@ typedef struct CPUHotplugFeatures {
 } CPUHotplugFeatures;
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-hwaddr io_base,
+hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method);
+const char *event_handler_method,
+AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
 
-- 
2.34.1




[PATCH V4 02/10] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2023-10-09 Thread Salil Mehta via
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
appropriate common header file.

Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
---
 hw/acpi/cpu.c | 2 +-
 include/hw/acpi/cpu_hotplug.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 19c154d78f..45defdc0e2 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -1,12 +1,12 @@
 #include "qemu/osdep.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-acpi.h"
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932a..48b291e45e 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -19,6 +19,8 @@
 #include "hw/hotplug.h"
 #include "hw/acpi/cpu.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuHotplug {
 Object *device;
 MemoryRegion io;
-- 
2.34.1




[PATCH V4 03/10] hw/acpi: Add ACPI CPU hotplug init stub

2023-10-09 Thread Salil Mehta via
ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
stub to avoid compilation break.

Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
---
 hw/acpi/acpi-cpu-hotplug-stub.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index 3fc4b14c26..c6c61bb9cd 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+ CPUHotplugState *state, hwaddr base_addr)
+{
+return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
 return;
-- 
2.34.1




[PATCH V4 04/10] hw/acpi: Init GED framework with CPU hotplug events

2023-10-09 Thread Salil Mehta via
ACPI GED(as described in the ACPI 6.2 spec) can be used to generate ACPI events
when OSPM/guest receives an interrupt listed in the _CRS object of GED. OSPM
then maps or demultiplexes the event by evaluating _EVT method.

This change adds the support of CPU hotplug event initialization in the
existing GED framework.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
---
 hw/acpi/generic_event_device.c | 8 
 include/hw/acpi/generic_event_device.h | 5 +
 2 files changed, 13 insertions(+)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index a3d31631fe..d2fa1d0e4a 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -25,6 +25,7 @@ static const uint32_t ged_supported_events[] = {
 ACPI_GED_MEM_HOTPLUG_EVT,
 ACPI_GED_PWR_DOWN_EVT,
 ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ACPI_GED_CPU_HOTPLUG_EVT,
 };
 
 /*
@@ -400,6 +401,13 @@ static void acpi_ged_initfn(Object *obj)
 memory_region_init_io(_st->regs, obj, _regs_ops, ged_st,
   TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT);
 sysbus_init_mmio(sbd, _st->regs);
+
+s->cpuhp.device = OBJECT(s);
+memory_region_init(>container_cpuhp, OBJECT(dev), "cpuhp container",
+   ACPI_CPU_HOTPLUG_REG_LEN);
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), >container_cpuhp);
+cpu_hotplug_hw_init(>container_cpuhp, OBJECT(dev),
+>cpuhp_state, 0);
 }
 
 static void acpi_ged_class_init(ObjectClass *class, void *data)
diff --git a/include/hw/acpi/generic_event_device.h 
b/include/hw/acpi/generic_event_device.h
index d831bbd889..d0a5a43abf 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -60,6 +60,7 @@
 #define HW_ACPI_GENERIC_EVENT_DEVICE_H
 
 #include "hw/sysbus.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/ghes.h"
 #include "qom/object.h"
@@ -97,6 +98,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
 #define ACPI_GED_MEM_HOTPLUG_EVT   0x1
 #define ACPI_GED_PWR_DOWN_EVT  0x2
 #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
+#define ACPI_GED_CPU_HOTPLUG_EVT0x8
 
 typedef struct GEDState {
 MemoryRegion evt;
@@ -108,6 +110,9 @@ struct AcpiGedState {
 SysBusDevice parent_obj;
 MemHotplugState memhp_state;
 MemoryRegion container_memhp;
+CPUHotplugState cpuhp_state;
+MemoryRegion container_cpuhp;
+AcpiCpuHotplug cpuhp;
 GEDState ged_state;
 uint32_t ged_event_bitmap;
 qemu_irq irq;
-- 
2.34.1




[PATCH V4 01/10] accel/kvm: Extract common KVM vCPU {creation, parking} code

2023-10-09 Thread Salil Mehta via
KVM vCPU creation is done once during the initialization of the VM when Qemu
thread is spawned. This is common to all the architectures.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed and its
representative KVM vCPU object/context in Qemu is parked.

Refactor common logic so that some APIs could be reused by vCPU Hotplug code.

Signed-off-by: Salil Mehta 
---
 accel/kvm/kvm-all.c| 64 --
 accel/kvm/trace-events |  4 +++
 include/sysemu/kvm.h   | 16 +++
 3 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index ff1578bb32..0dcaa15276 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -137,6 +137,7 @@ static QemuMutex kml_slots_lock;
 #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
 
 static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
+static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
 
 static inline void kvm_resample_fd_remove(int gsi)
 {
@@ -320,14 +321,53 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_get_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-DPRINTF("kvm_destroy_vcpu\n");
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -353,10 +393,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -377,6 +414,8 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 if (cpu->vcpu_id == vcpu_id) {
 int kvm_fd;
 
+trace_kvm_get_vcpu(vcpu_id);
+
 QLIST_REMOVE(cpu, node);
 kvm_fd = cpu->kvm_fd;
 g_free(cpu);
@@ -384,7 +423,7 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 }
 }
 
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
+return -ENOENT;
 }
 
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
@@ -395,19 +434,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+ret = kvm_create_vcpu(cpu);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  kvm_arch_vcpu_id(cpu));
 goto err;
 }
 
-cpu->kvm_fd = ret;
-cpu->kvm_state = s;
-cpu->vcpu_dirty = true;
-cpu->dirty_pages = 0;
-cpu->throttle_us_per_full = 0;
-
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
 ret = mmap_size;
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
index 399aaeb0ec..08e2dc253f 100644
--- a/accel/kvm/trace-events
+++ b/accel/kvm/trace-events
@@ -9,6 +9,10 @@ kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 
0x%x, arg %p"
 kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve 
ONEREG %" PRIu64 " from KVM: %s"
 kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set 
ONEREG %" PRIu64 " to KVM: %s"
 kvm_init_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
+kvm_create_vcpu(int cpu_index, unsigned long arch_cpu_id) "creating KVM cpu: 
cpu_index: %d arch vcpu-id: %lu"
+kvm_get_vcpu(unsigned long arch_cpu_id) "unparking KVM vcpu: arch vcpu-id: %lu"
+kvm_destroy_vcpu(int cpu_index, unsigned long arch_cpu_id) "destroy vcpu: 
cpu_index: %d arch 

[PATCH V4 00/10] Add architecture agnostic code to support vCPU Hotplug

2023-10-09 Thread Salil Mehta via
Virtual CPU hotplug support is being added across various architectures[1][3].
This series adds various code bits common across all architectures:

1. vCPU creation and Parking code refactor [Patch 1]
2. Update ACPI GED framework to support vCPU Hotplug [Patch 4,6,7]
3. ACPI CPUs AML code change [Patch 5]
4. Helper functions to support unrealization of CPU objects [Patch 8,9]
5. Misc [Patch 2,3,10]


Repository:

[*] https://github.com/salil-mehta/qemu.git virt-cpuhp-armv8/rfc-v2.common.v4


Revision History:

RFC V3 -> RFC V4
1. Addressed David Hilderbrand's comments
   - Fixed the wrong doc comment of kvm_park_vcpu API prototype
   - Added Reviewed-by tags for patches {2,4}
Link: 
https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/

RFC V2 -> RFC V3
1. Addressed Jonathan Cameron's comments
   - Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to 'integer'
   - Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
   - Updated [Patch V2 03/10] commit-log with details of ACPI_CPU_SCAN_METHOD 
macro
   - Updated [Patch V2 05/10] commit-log with details of conditional event 
handler method
   - Added Reviewed-by tags for patches {2,3,4,6,7}
2. Addressed Gavin Shan's comments
   - Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
   - Fixed return value in kvm_get_vcpu from -1 to -ENOENT
   - Reset the value of 'gdb_num_g_regs' in gdb_unregister_coprocessor_all
   - Fixed the kvm_{create,park}_vcpu prototypes docs
   - Added Reviewed-by tags for patches {2,3,4,5,6,7,9,10}
3. Addressed one earlier missed comment by Alex Bennée in RFC V1
   - Added traces instead of DPRINTF in the newly added and some existing 
functions
Link: 
https://lore.kernel.org/qemu-devel/20230930001933.2660-1-salil.me...@huawei.com/

RFC V1 -> RFC V2
1. Addressed Alex Bennée's comments
   - Refactored the kvm_create_vcpu logic to get rid of goto
   - Added the docs for kvm_{create,park}_vcpu prototypes
   - Splitted the gdbstub and AddressSpace destruction change into separate 
patches
   - Added Reviewed-by tags for patches {2,10}
Link: 
https://lore.kernel.org/qemu-devel/20230929124304.13672-1-salil.me...@huawei.com/

References:

[1] 
https://lore.kernel.org/qemu-devel/20230926100436.28284-1-salil.me...@huawei.com/
[2] https://lore.kernel.org/all/20230913163823.7880-1-james.mo...@arm.com/
[3] 
https://lore.kernel.org/qemu-devel/cover.1695697701.git.lixiang...@loongson.cn/


Jean-Philippe Brucker (1):
  target/arm/kvm: Write CPU state back to KVM on reset

Salil Mehta (9):
  accel/kvm: Extract common KVM vCPU {creation,parking} code
  hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file
  hw/acpi: Add ACPI CPU hotplug init stub
  hw/acpi: Init GED framework with CPU hotplug events
  hw/acpi: Update CPUs AML with cpu-(ctrl)dev change
  hw/acpi: Update GED _EVT method AML with CPU scan
  hw/acpi: Update ACPI GED framework to support vCPU Hotplug
  physmem: Add helper function to destroy CPU AddressSpace
  gdbstub: Add helper function to unregister GDB register space

 accel/kvm/kvm-all.c| 64 --
 accel/kvm/trace-events |  4 ++
 gdbstub/gdbstub.c  | 15 ++
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 +++
 hw/acpi/cpu.c  | 27 +++
 hw/acpi/generic_event_device.c | 22 +
 hw/i386/acpi-build.c   |  2 +-
 include/exec/cpu-common.h  |  8 
 include/exec/gdbstub.h |  5 ++
 include/hw/acpi/cpu.h  |  5 +-
 include/hw/acpi/cpu_hotplug.h  |  4 ++
 include/hw/acpi/generic_event_device.h |  5 ++
 include/hw/core/cpu.h  |  1 +
 include/sysemu/kvm.h   | 16 +++
 softmmu/physmem.c  | 25 ++
 target/arm/kvm.c   |  8 +++-
 16 files changed, 189 insertions(+), 28 deletions(-)

-- 
2.34.1




[PATCH v2 2/3] hw/pci-host: Add emulation of Mai Logic Articia S

2023-10-09 Thread BALATON Zoltan
The Articia S is a generic chipset supporting several different CPUs
that were among others used on some PPC boards. This is a minimal
emulation of the parts needed for emulating the AmigaOne board.

Signed-off-by: BALATON Zoltan 
---
 hw/pci-host/Kconfig   |   5 +
 hw/pci-host/articia.c | 293 ++
 hw/pci-host/meson.build   |   2 +
 include/hw/pci-host/articia.h |  17 ++
 4 files changed, 317 insertions(+)
 create mode 100644 hw/pci-host/articia.c
 create mode 100644 include/hw/pci-host/articia.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index a07070eddf..33014c80a4 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -73,6 +73,11 @@ config SH_PCI
 bool
 select PCI
 
+config ARTICIA
+bool
+select PCI
+select I8259
+
 config MV64361
 bool
 select PCI
diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
new file mode 100644
index 00..f3fcc49f81
--- /dev/null
+++ b/hw/pci-host/articia.c
@@ -0,0 +1,293 @@
+/*
+ * Mai Logic Articia S emulation
+ *
+ * Copyright (c) 2023 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/pci/pci_device.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/i2c/bitbang_i2c.h"
+#include "hw/intc/i8259.h"
+#include "hw/pci-host/articia.h"
+
+/*
+ * This is a minimal emulation of this chip as used in AmigaOne board.
+ * Most features are missing but those are not needed by firmware and guests.
+ */
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaState, ARTICIA)
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaHostState, ARTICIA_PCI_HOST)
+struct ArticiaHostState {
+PCIDevice parent_obj;
+
+ArticiaState *as;
+};
+
+/* TYPE_ARTICIA */
+
+struct ArticiaState {
+PCIHostState parent_obj;
+
+qemu_irq irq[PCI_NUM_PINS];
+MemoryRegion io;
+MemoryRegion mem;
+MemoryRegion reg;
+
+bitbang_i2c_interface smbus;
+uint32_t gpio; /* bits 0-7 in, 8-15 out, 16-23 direction (0 in, 1 out) */
+hwaddr gpio_base;
+MemoryRegion gpio_reg;
+};
+
+static uint64_t articia_gpio_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ArticiaState *s = opaque;
+
+return (s->gpio >> (addr * 8)) & 0xff;
+}
+
+static void articia_gpio_write(void *opaque, hwaddr addr, uint64_t val,
+   unsigned int size)
+{
+ArticiaState *s = opaque;
+uint32_t sh = addr * 8;
+
+if (addr == 0) {
+/* in bits read only? */
+return;
+}
+
+if ((s->gpio & (0xff << sh)) != (val & 0xff) << sh) {
+s->gpio &= ~(0xff << sh | 0xff);
+s->gpio |= (val & 0xff) << sh;
+s->gpio |= bitbang_i2c_set(>smbus, BITBANG_I2C_SDA,
+   s->gpio & BIT(16) ?
+   !!(s->gpio & BIT(8)) : 1);
+if ((s->gpio & BIT(17))) {
+s->gpio &= ~BIT(0);
+s->gpio |= bitbang_i2c_set(>smbus, BITBANG_I2C_SCL,
+   !!(s->gpio & BIT(9)));
+}
+}
+}
+
+static const MemoryRegionOps articia_gpio_ops = {
+.read = articia_gpio_read,
+.write = articia_gpio_write,
+.valid.min_access_size = 1,
+.valid.max_access_size = 1,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static uint64_t articia_reg_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ArticiaState *s = opaque;
+uint64_t ret = UINT_MAX;
+
+switch (addr) {
+case 0xc00cf8:
+ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(s), 0, size);
+break;
+case 0xe00cfc ... 0xe00cff:
+ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(s), addr - 0xe00cfc, 
size);
+break;
+case 0xf0:
+ret = pic_read_irq(isa_pic);
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register read 0x%"
+  HWADDR_PRIx " %d\n", __func__, addr, size);
+break;
+}
+return ret;
+}
+
+static void articia_reg_write(void *opaque, hwaddr addr, uint64_t val,
+  unsigned int size)
+{
+ArticiaState *s = opaque;
+
+switch (addr) {
+case 0xc00cf8:
+pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(s), 0, val, size);
+break;
+case 0xe00cfc ... 0xe00cff:
+pci_host_data_le_ops.write(PCI_HOST_BRIDGE(s), addr, val, size);
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register write 0x%"
+  HWADDR_PRIx " %d <- %"PRIx64"\n", __func__, addr, size, 
val);
+break;
+}
+}
+
+static const MemoryRegionOps articia_reg_ops = {
+.read = articia_reg_read,
+.write = articia_reg_write,
+.valid.min_access_size = 1,
+.valid.max_access_size = 4,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void articia_pcihost_set_irq(void *opaque, int n, int level)
+{
+ArticiaState *s = opaque;
+

[PATCH v2 3/3] hw/ppc: Add emulation of AmigaOne XE board

2023-10-09 Thread BALATON Zoltan
The AmigaOne is a rebranded MAI Teron board that uses U-Boot firmware
with patches to support AmigaOS and is very similar to pegasos2 so can
be easily emulated sharing most code with pegasos2. The reason to
emulate it is that AmigaOS comes in different versions for AmigaOne
and PegasosII which only have drivers for one machine and firmware so
these only run on the specific machine. Adding this board allows
another AmigaOS version to be used reusing already existing peagasos2
emulation. (The AmigaOne was the first of these boards so likely most
widespread which then inspired Pegasos that was later replaced with
PegasosII due to problems with Articia S, so these have a lot of
similarity. Pegasos mainly ran MorphOS while the PegasosII version of
AmigaOS was added later and therefore less common than the AmigaOne
version.)

Signed-off-by: BALATON Zoltan 
---
 MAINTAINERS |   8 ++
 configs/devices/ppc-softmmu/default.mak |   1 +
 hw/ppc/Kconfig  |   7 +
 hw/ppc/amigaone.c   | 164 
 hw/ppc/meson.build  |   2 +
 5 files changed, 182 insertions(+)
 create mode 100644 hw/ppc/amigaone.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7f0e20fde6..03f908c153 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1490,6 +1490,14 @@ F: hw/pci-host/mv64361.c
 F: hw/pci-host/mv643xx.h
 F: include/hw/pci-host/mv64361.h
 
+amigaone
+M: BALATON Zoltan 
+L: qemu-...@nongnu.org
+S: Maintained
+F: hw/ppc/amigaone.c
+F: hw/pci-host/articia.c
+F: include/hw/pci-host/articia.h
+
 Virtual Open Firmware (VOF)
 M: Alexey Kardashevskiy 
 R: David Gibson 
diff --git a/configs/devices/ppc-softmmu/default.mak 
b/configs/devices/ppc-softmmu/default.mak
index a887f5438b..b85fd2bcd7 100644
--- a/configs/devices/ppc-softmmu/default.mak
+++ b/configs/devices/ppc-softmmu/default.mak
@@ -14,6 +14,7 @@ CONFIG_SAM460EX=y
 CONFIG_MAC_OLDWORLD=y
 CONFIG_MAC_NEWWORLD=y
 
+CONFIG_AMIGAONE=y
 CONFIG_PEGASOS2=y
 
 # For PReP
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 5dfbf47ef5..56f0475a8e 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -69,6 +69,13 @@ config SAM460EX
 select USB_OHCI
 select FDT_PPC
 
+config AMIGAONE
+bool
+imply ATI_VGA
+select ARTICIA
+select VT82C686
+select SMBUS_EEPROM
+
 config PEGASOS2
 bool
 imply ATI_VGA
diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c
new file mode 100644
index 00..3589924c8a
--- /dev/null
+++ b/hw/ppc/amigaone.c
@@ -0,0 +1,164 @@
+/*
+ * QEMU Eyetech AmigaOne/Mai Logic Teron emulation
+ *
+ * Copyright (c) 2023 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/datadir.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "hw/ppc/ppc.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "hw/pci-host/articia.h"
+#include "hw/isa/vt82c686.h"
+#include "hw/ide/pci.h"
+#include "hw/i2c/smbus_eeprom.h"
+#include "hw/ppc/ppc.h"
+#include "sysemu/reset.h"
+#include "kvm_ppc.h"
+
+#define BUS_FREQ_HZ 1
+
+/*
+ * Firmware binary available at
+ * 
https://www.hyperion-entertainment.com/index.php/downloads?view=files=28
+ * then "tail -c 524288 updater.image >u-boot-amigaone.bin"
+ *
+ * BIOS emulator in firmware cannot run QEMU vgabios and hangs on it, use
+ * -device VGA,romfile=VGABIOS-lgpl-latest.bin
+ * from http://www.nongnu.org/vgabios/ instead.
+ */
+#define PROM_FILENAME "u-boot-amigaone.bin"
+#define PROM_ADDR 0xfff0
+#define PROM_SIZE (512 * KiB)
+
+static void amigaone_cpu_reset(void *opaque)
+{
+PowerPCCPU *cpu = opaque;
+
+cpu_reset(CPU(cpu));
+cpu_ppc_tb_reset(>env);
+}
+
+static void fix_spd_data(uint8_t *spd)
+{
+uint32_t bank_size = 4 * MiB * spd[31];
+uint32_t rows = bank_size / spd[13] / spd[17];
+spd[3] = ctz32(rows) - spd[4];
+}
+
+static void amigaone_init(MachineState *machine)
+{
+PowerPCCPU *cpu;
+CPUPPCState *env;
+MemoryRegion *rom, *pci_mem, *mr;
+const char *fwname = machine->firmware ?: PROM_FILENAME;
+char *filename;
+ssize_t sz;
+PCIBus *pci_bus;
+Object *via;
+DeviceState *dev;
+I2CBus *i2c_bus;
+uint8_t *spd_data;
+int i;
+
+/* init CPU */
+cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
+env = >env;
+if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
+error_report("Incompatible CPU, only 6xx bus supported");
+exit(1);
+}
+cpu_ppc_tb_init(env, BUS_FREQ_HZ / 4);
+qemu_register_reset(amigaone_cpu_reset, cpu);
+
+/* RAM */
+if (machine->ram_size > 2 * GiB) {
+error_report("RAM size more than 2 GiB is not supported");
+exit(1);
+}
+memory_region_add_subregion(get_system_memory(), 0, machine->ram);
+if (machine->ram_size < 1 * GiB + 32 * KiB) {
+/* Firmware uses this area for startup */
+mr = 

[PATCH v2 0/3] Add emulation of AmigaOne XE board

2023-10-09 Thread BALATON Zoltan
Changes in v2:
- Update comment and commit message in patch 1 (Mark)
- Fix irq mapping in patch 2 (Volker)

Regards,
BALATON Zoltan

BALATON Zoltan (3):
  via-ide: Fix legacy mode emulation
  hw/pci-host: Add emulation of Mai Logic Articia S
  hw/ppc: Add emulation of AmigaOne XE board

 MAINTAINERS |   8 +
 configs/devices/ppc-softmmu/default.mak |   1 +
 hw/ide/via.c|  41 +++-
 hw/pci-host/Kconfig |   5 +
 hw/pci-host/articia.c   | 293 
 hw/pci-host/meson.build |   2 +
 hw/ppc/Kconfig  |   7 +
 hw/ppc/amigaone.c   | 164 +
 hw/ppc/meson.build  |   2 +
 include/hw/pci-host/articia.h   |  17 ++
 10 files changed, 535 insertions(+), 5 deletions(-)
 create mode 100644 hw/pci-host/articia.c
 create mode 100644 hw/ppc/amigaone.c
 create mode 100644 include/hw/pci-host/articia.h

-- 
2.30.9




[PATCH v2 1/3] via-ide: Fix legacy mode emulation

2023-10-09 Thread BALATON Zoltan
The initial value for BARs were set in reset method for emulating
legacy mode at start but this does not work because PCI code resets
BARs after calling device reset method. Remove this ineffective
default to avoid confusion.

Instead move setting the BARs to a callback on writing the PCI config
regsiter that sets legacy mode (which firmwares needing this mode seem
to do) and fix their values to program it to use legacy port numbers
in this case. This does not fully emulate what the data sheet says
(which is not very clear on this) but it implements enogh to allow
both modes as used by firmwares of machines we emulate.

Signed-off-by: BALATON Zoltan 
---
 hw/ide/via.c | 41 -
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index fff23803a6..43e8af8d69 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -132,11 +132,6 @@ static void via_ide_reset(DeviceState *dev)
 pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
  PCI_STATUS_DEVSEL_MEDIUM);
 
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, 0x01f0);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_1, 0x03f4);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x0170);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x0374);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0xcc01); /* BMIBA: 20-23h 
*/
 pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x010e);
 
 /* IDE chip enable, IDE configuration 1/2, IDE FIFO Configuration*/
@@ -159,6 +154,41 @@ static void via_ide_reset(DeviceState *dev)
 pci_set_long(pci_conf + 0xc0, 0x00020001);
 }
 
+static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr,
+  uint32_t val, int len)
+{
+pci_default_write_config(pd, addr, val, len);
+/*
+ * Bits 0 and 2 of the PCI programming interface register select between
+ * legacy and native mode for the two IDE channels. We don't emulate this
+ * because we cannot easily switch between ISA and PCI in QEMU so instead
+ * when guest selects legacy mode we set the PCI BARs to legacy ports which
+ * works the same. We also don't care about setting each channel separately
+ * as no guest is known to do or need that. We only do this when BARs are
+ * unset when writing this register as logs from real hardware show that
+ * setting legacy mode after BARs were set it will still use ports set by
+ * BARs not ISA ports (e.g. pegasos2 Linux does this after firmware set
+ * native mode and programmed BARs and calls it non-100% native mode).
+ * But if 0x8a is written righr after reset without setting BARs then we
+ * want legacy ports (this is done by the AmigaOne firmware).
+ */
+if (addr == PCI_CLASS_PROG && val == 0x8a &&
+pci_get_long(pd->config + PCI_BASE_ADDRESS_0) ==
+PCI_BASE_ADDRESS_SPACE_IO) {
+pci_set_long(pd->config + PCI_BASE_ADDRESS_0, 0x1f0
+ | PCI_BASE_ADDRESS_SPACE_IO);
+pci_set_long(pd->config + PCI_BASE_ADDRESS_1, 0x3f6
+ | PCI_BASE_ADDRESS_SPACE_IO);
+pci_set_long(pd->config + PCI_BASE_ADDRESS_2, 0x170
+ | PCI_BASE_ADDRESS_SPACE_IO);
+pci_set_long(pd->config + PCI_BASE_ADDRESS_3, 0x376
+ | PCI_BASE_ADDRESS_SPACE_IO);
+/* BMIBA: 20-23h */
+pci_set_long(pd->config + PCI_BASE_ADDRESS_4, 0xcc00
+ | PCI_BASE_ADDRESS_SPACE_IO);
+}
+}
+
 static void via_ide_realize(PCIDevice *dev, Error **errp)
 {
 PCIIDEState *d = PCI_IDE(dev);
@@ -221,6 +251,7 @@ static void via_ide_class_init(ObjectClass *klass, void 
*data)
 /* Reason: only works as function of VIA southbridge */
 dc->user_creatable = false;
 
+k->config_write = via_ide_cfg_write;
 k->realize = via_ide_realize;
 k->exit = via_ide_exitfn;
 k->vendor_id = PCI_VENDOR_ID_VIA;
-- 
2.30.9




Re: [PATCH] docs/about: Deprecate the 'next-cube' m68k machine

2023-10-09 Thread Mark Cave-Ayland

On 07/10/2023 08:23, Thomas Huth wrote:

(added Natalia who was the GSoC mentor for the NeXT cube work)


The machine is incomplete, and unfortunately the hoped-for improvements
never happened. So it's maybe best if we mark this machine as deprecated
and finally remove it again in case it gets into the way of a code
refactoring or other reasons.

Signed-off-by: Thomas Huth 
---
  docs/about/deprecated.rst | 8 
  1 file changed, 8 insertions(+)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 3b074b9ed4..2f6dadd12f 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -253,6 +253,14 @@ deprecated; use the new name ``dtb-randomness`` instead. 
The new name
  better reflects the way this property affects all random data within
  the device tree blob, not just the ``kaslr-seed`` node.
  
+``next-cube`` m68k machine (since 8.2)

+''
+
+The machine never got fully implemented and can only show the firmware prompt.
+Given the incomplete state and slow progress on improvements, it might get
+removed again without replacement.
+
+
  Backend options
  ---


I'm torn a bit by this one - on the one hand the NeXT code could do with some love, 
but then given that the code already uses qdev/QOM then there isn't really much in 
the way of maintenance burden. The main concern for me at the moment is the use of 
the old-style memory accessors that pre-date the memory API.


With my latest ESP patches I think it shouldn't be too hard to update the NeXT DMA 
controller to get SCSI working, so perhaps we can leave it for now if it doesn't 
cause too many problems?


Natalia, any comments from your side? In particular what sources did you point Bryce 
towards in order to reverse engineer the NeXT hardware?



ATB,

Mark.




RE: [PATCH v2 3/3] target/hexagon: avoid shadowing globals

2023-10-09 Thread ltaylorsimpson



> -Original Message-
> From: Brian Cain 
> Sent: Sunday, October 8, 2023 7:50 AM
> To: ltaylorsimp...@gmail.com; qemu-devel@nongnu.org
> Cc: arm...@redhat.com; richard.hender...@linaro.org; phi...@linaro.org;
> peter.mayd...@linaro.org; Matheus Bernardino (QUIC)
> ; stefa...@redhat.com; a...@rev.ng;
> a...@rev.ng; Marco Liebel (QUIC) 
> Subject: RE: [PATCH v2 3/3] target/hexagon: avoid shadowing globals
> 
> 
> 
> > -Original Message-
> > From: ltaylorsimp...@gmail.com 
> > Sent: Friday, October 6, 2023 11:01 AM
> > To: Brian Cain ; qemu-devel@nongnu.org
> > Cc: arm...@redhat.com; richard.hender...@linaro.org;
> > phi...@linaro.org; peter.mayd...@linaro.org; Matheus Bernardino (QUIC)
> > ; stefa...@redhat.com; a...@rev.ng;
> > a...@rev.ng; Marco Liebel (QUIC) 
> > Subject: RE: [PATCH v2 3/3] target/hexagon: avoid shadowing globals
> >
> > WARNING: This email originated from outside of Qualcomm. Please be
> > wary of any links or attachments, and do not enable macros.
> >
> > > -Original Message-
> > > From: Brian Cain 
> > > Sent: Thursday, October 5, 2023 4:22 PM
> > > To: qemu-devel@nongnu.org
> > > Cc: bc...@quicinc.com; arm...@redhat.com;
> > > richard.hender...@linaro.org; phi...@linaro.org;
> > > peter.mayd...@linaro.org; quic_mathb...@quicinc.com;
> > > stefa...@redhat.com; a...@rev.ng; a...@rev.ng;
> > > quic_mlie...@quicinc.com; ltaylorsimp...@gmail.com
> > > Subject: [PATCH v2 3/3] target/hexagon: avoid shadowing globals
> > >
> > > The typedef `vaddr` is shadowed by `vaddr` identifiers, so we rename
> > > the identifiers to avoid shadowing the type name.
> > >
> > > The global `cpu_env` is shadowed by local `cpu_env` arguments, so we
> > > rename the function arguments to avoid shadowing the global.
> > >
> > > Signed-off-by: Brian Cain 
> > > ---
> > >  target/hexagon/genptr.c | 56 -
> > >  target/hexagon/genptr.h | 18 
> > >  target/hexagon/mmvec/system_ext_mmvec.c |  4 +-
> > > target/hexagon/mmvec/system_ext_mmvec.h |  2 +-
> > >  target/hexagon/op_helper.c  |  4 +-
> > >  5 files changed, 42 insertions(+), 42 deletions(-)
> > >
> > > diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index
> > > 217bc7bb5a..11377ac92b 100644
> > > --- a/target/hexagon/genptr.c
> > > +++ b/target/hexagon/genptr.c
> > > @@ -334,28 +334,28 @@ void gen_set_byte_i64(int N, TCGv_i64 result,
> > TCGv
> > > src)
> > >  tcg_gen_deposit_i64(result, result, src64, N * 8, 8);  }
> > >
> > > -static inline void gen_load_locked4u(TCGv dest, TCGv vaddr, int
> > > mem_index)
> > > +static inline void gen_load_locked4u(TCGv dest, TCGv v_addr, int
> > > +mem_index)
> >
> > I'd recommend moving both the type and the arg name to the new line,
> > also indent the new line.
> > static inline void gen_load_locked4u(TCGv dest, TCGv v_addr,
> >   int
> > mem_index)
> >
> >
> I could be mistaken but AFAICT none of these lines are wrapped in the way
> they're quoted above  in my patch (nor the baseline).  I don't think any of
> these lines exceed 80 columns, so they shouldn't need wrapping, either.
> 
> I double checked how it's displayed at the archive
> https://lists.gnu.org/archive/html/qemu-devel/2023-10/msg01667.html to
> make sure that it wasn't a misconfiguration of my mailer.  For another
> perspective - refer to the commit used to create this patch:
> https://github.com/quic/qemu/commit/7f20565d403d16337ab6d69ee663121
> a3eef71e6
> 
> Is your review comment that "these lines should be wrapped and when you
> do, make sure you do it like this"?  Or "if you are going to wrap them, wrap
> them like this"?  Or something else?

Yes.  It looked like some adding the v_ would sometimes put the line over the 
80 character size.
If so, wrap them as described.  If not, no wrapping is needed.


> 
> > Otherwise,
> > Reviewed-by: Taylor Simpson 
> >





Re: [PATCH 3/3] vfio/ccw: Remove redundant definition of TYPE_VFIO_CCW

2023-10-09 Thread Eric Farman
On Mon, 2023-10-09 at 10:20 +0800, Zhenzhong Duan wrote:
> No functional changes.
> 
> Signed-off-by: Zhenzhong Duan 

I see Cedric has already queued this, but FWIW:

Reviewed-by: Eric Farman 

> ---
>  include/hw/s390x/vfio-ccw.h | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-
> ccw.h
> index 63a909eb7e..4209d27657 100644
> --- a/include/hw/s390x/vfio-ccw.h
> +++ b/include/hw/s390x/vfio-ccw.h
> @@ -22,6 +22,4 @@
>  #define TYPE_VFIO_CCW "vfio-ccw"
>  OBJECT_DECLARE_SIMPLE_TYPE(VFIOCCWDevice, VFIO_CCW)
>  
> -#define TYPE_VFIO_CCW "vfio-ccw"
> -
>  #endif




[PATCH v2 0/6] scripts/migration: Fix analyze-migration.py and add a test

2023-10-09 Thread Fabiano Rosas
was: [PATCH] qtest/migration: Add a test for the analyze-migration script
https://lore.kernel.org/r/20230927214756.14117-1-faro...@suse.de

The analyze-migration.py script should be kept in sync with the code
that generates the migration stream. The addition/removal of sections
and flags from the stream can cause the script to break. Issues when
parsing the stream mostly manifest in the form of cryptic python
errors such as:

Looking at git log, it seems that this is a fairly useful script for
people debugging issues with the migration stream. Let's add a test
for it to catch bugs early avoid keeping a broken script in the tree.

People suggested putting this in avocado or a dedicated shell
script. I hope looking at the patches it becomes clear that it's best
to have this along with migration-test. Mostly to avoid duplicating
capabilities code and arch-specific flags.

CI run: https://gitlab.com/farosas/qemu/-/pipelines/1030789937

Fabiano Rosas (5):
  migration: Fix analyze-migration.py 'configuration' parsing
  migration: Add capability parsing to analyze-migration.py
  migration: Fix analyze-migration.py when ignore-shared is used
  migration: Fix analyze-migration read operation signedness
  tests/qtest/migration: Add a test for the analyze-migration script

Nikolay Borisov (1):
  migration: Add the configuration vmstate to the json writer

 migration/migration.c|  1 +
 migration/savevm.c   | 20 ---
 scripts/analyze-migration.py | 67 
 tests/qtest/meson.build  |  2 ++
 tests/qtest/migration-test.c | 60 
 5 files changed, 139 insertions(+), 11 deletions(-)

-- 
2.35.3




[PATCH v2 3/6] migration: Add capability parsing to analyze-migration.py

2023-10-09 Thread Fabiano Rosas
The script is broken when the configuration/capabilities section is
present. Add support for parsing the capabilities so we can fix it in
the next patch.

Signed-off-by: Fabiano Rosas 
---
 scripts/analyze-migration.py | 38 
 1 file changed, 38 insertions(+)

diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py
index 24687db497..c700fed64d 100755
--- a/scripts/analyze-migration.py
+++ b/scripts/analyze-migration.py
@@ -264,6 +264,24 @@ class ConfigurationSection(object):
 def __init__(self, file, desc):
 self.file = file
 self.desc = desc
+self.caps = []
+
+def parse_capabilities(self, vmsd_caps):
+if not vmsd_caps:
+return
+
+ncaps = vmsd_caps.data['caps_count'].data
+self.caps = vmsd_caps.data['capabilities']
+
+if type(self.caps) != list:
+self.caps = [self.caps]
+
+if len(self.caps) != ncaps:
+raise Exception("Number of capabilities doesn't match "
+"caps_count field")
+
+def has_capability(self, cap):
+return any([str(c) == cap for c in self.caps])
 
 def read(self):
 if self.desc:
@@ -271,6 +289,8 @@ def read(self):
 section = VMSDSection(self.file, version_id, self.desc,
   'configuration')
 section.read()
+self.parse_capabilities(
+section.data.get("configuration/capabilities"))
 else:
 # backward compatibility for older streams that don't have
 # the configuration section in the json
@@ -297,6 +317,23 @@ def read(self):
 self.data = self.file.readvar(size)
 return self.data
 
+class VMSDFieldCap(object):
+def __init__(self, desc, file):
+self.file = file
+self.desc = desc
+self.data = ""
+
+def __repr__(self):
+return self.data
+
+def __str__(self):
+return self.data
+
+def read(self):
+len = self.file.read8()
+self.data = self.file.readstr(len)
+
+
 class VMSDFieldInt(VMSDFieldGeneric):
 def __init__(self, desc, file):
 super(VMSDFieldInt, self).__init__(desc, file)
@@ -471,6 +508,7 @@ def getDict(self):
 "unused_buffer" : VMSDFieldGeneric,
 "bitmap" : VMSDFieldGeneric,
 "struct" : VMSDFieldStruct,
+"capability": VMSDFieldCap,
 "unknown" : VMSDFieldGeneric,
 }
 
-- 
2.35.3




[PATCH v2 1/6] migration: Add the configuration vmstate to the json writer

2023-10-09 Thread Fabiano Rosas
From: Nikolay Borisov 

Make the migration json writer part of MigrationState struct, allowing
the 'configuration' object be serialized to json.

This will facilitate the parsing of the 'configuration' object in the
next patch that fixes analyze-migration.py for arm.

Signed-off-by: Nikolay Borisov 
Signed-off-by: Fabiano Rosas 
---
farosas: rewrote the commit message. The previous one was tied to
fixed-ram.
---
 migration/migration.c |  1 +
 migration/savevm.c| 20 
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 585d3c8f55..dde8471f83 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1430,6 +1430,7 @@ int migrate_init(MigrationState *s, Error **errp)
 error_free(s->error);
 s->error = NULL;
 s->hostname = NULL;
+s->vmdesc = NULL;
 
 migrate_set_state(>state, MIGRATION_STATUS_NONE, 
MIGRATION_STATUS_SETUP);
 
diff --git a/migration/savevm.c b/migration/savevm.c
index 60eec7c31f..5343cbc234 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1217,13 +1217,27 @@ void qemu_savevm_non_migratable_list(strList **reasons)
 
 void qemu_savevm_state_header(QEMUFile *f)
 {
+MigrationState *s = migrate_get_current();
+
+s->vmdesc = json_writer_new(false);
+
 trace_savevm_state_header();
 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
 
-if (migrate_get_current()->send_configuration) {
+if (s->send_configuration) {
 qemu_put_byte(f, QEMU_VM_CONFIGURATION);
-vmstate_save_state(f, _configuration, _state, 0);
+
+/*
+ * This starts the main json object and is paired with the
+ * json_writer_end_object in
+ * qemu_savevm_state_complete_precopy_non_iterable
+ */
+json_writer_start_object(s->vmdesc, NULL);
+
+json_writer_start_object(s->vmdesc, "configuration");
+vmstate_save_state(f, _configuration, _state, 
s->vmdesc);
+json_writer_end_object(s->vmdesc);
 }
 }
 
@@ -1272,8 +1286,6 @@ void qemu_savevm_state_setup(QEMUFile *f)
 Error *local_err = NULL;
 int ret;
 
-ms->vmdesc = json_writer_new(false);
-json_writer_start_object(ms->vmdesc, NULL);
 json_writer_int64(ms->vmdesc, "page_size", qemu_target_page_size());
 json_writer_start_array(ms->vmdesc, "devices");
 
-- 
2.35.3




[PATCH v2 2/6] migration: Fix analyze-migration.py 'configuration' parsing

2023-10-09 Thread Fabiano Rosas
The 'configuration' state subsections are currently not being parsed
and the script fails when analyzing an aarch64 stream:

Traceback (most recent call last):
  File "./scripts/analyze-migration.py", line 625, in 
dump.read(dump_memory = args.memory)
  File "./scripts/analyze-migration.py", line 571, in read
raise Exception("Unknown section type: %d" % section_type)
Exception: Unknown section type: 5

Signed-off-by: Fabiano Rosas 
---
 scripts/analyze-migration.py | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py
index 082424558b..24687db497 100755
--- a/scripts/analyze-migration.py
+++ b/scripts/analyze-migration.py
@@ -261,12 +261,21 @@ def getDict(self):
 
 
 class ConfigurationSection(object):
-def __init__(self, file):
+def __init__(self, file, desc):
 self.file = file
+self.desc = desc
 
 def read(self):
-name_len = self.file.read32()
-name = self.file.readstr(len = name_len)
+if self.desc:
+version_id = self.desc['version']
+section = VMSDSection(self.file, version_id, self.desc,
+  'configuration')
+section.read()
+else:
+# backward compatibility for older streams that don't have
+# the configuration section in the json
+name_len = self.file.read32()
+name = self.file.readstr(len = name_len)
 
 class VMSDFieldGeneric(object):
 def __init__(self, desc, file):
@@ -532,7 +541,8 @@ def read(self, desc_only = False, dump_memory = False, 
write_memory = False):
 if section_type == self.QEMU_VM_EOF:
 break
 elif section_type == self.QEMU_VM_CONFIGURATION:
-section = ConfigurationSection(file)
+config_desc = self.vmsd_desc.get('configuration')
+section = ConfigurationSection(file, config_desc)
 section.read()
 elif section_type == self.QEMU_VM_SECTION_START or section_type == 
self.QEMU_VM_SECTION_FULL:
 section_id = file.read32()
-- 
2.35.3




[PATCH v2 6/6] tests/qtest/migration: Add a test for the analyze-migration script

2023-10-09 Thread Fabiano Rosas
Add a smoke test that migrates to a file and gives it to the
script. It should catch the most annoying errors such as changes in
the ram flags.

After code has been merged it becomes way harder to figure out what is
causing the script to fail, the person making the change is the most
likely to know right away what the problem is.

Signed-off-by: Fabiano Rosas 
---
 tests/qtest/meson.build  |  2 ++
 tests/qtest/migration-test.c | 60 
 2 files changed, 62 insertions(+)

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 1fba07f4ed..5e82eccb62 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -356,6 +356,8 @@ foreach dir : target_dirs
 test_deps += [qsd]
   endif
 
+  qtest_env.set('PYTHON', python.full_path())
+
   foreach test : target_qtests
 # Executables are shared across targets, declare them only the first time 
we
 # encounter them
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index 46f1c275a2..cb1b6e890c 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -66,6 +66,8 @@ static bool got_dst_resume;
  */
 #define DIRTYLIMIT_TOLERANCE_RANGE  25  /* MB/s */
 
+#define ANALYZE_SCRIPT "scripts/analyze-migration.py"
+
 #if defined(__linux__)
 #include 
 #include 
@@ -1510,6 +1512,61 @@ static void test_baddest(void)
 test_migrate_end(from, to, false);
 }
 
+#ifndef _WIN32
+static void test_analyze_script(void)
+{
+MigrateStart args = {
+.opts_source = "-uuid ----",
+};
+QTestState *from, *to;
+g_autofree char *uri = NULL;
+g_autofree char *file = NULL;
+int pid, wstatus;
+const char *python = g_getenv("PYTHON");
+
+if (!python) {
+g_test_skip("PYTHON variable not set");
+return;
+}
+
+/* dummy url */
+if (test_migrate_start(, , "tcp:127.0.0.1:0", )) {
+return;
+}
+
+/*
+ * Setting these two capabilities causes the "configuration"
+ * vmstate to include subsections for them. The script needs to
+ * parse those subsections properly.
+ */
+migrate_set_capability(from, "validate-uuid", true);
+migrate_set_capability(from, "x-ignore-shared", true);
+
+file = g_strdup_printf("%s/migfile", tmpfs);
+uri = g_strdup_printf("exec:cat > %s", file);
+
+migrate_ensure_converge(from);
+migrate_qmp(from, uri, "{}");
+wait_for_migration_complete(from);
+
+pid = fork();
+if (!pid) {
+close(1);
+open("/dev/null", O_WRONLY);
+execl(python, python, ANALYZE_SCRIPT, "-f", file, NULL);
+g_assert_not_reached();
+}
+
+g_assert(waitpid(pid, , 0) == pid);
+if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0) {
+g_test_message("Failed to analyze the migration stream");
+g_test_fail();
+}
+test_migrate_end(from, to, false);
+cleanup("migfile");
+}
+#endif
+
 static void test_precopy_common(MigrateCommon *args)
 {
 QTestState *from, *to;
@@ -2844,6 +2901,9 @@ int main(int argc, char **argv)
 }
 
 qtest_add_func("/migration/bad_dest", test_baddest);
+#ifndef _WIN32
+qtest_add_func("/migration/analyze-script", test_analyze_script);
+#endif
 qtest_add_func("/migration/precopy/unix/plain", test_precopy_unix_plain);
 qtest_add_func("/migration/precopy/unix/xbzrle", test_precopy_unix_xbzrle);
 /*
-- 
2.35.3




[PATCH v2 4/6] migration: Fix analyze-migration.py when ignore-shared is used

2023-10-09 Thread Fabiano Rosas
The script is currently broken when the x-ignore-shared capability is
used:

Traceback (most recent call last):
  File "./scripts/analyze-migration.py", line 656, in 
dump.read(dump_memory = args.memory)
  File "./scripts/analyze-migration.py", line 593, in read
section.read()
  File "./scripts/analyze-migration.py", line 163, in read
self.name = self.file.readstr(len = namelen)
  File "./scripts/analyze-migration.py", line 53, in readstr
return self.readvar(len).decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 55: 
invalid start byte

We're currently adding data to the middle of the ram section depending
on the presence of the capability. As a consequence, any code loading
the ram section needs to know about capabilities so it can interpret
the stream.

Skip the byte that's added when x-ignore-shared is used to fix the
script.

Signed-off-by: Fabiano Rosas 
---
 scripts/analyze-migration.py | 5 +
 1 file changed, 5 insertions(+)

diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py
index c700fed64d..56ab04dd2d 100755
--- a/scripts/analyze-migration.py
+++ b/scripts/analyze-migration.py
@@ -123,6 +123,7 @@ def __init__(self, file, version_id, ramargs, section_key):
 self.TARGET_PAGE_SIZE = ramargs['page_size']
 self.dump_memory = ramargs['dump_memory']
 self.write_memory = ramargs['write_memory']
+self.ignore_shared = ramargs['ignore_shared']
 self.sizeinfo = collections.OrderedDict()
 self.data = collections.OrderedDict()
 self.data['section sizes'] = self.sizeinfo
@@ -169,6 +170,8 @@ def read(self):
 f.truncate(0)
 f.truncate(len)
 self.files[self.name] = f
+if self.ignore_shared:
+mr_addr = self.file.read64()
 flags &= ~self.RAM_SAVE_FLAG_MEM_SIZE
 
 if flags & self.RAM_SAVE_FLAG_COMPRESS:
@@ -572,6 +575,7 @@ def read(self, desc_only = False, dump_memory = False, 
write_memory = False):
 ramargs['page_size'] = self.vmsd_desc['page_size']
 ramargs['dump_memory'] = dump_memory
 ramargs['write_memory'] = write_memory
+ramargs['ignore_shared'] = False
 self.section_classes[('ram',0)][1] = ramargs
 
 while True:
@@ -582,6 +586,7 @@ def read(self, desc_only = False, dump_memory = False, 
write_memory = False):
 config_desc = self.vmsd_desc.get('configuration')
 section = ConfigurationSection(file, config_desc)
 section.read()
+ramargs['ignore_shared'] = 
section.has_capability('x-ignore-shared')
 elif section_type == self.QEMU_VM_SECTION_START or section_type == 
self.QEMU_VM_SECTION_FULL:
 section_id = file.read32()
 name = file.readstr()
-- 
2.35.3




[PATCH v2 5/6] migration: Fix analyze-migration read operation signedness

2023-10-09 Thread Fabiano Rosas
The migration code uses unsigned values for 16, 32 and 64-bit
operations. Fix the script to do the same.

This was causing an issue when parsing the migration stream generated
on the ppc64 target because one of instance_ids was larger than the
32bit signed maximum:

Traceback (most recent call last):
  File "/home/fabiano/kvm/qemu/build/scripts/analyze-migration.py", line 658, 
in 
dump.read(dump_memory = args.memory)
  File "/home/fabiano/kvm/qemu/build/scripts/analyze-migration.py", line 592, 
in read
classdesc = self.section_classes[section_key]
KeyError: ('spapr_iommu', -2147483648)

Signed-off-by: Fabiano Rosas 
---
 scripts/analyze-migration.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py
index 56ab04dd2d..de506cb8bf 100755
--- a/scripts/analyze-migration.py
+++ b/scripts/analyze-migration.py
@@ -38,13 +38,13 @@ def __init__(self, filename):
 self.file = open(self.filename, "rb")
 
 def read64(self):
-return int.from_bytes(self.file.read(8), byteorder='big', signed=True)
+return int.from_bytes(self.file.read(8), byteorder='big', signed=False)
 
 def read32(self):
-return int.from_bytes(self.file.read(4), byteorder='big', signed=True)
+return int.from_bytes(self.file.read(4), byteorder='big', signed=False)
 
 def read16(self):
-return int.from_bytes(self.file.read(2), byteorder='big', signed=True)
+return int.from_bytes(self.file.read(2), byteorder='big', signed=False)
 
 def read8(self):
 return int.from_bytes(self.file.read(1), byteorder='big', signed=True)
-- 
2.35.3




[PATCH] ppc/pnv: Add an I2C master controller model

2023-10-09 Thread Glenn Miles
From: Cédric Le Goater 

Not supported :

 . 10 bit addresses
 . multimaster
 . slave

Signed-off-by: Cédric Le Goater 
Signed-off-by: Glenn Miles 
[milesg: fixed formatting warning]
---
 hw/ppc/meson.build |   1 +
 hw/ppc/pnv.c   |  26 ++
 hw/ppc/pnv_i2c.c   | 678 +
 include/hw/ppc/pnv_chip.h  |   4 +
 include/hw/ppc/pnv_i2c.h   |  39 +++
 include/hw/ppc/pnv_xscom.h |   3 +
 6 files changed, 751 insertions(+)
 create mode 100644 hw/ppc/pnv_i2c.c
 create mode 100644 include/hw/ppc/pnv_i2c.h

diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 7c2c52434a..87b756a701 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -43,6 +43,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files(
   'pnv.c',
   'pnv_xscom.c',
   'pnv_core.c',
+  'pnv_i2c.c',
   'pnv_lpc.c',
   'pnv_psi.c',
   'pnv_occ.c',
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index eb54f93986..32b6d9889d 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1438,6 +1438,10 @@ static void pnv_chip_power9_instance_init(Object *obj)
 object_initialize_child(obj, "pec[*]", >pecs[i],
 TYPE_PNV_PHB4_PEC);
 }
+
+for (i = 0; i < PNV9_CHIP_MAX_I2C; i++) {
+object_initialize_child(obj, "i2c[*]", >i2c[i], TYPE_PNV_I2C);
+}
 }
 
 static void pnv_chip_quad_realize_one(PnvChip *chip, PnvQuad *eq,
@@ -1510,6 +1514,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, 
Error **errp)
 PnvChip *chip = PNV_CHIP(dev);
 Pnv9Psi *psi9 = >psi;
 Error *local_err = NULL;
+int i;
 
 /* XSCOM bridge is first */
 pnv_xscom_realize(chip, PNV9_XSCOM_SIZE, _err);
@@ -1613,6 +1618,27 @@ static void pnv_chip_power9_realize(DeviceState *dev, 
Error **errp)
 error_propagate(errp, local_err);
 return;
 }
+
+/*
+ * I2C
+ * TODO: The number of busses is specific to each platform
+ */
+for (i = 0; i < PNV9_CHIP_MAX_I2C; i++) {
+Object *obj =  OBJECT(>i2c[i]);
+
+object_property_set_int(obj, "engine", i + 1, _fatal);
+object_property_set_int(obj, "num-busses", 1, _fatal);
+object_property_set_link(obj, "chip", OBJECT(chip), _abort);
+if (!qdev_realize(DEVICE(obj), NULL, errp)) {
+return;
+}
+pnv_xscom_add_subregion(chip, PNV9_XSCOM_I2CM_BASE +
+   chip9->i2c[i].engine * PNV9_XSCOM_I2CM_SIZE,
+>i2c[i].xscom_regs);
+qdev_connect_gpio_out(DEVICE(>i2c[i]), 0,
+  qdev_get_gpio_in(DEVICE(>psi),
+   PSIHB9_IRQ_SBE_I2C));
+}
 }
 
 static uint32_t pnv_chip_power9_xscom_pcba(PnvChip *chip, uint64_t addr)
diff --git a/hw/ppc/pnv_i2c.c b/hw/ppc/pnv_i2c.c
new file mode 100644
index 00..8c191912bf
--- /dev/null
+++ b/hw/ppc/pnv_i2c.c
@@ -0,0 +1,678 @@
+/*
+ * QEMU PowerPC PowerNV Processor I2C model
+ *
+ * Copyright (c) 2019-2021, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "sysemu/reset.h"
+
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_chip.h"
+#include "hw/ppc/pnv_i2c.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/fdt.h"
+
+#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
+ * 

Re: [PATCH 2/3] target/riscv: Support discontinuous PMU counters

2023-10-09 Thread Atish Kumar Patra
On Sun, Oct 8, 2023 at 5:58 PM Alistair Francis  wrote:
>
> On Wed, Oct 4, 2023 at 7:36 PM Rob Bradford  wrote:
> >
> > Hi Atish,
> >
> > On Tue, 2023-10-03 at 13:25 -0700, Atish Kumar Patra wrote:
> > > On Tue, Oct 3, 2023 at 5:51 AM Rob Bradford 
> > > wrote:
> > > >
> > > > There is no requirement that the enabled counters in the platform
> > > > are
> > > > continuously numbered. Add a "pmu-mask" property that, if
> > > > specified, can
> > > > be used to specify the enabled PMUs. In order to avoid ambiguity if
> > > > "pmu-mask" is specified then "pmu-num" must also match the number
> > > > of
> > > > bits set in the mask.
> > > >
> > > > Signed-off-by: Rob Bradford 
> > > > ---
> > > >  target/riscv/cpu.c |  1 +
> > > >  target/riscv/cpu_cfg.h |  1 +
> > > >  target/riscv/pmu.c | 15 +--
> > > >  3 files changed, 15 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > > > index 9d79c20c1a..b89b006a76 100644
> > > > --- a/target/riscv/cpu.c
> > > > +++ b/target/riscv/cpu.c
> > > > @@ -1817,6 +1817,7 @@ static void
> > > > riscv_cpu_add_misa_properties(Object *cpu_obj)
> > > >  static Property riscv_cpu_extensions[] = {
> > > >  /* Defaults for standard extensions */
> > > >  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > > > +DEFINE_PROP_UINT32("pmu-mask", RISCVCPU, cfg.pmu_mask, 0),
> > > >  DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf,
> > > > false),
> > > >  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> > > >  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> > > > diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> > > > index 0e6a0f245c..40f7d970bc 100644
> > > > --- a/target/riscv/cpu_cfg.h
> > > > +++ b/target/riscv/cpu_cfg.h
> > > > @@ -124,6 +124,7 @@ struct RISCVCPUConfig {
> > > >  bool ext_XVentanaCondOps;
> > > >
> > > >  uint8_t pmu_num;
> > > > +uint32_t pmu_mask;
> > > >  char *priv_spec;
> > > >  char *user_spec;
> > > >  char *bext_spec;
> > > > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > > > index 13801ccb78..f97e25a1f6 100644
> > > > --- a/target/riscv/pmu.c
> > > > +++ b/target/riscv/pmu.c
> > > > @@ -437,6 +437,13 @@ int riscv_pmu_setup_timer(CPURISCVState *env,
> > > > uint64_t value, uint32_t ctr_idx)
> > > >  void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
> > > >  {
> > > >  uint8_t pmu_num = cpu->cfg.pmu_num;
> > > > +uint32_t pmu_mask = cpu->cfg.pmu_mask;
> > > > +
> > > > +if (pmu_mask && ctpop32(pmu_mask) != pmu_num) {
> > > > +error_setg(errp, "Mismatch between number of enabled
> > > > counters in "
> > > > + "\"pmu-mask\" and \"pmu-num\"");
> > > > +return;
> > > > +}
> > > >
> > >
> > > Is that necessary for the default case? I am thinking of marking
> > > pmu-num as deprecated and pmu-mask
> > > as the preferred way of doing things as it is more flexible. There is
> > > no real benefit carrying both.
> > > The default pmu-mask value will change in that case.
> > > We can just overwrite pmu-num with ctpop32(pmu_mask) if pmu-mask is
> > > available. Thoughts ?
> > >
> >
> > I agree it makes sense to me that there is only one way for the user to
> > adjust the PMU count. However i'm not sure how we can handle the
> > transition if we choose to deprecate "pmu-num".
> >
> > If we change the default "pmu-mask" to MAKE_32BIT_MASK(3, 16) then that
> > value in the config will always be set - you propose that we overwrite
> > "pmu-num" with the popcount of that property. But that will break if
>
> Couldn't we deprecate "pmu-num" and then throw an error if both are
> set? Then we can migrate away from "pmu-num"
>

Yeah. pmu-num should be only available as a command line property and
marked deprecated.
If only pmu-num is set, it gets converted to a mask and throws a warning
that this is a deprecated property.
If only the pmu-mask is set, nothing additional is needed. These
patches are sufficient.
If nothing is set, the pmu-mask will be set to MAKE_32BIT_MASK(3, 16).
If a CPU init code uses pmu-num, we should change it to mask. The upstream code
doesn't have any other usage. Any downstream user will have to move
away from pmu-num
once this series is merged.

> Alistair
>
> > the user has an existing setup that changes the value of "pmu-num"
> > (either as a property at runtime or in the CPU init code).
> >
> > One option would be to not make the mask configurable as property and
> > make choosing the layout of the counters something that the specialised
> > CPU init can choose to do.
> >
> > Cheers,
> >
> > Rob
> >
> > > >  if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
> > > >  error_setg(errp, "Number of counters exceeds maximum
> > > > available");
> > > > @@ -449,6 +456,10 @@ void riscv_pmu_init(RISCVCPU *cpu, Error
> > > > **errp)
> > > >  return;
> > > >  }
> > > >
> > > > -/* Create a bitmask of 

Re: [PATCH v4 02/10] hw/fsi: Introduce IBM's scratchpad

2023-10-09 Thread Ninad Palsule

Hello Cedric,

On 9/11/23 07:19, Cédric Le Goater wrote:

On 9/9/23 00:28, Ninad Palsule wrote:

This is a part of patchset where IBM's Flexible Service Interface is
introduced.

The LBUS device is embeded inside the scratchpad. The scratchpad
provides a non-functional registers. There is a 1-1 relation between
scratchpad and LBUS devices. Each LBUS device has 1K memory mapped in
the LBUS.



The commit log is a bit confusing.


I have improved it in my next patch. Please check and let me know.

Thanks for the review.

~Ninad



C.




Signed-off-by: Andrew Jeffery 
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
v2:
- Incorporated Joel's review comments.
---
  hw/fsi/Kconfig |   4 ++
  hw/fsi/engine-scratchpad.c | 100 +
  hw/fsi/meson.build |   1 +
  include/hw/fsi/engine-scratchpad.h |  33 ++
  4 files changed, 138 insertions(+)
  create mode 100644 hw/fsi/engine-scratchpad.c
  create mode 100644 include/hw/fsi/engine-scratchpad.h

diff --git a/hw/fsi/Kconfig b/hw/fsi/Kconfig
index 687449e14e..2a9c49f2c9 100644
--- a/hw/fsi/Kconfig
+++ b/hw/fsi/Kconfig
@@ -1,2 +1,6 @@
+config SCRATCHPAD
+    bool
+    select LBUS
+
  config LBUS
  bool
diff --git a/hw/fsi/engine-scratchpad.c b/hw/fsi/engine-scratchpad.c
new file mode 100644
index 00..15a8f8cc66
--- /dev/null
+++ b/hw/fsi/engine-scratchpad.c
@@ -0,0 +1,100 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2023 IBM Corp.
+ *
+ * IBM scratchpad engine
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qemu/log.h"
+
+#include "hw/fsi/engine-scratchpad.h"
+
+static uint64_t scratchpad_read(void *opaque, hwaddr addr, unsigned 
size)

+{
+    ScratchPad *s = SCRATCHPAD(opaque);
+
+    qemu_log_mask(LOG_UNIMP, "%s: read @0x%" HWADDR_PRIx " size=%d\n",
+  __func__, addr, size);
+
+    if (addr) {
+    qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out of bounds read: 0x%"HWADDR_PRIx" for 
%u\n",

+  __func__, addr, size);
+    return 0;
+    }
+
+    return s->reg;
+}
+
+static void scratchpad_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned size)
+{
+    ScratchPad *s = SCRATCHPAD(opaque);
+
+    qemu_log_mask(LOG_UNIMP, "%s: write @0x%" HWADDR_PRIx " size=%d "
+  "value=%"PRIx64"\n", __func__, addr, size, data);
+
+    if (addr) {
+    qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out of bounds write: 0x%"HWADDR_PRIx" for 
%u\n",

+  __func__, addr, size);
+    return;
+    }
+
+    s->reg = data;
+}
+
+static const struct MemoryRegionOps scratchpad_ops = {
+    .read = scratchpad_read,
+    .write = scratchpad_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void scratchpad_realize(DeviceState *dev, Error **errp)
+{
+    LBusDevice *ldev = LBUS_DEVICE(dev);
+
+    memory_region_init_io(>iomem, OBJECT(ldev), _ops,
+  ldev, TYPE_SCRATCHPAD, 0x400);
+}
+
+static void scratchpad_reset(DeviceState *dev)
+{
+    ScratchPad *s = SCRATCHPAD(dev);
+
+    s->reg = 0;
+}
+
+static void scratchpad_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    LBusDeviceClass *ldc = LBUS_DEVICE_CLASS(klass);
+
+    dc->realize = scratchpad_realize;
+    dc->reset = scratchpad_reset;
+
+    ldc->config =
+  ENGINE_CONFIG_NEXT    /* valid */
+    | 0x0001    /* slots */
+    | 0x1000    /* version */
+    | ENGINE_CONFIG_TYPE_SCRATCHPAD /* type */
+    | 0x0007;   /* crc */
+}
+
+static const TypeInfo scratchpad_info = {
+    .name = TYPE_SCRATCHPAD,
+    .parent = TYPE_LBUS_DEVICE,
+    .instance_size = sizeof(ScratchPad),
+    .class_init = scratchpad_class_init,
+    .class_size = sizeof(LBusDeviceClass),
+};
+
+static void scratchpad_register_types(void)
+{
+    type_register_static(_info);
+}
+
+type_init(scratchpad_register_types);
diff --git a/hw/fsi/meson.build b/hw/fsi/meson.build
index e1007d5fea..f90e09ddab 100644
--- a/hw/fsi/meson.build
+++ b/hw/fsi/meson.build
@@ -1 +1,2 @@
  system_ss.add(when: 'CONFIG_LBUS', if_true: files('lbus.c'))
+system_ss.add(when: 'CONFIG_SCRATCHPAD', if_true: 
files('engine-scratchpad.c'))
diff --git a/include/hw/fsi/engine-scratchpad.h 
b/include/hw/fsi/engine-scratchpad.h

new file mode 100644
index 00..63bf89ac5a
--- /dev/null
+++ b/include/hw/fsi/engine-scratchpad.h
@@ -0,0 +1,33 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2023 IBM Corp.
+ *
+ * IBM scratchpad engne
+ */
+#ifndef FSI_ENGINE_SCRATCHPAD_H
+#define FSI_ENGINE_SCRATCHPAD_H
+
+#include "qemu/bitops.h"
+
+#include "hw/fsi/lbus.h"
+
+#define ENGINE_CONFIG_NEXT  BE_BIT(0)
+#define ENGINE_CONFIG_VPD   BE_BIT(1)
+#define ENGINE_CONFIG_SLOTS 

Re: [PATCH v3 10/10] tests/migration-test: Add a test for postcopy hangs during RECOVER

2023-10-09 Thread Fabiano Rosas
Fabiano Rosas  writes:

> Peter Xu  writes:
>
>> On Thu, Oct 05, 2023 at 06:10:20PM -0300, Fabiano Rosas wrote:
>>> Peter Xu  writes:
>>> 
>>> > On Thu, Oct 05, 2023 at 10:37:56AM -0300, Fabiano Rosas wrote:
>>> >> >> +/*
>>> >> >> + * Make sure both QEMU instances will go into RECOVER stage, 
>>> >> >> then test
>>> >> >> + * kicking them out using migrate-pause.
>>> >> >> + */
>>> >> >> +wait_for_postcopy_status(from, "postcopy-recover");
>>> >> >> +wait_for_postcopy_status(to, "postcopy-recover");
>>> >> >
>>> >> > Is this wait out of place? I think we're trying to resume too fast 
>>> >> > after
>>> >> > migrate_recover():
>>> >> >
>>> >> > # {
>>> >> > # "error": {
>>> >> > # "class": "GenericError",
>>> >> > # "desc": "Cannot resume if there is no paused migration"
>>> >> > # }
>>> >> > # }
>>> >> >
>>> >> 
>>> >> Ugh, sorry about the long lines:
>>> >> 
>>> >> {
>>> >> "error": {
>>> >> "class": "GenericError",
>>> >> "desc": "Cannot resume if there is no paused migration"
>>> >> }
>>> >> }
>>> >
>>> > Sorry I didn't get you here.  Could you elaborate your question?
>>> >
>>> 
>>> The test is sometimes failing with the above message.
>>> 
>>> But indeed my question doesn't make sense. I forgot migrate_recover
>>> happens on the destination. Nevermind.
>>> 
>>> The bug is still present nonetheless. We're going into migrate_prepare
>>> in some state other than POSTCOPY_PAUSED.
>>
>> Oh I see.  Interestingly I cannot reproduce on my host, just like last
>> time..
>>
>> What is your setup for running the test?  Anything special?  Here's my
>> cmdline:
>
> The crudest oneliner:
>
> for i in $(seq 1 ); do echo "$i ="; \
> QTEST_QEMU_BINARY=./qemu-system-x86_64 \
> ./tests/qtest/migration-test -r /x86_64/migration/postcopy/recovery || break 
> ; done
>
> I suspect my system has something specific to it that affects the timing
> of the tests. But I have no idea what it could be.
>
> $ lscpu   
> Architecture:x86_64  
>   CPU op-mode(s):32-bit, 64-bit
>   Address sizes: 39 bits physical, 48 bits virtual
>   Byte Order:Little Endian
> CPU(s):  16
>   On-line CPU(s) list:   0-15
> Vendor ID:   GenuineIntel
>   Model name:11th Gen Intel(R) Core(TM) i7-11850H @ 2.50GHz
> CPU family:  6
> Model:   141
> Thread(s) per core:  2
> Core(s) per socket:  8
> Socket(s):   1
> Stepping:1
> CPU max MHz: 4800.
> CPU min MHz: 800.
> BogoMIPS:4992.00
>
>>
>> $ cat reproduce.sh 
>> index=$1
>> loop=0
>>
>> while :; do
>> echo "Starting loop=$loop..."
>> QTEST_QEMU_BINARY=./qemu-system-x86_64 ./tests/qtest/migration-test 
>> -p /x86_64/migration/postcopy/recovery/double-failures
>> if [[ $? != 0 ]]; then
>> echo "index $index REPRODUCED (loop=$loop) !"
>> break
>> fi
>> loop=$(( loop + 1 ))
>> done
>>
>> Survives 200+ loops and kept going.
>>
>> However I think I saw what's wrong here, could you help try below fixup?
>>
>
> Sure. I won't get to it until tomorrow though.

It seems to have fixed the issue. 3500 iterations and still going.



Re: [PATCH v4 02/10] hw/fsi: Introduce IBM's scratchpad

2023-10-09 Thread Ninad Palsule

Hello Cedric,


On 9/9/23 03:37, Cédric Le Goater wrote:

On 9/9/23 00:28, Ninad Palsule wrote:

This is a part of patchset where IBM's Flexible Service Interface is
introduced.

The LBUS device is embeded inside the scratchpad. The scratchpad


embedded

Fixed



provides a non-functional registers. There is a 1-1 relation between
scratchpad and LBUS devices. Each LBUS device has 1K memory mapped in
the LBUS.

Signed-off-by: Andrew Jeffery 
Signed-off-by: Cédric Le Goater 
Signed-off-by: Ninad Palsule 
---
v2:
- Incorporated Joel's review comments.
---
  hw/fsi/Kconfig |   4 ++
  hw/fsi/engine-scratchpad.c | 100 +
  hw/fsi/meson.build |   1 +
  include/hw/fsi/engine-scratchpad.h |  33 ++
  4 files changed, 138 insertions(+)
  create mode 100644 hw/fsi/engine-scratchpad.c
  create mode 100644 include/hw/fsi/engine-scratchpad.h

diff --git a/hw/fsi/Kconfig b/hw/fsi/Kconfig
index 687449e14e..2a9c49f2c9 100644
--- a/hw/fsi/Kconfig
+++ b/hw/fsi/Kconfig
@@ -1,2 +1,6 @@
+config SCRATCHPAD
+    bool
+    select LBUS
+
  config LBUS
  bool
diff --git a/hw/fsi/engine-scratchpad.c b/hw/fsi/engine-scratchpad.c
new file mode 100644
index 00..15a8f8cc66
--- /dev/null
+++ b/hw/fsi/engine-scratchpad.c
@@ -0,0 +1,100 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2023 IBM Corp.
+ *
+ * IBM scratchpad engine
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qemu/log.h"
+
+#include "hw/fsi/engine-scratchpad.h"
+
+static uint64_t scratchpad_read(void *opaque, hwaddr addr, unsigned 
size)

+{
+    ScratchPad *s = SCRATCHPAD(opaque);
+
+    qemu_log_mask(LOG_UNIMP, "%s: read @0x%" HWADDR_PRIx " size=%d\n",
+  __func__, addr, size);


This should be a trace event. The comment applies to all similar usage.

Fixed all required places.



+
+    if (addr) {
+    qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out of bounds read: 0x%"HWADDR_PRIx" for 
%u\n",

+  __func__, addr, size);
+    return 0;


if the MMIO region is correctly sized, this should not be necessary. Do
you plans to add support for registers ?


If required I am going to implement registers. Current plan is to get 
initial changes in and then add more stuff.






+    }
+
+    return s->reg;
+}
+
+static void scratchpad_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned size)
+{
+    ScratchPad *s = SCRATCHPAD(opaque);
+
+    qemu_log_mask(LOG_UNIMP, "%s: write @0x%" HWADDR_PRIx " size=%d "
+  "value=%"PRIx64"\n", __func__, addr, size, data);


trace event

Fixed



+
+    if (addr) {
+    qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out of bounds write: 0x%"HWADDR_PRIx" for 
%u\n",

+  __func__, addr, size);
+    return;
+    }
+
+    s->reg = data;
+}
+
+static const struct MemoryRegionOps scratchpad_ops = {
+    .read = scratchpad_read,
+    .write = scratchpad_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void scratchpad_realize(DeviceState *dev, Error **errp)
+{
+    LBusDevice *ldev = LBUS_DEVICE(dev);
+
+    memory_region_init_io(>iomem, OBJECT(ldev), _ops,
+  ldev, TYPE_SCRATCHPAD, 0x400);
+}
+
+static void scratchpad_reset(DeviceState *dev)
+{
+    ScratchPad *s = SCRATCHPAD(dev);
+
+    s->reg = 0;
+}
+
+static void scratchpad_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    LBusDeviceClass *ldc = LBUS_DEVICE_CLASS(klass);
+
+    dc->realize = scratchpad_realize;
+    dc->reset = scratchpad_reset;
+
+    ldc->config =
+  ENGINE_CONFIG_NEXT    /* valid */
+    | 0x0001    /* slots */
+    | 0x1000    /* version */
+    | ENGINE_CONFIG_TYPE_SCRATCHPAD /* type */
+    | 0x0007;   /* crc */


where is ->config used ?


Yes, Its not but I am thinking of keeping it as next step we may need it.

Thanks for the review.

~ Ninad





+}
+
+static const TypeInfo scratchpad_info = {
+    .name = TYPE_SCRATCHPAD,
+    .parent = TYPE_LBUS_DEVICE,
+    .instance_size = sizeof(ScratchPad),
+    .class_init = scratchpad_class_init,
+    .class_size = sizeof(LBusDeviceClass),
+};
+
+static void scratchpad_register_types(void)
+{
+    type_register_static(_info);
+}
+
+type_init(scratchpad_register_types);
diff --git a/hw/fsi/meson.build b/hw/fsi/meson.build
index e1007d5fea..f90e09ddab 100644
--- a/hw/fsi/meson.build
+++ b/hw/fsi/meson.build
@@ -1 +1,2 @@
  system_ss.add(when: 'CONFIG_LBUS', if_true: files('lbus.c'))
+system_ss.add(when: 'CONFIG_SCRATCHPAD', if_true: 
files('engine-scratchpad.c'))
diff --git a/include/hw/fsi/engine-scratchpad.h 
b/include/hw/fsi/engine-scratchpad.h

new file mode 100644
index 00..63bf89ac5a
--- /dev/null
+++ b/include/hw/fsi/engine-scratchpad.h
@@ -0,0 +1,33 @@
+/*
+ * 

[PATCH 2/3] hw/misc/mips_itu: Declare itc_reconfigure() in 'hw/misc/mips_itu.h'

2023-10-09 Thread Philippe Mathieu-Daudé
We already provide "hw/misc/mips_itu.h" to declare prototype
related to MIPSITUState. Move itc_reconfigure() declaration
there.

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/misc/mips_itu.h  | 2 ++
 target/mips/cpu.h   | 3 ---
 target/mips/tcg/sysemu/cp0_helper.c | 1 +
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/hw/misc/mips_itu.h b/include/hw/misc/mips_itu.h
index 35218b2d14..a413789151 100644
--- a/include/hw/misc/mips_itu.h
+++ b/include/hw/misc/mips_itu.h
@@ -79,4 +79,6 @@ struct MIPSITUState {
 /* Get ITC Configuration Tag memory region. */
 MemoryRegion *mips_itu_get_tag_region(MIPSITUState *itu);
 
+void itc_reconfigure(struct MIPSITUState *tag);
+
 #endif /* MIPS_ITU_H */
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index fb44defc93..5fddceff3a 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1350,9 +1350,6 @@ void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int 
level);
 void cpu_mips_irq_init_cpu(MIPSCPU *cpu);
 void cpu_mips_clock_init(MIPSCPU *cpu);
 
-/* mips_itu.c */
-void itc_reconfigure(struct MIPSITUState *tag);
-
 #endif /* !CONFIG_USER_ONLY */
 
 /* helper.c */
diff --git a/target/mips/tcg/sysemu/cp0_helper.c 
b/target/mips/tcg/sysemu/cp0_helper.c
index 5da1124589..d349548743 100644
--- a/target/mips/tcg/sysemu/cp0_helper.c
+++ b/target/mips/tcg/sysemu/cp0_helper.c
@@ -28,6 +28,7 @@
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
+#include "hw/misc/mips_itu.h"
 
 
 /* SMP helpers.  */
-- 
2.41.0




[PATCH 3/3] hw/misc/mips_itu: Make MIPSITUState target agnostic

2023-10-09 Thread Philippe Mathieu-Daudé
When prototyping a heterogenous machine including the ITU,
we get:

  include/hw/misc/mips_itu.h:76:5: error: unknown type name 'MIPSCPU'
  MIPSCPU *cpu0;
  ^

MIPSCPU is declared in the target specific "cpu.h" header,
but we don't want to include it, because "cpu.h" is target
specific and its inclusion taints all files including
"mips_itu.h", which become target specific too. We can
however use the 'ArchCPU *' type in the public header.
By keeping the TYPE_MIPS_CPU QOM type check in the link
property declaration, QOM core code will still check the
property is a correct MIPS CPU.

TYPE_MIPS_ITU is still built per-(MIPS)target, but its header
can now be included by other targets.

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/misc/mips_itu.h | 2 +-
 hw/misc/mips_itu.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/hw/misc/mips_itu.h b/include/hw/misc/mips_itu.h
index a413789151..5caed6cc36 100644
--- a/include/hw/misc/mips_itu.h
+++ b/include/hw/misc/mips_itu.h
@@ -73,7 +73,7 @@ struct MIPSITUState {
 
 /* SAAR */
 uint64_t *saar;
-MIPSCPU *cpu0;
+ArchCPU *cpu0;
 };
 
 /* Get ITC Configuration Tag memory region. */
diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index 0eda302db4..5a83ccc4e8 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -532,7 +532,7 @@ static void mips_itu_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-env = >cpu0->env;
+env = _CPU(s->cpu0)->env;
 if (env->saarp) {
 s->saar = env->CP0_SAAR;
 }
@@ -563,7 +563,7 @@ static Property mips_itu_properties[] = {
   ITC_FIFO_NUM_MAX),
 DEFINE_PROP_UINT32("num-semaphores", MIPSITUState, num_semaphores,
   ITC_SEMAPH_NUM_MAX),
-DEFINE_PROP_LINK("cpu[0]", MIPSITUState, cpu0, TYPE_MIPS_CPU, MIPSCPU *),
+DEFINE_PROP_LINK("cpu[0]", MIPSITUState, cpu0, TYPE_MIPS_CPU, ArchCPU *),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.41.0




[PATCH 1/3] hw/mips: Merge 'hw/mips/cpudevs.h' with 'target/mips/cpu.h'

2023-10-09 Thread Philippe Mathieu-Daudé
"hw/mips/cpudevs.h" contains declarations which are specific
to the MIPS architecture; it doesn't make sense for these to
be called from a non-MIPS architecture. Move the declarations
to "target/mips/cpu.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/mips/cpudevs.h   | 14 --
 target/mips/cpu.h   |  4 +++-
 hw/mips/cps.c   |  1 -
 hw/mips/fuloong2e.c |  1 -
 hw/mips/jazz.c  |  1 -
 hw/mips/loongson3_virt.c|  1 -
 hw/mips/malta.c |  1 -
 hw/mips/mips_int.c  |  1 -
 hw/mips/mipssim.c   |  1 -
 target/mips/sysemu/cp0_timer.c  |  1 -
 target/mips/tcg/sysemu/tlb_helper.c |  1 -
 11 files changed, 3 insertions(+), 24 deletions(-)
 delete mode 100644 include/hw/mips/cpudevs.h

diff --git a/include/hw/mips/cpudevs.h b/include/hw/mips/cpudevs.h
deleted file mode 100644
index f7c9728fa9..00
--- a/include/hw/mips/cpudevs.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef HW_MIPS_CPUDEVS_H
-#define HW_MIPS_CPUDEVS_H
-
-#include "target/mips/cpu-qom.h"
-
-/* Definitions for MIPS CPU internal devices.  */
-
-/* mips_int.c */
-void cpu_mips_irq_init_cpu(MIPSCPU *cpu);
-
-/* mips_timer.c */
-void cpu_mips_clock_init(MIPSCPU *cpu);
-
-#endif
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 67f8e8b988..fb44defc93 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1345,8 +1345,10 @@ uint64_t cpu_mips_phys_to_kseg1(void *opaque, uint64_t 
addr);
 
 #if !defined(CONFIG_USER_ONLY)
 
-/* mips_int.c */
+/* HW declaration specific to the MIPS target */
 void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
+void cpu_mips_irq_init_cpu(MIPSCPU *cpu);
+void cpu_mips_clock_init(MIPSCPU *cpu);
 
 /* mips_itu.c */
 void itc_reconfigure(struct MIPSITUState *tag);
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 2b5269ebf1..b6612c1762 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -24,7 +24,6 @@
 #include "hw/mips/mips.h"
 #include "hw/qdev-clock.h"
 #include "hw/qdev-properties.h"
-#include "hw/mips/cpudevs.h"
 #include "sysemu/kvm.h"
 #include "sysemu/reset.h"
 
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index c6109633fe..97b2c8ed8e 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -30,7 +30,6 @@
 #include "hw/block/flash.h"
 #include "hw/mips/mips.h"
 #include "hw/mips/bootloader.h"
-#include "hw/mips/cpudevs.h"
 #include "hw/pci/pci.h"
 #include "hw/loader.h"
 #include "hw/ide/pci.h"
diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index c32d2b0b0a..86dfe05ea8 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -26,7 +26,6 @@
 #include "qemu/datadir.h"
 #include "hw/clock.h"
 #include "hw/mips/mips.h"
-#include "hw/mips/cpudevs.h"
 #include "hw/intc/i8259.h"
 #include "hw/dma/i8257.h"
 #include "hw/char/serial.h"
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index b74b358874..33eae01eca 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -32,7 +32,6 @@
 #include "hw/char/serial.h"
 #include "hw/intc/loongson_liointc.h"
 #include "hw/mips/mips.h"
-#include "hw/mips/cpudevs.h"
 #include "hw/mips/fw_cfg.h"
 #include "hw/mips/loongson3_bootp.h"
 #include "hw/misc/unimp.h"
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index dac27fad9d..b0110c4da6 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -37,7 +37,6 @@
 #include "hw/block/flash.h"
 #include "hw/mips/mips.h"
 #include "hw/mips/bootloader.h"
-#include "hw/mips/cpudevs.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bus.h"
 #include "qemu/log.h"
diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
index 73437cd90f..6c32e466a3 100644
--- a/hw/mips/mips_int.c
+++ b/hw/mips/mips_int.c
@@ -23,7 +23,6 @@
 #include "qemu/osdep.h"
 #include "qemu/main-loop.h"
 #include "hw/irq.h"
-#include "hw/mips/cpudevs.h"
 #include "sysemu/kvm.h"
 #include "kvm_mips.h"
 
diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c
index 2f951f7fc6..4f743f37eb 100644
--- a/hw/mips/mipssim.c
+++ b/hw/mips/mipssim.c
@@ -30,7 +30,6 @@
 #include "qemu/datadir.h"
 #include "hw/clock.h"
 #include "hw/mips/mips.h"
-#include "hw/mips/cpudevs.h"
 #include "hw/char/serial.h"
 #include "hw/isa/isa.h"
 #include "net/net.h"
diff --git a/target/mips/sysemu/cp0_timer.c b/target/mips/sysemu/cp0_timer.c
index 9d2bcb0dea..62de502caa 100644
--- a/target/mips/sysemu/cp0_timer.c
+++ b/target/mips/sysemu/cp0_timer.c
@@ -22,7 +22,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/irq.h"
-#include "hw/mips/cpudevs.h"
 #include "qemu/timer.h"
 #include "sysemu/kvm.h"
 #include "internal.h"
diff --git a/target/mips/tcg/sysemu/tlb_helper.c 
b/target/mips/tcg/sysemu/tlb_helper.c
index 7dbc2e24c4..4ede904800 100644
--- a/target/mips/tcg/sysemu/tlb_helper.c
+++ b/target/mips/tcg/sysemu/tlb_helper.c
@@ -24,7 +24,6 @@
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/log.h"
-#include "hw/mips/cpudevs.h"
 #include "exec/helper-proto.h"
 
 /* TLB management */
-- 
2.41.0

[PATCH 0/3] hw/mips: Cleanup in preparation of heterogenous prototype

2023-10-09 Thread Philippe Mathieu-Daudé
Prepare few MIPS hardware to be integrated in a
heterogeneous machine:
- Restrict MIPS-specific HW declaration to target/mips/
- Replace MIPSCPU by ArchCPU in common HW

Philippe Mathieu-Daudé (3):
  hw/mips: Merge 'hw/mips/cpudevs.h' with 'target/mips/cpu.h'
  hw/misc/mips_itu: Declare itc_reconfigure() in 'hw/misc/mips_itu.h'
  hw/misc/mips_itu: Make MIPSITUState target agnostic

 include/hw/mips/cpudevs.h   | 14 --
 include/hw/misc/mips_itu.h  |  4 +++-
 target/mips/cpu.h   |  7 +++
 hw/mips/cps.c   |  1 -
 hw/mips/fuloong2e.c |  1 -
 hw/mips/jazz.c  |  1 -
 hw/mips/loongson3_virt.c|  1 -
 hw/mips/malta.c |  1 -
 hw/mips/mips_int.c  |  1 -
 hw/mips/mipssim.c   |  1 -
 hw/misc/mips_itu.c  |  4 ++--
 target/mips/sysemu/cp0_timer.c  |  1 -
 target/mips/tcg/sysemu/cp0_helper.c |  1 +
 target/mips/tcg/sysemu/tlb_helper.c |  1 -
 14 files changed, 9 insertions(+), 30 deletions(-)
 delete mode 100644 include/hw/mips/cpudevs.h

-- 
2.41.0




[PATCH v2 1/2] target/s390x/kvm: Turn KVM_CAP_SYNC_REGS into a hard requirement

2023-10-09 Thread Thomas Huth
Since we already require at least kernel 3.15 in the s390x KVM code,
we can assume that the KVM_CAP_SYNC_REGS capability is always there.
Thus turn this into a hard requirement now.

Signed-off-by: Thomas Huth 
---
 target/s390x/kvm/kvm.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index bc5c56a305..b3e2eaa2eb 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -337,21 +337,29 @@ int kvm_arch_get_default_type(MachineState *ms)
 
 int kvm_arch_init(MachineState *ms, KVMState *s)
 {
+int required_caps[] = {
+KVM_CAP_DEVICE_CTRL,
+KVM_CAP_SYNC_REGS,
+};
+
+for (int i = 0; i < ARRAY_SIZE(required_caps); i++) {
+if (!kvm_check_extension(s, required_caps[i])) {
+error_report("KVM is missing capability #%d - "
+ "please use kernel 3.15 or newer", required_caps[i]);
+return -1;
+}
+}
+
 object_class_foreach(ccw_machine_class_foreach, TYPE_S390_CCW_MACHINE,
  false, NULL);
 
-if (!kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) {
-error_report("KVM is missing capability KVM_CAP_DEVICE_CTRL - "
- "please use kernel 3.15 or newer");
-return -1;
-}
 if (!kvm_check_extension(s, KVM_CAP_S390_COW)) {
 error_report("KVM is missing capability KVM_CAP_S390_COW - "
  "unsupported environment");
 return -1;
 }
 
-cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
+cap_sync_regs = true;
 cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
 cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
 cap_mem_op_extension = kvm_check_extension(s, 
KVM_CAP_S390_MEM_OP_EXTENSION);
-- 
2.41.0




[PATCH v2 0/2] target/s390x/kvm: Simplify the synchronization code

2023-10-09 Thread Thomas Huth
KVM_SYNC_GPRS, KVM_SYNC_ACRS, KVM_SYNC_CRS and KVM_SYNC_PREFIX are
available since kernel 3.10. Since we already require at least kernel
3.15 in the s390x KVM code, we can also assume that the KVM_CAP_SYNC_REGS
sync code is always possible for these registers, and remove the
related checks and fallbacks via KVM_SET_REGS and KVM_GET_REGS.

v2:
- Split the patch from v1 into two patches
- Use a #define KVM_SYNC_REQUIRED_BITS for the required sync bits
- Use memcpy() instead of for-loops for copying the registers

Thomas Huth (2):
  target/s390x/kvm: Turn KVM_CAP_SYNC_REGS into a hard requirement
  target/s390x/kvm: Simplify the GPRs, ACRs, CRs and prefix
synchronization code

 target/s390x/kvm/kvm.c | 120 -
 1 file changed, 33 insertions(+), 87 deletions(-)

-- 
2.41.0




[PATCH] Revert "configure: Add workaround for ccache and clang"

2023-10-09 Thread Yonggang Luo
This reverts commit fd0e60530f10078f488fa3e9591cc7db5732989c.

According to 
https://peter.eisentraut.org/blog/2014/12/01/ccache-and-clang-part-3
it's already fixed in new version of ccache

According to https://ccache.dev/manual/4.8.html#config_run_second_cpp
CCACHE_CPP2 are default to true for new version ccache

Signed-off-by: Yonggang Luo 
---
 configure | 32 
 1 file changed, 32 deletions(-)

diff --git a/configure b/configure
index e08127045d..3f8dd94b50 100755
--- a/configure
+++ b/configure
@@ -1161,34 +1161,6 @@ EOF
   fi
 fi
 
-
-# check if ccache is interfering with
-# semantic analysis of macros
-
-unset CCACHE_CPP2
-ccache_cpp2=no
-cat > $TMPC << EOF
-static const int Z = 1;
-#define fn() ({ Z; })
-#define TAUT(X) ((X) == Z)
-#define PAREN(X, Y) (X == Y)
-#define ID(X) (X)
-int main(void)
-{
-int x = 0, y = 0;
-x = ID(x);
-x = fn();
-fn();
-if (PAREN(x, y)) return 0;
-if (TAUT(Z)) return 0;
-return 0;
-}
-EOF
-
-if ! compile_object "-Werror"; then
-ccache_cpp2=yes
-fi
-
 ##
 # functions to probe cross compilers
 
@@ -1722,10 +1694,6 @@ if test "$default_targets" = "yes"; then
   echo "CONFIG_DEFAULT_TARGETS=y" >> $config_host_mak
 fi
 
-if test "$ccache_cpp2" = "yes"; then
-  echo "export CCACHE_CPP2=y" >> $config_host_mak
-fi
-
 # contrib/plugins configuration
 echo "# Automatically generated by configure - do not modify" > 
contrib/plugins/$config_host_mak
 echo "SRC_PATH=$source_path/contrib/plugins" >> 
contrib/plugins/$config_host_mak
-- 
2.39.0.windows.1




[PATCH v2 2/2] target/s390x/kvm: Simplify the GPRs, ACRs, CRs and prefix synchronization code

2023-10-09 Thread Thomas Huth
KVM_SYNC_GPRS, KVM_SYNC_ACRS, KVM_SYNC_CRS and KVM_SYNC_PREFIX are
available since kernel 3.10. Since we already require at least kernel
3.15 in the s390x KVM code, we can also assume that the KVM_CAP_SYNC_REGS
sync code is always possible for these registers, and remove the
related checks and fallbacks via KVM_SET_REGS and KVM_GET_REGS.

Signed-off-by: Thomas Huth 
---
 target/s390x/kvm/kvm.c | 102 -
 1 file changed, 20 insertions(+), 82 deletions(-)

diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index b3e2eaa2eb..b988fc3abb 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -138,7 +138,6 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
 };
 
-static int cap_sync_regs;
 static int cap_async_pf;
 static int cap_mem_op;
 static int cap_mem_op_extension;
@@ -359,7 +358,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 return -1;
 }
 
-cap_sync_regs = true;
 cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
 cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
 cap_mem_op_extension = kvm_check_extension(s, 
KVM_CAP_S390_MEM_OP_EXTENSION);
@@ -466,15 +464,16 @@ void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
 
 static int can_sync_regs(CPUState *cs, int regs)
 {
-return cap_sync_regs && (cs->kvm_run->kvm_valid_regs & regs) == regs;
+return (cs->kvm_run->kvm_valid_regs & regs) == regs;
 }
 
+#define KVM_SYNC_REQUIRED_BITS (KVM_SYNC_GPRS | KVM_SYNC_ACRS | \
+KVM_SYNC_CRS | KVM_SYNC_PREFIX)
+
 int kvm_arch_put_registers(CPUState *cs, int level)
 {
 S390CPU *cpu = S390_CPU(cs);
 CPUS390XState *env = >env;
-struct kvm_sregs sregs;
-struct kvm_regs regs;
 struct kvm_fpu fpu = {};
 int r;
 int i;
@@ -483,20 +482,14 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 cs->kvm_run->psw_addr = env->psw.addr;
 cs->kvm_run->psw_mask = env->psw.mask;
 
-if (can_sync_regs(cs, KVM_SYNC_GPRS)) {
-for (i = 0; i < 16; i++) {
-cs->kvm_run->s.regs.gprs[i] = env->regs[i];
-cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_GPRS;
-}
-} else {
-for (i = 0; i < 16; i++) {
-regs.gprs[i] = env->regs[i];
-}
-r = kvm_vcpu_ioctl(cs, KVM_SET_REGS, );
-if (r < 0) {
-return r;
-}
-}
+g_assert((cs->kvm_run->kvm_valid_regs & KVM_SYNC_REQUIRED_BITS) ==
+ KVM_SYNC_REQUIRED_BITS);
+cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_REQUIRED_BITS;
+memcpy(cs->kvm_run->s.regs.gprs, env->regs, 
sizeof(cs->kvm_run->s.regs.gprs));
+memcpy(cs->kvm_run->s.regs.acrs, env->aregs, 
sizeof(cs->kvm_run->s.regs.acrs));
+memcpy(cs->kvm_run->s.regs.crs, env->cregs, 
sizeof(cs->kvm_run->s.regs.crs));
+
+cs->kvm_run->s.regs.prefix = env->psa;
 
 if (can_sync_regs(cs, KVM_SYNC_VRS)) {
 for (i = 0; i < 32; i++) {
@@ -575,25 +568,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 }
 }
 
-/* access registers and control registers*/
-if (can_sync_regs(cs, KVM_SYNC_ACRS | KVM_SYNC_CRS)) {
-for (i = 0; i < 16; i++) {
-cs->kvm_run->s.regs.acrs[i] = env->aregs[i];
-cs->kvm_run->s.regs.crs[i] = env->cregs[i];
-}
-cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_ACRS;
-cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_CRS;
-} else {
-for (i = 0; i < 16; i++) {
-sregs.acrs[i] = env->aregs[i];
-sregs.crs[i] = env->cregs[i];
-}
-r = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, );
-if (r < 0) {
-return r;
-}
-}
-
 if (can_sync_regs(cs, KVM_SYNC_GSCB)) {
 memcpy(cs->kvm_run->s.regs.gscb, env->gscb, 32);
 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_GSCB;
@@ -615,13 +589,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
 }
 
-/* Finally the prefix */
-if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
-cs->kvm_run->s.regs.prefix = env->psa;
-cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_PREFIX;
-} else {
-/* prefix is only supported via sync regs */
-}
 return 0;
 }
 
@@ -629,8 +596,6 @@ int kvm_arch_get_registers(CPUState *cs)
 {
 S390CPU *cpu = S390_CPU(cs);
 CPUS390XState *env = >env;
-struct kvm_sregs sregs;
-struct kvm_regs regs;
 struct kvm_fpu fpu;
 int i, r;
 
@@ -638,37 +603,15 @@ int kvm_arch_get_registers(CPUState *cs)
 env->psw.addr = cs->kvm_run->psw_addr;
 env->psw.mask = cs->kvm_run->psw_mask;
 
-/* the GPRS */
-if (can_sync_regs(cs, KVM_SYNC_GPRS)) {
-for (i = 0; i < 16; i++) {
-env->regs[i] = cs->kvm_run->s.regs.gprs[i];
-}
-} else {
-r = kvm_vcpu_ioctl(cs, KVM_GET_REGS, );
-if (r < 0) {
-return r;
-}
- for (i = 0; i < 16; i++) {
-  

  1   2   3   4   >