Re: [PATCH v3 02/29] hw/core: Declare CPUArchId::cpu as CPUState instead of Object

2024-01-29 Thread Richard Henderson

On 1/30/24 02:44, Philippe Mathieu-Daudé wrote:

Do not accept any Object for CPUArchId::cpu field,
restrict it to CPUState type.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/hw/boards.h| 2 +-
  hw/core/machine.c  | 4 ++--
  hw/i386/x86.c  | 2 +-
  hw/loongarch/virt.c| 2 +-
  hw/ppc/spapr.c | 5 ++---
  hw/s390x/s390-virtio-ccw.c | 2 +-
  6 files changed, 8 insertions(+), 9 deletions(-)


Reviewed-by: Richard Henderson 

r~



[PATCH v1] scripts/checkpatch.pl: check for placeholders in cover letter patches

2024-01-29 Thread Manos Pitsidianakis
Check if a file argument is a cover letter patch produced by
git-format-patch --cover-letter; It is initialized with subject suffix "
*** SUBJECT HERE ***" and body prefix " *** BLURB HERE ***". If they
exist, warn the user.

Signed-off-by: Manos Pitsidianakis 
---
 scripts/checkpatch.pl | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 7026895074..34f12c9848 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1650,6 +1650,20 @@ sub process {
$non_utf8_charset = 1;
}
 
+# Check if this is a cover letter patch produced by git-format-patch
+# --cover-letter; It is initialized with subject suffix
+# " *** SUBJECT HERE ***" and body prefix " *** BLURB HERE ***"
+   if ($in_header_lines &&
+   $rawline =~ /^Subject:.+[*]{3} SUBJECT HERE [*]{3}\s*$/) {
+WARN("Patch appears to be a cover letter with uninitialized subject" .
+ " '*** SUBJECT HERE ***'\n$hereline\n");
+   }
+
+   if ($rawline =~ /^[*]{3} BLURB HERE [*]{3}\s*$/) {
+WARN("Patch appears to be a cover letter with leftover placeholder " .
+ "text '*** BLURB HERE ***'\n$hereline\n");
+   }
+
if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
$rawline =~ /$NON_ASCII_UTF8/) {
WARN("8-bit UTF-8 used in possible commit log\n" . 
$herecurr);

base-commit: 11be70677c70fdccd452a3233653949b79e97908
-- 
γαῖα πυρί μιχθήτω




Re: [PATCH v3 01/29] bulk: Access existing variables initialized to >F when available

2024-01-29 Thread Richard Henderson

On 1/30/24 02:44, Philippe Mathieu-Daudé wrote:

When a variable is initialized to >field, use it
in place. Rationale: while this makes the code more concise,
this also helps static analyzers.

Mechanical change using the following Coccinelle spatch script:

  @@
  type S, F;
  identifier s, m, v;
  @@
   S *s;
   ...
   F *v = >m;
   <+...
  ->m
  +v
   ...+>

Inspired-by: Zhao Liu
Signed-off-by: Philippe Mathieu-Daudé
---


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 04/22] target/sparc: Introduce gen_{load,store}_fpr_Q

2024-01-29 Thread Philippe Mathieu-Daudé

On 3/11/23 18:38, Richard Henderson wrote:

Use them for trans_FMOVq.

Signed-off-by: Richard Henderson 
---
  target/sparc/translate.c | 25 +++--
  1 file changed, 19 insertions(+), 6 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH 03/22] target/sparc: Remove gen_dest_fpr_F

2024-01-29 Thread Philippe Mathieu-Daudé

On 3/11/23 18:38, Richard Henderson wrote:

Replace with tcg_temp_new_i32.

Signed-off-by: Richard Henderson 
---
  target/sparc/translate.c | 17 ++---
  1 file changed, 6 insertions(+), 11 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v2 11/14] plugins: remove non per_vcpu inline operation from API

2024-01-29 Thread Pierrick Bouvier

On 1/26/24 20:26, Alex Bennée wrote:

Pierrick Bouvier  writes:


Now we have a thread-safe equivalent of inline operation, and that all
plugins were changed to use it, there is no point to keep the old API.

In more, it will help when we implement more functionality (conditional
callbacks), as we can assume that we operate on a scoreboard.

Bump API version as it's a breaking change for existing plugins.

Signed-off-by: Pierrick Bouvier 
---
  include/qemu/qemu-plugin.h | 59 --
  plugins/api.c  | 29 ---
  2 files changed, 6 insertions(+), 82 deletions(-)

diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 55f918db1b0..3ee514f79cf 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -51,11 +51,16 @@ typedef uint64_t qemu_plugin_id_t;
   *
   * The plugins export the API they were built against by exposing the
   * symbol qemu_plugin_version which can be checked.
+ *
+ * Version 2:
+ * Remove qemu_plugin_register_vcpu_{tb, insn, mem}_exec_inline.
+ * Those functions are replaced by *_per_vcpu variants, which guarantees
+ * thread-safety for operations.
   */
  
  extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
  
-#define QEMU_PLUGIN_VERSION 1

+#define QEMU_PLUGIN_VERSION 2


I think technically the adding new API bumps this, the deprecating the
old version bumps:

   QEMU_PLUGIN_MIN_VERSION

to the same.



Yes, you're right, it would prevent plugin using removed function to 
work. I'll update MIN_VERSION too.


  
  /**

   * struct qemu_info_t - system information for plugins
@@ -311,25 +316,6 @@ enum qemu_plugin_op {
  QEMU_PLUGIN_INLINE_ADD_U64,
  };
  
-/**

- * qemu_plugin_register_vcpu_tb_exec_inline() - execution inline op
- * @tb: the opaque qemu_plugin_tb handle for the translation
- * @op: the type of qemu_plugin_op (e.g. ADD_U64)
- * @ptr: the target memory location for the op
- * @imm: the op data (e.g. 1)
- *
- * Insert an inline op to every time a translated unit executes.
- * Useful if you just want to increment a single counter somewhere in
- * memory.
- *
- * Note: ops are not atomic so in multi-threaded/multi-smp situations
- * you will get inexact results.
- */
-QEMU_PLUGIN_API
-void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
-  enum qemu_plugin_op op,
-  void *ptr, uint64_t imm);
-
  /**
   * qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu() - execution inline op
   * @tb: the opaque qemu_plugin_tb handle for the translation
@@ -361,21 +347,6 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct 
qemu_plugin_insn *insn,
  enum qemu_plugin_cb_flags flags,
  void *userdata);
  
-/**

- * qemu_plugin_register_vcpu_insn_exec_inline() - insn execution inline op
- * @insn: the opaque qemu_plugin_insn handle for an instruction
- * @op: the type of qemu_plugin_op (e.g. ADD_U64)
- * @ptr: the target memory location for the op
- * @imm: the op data (e.g. 1)
- *
- * Insert an inline op to every time an instruction executes. Useful
- * if you just want to increment a single counter somewhere in memory.
- */
-QEMU_PLUGIN_API
-void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
-enum qemu_plugin_op op,
-void *ptr, uint64_t imm);
-
  /**
   * qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu() - insn exec inline op
   * @insn: the opaque qemu_plugin_insn handle for an instruction
@@ -599,24 +570,6 @@ void qemu_plugin_register_vcpu_mem_cb(struct 
qemu_plugin_insn *insn,
enum qemu_plugin_mem_rw rw,
void *userdata);
  
-/**

- * qemu_plugin_register_vcpu_mem_inline() - register an inline op to any 
memory access
- * @insn: handle for instruction to instrument
- * @rw: apply to reads, writes or both
- * @op: the op, of type qemu_plugin_op
- * @ptr: pointer memory for the op
- * @imm: immediate data for @op
- *
- * This registers a inline op every memory access generated by the
- * instruction. This provides for a lightweight but not thread-safe
- * way of counting the number of operations done.
- */
-QEMU_PLUGIN_API
-void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
-  enum qemu_plugin_mem_rw rw,
-  enum qemu_plugin_op op, void *ptr,
-  uint64_t imm);
-
  /**
   * qemu_plugin_register_vcpu_mem_inline_per_vcpu() - inline op for mem access
   * @insn: handle for instruction to instrument
diff --git a/plugins/api.c b/plugins/api.c
index 132d5e0bec1..29915d3c142 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -101,16 +101,6 @@ void 

Re: [PATCH v2 14/14] contrib/plugins/execlog: fix new warnings

2024-01-29 Thread Pierrick Bouvier

On 1/26/24 20:31, Alex Bennée wrote:

Pierrick Bouvier  writes:


‘g_pattern_match_string’ is deprecated,
Use 'g_pattern_spec_match_string' instead.


Unfortunately this isn't enough as we can still build on older glibs:

   /* Ask for warnings for anything that was marked deprecated in
* the defined version, or before. It is a candidate for rewrite.
*/
   #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56

You can do something like:

   /*
* g_pattern_match_string has been deprecated in Glib since 2.70 and
* will complain about it if you try to use it. Fortunately the
* signature of both functions is the same making it easy to work
* around.
*/
   static inline
   gboolean g_pattern_spec_match_string_qemu(GPatternSpec *pspec,
 const gchar *string)
   {
   #if GLIB_CHECK_VERSION(2, 70, 0)
   return g_pattern_spec_match_string(pspec, string);
   #else
   return g_pattern_match_string(pspec, string);
   #endif
   };
   #define g_pattern_spec_match_string(p, s) 
g_pattern_spec_match_string_qemu(p, s)

in glib-compat.h but I was wondering if it would be valid to add that
dependency to plugins. We might get away with it as it doesn't include
anything from QEMU itself.



Oh I see.
Since it's the only plugin using this so far, and it's a "contrib" 
plugins, I'll simply drop this patch for now. We can always discuss this 
again in the future.


I think you are right, and it's not worth adding this to glib-compat.h.



passing argument 2 of ‘g_ptr_array_add’ discards ‘const’ qualifier from
pointer target type

Signed-off-by: Pierrick Bouvier 
---
  contrib/plugins/execlog.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index 5a4de1c93be..d12137ce5c0 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -336,8 +336,8 @@ static void registers_init(int vcpu_index)
  for (int p = 0; p < rmatches->len; p++) {
  g_autoptr(GPatternSpec) pat = 
g_pattern_spec_new(rmatches->pdata[p]);
  g_autofree gchar *rd_lower = g_utf8_strdown(rd->name, -1);
-if (g_pattern_match_string(pat, rd->name) ||
-g_pattern_match_string(pat, rd_lower)) {
+if (g_pattern_spec_match_string(pat, rd->name) ||
+g_pattern_spec_match_string(pat, rd_lower)) {
  Register *reg = init_vcpu_register(vcpu_index, rd);
  g_ptr_array_add(registers, reg);
  
@@ -345,7 +345,7 @@ static void registers_init(int vcpu_index)

  if (disas_assist) {
  g_mutex_lock(_reg_name_lock);
  if (!g_ptr_array_find(all_reg_names, reg->name, 
NULL)) {
-g_ptr_array_add(all_reg_names, reg->name);
+g_ptr_array_add(all_reg_names, 
(gpointer)reg->name);
  }
  g_mutex_unlock(_reg_name_lock);
  }




Re: [PATCH v3 26/29] target/sparc: Prefer fast cpu_env() over slower CPU QOM cast macro

2024-01-29 Thread Philippe Mathieu-Daudé

On 29/1/24 17:45, Philippe Mathieu-Daudé wrote:

Mechanical patch produced running the command documented
in scripts/coccinelle/cpu_env.cocci_template header.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
  target/sparc/cpu.c  | 17 +
  target/sparc/gdbstub.c  |  3 +--
  target/sparc/int32_helper.c |  3 +--
  target/sparc/int64_helper.c |  3 +--
  target/sparc/ldst_helper.c  |  6 ++
  target/sparc/mmu_helper.c   | 15 +--
  target/sparc/translate.c|  9 +++--
  7 files changed, 18 insertions(+), 38 deletions(-)


Per v2:
Reviewed-by: Mark Cave-Ayland 

(https://lore.kernel.org/qemu-devel/140c63fc-f99c-41f3-b96c-5f9d88fa8...@ilande.co.uk/)



Re: [PATCH 01/33] include/hw/core: Add mmu_index to CPUClass

2024-01-29 Thread Richard Henderson

On 1/30/24 17:46, Philippe Mathieu-Daudé wrote:

Hi Richard,

On 30/1/24 00:30, Richard Henderson wrote:

To be used after all targets have populated the hook.

Signed-off-by: Richard Henderson 
---
  include/hw/core/cpu.h | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 2c284d6397..4385ce54c9 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -103,6 +103,8 @@ struct SysemuCPUOps;
   * @parse_features: Callback to parse command line arguments.
   * @reset_dump_flags: #CPUDumpFlags to use for reset logging.
   * @has_work: Callback for checking if there is work to do.
+ * @mmu_index: Callback for choosing softmmu mmu index;
+ *   may be used internally by memory_rw_debug without TCG.
   * @memory_rw_debug: Callback for GDB memory access.
   * @dump_state: Callback for dumping state.
   * @query_cpu_fast:
@@ -150,6 +152,7 @@ struct CPUClass {
  void (*parse_features)(const char *typename, char *str, Error **errp);
  bool (*has_work)(CPUState *cpu);
+    int (*mmu_index)(CPUState *cpu, bool ifetch);


Can the index ever be negative?


No.


Would it be useful to also have a mmu_index_max() so we could
check mmu_index() is in range in the final cpu_mmu_index()?


We have NB_MMU_MODES, a target-independent constant.


r~




Re: [PATCH v2 05/14] tests/plugin: add test plugin for inline operations

2024-01-29 Thread Pierrick Bouvier

On 1/26/24 20:05, Alex Bennée wrote:

Pierrick Bouvier  writes:


For now, it simply performs instruction, bb and mem count, and ensure
that inline vs callback versions have the same result. Later, we'll
extend it when new inline operations are added.

Use existing plugins to test everything works is a bit cumbersome, as
different events are treated in different plugins. Thus, this new one.

Signed-off-by: Pierrick Bouvier 
---
  tests/plugin/inline.c| 182 +++
  tests/plugin/meson.build |   2 +-
  2 files changed, 183 insertions(+), 1 deletion(-)
  create mode 100644 tests/plugin/inline.c

diff --git a/tests/plugin/inline.c b/tests/plugin/inline.c
new file mode 100644
index 000..28d1c3b1e48
--- /dev/null
+++ b/tests/plugin/inline.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2023, Pierrick Bouvier 
+ *
+ * Demonstrates and tests usage of inline ops.
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+typedef struct {
+uint64_t count_tb;
+uint64_t count_tb_inline;
+uint64_t count_insn;
+uint64_t count_insn_inline;
+uint64_t count_mem;
+uint64_t count_mem_inline;
+} CPUCount;


I wonder if there is any way to enforce the structures being an array of
64 bit counts? I do worry the compiler might want day decide to do
something silly but legal leading to confusion.

I guess qemu_plugin_scoreboard_new could:

   g_assert((element_size % sizeof(uint64_t)) == 0)



Given explaination on patch [02/14], do you see more that CPUCount could 
hold any type, and qemu_plugin_u64 allows to target a specific member in it?


In general, qemu plugin runtime simply is given an offset and total size 
of the struct, so a compiled plugin can have any optimization/padding on 
this struct without this affecting the result.



?


+static qemu_plugin_u64_t count_tb;
+static qemu_plugin_u64_t count_tb_inline;
+static qemu_plugin_u64_t count_insn;
+static qemu_plugin_u64_t count_insn_inline;
+static qemu_plugin_u64_t count_mem;
+static qemu_plugin_u64_t count_mem_inline;


Can't this just be a non scoreboard instance of CPUCount?



We could always use:
CPUCount* count = qemu_plugin_scoreboard_get(score, i);
count->count_tb++;

However, the part where we sum all values would now need some glue code, 
which is longer and more error prone than having those definition here 
(and declaration in install function).



+
+static uint64_t global_count_tb;
+static uint64_t global_count_insn;
+static uint64_t global_count_mem;
+static unsigned int max_cpu_index;
+static GMutex tb_lock;
+static GMutex insn_lock;
+static GMutex mem_lock;
+
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
+static void stats_insn(void)
+{
+const uint64_t expected = global_count_insn;
+const uint64_t per_vcpu = qemu_plugin_u64_sum(count_insn);
+const uint64_t inl_per_vcpu =
+qemu_plugin_u64_sum(count_insn_inline);
+printf("insn: %" PRIu64 "\n", expected);
+printf("insn: %" PRIu64 " (per vcpu)\n", per_vcpu);
+printf("insn: %" PRIu64 " (per vcpu inline)\n", inl_per_vcpu);
+g_assert(expected > 0);
+g_assert(per_vcpu == expected);
+g_assert(inl_per_vcpu == expected);
+}
+
+static void stats_tb(void)
+{
+const uint64_t expected = global_count_tb;
+const uint64_t per_vcpu = qemu_plugin_u64_sum(count_tb);
+const uint64_t inl_per_vcpu =
+qemu_plugin_u64_sum(count_tb_inline);
+printf("tb: %" PRIu64 "\n", expected);
+printf("tb: %" PRIu64 " (per vcpu)\n", per_vcpu);
+printf("tb: %" PRIu64 " (per vcpu inline)\n", inl_per_vcpu);
+g_assert(expected > 0);
+g_assert(per_vcpu == expected);
+g_assert(inl_per_vcpu == expected);
+}
+
+static void stats_mem(void)
+{
+const uint64_t expected = global_count_mem;
+const uint64_t per_vcpu = qemu_plugin_u64_sum(count_mem);
+const uint64_t inl_per_vcpu =
+qemu_plugin_u64_sum(count_mem_inline);
+printf("mem: %" PRIu64 "\n", expected);
+printf("mem: %" PRIu64 " (per vcpu)\n", per_vcpu);
+printf("mem: %" PRIu64 " (per vcpu inline)\n", inl_per_vcpu);
+g_assert(expected > 0);
+g_assert(per_vcpu == expected);
+g_assert(inl_per_vcpu == expected);
+}
+
+static void plugin_exit(qemu_plugin_id_t id, void *udata)
+{
+const unsigned int num_cpus = qemu_plugin_scoreboard_size(counts);
+g_assert(num_cpus == max_cpu_index + 1);
+
+for (int i = 0; i < num_cpus ; ++i) {
+const uint64_t tb = *qemu_plugin_u64_get(count_tb, i);
+const uint64_t tb_inline = *qemu_plugin_u64_get(count_tb_inline, i);
+const uint64_t insn = *qemu_plugin_u64_get(count_insn, i);
+const uint64_t insn_inline = *qemu_plugin_u64_get(count_insn_inline, 
i);
+const uint64_t mem = *qemu_plugin_u64_get(count_mem, i);
+const uint64_t mem_inline = *qemu_plugin_u64_get(count_mem_inline, i);
+printf("cpu %d: 

Re: Assistance Required for QEMU Hardfault Error with Cortex-M33 on MPS2AN505

2024-01-29 Thread sanjana gogte
I wanted to express my gratitude for your insightful solution concerning
the INVSTATE fault I was encountering. After recompiling my code with the
-mthumb compiler flag, the exception is no longer being raised, which marks
a significant step forward in my project.

However, I've encountered another challenge while working with a specific
version of QEMU (QEMU emulator version 7.1.0, v2.6.0-55433-g23b643ba16).
While the code runs flawlessly on QEMU version 8.1.50
(v8.1.0-2375-g516fffc993), the earlier version throws a hard fault, which
is critical to my use case.

The use case involves attaching a remote port to the MPS2-AN505, and for
this, I need to utilize Xilinx’s fork of QEMU, which is based on version
7.1.0 (v2.6.0-55433-g23b643ba16). The error I encounter during emulation is
as follows:

Loaded reset SP 0x0 PC 0x0 from vector table
Loaded reset SP 0x1008 PC 0x1009 from vector table
Taking exception 3 [Prefetch Abort] on CPU 0
...at fault address 0x1080
...with CFSR.IBUSERR
...taking pending secure exception 3
...loading from element 3 00c
...loaded new PC 0x1011 of secure vector table at 0x1
Taking exception 3 [Prefetch Abort] on CPU 0
...at fault address 0x1080
...with CFSR.IBUSERR
qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)

Observations: When I trace it using the GDB:

Remote debugging using: 1234


Reset_Handler () at boot.s:20

20  blx helper

(gdb) l

15 blx R0

16

17  .type Reset_Handler, function

18  .global Reset_Handler

19  Reset_Handler:

20  blx helper

21  bx  lr

22

(gdb) s

Remote connection closed



It goes to prefetch abort as soon as I step into reset handler and the
connection gets closed.
What I do not understand is:

1) Why is my PC going to address 0x1080?


2) When I use Qemu version 8.1.50 (v8.1.0-2375-g516fffc993), the PC goes to
the right address and does not throw a prefetch abort.


Please give me your insights on how I can fix this.


Some of my code for your reference:


My startup code :

.syntax unified

.thumb


.section .isr_vector

.long__StackTop

.longReset_Handler




.text

.type helper,function

.global helper

helper :

   ldr R0, = main

   blx R0


.type Reset_Handler, function

.global Reset_Handler

Reset_Handler:

blx helper

bx  lr



( Like you mentioned  previously , In the .isr_vector section I tried making
the other exception handlers  point to branch-to-self instructions but that
gives me the same error )


My linker code :


/* Linker script to configure memory regions. */

MEMORY

{

   NS_CODE (rx) : ORIGIN = 0x, LENGTH = 512K

   S_CODE_BOOT (rx) : ORIGIN = 0x1000, LENGTH = 512K

   RAM   (rwx) : ORIGIN = 0x2000, LENGTH = 512K

}


/* Entry Point */

ENTRY(Reset_Handler)


SECTIONS

{

.text :

{

KEEP(*(.isr_vector))

*(.text)

*(.data)

*(.bss)

} > S_CODE_BOOT

/* Set stack top to end of S_CODE_BOOT. */

__StackTop = ORIGIN(S_CODE_BOOT) + LENGTH(S_CODE_BOOT);




}


kernel.list file :


kernel.elf: file format elf32-littlearm


Disassembly of section .text:

1000 :
1000: 1008 .word 0x1008
1004: 100d .word 0x100d

1008 :
1008: 4802   ldr r0, [pc, #8] @ (1014 )
100a: 4780   blx r0

100c :
100c: f7ff fffc bl 1008 
1010: 4770   bx lr
1012:    .short 0x
1014: 1019 .word 0x1019

1018 :
1018: b480   push {r7}
101a: af00   add r7, sp, #0
101c: e7fe   b.n 101c 






On Thu, 18 Jan 2024 at 15:34, Peter Maydell 
wrote:

> On Thu, 18 Jan 2024 at 06:30, sanjana gogte  wrote:
> >
> > Hi,
> > 1) I am using QEMU Version 7.1.0. I am currently using this version with
> a plan to connect the remote port from Xilinx to the mps2an505 board. The
> decision to use this specific version is heavily influenced by the fact
> that it is the same version utilized by Xilinx's QEMU.
> >
> > 2) Debug Logs :
> > guest_errors:
> >
> > Invalid read at addr 0x1000, size 4, region '(null)', reason:
> rejected
> > Invalid read at addr 0x1004, size 4, region '(null)', reason:
> rejected
> > Invalid read at addr 0x1080, size 2, region '(null)', reason:
> rejected
> > qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)
> >
> > in_asm:
>
> >
> > IN:
> > 0x1008:
> > OBJD-T: 00480047
>
> Whoever built your QEMU didn't do it with libcapstone-dev
> installed, so the debug logs have only binary dumps of
> instructions, not the actual instructions, which is a pity
> (--enable-capstone will force configure to either find the
> necessary library or else give you an error message.)
>
> Also, I did not mean "do logs of every -d option separately",
> I meant "do a single log, with -d
> in_asm,exec,cpu,int,cpu_reset,unimp,guest_errors,nochain"
> That way you get the different bits of logging in 

Re: [PATCH 2/4] isa: extract FDC37M81X to a separate file

2024-01-29 Thread Philippe Mathieu-Daudé

On 29/1/24 21:26, Paolo Bonzini wrote:

On Mon, Jan 29, 2024 at 8:49 PM Bernhard Beschow  wrote:

Don't we prefer a macro for below code? While touching the code we could use 
it. (Sorry I can't recall its name from the top of my head and I don't have 
access to the code right now).


Ah yeah, OBJECT_DEFINE_TYPE. Not sure it's much of a win because
neither finalize or instance_init are required here.


Bernhard likely meant type_init() -> DEFINE_TYPES().




Re: [PATCH 01/33] include/hw/core: Add mmu_index to CPUClass

2024-01-29 Thread Philippe Mathieu-Daudé

Hi Richard,

On 30/1/24 00:30, Richard Henderson wrote:

To be used after all targets have populated the hook.

Signed-off-by: Richard Henderson 
---
  include/hw/core/cpu.h | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 2c284d6397..4385ce54c9 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -103,6 +103,8 @@ struct SysemuCPUOps;
   * @parse_features: Callback to parse command line arguments.
   * @reset_dump_flags: #CPUDumpFlags to use for reset logging.
   * @has_work: Callback for checking if there is work to do.
+ * @mmu_index: Callback for choosing softmmu mmu index;
+ *   may be used internally by memory_rw_debug without TCG.
   * @memory_rw_debug: Callback for GDB memory access.
   * @dump_state: Callback for dumping state.
   * @query_cpu_fast:
@@ -150,6 +152,7 @@ struct CPUClass {
  void (*parse_features)(const char *typename, char *str, Error **errp);
  
  bool (*has_work)(CPUState *cpu);

+int (*mmu_index)(CPUState *cpu, bool ifetch);


Can the index ever be negative?

Would it be useful to also have a mmu_index_max() so we could
check mmu_index() is in range in the final cpu_mmu_index()?


  int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
 uint8_t *buf, int len, bool is_write);
  void (*dump_state)(CPUState *cpu, FILE *, int flags);





Re: [PATCH 09/33] target/hppa: Populate CPUClass.mmu_index

2024-01-29 Thread Helge Deller

On 1/30/24 00:30, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  target/hppa/cpu.h |  7 ++-
  target/hppa/cpu.c | 12 
  2 files changed, 14 insertions(+), 5 deletions(-)


Reviewed-by: Helge Deller 





diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 6a153405d2..04439f247d 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -281,16 +281,13 @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
  return hppa_is_pa20(env) ? 0 : PA10_BTLB_FIXED + PA10_BTLB_VARIABLE;
  }

+int hppa_cpu_mmu_index(CPUState *cs, bool ifetch);
  static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch)
  {
  #ifdef CONFIG_USER_ONLY
  return MMU_USER_IDX;
  #else
-if (env->psw & (ifetch ? PSW_C : PSW_D)) {
-return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
-}
-/* mmu disabled */
-return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
+return hppa_cpu_mmu_index(env_cpu(env), ifetch);
  #endif
  }

diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 3c019855b4..fbb37e541e 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -94,6 +94,17 @@ static bool hppa_cpu_has_work(CPUState *cs)
  return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
  }

+int hppa_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+CPUHPPAState *env = cpu_env(cs);
+
+if (env->psw & (ifetch ? PSW_C : PSW_D)) {
+return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
+}
+/* mmu disabled */
+return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
+}
+
  static void hppa_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
  {
  info->mach = bfd_mach_hppa20;
@@ -194,6 +205,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)

  cc->class_by_name = hppa_cpu_class_by_name;
  cc->has_work = hppa_cpu_has_work;
+cc->mmu_index = hppa_cpu_mmu_index;
  cc->dump_state = hppa_cpu_dump_state;
  cc->set_pc = hppa_cpu_set_pc;
  cc->get_pc = hppa_cpu_get_pc;





Re: [PATCH v2 02/14] plugins: scoreboard API

2024-01-29 Thread Pierrick Bouvier

On 1/26/24 19:14, Alex Bennée wrote:

Pierrick Bouvier  writes:


We introduce a cpu local storage, automatically managed (and extended)
by QEMU itself. Plugin allocate a scoreboard, and don't have to deal
with how many cpus are launched.

This API will be used by new inline functions but callbacks can benefit
from this as well. This way, they can operate without a global lock for
simple operations.

New functions:
- qemu_plugin_scoreboard_free
- qemu_plugin_scoreboard_get
- qemu_plugin_scoreboard_new
- qemu_plugin_scoreboard_size

In more, we define a qemu_plugin_u64_t, which is a simple struct holding
a pointer to a scoreboard, and a given offset.
This allows to have a scoreboard containing structs, without having to
bring offset for all operations on a specific field.

Since most of the plugins are simply collecting a sum of per-cpu values,
qemu_plugin_u64_t directly support this operation as well.

New functions:
- qemu_plugin_u64_get
- qemu_plugin_u64_sum
New macros:
- qemu_plugin_u64
- qemu_plugin_u64_struct

Signed-off-by: Pierrick Bouvier 
---
  include/qemu/plugin.h|  7 +++
  include/qemu/qemu-plugin.h   | 75 
  plugins/api.c| 39 +++
  plugins/core.c   | 97 
  plugins/plugin.h |  8 +++
  plugins/qemu-plugins.symbols |  6 +++
  6 files changed, 232 insertions(+)

diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index 9346249145d..5f340192e56 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -115,6 +115,13 @@ struct qemu_plugin_insn {
  bool mem_only;
  };
  
+/* A scoreboard is an array of values, indexed by vcpu_index */

+struct qemu_plugin_scoreboard {
+GArray *data;
+size_t size;


Can we get size from GArray->len itself?



GArray->len matches the allocated size, which is different from 
"semantic" size. I'll answer to why it was implemented this way in a 
next comment.



+size_t element_size;
+};
+
  /*
   * qemu_plugin_insn allocate and cleanup functions. We don't expect to
   * cleanup many of these structures. They are reused for each fresh
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 2c1930e7e45..934059d64c2 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -220,6 +220,23 @@ void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t 
id,
  struct qemu_plugin_tb;
  /** struct qemu_plugin_insn - Opaque handle for a translated instruction */
  struct qemu_plugin_insn;
+/**
+ * struct qemu_plugin_scoreboard - Opaque handle for a scoreboard
+ *
+ * A scoreboard is an array of data, indexed by vcpu_index.
+ **/


stray *'s - I think this is what trips up kdoc.



Thanks, fixed that in a new version. I now build with documentation 
enabled, so should not happen again, sorry.



+struct qemu_plugin_scoreboard;
+
+/**
+ * qemu_plugin_u64_t - uint64_t member of an entry in a scoreboard


We generally reserve lower_case_with_underscores_ending_with_a_t for
scalar types. Its also a little generic. Maybe qemu_plugin_scoreboard_ref?



For _t suffix, I hesitated on this, and followed the qemu_info_t struct 
example in the same header.


In the beginning, I picked qemu_plugin_scoreboard_u64, but realized the 
name was far too long. qemu_plugin_u64 seemed like the right spot 
between length/meaning.
I would like to defend the u64 meaning, because it was explicitely made 
to express u64 type, instead of a generic scoreboard entry/ref.


In more, based on other comments made, maybe it was not clear that a 
qemu_plugin_u64 does not necessarily point to a "whole" entry in 
scoreboard, but it can target a struct member (u64) in a given entry as 
well. (i.e. scoreboard[i].member). I'll give a more detailed answer 
below in this message.


This way, scoreboard can be composed of struct values, and a 
qemu_plugin_u64 allows to work on a specific member of that struct 
without having to manipulate offset everywhere. Thus the get and sum 
operation on this type.


Does it makes more sense to you given this?


+ *
+ * This field allows to access a specific uint64_t member in one given entry,
+ * located at a specified offset. Inline operations expect this as entry.
+ */
+typedef struct qemu_plugin_u64 {

 > I don't think you need the forward declaration here (which clashes later
on).



Initially wrote this without a typedef, and left this afterwards. Will 
remove it, thanks!



+struct qemu_plugin_scoreboard *score;
+size_t offset;
+} qemu_plugin_u64_t;
  
  /**

   * enum qemu_plugin_cb_flags - type of callback
@@ -754,5 +771,63 @@ int qemu_plugin_read_register(unsigned int vcpu,
struct qemu_plugin_register *handle,
GByteArray *buf);
  
+/**

+ * qemu_plugin_scoreboard_new() - alloc a new scoreboard
+ *
+ * Returns a pointer to a new scoreboard. It must be freed using
+ * qemu_plugin_scoreboard_free.
+ */
+QEMU_PLUGIN_API

[PATCH v3 2/2] hw/block/block.c: improve confusing blk_check_size_and_read_all() error

2024-01-29 Thread Manos Pitsidianakis
In cases where a device tries to read more bytes than the block device
contains, the error is vague: "device requires X bytes, block backend
provides Y bytes".

This patch changes the errors of this function to include the block
backend name, the device id and device type name where appropriate.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Manos Pitsidianakis 
---
 include/hw/block/block.h |  4 ++--
 hw/block/block.c | 25 +++--
 hw/block/m25p80.c|  3 ++-
 hw/block/pflash_cfi01.c  |  4 ++--
 hw/block/pflash_cfi02.c  |  2 +-
 5 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 15fff66435..de3946a5f1 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -88,8 +88,8 @@ static inline unsigned int get_physical_block_exp(BlockConf 
*conf)
 
 /* Backend access helpers */
 
-bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size,
- Error **errp);
+bool blk_check_size_and_read_all(BlockBackend *blk, DeviceState *dev,
+ void *buf, hwaddr size, Error **errp);
 
 /* Configuration helpers */
 
diff --git a/hw/block/block.c b/hw/block/block.c
index 9f52ee6e72..ec4a675490 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -54,29 +54,30 @@ static int blk_pread_nonzeroes(BlockBackend *blk, hwaddr 
size, void *buf)
  * BDRV_REQUEST_MAX_BYTES.
  * On success, return true.
  * On failure, store an error through @errp and return false.
- * Note that the error messages do not identify the block backend.
- * TODO Since callers don't either, this can result in confusing
- * errors.
+ *
  * This function not intended for actual block devices, which read on
  * demand.  It's for things like memory devices that (ab)use a block
  * backend to provide persistence.
  */
-bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size,
- Error **errp)
+bool blk_check_size_and_read_all(BlockBackend *blk, DeviceState *dev,
+ void *buf, hwaddr size, Error **errp)
 {
 int64_t blk_len;
 int ret;
+g_autofree char *dev_id = NULL;
 
 blk_len = blk_getlength(blk);
 if (blk_len < 0) {
 error_setg_errno(errp, -blk_len,
- "can't get size of block backend");
+ "can't get size of %s block backend", blk_name(blk));
 return false;
 }
 if (blk_len != size) {
-error_setg(errp, "device requires %" HWADDR_PRIu " bytes, "
-   "block backend provides %" PRIu64 " bytes",
-   size, blk_len);
+dev_id = qdev_get_human_name(dev);
+error_setg(errp, "%s device '%s' requires %" HWADDR_PRIu
+   " bytes, %s block backend provides %" PRIu64 " bytes",
+   object_get_typename(OBJECT(dev)), dev_id, size,
+   blk_name(blk), blk_len);
 return false;
 }
 
@@ -89,7 +90,11 @@ bool blk_check_size_and_read_all(BlockBackend *blk, void 
*buf, hwaddr size,
 assert(size <= BDRV_REQUEST_MAX_BYTES);
 ret = blk_pread_nonzeroes(blk, size, buf);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "can't read block backend");
+dev_id = qdev_get_human_name(dev);
+error_setg_errno(errp, -ret, "can't read %s block backend"
+ " for %s device '%s'",
+ blk_name(blk), object_get_typename(OBJECT(dev)),
+ dev_id);
 return false;
 }
 return true;
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 26ce895628..0a12030a3a 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -1617,7 +1617,8 @@ static void m25p80_realize(SSIPeripheral *ss, Error 
**errp)
 trace_m25p80_binding(s);
 s->storage = blk_blockalign(s->blk, s->size);
 
-if (!blk_check_size_and_read_all(s->blk, s->storage, s->size, errp)) {
+if (!blk_check_size_and_read_all(s->blk, DEVICE(s),
+ s->storage, s->size, errp)) {
 return;
 }
 } else {
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index f956f8bcf7..1bda8424b9 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -848,8 +848,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
 }
 
 if (pfl->blk) {
-if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, total_len,
- errp)) {
+if (!blk_check_size_and_read_all(pfl->blk, dev, pfl->storage,
+ total_len, errp)) {
 vmstate_unregister_ram(>mem, DEVICE(pfl));
 return;
 }
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 6fa56f14c0..2314142373 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -902,7 +902,7 

[PATCH v3 1/2] hw/core/qdev.c: add qdev_get_human_name()

2024-01-29 Thread Manos Pitsidianakis
Add a simple method to return some kind of human readable identifier for
use in error messages.

Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Manos Pitsidianakis 
---
 include/hw/qdev-core.h | 14 ++
 hw/core/qdev.c |  8 
 2 files changed, 22 insertions(+)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 151d968238..66338f479f 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -993,6 +993,20 @@ const char *qdev_fw_name(DeviceState *dev);
 void qdev_assert_realized_properly(void);
 Object *qdev_get_machine(void);
 
+/**
+ * qdev_get_human_name() - Return a human-readable name for a device
+ * @dev: The device. Must be a valid and non-NULL pointer.
+ *
+ * .. note::
+ *This function is intended for user friendly error messages.
+ *
+ * Returns: A newly allocated string containing the device id if not null,
+ * else the object canonical path.
+ *
+ * Use g_free() to free it.
+ */
+char *qdev_get_human_name(DeviceState *dev);
+
 /* FIXME: make this a link<> */
 bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
 
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 43d863b0c5..c68d0f7c51 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -879,6 +879,14 @@ Object *qdev_get_machine(void)
 return dev;
 }
 
+char *qdev_get_human_name(DeviceState *dev)
+{
+g_assert(dev != NULL);
+
+return dev->id ?
+   g_strdup(dev->id) : object_get_canonical_path(OBJECT(dev));
+}
+
 static MachineInitPhase machine_phase;
 
 bool phase_check(MachineInitPhase phase)
-- 
γαῖα πυρί μιχθήτω




[PATCH v3 0/2] hw/block/block.c: improve confusing error

2024-01-29 Thread Manos Pitsidianakis
In cases where a device tries to read more bytes than the block device
contains with the blk_check_size_and_read_all() function, the error is
vague: "device requires X bytes, block backend provides Y bytes".

This patch changes the errors of this function to include the block
backend name, the device id and device type name where appropriate.

Version 3:
- Changed phrasing "%s device with id='%s'" to "%s device '%s'" since
  second parameter might be either device id or device path.
(thanks Stefan Hajnoczi )

Version 2:
- Assert dev is not NULL on qdev_get_human_name
(thanks Phil Mathieu-Daudé )

Manos Pitsidianakis (2):
  hw/core/qdev.c: add qdev_get_human_name()
  hw/block/block.c: improve confusing blk_check_size_and_read_all()
error

 include/hw/block/block.h |  4 ++--
 include/hw/qdev-core.h   | 14 ++
 hw/block/block.c | 25 +++--
 hw/block/m25p80.c|  3 ++-
 hw/block/pflash_cfi01.c  |  4 ++--
 hw/block/pflash_cfi02.c  |  2 +-
 hw/core/qdev.c   |  8 
 7 files changed, 44 insertions(+), 16 deletions(-)

Range-diff against v2:
1:  5fb5879708 ! 1:  8b566bfced hw/core/qdev.c: add qdev_get_human_name()
@@ Commit message
 Add a simple method to return some kind of human readable identifier 
for
 use in error messages.
 
+Reviewed-by: Stefan Hajnoczi 
 Signed-off-by: Manos Pitsidianakis 
 
  ## include/hw/qdev-core.h ##
2:  8e7eb17fbd ! 2:  7260eadff2 hw/block/block.c: improve confusing 
blk_check_size_and_read_all() error
@@ hw/block/block.c: static int blk_pread_nonzeroes(BlockBackend *blk, 
hwaddr size,
 -   "block backend provides %" PRIu64 " bytes",
 -   size, blk_len);
 +dev_id = qdev_get_human_name(dev);
-+error_setg(errp, "%s device with id='%s' requires %" HWADDR_PRIu
++error_setg(errp, "%s device '%s' requires %" HWADDR_PRIu
 +   " bytes, %s block backend provides %" PRIu64 " bytes",
 +   object_get_typename(OBJECT(dev)), dev_id, size,
 +   blk_name(blk), blk_len);
@@ hw/block/block.c: bool blk_check_size_and_read_all(BlockBackend *blk, 
void *buf,
 -error_setg_errno(errp, -ret, "can't read block backend");
 +dev_id = qdev_get_human_name(dev);
 +error_setg_errno(errp, -ret, "can't read %s block backend"
-+ "for %s device with id='%s'",
++ " for %s device '%s'",
 + blk_name(blk), object_get_typename(OBJECT(dev)),
 + dev_id);
  return false;

base-commit: 11be70677c70fdccd452a3233653949b79e97908
-- 
γαῖα πυρί μιχθήτω




Re: [PATCH] backends/hostmem: Fix block comments style (checkpatch.pl warnings)

2024-01-29 Thread Xiaoyao Li

On 1/30/2024 2:31 AM, Philippe Mathieu-Daudé wrote:

While re-indenting code in host_memory_backend_memory_complete(),
we triggered various "Block comments use a leading /* on a separate
line" warnings from checkpatch.pl. Correct the comments style.

Fixes: e199f7ad4d ("backends: Simplify host_memory_backend_memory_complete()")
Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Xiaoyao Li 


---
  backends/hostmem.c | 12 
  1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/backends/hostmem.c b/backends/hostmem.c
index 30f69b2cb5..987f6f591e 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -344,9 +344,11 @@ host_memory_backend_memory_complete(UserCreatable *uc, 
Error **errp)
  unsigned long lastbit = find_last_bit(backend->host_nodes, MAX_NODES);
  /* lastbit == MAX_NODES means maxnode = 0 */
  unsigned long maxnode = (lastbit + 1) % (MAX_NODES + 1);
-/* ensure policy won't be ignored in case memory is preallocated
+/*
+ * Ensure policy won't be ignored in case memory is preallocated
   * before mbind(). note: MPOL_MF_STRICT is ignored on hugepages so
- * this doesn't catch hugepage case. */
+ * this doesn't catch hugepage case.
+ */
  unsigned flags = MPOL_MF_STRICT | MPOL_MF_MOVE;
  int mode = backend->policy;
  
@@ -363,7 +365,8 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)

  return;
  }
  
-/* We can have up to MAX_NODES nodes, but we need to pass maxnode+1

+/*
+ * We can have up to MAX_NODES nodes, but we need to pass maxnode+1
   * as argument to mbind() due to an old Linux bug (feature?) which
   * cuts off the last specified node. This means backend->host_nodes
   * must have MAX_NODES+1 bits available.
@@ -391,7 +394,8 @@ host_memory_backend_memory_complete(UserCreatable *uc, 
Error **errp)
  }
  }
  #endif
-/* Preallocate memory after the NUMA policy has been instantiated.
+/*
+ * Preallocate memory after the NUMA policy has been instantiated.
   * This is necessary to guarantee memory is allocated with
   * specified NUMA policy in place.
   */





Re: [PATCH v2 1/2] hw/smbios: Fix OEM strings table option validation

2024-01-29 Thread Ani Sinha



> On 29-Jan-2024, at 13:33, Akihiko Odaki  wrote:
> 
> qemu_smbios_type11_opts did not have the list terminator and that
> resulted in out-of-bound memory access. It also needs to have an element
> for the type option.
> 
> Cc: qemu-sta...@nongnu.org
> Fixes: 2d6dcbf93fb0 ("smbios: support setting OEM strings table")
> Signed-off-by: Akihiko Odaki 
> Reviewed-by: Michael Tokarev 

Reviewed-by: Ani Sinha 
> ---
> hw/smbios/smbios.c | 6 ++
> 1 file changed, 6 insertions(+)
> 
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 2a90601ac5d9..522ed1ed9fe3 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -369,6 +369,11 @@ static const QemuOptDesc qemu_smbios_type8_opts[] = {
> };
> 
> static const QemuOptDesc qemu_smbios_type11_opts[] = {
> +{
> +.name = "type",
> +.type = QEMU_OPT_NUMBER,
> +.help = "SMBIOS element type",
> +},
> {
> .name = "value",
> .type = QEMU_OPT_STRING,
> @@ -379,6 +384,7 @@ static const QemuOptDesc qemu_smbios_type11_opts[] = {
> .type = QEMU_OPT_STRING,
> .help = "OEM string data from file",
> },
> +{ /* end of list */ }
> };
> 
> static const QemuOptDesc qemu_smbios_type17_opts[] = {
> 
> -- 
> 2.43.0
> 




Re: [PATCH v2 2/2] hw/smbios: Fix port connector option validation

2024-01-29 Thread Ani Sinha



> On 29-Jan-2024, at 13:33, Akihiko Odaki  wrote:
> 
> qemu_smbios_type8_opts did not have the list terminator and that
> resulted in out-of-bound memory access. It also needs to have an element
> for the type option.
> 
> Cc: qemu-sta...@nongnu.org
> Fixes: fd8caa253c56 ("hw/smbios: support for type 8 (port connector)")
> Signed-off-by: Akihiko Odaki 
> Reviewed-by: Michael Tokarev 

Reviewed-by: Ani Sinha 

> ---
> hw/smbios/smbios.c | 6 ++
> 1 file changed, 6 insertions(+)
> 
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 522ed1ed9fe3..8a44d3f271de 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -346,6 +346,11 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
> };
> 
> static const QemuOptDesc qemu_smbios_type8_opts[] = {
> +{
> +.name = "type",
> +.type = QEMU_OPT_NUMBER,
> +.help = "SMBIOS element type",
> +},
> {
> .name = "internal_reference",
> .type = QEMU_OPT_STRING,
> @@ -366,6 +371,7 @@ static const QemuOptDesc qemu_smbios_type8_opts[] = {
> .type = QEMU_OPT_NUMBER,
> .help = "port type",
> },
> +{ /* end of list */ }
> };
> 
> static const QemuOptDesc qemu_smbios_type11_opts[] = {
> 
> -- 
> 2.43.0
> 




Re: [PATCH v5 6/6] tests/qtest/pvpanic: add tests for pvshutdown event

2024-01-29 Thread Thomas Huth

On 29/01/2024 20.28, Thomas Weißschuh wrote:

Validate that a shutdown via the pvpanic device emits the correct
QMP events.

Signed-off-by: Thomas Weißschuh 
---
  tests/qtest/pvpanic-pci-test.c | 39 +++
  tests/qtest/pvpanic-test.c | 29 +
  2 files changed, 68 insertions(+)

diff --git a/tests/qtest/pvpanic-pci-test.c b/tests/qtest/pvpanic-pci-test.c
index b372caf41dc0..e1c05d383219 100644
--- a/tests/qtest/pvpanic-pci-test.c
+++ b/tests/qtest/pvpanic-pci-test.c
@@ -85,11 +85,50 @@ static void test_panic(void)
  qtest_quit(qts);
  }
  
+static void test_pvshutdown(void)

+{
+uint8_t val;
+QDict *response, *data;
+QTestState *qts;
+QPCIBus *pcibus;
+QPCIDevice *dev;
+QPCIBar bar;
+
+qts = qtest_init("-device pvpanic-pci,addr=04.0");
+pcibus = qpci_new_pc(qts, NULL);
+dev = qpci_device_find(pcibus, QPCI_DEVFN(0x4, 0x0));
+qpci_device_enable(dev);
+bar = qpci_iomap(dev, 0, NULL);
+
+qpci_memread(dev, bar, 0, , sizeof(val));
+g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
+
+val = 4;


Could you use PVPANIC_SHUTDOWN here instead of the magic value?


+qpci_memwrite(dev, bar, 0, , sizeof(val));
+
+response = qtest_qmp_eventwait_ref(qts, "GUEST_PVSHUTDOWN");
+qobject_unref(response);
+
+response = qtest_qmp_eventwait_ref(qts, "SHUTDOWN");
+g_assert(qdict_haskey(response, "data"));
+data = qdict_get_qdict(response, "data");
+g_assert(qdict_haskey(data, "guest"));
+g_assert(qdict_get_bool(data, "guest"));
+g_assert(qdict_haskey(data, "reason"));
+g_assert_cmpstr(qdict_get_str(data, "reason"), ==, "guest-shutdown");
+qobject_unref(response);
+
+g_free(dev);
+qpci_free_pc(pcibus);
+qtest_quit(qts);
+}
+
  int main(int argc, char **argv)
  {
  g_test_init(, , NULL);
  qtest_add_func("/pvpanic-pci/panic", test_panic);
  qtest_add_func("/pvpanic-pci/panic-nopause", test_panic_nopause);
+qtest_add_func("/pvpanic-pci/pvshutdown", test_pvshutdown);
  
  return g_test_run();

  }
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
index ccc603472f5d..ff1f25f46586 100644
--- a/tests/qtest/pvpanic-test.c
+++ b/tests/qtest/pvpanic-test.c
@@ -58,11 +58,40 @@ static void test_panic(void)
  qtest_quit(qts);
  }
  
+static void test_pvshutdown(void)

+{
+uint8_t val;
+QDict *response, *data;
+QTestState *qts;
+
+qts = qtest_init("-device pvpanic");
+
+val = qtest_inb(qts, 0x505);
+g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
+
+qtest_outb(qts, 0x505, 0x4);


dito, use PVPANIC_SHUTDOWN instead of 4 ?

(as a separate clean-up, we should maybe also introduce a #define for 0x505 
one day, but that's something for another patch)



+response = qtest_qmp_eventwait_ref(qts, "GUEST_PVSHUTDOWN");
+qobject_unref(response);
+
+response = qtest_qmp_eventwait_ref(qts, "SHUTDOWN");
+g_assert(qdict_haskey(response, "data"));
+data = qdict_get_qdict(response, "data");
+g_assert(qdict_haskey(data, "guest"));
+g_assert(qdict_get_bool(data, "guest"));
+g_assert(qdict_haskey(data, "reason"));
+g_assert_cmpstr(qdict_get_str(data, "reason"), ==, "guest-shutdown");
+qobject_unref(response);
+
+qtest_quit(qts);
+}
+
  int main(int argc, char **argv)
  {
  g_test_init(, , NULL);
  qtest_add_func("/pvpanic/panic", test_panic);
  qtest_add_func("/pvpanic/panic-nopause", test_panic_nopause);
+qtest_add_func("/pvpanic/pvshutdown", test_pvshutdown);
  
  return g_test_run();

  }



With PVPANIC_SHUTDOWN instead of 4:
Reviewed-by: Thomas Huth 




Re: [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method

2024-01-29 Thread Manos Pitsidianakis

On Tue, 30 Jan 2024 03:26, Gurchetan Singh  wrote:

On Mon, Jan 29, 2024 at 7:46 AM Manos Pitsidianakis <
manos.pitsidiana...@linaro.org> wrote:


When the Rutabaga GPU device frees resources, it calls
rutabaga_resource_unref for that resource_id. However, when the generic
VirtIOGPU functions destroys resources, it only removes the
virtio_gpu_simple_resource from the device's VirtIOGPU->reslist list.
The rutabaga resource associated with that resource_id is then leaked.

This commit overrides the resource_destroy class method introduced in
the previous commit to fix this.

Signed-off-by: Manos Pitsidianakis 
---
 hw/display/virtio-gpu-rutabaga.c | 51 
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/hw/display/virtio-gpu-rutabaga.c
b/hw/display/virtio-gpu-rutabaga.c
index 9e67f9bd51..6ac0776005 100644
--- a/hw/display/virtio-gpu-rutabaga.c
+++ b/hw/display/virtio-gpu-rutabaga.c
@@ -148,14 +148,42 @@ rutabaga_cmd_create_resource_3d(VirtIOGPU *g,
 }

 static void
+virtio_gpu_rutabaga_resource_unref(VirtIOGPU *g,
+   struct virtio_gpu_simple_resource *res,
+   Error **errp)
+{
+int32_t result;
+const char *strerror = NULL;
+VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
+
+result = rutabaga_resource_unref(vr->rutabaga, res->resource_id);
+if (result) {
+error_setg(errp, "%s: rutabaga_resource_unref returned %"PRIi32
+   " for resource_id = %"PRIu32, __func__, result,
+   res->resource_id);
+strerror = strerrorname_np((int)result);
+if (strerror != NULL) {
+error_append_hint(errp, "%s: %s\n",
+  strerror, strerrordesc_np((int)result) ? :
"");
+}



Can't we rely on virtio_gpu_rutabaga_debug_cb(..) to report an error when
the resource ID is not found?



IIUC that callback is called from the external library, and uses its own 
type (const struct rutabaga *debug) which is not how the interface works 
here. rutabaga_resource_unref() returns an int32_t. Besides this isn't a 
debug print but an error print.





+}
+
+if (res->image) {
+pixman_image_unref(res->image);
+}
+
+QTAILQ_REMOVE(>reslist, res, next);
+g_free(res);
+}
+
+static void
 rutabaga_cmd_resource_unref(VirtIOGPU *g,
 struct virtio_gpu_ctrl_command *cmd)
 {
-int32_t result;
+int32_t result = 0;
 struct virtio_gpu_simple_resource *res;
 struct virtio_gpu_resource_unref unref;
-
-VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
+Error *local_err = NULL;

 VIRTIO_GPU_FILL_CMD(unref);

@@ -164,15 +192,14 @@ rutabaga_cmd_resource_unref(VirtIOGPU *g,
 res = virtio_gpu_find_resource(g, unref.resource_id);
 CHECK(res, cmd);

-result = rutabaga_resource_unref(vr->rutabaga, unref.resource_id);
-CHECK(!result, cmd);
-
-if (res->image) {
-pixman_image_unref(res->image);
+virtio_gpu_rutabaga_resource_unref(g, res, _err);
+if (local_err) {
+error_report_err(local_err);
+/* local_err was freed, do not reuse it. */
+local_err = NULL;
+result = 1;
 }
-
-QTAILQ_REMOVE(>reslist, res, next);
-g_free(res);
+CHECK(!result, cmd);
 }

 static void
@@ -1099,7 +1126,7 @@ static void
virtio_gpu_rutabaga_class_init(ObjectClass *klass, void *data)
 vgc->handle_ctrl = virtio_gpu_rutabaga_handle_ctrl;
 vgc->process_cmd = virtio_gpu_rutabaga_process_cmd;
 vgc->update_cursor_data = virtio_gpu_rutabaga_update_cursor;
-
+vgc->resource_destroy = virtio_gpu_rutabaga_resource_unref;
 vdc->realize = virtio_gpu_rutabaga_realize;
 device_class_set_props(dc, virtio_gpu_rutabaga_properties);
 }
--
γαῖα πυρί μιχθήτω






Re: [PATCH] hw/hyperv: Include missing headers

2024-01-29 Thread Thomas Huth

On 29/01/2024 18.00, Philippe Mathieu-Daudé wrote:

Include missing headers in order to avoid when refactoring
unrelated headers:

   hw/hyperv/hyperv.c:33:18: error: field ‘msg_page_mr’ has incomplete type
 33 | MemoryRegion msg_page_mr;
|  ^~~
   hw/hyperv/hyperv.c: In function ‘synic_update’:
   hw/hyperv/hyperv.c:64:13: error: implicit declaration of function 
‘memory_region_del_subregion’ [-Werror=implicit-function-declaration]
 64 | memory_region_del_subregion(get_system_memory(),
| ^~~
   hw/hyperv/hyperv.c: In function ‘hyperv_hcall_signal_event’:
   hw/hyperv/hyperv.c:683:17: error: implicit declaration of function 
‘ldq_phys’; did you mean ‘ldub_phys’? [-Werror=implicit-function-declaration]
683 | param = ldq_phys(_space_memory, addr);
| ^~~~
| ldub_phys
   hw/hyperv/hyperv.c:683:17: error: nested extern declaration of ‘ldq_phys’ 
[-Werror=nested-externs]
   hw/hyperv/hyperv.c: In function ‘hyperv_hcall_retreive_dbg_data’:
   hw/hyperv/hyperv.c:792:24: error: ‘TARGET_PAGE_SIZE’ undeclared (first use 
in this function); did you mean ‘TARGET_PAGE_BITS’?
792 | msg.u.recv.count = TARGET_PAGE_SIZE - sizeof(*debug_data_out);
|^~~~
|TARGET_PAGE_BITS
   hw/hyperv/hyperv.c: In function ‘hyperv_syndbg_send’:
   hw/hyperv/hyperv.c:885:16: error: ‘HV_SYNDBG_STATUS_INVALID’ undeclared 
(first use in this function)
885 | return HV_SYNDBG_STATUS_INVALID;
|^~~~

Signed-off-by: Philippe Mathieu-Daudé 
---
BTW who maintains this code?

$ ./scripts/get_maintainer.pl -f hw/hyperv/hyperv.c
get_maintainer.pl: No maintainers found, printing recent contributors.
get_maintainer.pl: Do not blindly cc: them on patches!  Use common sense.
---
  hw/hyperv/hyperv.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c
index 57b402b956..6c4a18dd0e 100644
--- a/hw/hyperv/hyperv.c
+++ b/hw/hyperv/hyperv.c
@@ -12,6 +12,7 @@
  #include "qemu/module.h"
  #include "qapi/error.h"
  #include "exec/address-spaces.h"
+#include "exec/memory.h"
  #include "sysemu/kvm.h"
  #include "qemu/bitops.h"
  #include "qemu/error-report.h"
@@ -21,6 +22,9 @@
  #include "qemu/rcu_queue.h"
  #include "hw/hyperv/hyperv.h"
  #include "qom/object.h"
+#include "target/i386/kvm/hyperv-proto.h"
+#include "target/i386/cpu.h"
+#include "exec/cpu-all.h"
  
  struct SynICState {

  DeviceState parent_obj;


Reviewed-by: Thomas Huth 




Re: [PATCH] Make 'uri' optional for migrate QAPI

2024-01-29 Thread Michael Tokarev

30.01.2024 04:35, Peter Xu:
..

This seems like a stable material too, - please let me know if it is not.


Yes it is. I used to be more careful on copying stable at least in the
commit message when I post patches, but forgot to do so when start picking
up..

Note that it's already merged in master 57fd4b4e10, while there should be a
test case to land later when ready (which won't need to copy stable).


I already picked it up from master yesterday, --
https://gitlab.com/mjt0k/qemu/-/commits/staging-8.2/ . Sometimes I pick up
the test cases too, especially (not in this case) when the actual change
makes existing tests to fail.  And yes, I've seen subsequent discussion
in the original thread (to which I replied) about adding the test case.


Since at it, just to double check how stable works for us: as long as the
commit has "Cc: qemu-sta...@nongnu.org" when merge should work, even
without the need to reply the patch copying stable list, am I right?


Well, basically, yes.  When you send a pull request with a patch which
has Cc: qemu-stable@, it will be Cc'd there by git send-email already.
Also, sometimes I scan all commits applied to master grepping for
Fixes:/Resolves: and similar patterns, and check if the change found
this way is relevant for stable or not, - but obviously this is much
less reliable (compared with when the actual patch author who understands
the situation much better marks the change explicitly) and often
requires extra confirmation round-trip.  Cc'ing qemu-stable@ in the
middle of discussion in qemu-devel@ will do the trick too.  The key
here is to mark the changes *somehow*.

My own work here is based on my local qemu-stable mailbox, plus the
commits scanning I mention above.

Thanks,

/mjt



Re: [PATCH] hw/intc/xics: Include missing 'cpu.h' header

2024-01-29 Thread Thomas Huth

On 29/01/2024 18.05, Philippe Mathieu-Daudé wrote:

Include missing headers in order to avoid when refactoring
unrelated headers:

   hw/intc/xics.c: In function 'icp_realize':
   hw/intc/xics.c:304:5: error: unknown type name 'PowerPCCPU'
 304 | PowerPCCPU *cpu;
 | ^~

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

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 8b25787227..700abfa7a6 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -40,6 +40,7 @@
  #include "hw/irq.h"
  #include "sysemu/kvm.h"
  #include "sysemu/reset.h"
+#include "target/ppc/cpu.h"
  
  void icp_pic_print_info(ICPState *icp, Monitor *mon)

  {


Reviewed-by: Thomas Huth 




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

2024-01-29 Thread Kasireddy, Vivek
Hi Alex, Eric, 

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

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

2024-01-29 Thread Peter Xu
On Mon, Jan 29, 2024 at 02:20:35PM +0200, Avihai Horon wrote:
> 
> On 29/01/2024 6:17, Peter Xu wrote:
> > External email: Use caution opening links or attachments
> > 
> > 
> > On Sun, Jan 28, 2024 at 05:43:52PM +0200, Avihai Horon wrote:
> > > On 25/01/2024 22:57, Fabiano Rosas wrote:
> > > > External email: Use caution opening links or attachments
> > > > 
> > > > 
> > > > Avihai Horon  writes:
> > > > 
> > > > > The commit in the fixes line moved multifd thread creation to a
> > > > > different location, but forgot to move the p->running = true 
> > > > > assignment
> > > > > as well. Thus, p->running is set to true before multifd thread is
> > > > > actually created.
> > > > > 
> > > > > p->running is used in multifd_save_cleanup() to decide whether to join
> > > > > the multifd thread or not.
> > > > > 
> > > > > With TLS, an error in multifd_tls_channel_connect() can lead to a
> > > > > segmentation fault because p->running is true but p->thread is never
> > > > > initialized, so multifd_save_cleanup() tries to join an uninitialized
> > > > > thread.
> > > > > 
> > > > > Fix it by moving p->running = true assignment right after multifd 
> > > > > thread
> > > > > creation. Also move qio_channel_set_delay() to there, as this is where
> > > > > it used to be originally.
> > > > > 
> > > > > Fixes: 29647140157a ("migration/tls: add support for multifd 
> > > > > tls-handshake")
> > > > > Signed-off-by: Avihai Horon 
> > > > Just for context, I haven't looked at this patch yet, but we were
> > > > planning to remove p->running altogether:
> > > > 
> > > > https://lore.kernel.org/r/20231110200241.20679-1-faro...@suse.de
> > > Thanks for putting me in the picture.
> > > I see that there has been a discussion about the multifd creation/treadown
> > > flow.
> > > In light of this discussion, I can already see a few problems in my series
> > > that I didn't notice before (such as the TLS handshake thread leak).
> > > The thread you mentioned here and some of my patches point out some 
> > > problems
> > > in multifd creation/treardown. I guess we can discuss it and see what's 
> > > the
> > > best way to solve them.
> > > 
> > > Regarding this patch, your solution indeed solves the bug that this patch
> > > addresses, so maybe this could be dropped (or only noted in your patch).
> > > 
> > > Maybe I should also put you (and Peter) in context for this whole series 
> > > --
> > > I am writing it as preparation for adding a separate migration channel for
> > > VFIO device migration, so VFIO devices could be migrated in parallel.
> > > So this series tries to lay down some foundations to facilitate it.
> > Avihai, is the throughput the only reason that VFIO would like to have a
> > separate channel?
> 
> Actually, the main reason is to be able to send and load multiple VFIO
> devices data in parallel.
> For example, today if we have three VFIO devices, they are migrated
> sequentially one after another.
> This particularly hurts during the complete pre-copy phase (downtime), as
> loading the VFIO data in destination involves FW interaction and resource
> allocation, which takes time and simply blocks the other devices from
> sending and loading their data.
> Providing a separate channel and thread for each VIFO device solves this
> problem and ideally reduces the VFIO contribution to downtime from sum{VFIO
> device #1, ..., VFIO device #N} to max{VFIO device #1, ..., VFIO device #N}.

I see.

> 
> > 
> > I'm wondering if we can also use multifd threads to send vfio data at some
> > point.  Now multifd indeed is closely bound to ram pages but maybe it'll
> > change in the near future to take any load?
> > 
> > Multifd is for solving the throughput issue already. If vfio has the same
> > goal, IMHO it'll be good to keep them using the same thread model, instead
> > of managing different threads in different places.  With that, any user
> > setting (for example, multifd-n-threads) will naturally apply to all
> > components, rather than relying on yet-another vfio-migration-threads-num
> > parameter.
> 
> Frankly, I didn't really put much attention to the throughput factor, and my
> plan is to introduce only a single thread per device.
> VFIO devices may have many GBs of data to migrate (e.g., vGPUs) and even
> mlx5 VFs can have a few GBs of data.
> So what you are saying here is interesting, although I didn't test such
> scenario to see the actual benefit.
> 
> I am trying to think if/how this could work and I have a few concerns:
> 1. RAM is made of fixed-positioned pages that can be randomly read/written,
> so sending these pages over multiple channels and loading them in the
> destination can work pretty naturally without much overhead.
>    VFIO device data, on the other hand, is just an opaque stream of bytes
> from QEMU point of view. This means that if we break this data to "packets"
> and send them over multiple channels, we must preserve the order by which
> this data was
>    originally read from the 

[PATCH v4 3/7] crypto: Modify the qcrypto_block_create to support creation flags

2024-01-29 Thread yong . huang
From: Hyman Huang 

Expand the signature of qcrypto_block_create to enable the
formation of LUKS volumes with detachable headers. To accomplish
that, introduce QCryptoBlockCreateFlags to instruct the creation
process to set the payload_offset_sector to 0.

Signed-off-by: Hyman Huang 
---
 block/crypto.c |  1 +
 block/qcow.c   |  2 +-
 block/qcow2.c  |  2 +-
 crypto/block-luks.c| 28 +---
 crypto/block.c |  4 +++-
 crypto/blockpriv.h |  2 ++
 include/crypto/block.h | 11 +++
 tests/unit/test-crypto-block.c |  2 ++
 8 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index e87dc84111..1b3f87922a 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -369,6 +369,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, 
int64_t size,
   block_crypto_create_init_func,
   block_crypto_create_write_func,
   ,
+  0,
   errp);
 
 if (!crypto) {
diff --git a/block/qcow.c b/block/qcow.c
index c6d0e15f1e..ca8e1d5ec8 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -885,7 +885,7 @@ qcow_co_create(BlockdevCreateOptions *opts, Error **errp)
 header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
 
 crypto = qcrypto_block_create(qcow_opts->encrypt, "encrypt.",
-  NULL, NULL, NULL, errp);
+  NULL, NULL, NULL, 0, errp);
 if (!crypto) {
 ret = -EINVAL;
 goto exit;
diff --git a/block/qcow2.c b/block/qcow2.c
index 9bee66fff5..204f5854cf 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3216,7 +3216,7 @@ qcow2_set_up_encryption(BlockDriverState *bs,
 crypto = qcrypto_block_create(cryptoopts, "encrypt.",
   qcow2_crypto_hdr_init_func,
   qcow2_crypto_hdr_write_func,
-  bs, errp);
+  bs, 0, errp);
 if (!crypto) {
 return -EINVAL;
 }
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 10373aaba4..8ad7cc44a5 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -1304,6 +1304,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
 const char *hash_alg;
 g_autofree char *cipher_mode_spec = NULL;
 uint64_t iters;
+uint64_t detached_header_size;
 
 memcpy(_opts, >u.luks, sizeof(luks_opts));
 if (!luks_opts.has_iter_time) {
@@ -1532,19 +1533,32 @@ qcrypto_block_luks_create(QCryptoBlock *block,
 slot->stripes = QCRYPTO_BLOCK_LUKS_STRIPES;
 }
 
-/* The total size of the LUKS headers is the partition header + key
- * slot headers, rounded up to the nearest sector, combined with
- * the size of each master key material region, also rounded up
- * to the nearest sector */
-luks->header.payload_offset_sector = header_sectors +
-QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS * split_key_sectors;
+if (block->detached_header) {
+/*
+ * For a detached LUKS header image, set the payload_offset_sector
+ * to 0 to specify the starting point for read/write
+ */
+luks->header.payload_offset_sector = 0;
+} else {
+/*
+ * The total size of the LUKS headers is the partition header + key
+ * slot headers, rounded up to the nearest sector, combined with
+ * the size of each master key material region, also rounded up
+ * to the nearest sector
+ */
+luks->header.payload_offset_sector = header_sectors +
+QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS * split_key_sectors;
+}
 
 block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
 block->payload_offset = luks->header.payload_offset_sector *
 block->sector_size;
+detached_header_size =
+(header_sectors + QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS *
+ split_key_sectors) * block->sector_size;
 
 /* Reserve header space to match payload offset */
-initfunc(block, block->payload_offset, opaque, _err);
+initfunc(block, detached_header_size, opaque, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 goto error;
diff --git a/crypto/block.c b/crypto/block.c
index 7bb4b74a37..506ea1d1a3 100644
--- a/crypto/block.c
+++ b/crypto/block.c
@@ -87,6 +87,7 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions 
*options,
QCryptoBlockInitFunc initfunc,
QCryptoBlockWriteFunc writefunc,
void *opaque,
+   unsigned int flags,
Error **errp)
 {
 QCryptoBlock *block = g_new0(QCryptoBlock, 1);
@@ -102,6 +103,7 @@ 

[PATCH v4 0/7] Support generic Luks encryption

2024-01-29 Thread yong . huang
From: Hyman Huang 

Sorry for the late post of version 4. The modifications are as follows:

v4:
- Rebase on master

- squash [PATCH v3 02/10] to [PATCH v3 01/10]

- refactor the logic of block_crypto_open_generic in [PATCH v3 02/10]
  as Daniel suggestted:
  a. drop the invalid parameter check for "header" option and use the
 ERRP_GUARD to probe the error of bdrv_open_child instead.
  b. add a new emum entry to QCryptoBlockOpenFlags to instruct the  
 process of LUKS volume open skip the payload overlap check instead
 of using the macro INVALID_SECTOR_OFFSET.

- drop the detached_header_size field and use local variable instead in
  [PATCH v3 04/10] 

- drop the detached-header option in [PATCH v3 04/10]

- drop the commit [PATCH v3 05/10]:
  crypto: Mark the payload_offset_sector invalid for detached LUKS header 

- introduce QCryptoBlockCreateFlags to instruct the creation process to
  set the payload_offset_sector to 0 in [PATCH v4 03/7]

- refactor the logic of block_crypto_co_create_luks in [PATCH v3 06/10]: 
  a. fix the compile failure
  b. use the existing 'fail:' label to handle the error logic

- refine the comment in qapi suggested by Markus.

- modify the test case to accommodate the new implementation. 

Thanks for commenting on this series, please review.

Best regared,

Yong

v3:
- Rebase on master
- Add a test case for detached LUKS header
- Adjust the design to honour preallocation of the payload device
- Adjust the design to honour the payload offset from the header,
  even when detached
- Support detached LUKS header creation using qemu-img
- Support detached LUKS header querying
- Do some code clean

v2:
- Simplify the design by reusing the LUKS driver to implement
  the generic Luks encryption, thank Daniel for the insightful 
  advice.
- rebase on master. 

This functionality was motivated by the following to-do list seen
in crypto documents:
https://wiki.qemu.org/Features/Block/Crypto 

The last chapter says we should "separate header volume": 

The LUKS format has ability to store the header in a separate volume
from the payload. We should extend the LUKS driver in QEMU to support
this use case.

By enhancing the LUKS driver, it is possible to implement
the LUKS volume with a detached header.

Normally a LUKS volume has a layout:
  disk:  | header | key material | disk payload data |

With a detached LUKS header, you need 2 disks so getting:
  disk1:  | header | key material |
  disk2:  | disk payload data |

There are a variety of benefits to doing this:
 * Secrecy - the disk2 cannot be identified as containing LUKS
 volume since there's no header
 * Control - if access to the disk1 is restricted, then even
 if someone has access to disk2 they can't unlock
 it. Might be useful if you have disks on NFS but
 want to restrict which host can launch a VM
 instance from it, by dynamically providing access
 to the header to a designated host
 * Flexibility - your application data volume may be a given
 size and it is inconvenient to resize it to
 add encryption.You can store the LUKS header
 separately and use the existing storage
 volume for payload
 * Recovery - corruption of a bit in the header may make the
  entire payload inaccessible. It might be
  convenient to take backups of the header. If
  your primary disk header becomes corrupt, you
  can unlock the data still by pointing to the
  backup detached header

Take the raw-format image as an example to introduce the usage
of the LUKS volume with a detached header:

1. prepare detached LUKS header images
$ dd if=/dev/zero of=test-header.img bs=1M count=32
$ dd if=/dev/zero of=test-payload.img bs=1M count=1000
$ cryptsetup luksFormat --header test-header.img test-payload.img
> --force-password --type luks1

2. block-add a protocol blockdev node of payload image
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-1-storage", "driver":"file",
> "filename":"test-payload.img"}}'

3. block-add a protocol blockdev node of LUKS header as above.
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-2-storage", "driver":"file",
> "filename": "test-header.img" }}'

4. object-add the secret for decrypting the cipher stored in
   LUKS header above
$ virsh qemu-monitor-command vm '{"execute":"object-add",
> "arguments":{"qom-type":"secret", "id":
> "libvirt-2-storage-secret0", "data":"abc123"}}'

5. block-add the raw-drived blockdev format node
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-1-format", "driver":"raw",
> "file":"libvirt-1-storage"}}'

6. block-add the luks-drived blockdev to link the raw disk
   with the LUKS header by specifying the field "header"
$ virsh qemu-monitor-command vm 

[PATCH v4 6/7] crypto: Introduce 'detached-header' field in QCryptoBlockInfoLUKS

2024-01-29 Thread yong . huang
From: Hyman Huang 

When querying the LUKS disk with the qemu-img tool or other APIs,
add information about whether the LUKS header is detached.

Additionally, update the test case with the appropriate
modification.

Signed-off-by: Hyman Huang 
---
 crypto/block-luks.c| 2 ++
 qapi/crypto.json   | 3 +++
 tests/qemu-iotests/210.out | 4 
 3 files changed, 9 insertions(+)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 8ad7cc44a5..3c168aa86f 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -1260,6 +1260,7 @@ qcrypto_block_luks_open(QCryptoBlock *block,
 block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
 block->payload_offset = luks->header.payload_offset_sector *
 block->sector_size;
+block->detached_header = (block->payload_offset == 0) ? true : false;
 
 return 0;
 
@@ -1884,6 +1885,7 @@ static int qcrypto_block_luks_get_info(QCryptoBlock 
*block,
 info->u.luks.master_key_iters = luks->header.master_key_iterations;
 info->u.luks.uuid = g_strndup((const char *)luks->header.uuid,
   sizeof(luks->header.uuid));
+info->u.luks.detached_header = block->detached_header;
 
 for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
 slot = g_new0(QCryptoBlockInfoLUKSSlot, 1);
diff --git a/qapi/crypto.json b/qapi/crypto.json
index 62fd145223..f8b00cdc4d 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -314,6 +314,8 @@
 #
 # @hash-alg: the master key hash algorithm
 #
+# @detached-header: whether the LUKS header is detached (Since 9.0)
+#
 # @payload-offset: offset to the payload data in bytes
 #
 # @master-key-iters: number of PBKDF2 iterations for key material
@@ -330,6 +332,7 @@
'ivgen-alg': 'QCryptoIVGenAlgorithm',
'*ivgen-hash-alg': 'QCryptoHashAlgorithm',
'hash-alg': 'QCryptoHashAlgorithm',
+   'detached-header': 'bool',
'payload-offset': 'int',
'master-key-iters': 'int',
'uuid': 'str',
diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out
index 96d9f749dd..94b29b2120 100644
--- a/tests/qemu-iotests/210.out
+++ b/tests/qemu-iotests/210.out
@@ -18,6 +18,7 @@ virtual size: 128 MiB (134217728 bytes)
 encrypted: yes
 Format specific information:
 ivgen alg: plain64
+detached header: false
 hash alg: sha256
 cipher alg: aes-256
 uuid: ----
@@ -70,6 +71,7 @@ virtual size: 64 MiB (67108864 bytes)
 encrypted: yes
 Format specific information:
 ivgen alg: plain64
+detached header: false
 hash alg: sha1
 cipher alg: aes-128
 uuid: ----
@@ -125,6 +127,7 @@ virtual size: 0 B (0 bytes)
 encrypted: yes
 Format specific information:
 ivgen alg: plain64
+detached header: false
 hash alg: sha256
 cipher alg: aes-256
 uuid: ----
@@ -195,6 +198,7 @@ virtual size: 0 B (0 bytes)
 encrypted: yes
 Format specific information:
 ivgen alg: plain64
+detached header: false
 hash alg: sha256
 cipher alg: aes-256
 uuid: ----
-- 
2.31.1




[PATCH v4 1/7] crypto: Support LUKS volume with detached header

2024-01-29 Thread yong . huang
From: Hyman Huang 

By enhancing the LUKS driver, it is possible to implement
the LUKS volume with a detached header.

Normally a LUKS volume has a layout:
  disk:  | header | key material | disk payload data |

With a detached LUKS header, you need 2 disks so getting:
  disk1:  | header | key material |
  disk2:  | disk payload data |

There are a variety of benefits to doing this:
 * Secrecy - the disk2 cannot be identified as containing LUKS
 volume since there's no header
 * Control - if access to the disk1 is restricted, then even
 if someone has access to disk2 they can't unlock
 it. Might be useful if you have disks on NFS but
 want to restrict which host can launch a VM
 instance from it, by dynamically providing access
 to the header to a designated host
 * Flexibility - your application data volume may be a given
 size and it is inconvenient to resize it to
 add encryption.You can store the LUKS header
 separately and use the existing storage
 volume for payload
 * Recovery - corruption of a bit in the header may make the
  entire payload inaccessible. It might be
  convenient to take backups of the header. If
  your primary disk header becomes corrupt, you
  can unlock the data still by pointing to the
  backup detached header

Take the raw-format image as an example to introduce the usage
of the LUKS volume with a detached header:

1. prepare detached LUKS header images
$ dd if=/dev/zero of=test-header.img bs=1M count=32
$ dd if=/dev/zero of=test-payload.img bs=1M count=1000
$ cryptsetup luksFormat --header test-header.img test-payload.img
> --force-password --type luks1

2. block-add a protocol blockdev node of payload image
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-1-storage", "driver":"file",
> "filename":"test-payload.img"}}'

3. block-add a protocol blockdev node of LUKS header as above.
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-2-storage", "driver":"file",
> "filename": "test-header.img" }}'

4. object-add the secret for decrypting the cipher stored in
   LUKS header above
$ virsh qemu-monitor-command vm '{"execute":"object-add",
> "arguments":{"qom-type":"secret", "id":
> "libvirt-2-storage-secret0", "data":"abc123"}}'

5. block-add the raw-drived blockdev format node
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-1-format", "driver":"raw",
> "file":"libvirt-1-storage"}}'

6. block-add the luks-drived blockdev to link the raw disk
   with the LUKS header by specifying the field "header"
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name":"libvirt-2-format", "driver":"luks",
> "file":"libvirt-1-format", "header":"libvirt-2-storage",
> "key-secret":"libvirt-2-format-secret0"}}'

7. hot-plug the virtio-blk device finally
$ virsh qemu-monitor-command vm '{"execute":"device_add",
> "arguments": {"num-queues":"1", "driver":"virtio-blk-pci",
> "drive": "libvirt-2-format", "id":"virtio-disk2"}}'

Starting a VM with a LUKS volume with detached header is
somewhat similar to hot-plug in that both maintaining the
same json command while the starting VM changes the
"blockdev-add/device_add" parameters to "blockdev/device".

Signed-off-by: Hyman Huang 
---
 block/crypto.c | 21 +++--
 crypto/block-luks.c| 11 +++
 include/crypto/block.h |  5 +
 qapi/block-core.json   |  5 -
 4 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index 921933a5e5..68656158e9 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -39,6 +39,7 @@ typedef struct BlockCrypto BlockCrypto;
 struct BlockCrypto {
 QCryptoBlock *block;
 bool updating_keys;
+BdrvChild *header;  /* Reference to the detached LUKS header */
 };
 
 
@@ -63,12 +64,14 @@ static int block_crypto_read_func(QCryptoBlock *block,
   Error **errp)
 {
 BlockDriverState *bs = opaque;
+BlockCrypto *crypto = bs->opaque;
 ssize_t ret;
 
 GLOBAL_STATE_CODE();
 GRAPH_RDLOCK_GUARD_MAINLOOP();
 
-ret = bdrv_pread(bs->file, offset, buflen, buf, 0);
+ret = bdrv_pread(crypto->header ? crypto->header : bs->file,
+ offset, buflen, buf, 0);
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not read encryption header");
 return ret;
@@ -84,12 +87,14 @@ static int block_crypto_write_func(QCryptoBlock *block,
Error **errp)
 {
 BlockDriverState *bs = opaque;
+BlockCrypto *crypto = bs->opaque;
 ssize_t ret;
 
 GLOBAL_STATE_CODE();
 GRAPH_RDLOCK_GUARD_MAINLOOP();
 
-ret = bdrv_pwrite(bs->file, offset, buflen, buf, 0);
+ret = 

[PATCH v4 7/7] tests: Add case for LUKS volume with detached header

2024-01-29 Thread yong . huang
From: Hyman Huang 

Also, add a section to the MAINTAINERS file for detached
LUKS header, it only has a test case in it currently.

Signed-off-by: Hyman Huang 
---
 MAINTAINERS   |   5 +
 tests/qemu-iotests/tests/luks-detached-header | 218 ++
 .../tests/luks-detached-header.out|   5 +
 3 files changed, 228 insertions(+)
 create mode 100755 tests/qemu-iotests/tests/luks-detached-header
 create mode 100644 tests/qemu-iotests/tests/luks-detached-header.out

diff --git a/MAINTAINERS b/MAINTAINERS
index dfaca8323e..fddd3348c2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3402,6 +3402,11 @@ F: migration/dirtyrate.c
 F: migration/dirtyrate.h
 F: include/sysemu/dirtyrate.h
 
+Detached LUKS header
+M: Hyman Huang 
+S: Maintained
+F: tests/qemu-iotests/tests/luks-detached-header
+
 D-Bus
 M: Marc-André Lureau 
 S: Maintained
diff --git a/tests/qemu-iotests/tests/luks-detached-header 
b/tests/qemu-iotests/tests/luks-detached-header
new file mode 100755
index 00..f0b5f3921c
--- /dev/null
+++ b/tests/qemu-iotests/tests/luks-detached-header
@@ -0,0 +1,218 @@
+#!/usr/bin/env python3
+# group: rw auto
+#
+# Test LUKS volume with detached header
+#
+# Copyright (C) 2024 SmartX Inc.
+#
+# Authors:
+# Hyman Huang 
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+import os
+import iotests
+from iotests import imgfmt, qemu_img_create, img_info_log, qemu_img_info, 
QMPTestCase
+
+
+image_size = 128 * 1024 * 1024
+
+luks_img = os.path.join(iotests.test_dir, 'luks.img')
+detached_header_img1 = os.path.join(iotests.test_dir, 'detached_header.img1')
+detached_header_img2 = os.path.join(iotests.test_dir, 'detached_header.img2')
+detached_payload_raw_img = os.path.join(iotests.test_dir, 
'detached_payload_raw.img')
+detached_payload_qcow2_img = os.path.join(iotests.test_dir, 
'detached_payload_qcow2.img')
+detached_header_raw_img = \
+
"json:{\"driver\":\"luks\",\"file\":{\"filename\":\"%s\"},\"header\":{\"filename\":\"%s\"}}"
 % (detached_payload_raw_img, detached_header_img1)
+detached_header_qcow2_img = \
+
"json:{\"driver\":\"luks\",\"file\":{\"filename\":\"%s\"},\"header\":{\"filename\":\"%s\"}}"
 % (detached_payload_qcow2_img, detached_header_img2)
+
+secret_obj = 'secret,id=sec0,data=foo'
+luks_opts = 'key-secret=sec0'
+
+
+class TestDetachedLUKSHeader(QMPTestCase):
+def setUp(self) -> None:
+self.vm = iotests.VM()
+self.vm.add_object(secret_obj)
+self.vm.launch()
+
+# 1. Create the normal LUKS disk with 128M size
+self.vm.blockdev_create({ 'driver': 'file',
+  'filename': luks_img,
+  'size': 0 })
+self.vm.qmp_log('blockdev-add', driver='file', filename=luks_img,
+ node_name='luks-1-storage')
+result = self.vm.blockdev_create({ 'driver': imgfmt,
+   'file': 'luks-1-storage',
+   'key-secret': 'sec0',
+   'size': image_size,
+   'iter-time': 10 })
+# None is expected
+self.assertEqual(result, None)
+
+# 2. Create the LUKS disk with detached header (raw)
+
+# Create detached LUKS header
+self.vm.blockdev_create({ 'driver': 'file',
+  'filename': detached_header_img1,
+  'size': 0 })
+self.vm.qmp_log('blockdev-add', driver='file', 
filename=detached_header_img1,
+ node_name='luks-2-header-storage')
+
+# Create detached LUKS raw payload
+self.vm.blockdev_create({ 'driver': 'file',
+  'filename': detached_payload_raw_img,
+  'size': 0 })
+self.vm.qmp_log('blockdev-add', driver='file',
+ filename=detached_payload_raw_img,
+ node_name='luks-2-payload-storage')
+
+# Format LUKS disk with detached header
+result = self.vm.blockdev_create({ 'driver': imgfmt,
+   'header': 'luks-2-header-storage',
+   'file': 'luks-2-payload-storage',
+   'key-secret': 'sec0',

[PATCH v4 4/7] block: Support detached LUKS header creation using blockdev-create

2024-01-29 Thread yong . huang
From: Hyman Huang 

Firstly, enable the ability to choose the block device containing
a detachable LUKS header by adding the 'header' parameter to
BlockdevCreateOptionsLUKS.

Secondly, when formatting the LUKS volume with a detachable header,
truncate the payload volume to length without a header size.

Using the qmp blockdev command, create the LUKS volume with a
detachable header as follows:

1. add the secret to lock/unlock the cipher stored in the
   detached LUKS header
$ virsh qemu-monitor-command vm '{"execute":"object-add",
> "arguments":{"qom-type": "secret", "id": "sec0", "data": "foo"}}'

2. create a header img with 0 size
$ virsh qemu-monitor-command vm '{"execute":"blockdev-create",
> "arguments":{"job-id":"job0", "options":{"driver":"file",
> "filename":"/path/to/detached_luks_header.img", "size":0 }}}'

3. add protocol blockdev node for header
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments": {"driver":"file", "filename":
> "/path/to/detached_luks_header.img", "node-name":
> "detached-luks-header-storage"}}'

4. create a payload img with 0 size
$ virsh qemu-monitor-command vm '{"execute":"blockdev-create",
> "arguments":{"job-id":"job1", "options":{"driver":"file",
> "filename":"/path/to/detached_luks_payload_raw.img", "size":0}}}'

5. add protocol blockdev node for payload
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments": {"driver":"file", "filename":
> "/path/to/detached_luks_payload_raw.img", "node-name":
> "luks-payload-raw-storage"}}'

6. do the formatting with 128M size
$ virsh qemu-monitor-command c81_node1 '{"execute":"blockdev-create",
> "arguments":{"job-id":"job2", "options":{"driver":"luks", "header":
> "detached-luks-header-storage", "file":"luks-payload-raw-storage",
> "size":134217728, "preallocation":"full", "key-secret":"sec0" }}}'

Signed-off-by: Hyman Huang 
---
 block/crypto.c   | 101 +++
 qapi/block-core.json |   3 ++
 2 files changed, 96 insertions(+), 8 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index 1b3f87922a..8e7ee5e9ac 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -162,6 +162,48 @@ error:
 return ret;
 }
 
+static int coroutine_fn GRAPH_UNLOCKED
+block_crypto_co_format_luks_payload(BlockdevCreateOptionsLUKS *luks_opts,
+Error **errp)
+{
+BlockDriverState *bs = NULL;
+BlockBackend *blk = NULL;
+Error *local_error = NULL;
+int ret;
+
+if (luks_opts->size > INT64_MAX) {
+return -EFBIG;
+}
+
+bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
+if (bs == NULL) {
+return -EIO;
+}
+
+blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE,
+ BLK_PERM_ALL, errp);
+if (!blk) {
+ret = -EPERM;
+goto fail;
+}
+
+ret = blk_truncate(blk, luks_opts->size, true,
+   luks_opts->preallocation, 0, _error);
+if (ret < 0) {
+if (ret == -EFBIG) {
+/* Replace the error message with a better one */
+error_free(local_error);
+error_setg(errp, "The requested file size is too large");
+}
+goto fail;
+}
+
+ret = 0;
+
+fail:
+bdrv_co_unref(bs);
+return ret;
+}
 
 static QemuOptsList block_crypto_runtime_opts_luks = {
 .name = "crypto",
@@ -341,7 +383,9 @@ static int block_crypto_open_generic(QCryptoBlockFormat 
format,
 static int coroutine_fn GRAPH_UNLOCKED
 block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
QCryptoBlockCreateOptions *opts,
-   PreallocMode prealloc, Error **errp)
+   PreallocMode prealloc,
+   unsigned int flags,
+   Error **errp)
 {
 int ret;
 BlockBackend *blk;
@@ -369,7 +413,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, 
int64_t size,
   block_crypto_create_init_func,
   block_crypto_create_write_func,
   ,
-  0,
+  flags,
   errp);
 
 if (!crypto) {
@@ -656,16 +700,26 @@ static int coroutine_fn GRAPH_UNLOCKED
 block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error 
**errp)
 {
 BlockdevCreateOptionsLUKS *luks_opts;
+BlockDriverState *hdr_bs = NULL;
 BlockDriverState *bs = NULL;
 QCryptoBlockCreateOptions create_opts;
 PreallocMode preallocation = PREALLOC_MODE_OFF;
+unsigned int cflags = 0;
 int ret;
 
 assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
 luks_opts = _options->u.luks;
 
-if (luks_opts->file == NULL) {
-error_setg(errp, "Formatting LUKS disk requires parameter 'file'");
+if (luks_opts->header == NULL && luks_opts->file == NULL) {
+

[PATCH v4 2/7] qapi: Make parameter 'file' optional for BlockdevCreateOptionsLUKS

2024-01-29 Thread yong . huang
From: Hyman Huang 

To support detached LUKS header creation, make the existing 'file'
field in BlockdevCreateOptionsLUKS optional.

Signed-off-by: Hyman Huang 
Reviewed-by: Daniel P. Berrangé 
---
 block/crypto.c   | 21 ++---
 qapi/block-core.json |  5 +++--
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index 68656158e9..e87dc84111 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -663,9 +663,9 @@ block_crypto_co_create_luks(BlockdevCreateOptions 
*create_options, Error **errp)
 assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
 luks_opts = _options->u.luks;
 
-bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
-if (bs == NULL) {
-return -EIO;
+if (luks_opts->file == NULL) {
+error_setg(errp, "Formatting LUKS disk requires parameter 'file'");
+return -EINVAL;
 }
 
 create_opts = (QCryptoBlockCreateOptions) {
@@ -677,10 +677,17 @@ block_crypto_co_create_luks(BlockdevCreateOptions 
*create_options, Error **errp)
 preallocation = luks_opts->preallocation;
 }
 
-ret = block_crypto_co_create_generic(bs, luks_opts->size, _opts,
- preallocation, errp);
-if (ret < 0) {
-goto fail;
+if (luks_opts->file) {
+bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
+if (bs == NULL) {
+return -EIO;
+}
+
+ret = block_crypto_co_create_generic(bs, luks_opts->size, _opts,
+ preallocation, errp);
+if (ret < 0) {
+goto fail;
+}
 }
 
 ret = 0;
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ae604c6019..69a88d613d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4957,7 +4957,8 @@
 #
 # Driver specific image creation options for LUKS.
 #
-# @file: Node to create the image format on
+# @file: Node to create the image format on, mandatory except when
+#'preallocation' is not requested
 #
 # @size: Size of the virtual disk in bytes
 #
@@ -4968,7 +4969,7 @@
 ##
 { 'struct': 'BlockdevCreateOptionsLUKS',
   'base': 'QCryptoBlockCreateOptionsLUKS',
-  'data': { 'file': 'BlockdevRef',
+  'data': { '*file':'BlockdevRef',
 'size': 'size',
 '*preallocation':   'PreallocMode' } }
 
-- 
2.31.1




[PATCH v4 5/7] block: Support detached LUKS header creation using qemu-img

2024-01-29 Thread yong . huang
From: Hyman Huang 

Even though a LUKS header might be created with cryptsetup,
qemu-img should be enhanced to accommodate it as well.

Add the 'detached-header' option to specify the creation of
a detached LUKS header. This is how it is used:
$ qemu-img create --object secret,id=sec0,data=abc123 -f luks
> -o cipher-alg=aes-256,cipher-mode=xts -o key-secret=sec0
> -o detached-header=true header.luks

Using qemu-img or cryptsetup tools to query information of
an LUKS header image as follows:

Assume a detached LUKS header image has been created by:
$ dd if=/dev/zero of=test-header.img bs=1M count=32
$ dd if=/dev/zero of=test-payload.img bs=1M count=1000
$ cryptsetup luksFormat --header test-header.img test-payload.img
> --force-password --type luks1

Header image information could be queried using cryptsetup:
$ cryptsetup luksDump test-header.img

or qemu-img:
$ qemu-img info 'json:{"driver":"luks","file":{"filename":
> "test-payload.img"},"header":{"filename":"test-header.img"}}'

When using qemu-img, keep in mind that the entire disk
information specified by the JSON-format string above must be
supplied on the commandline; if not, an overlay check will reveal
a problem with the LUKS volume check logic.

Signed-off-by: Hyman Huang 
---
 block.c  |  5 -
 block/crypto.c   | 10 +-
 block/crypto.h   |  8 
 qapi/crypto.json |  5 -
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/block.c b/block.c
index 30afdcbba6..1ed9214f66 100644
--- a/block.c
+++ b/block.c
@@ -7357,7 +7357,10 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 goto out;
 }
 
-if (size == -1) {
+/* Parameter 'size' is not needed for detached LUKS header */
+if (size == -1 &&
+!(!strcmp(fmt, "luks") &&
+  qemu_opt_get_bool(opts, "detached-header", false))) {
 error_setg(errp, "Image creation needs a size parameter");
 goto out;
 }
diff --git a/block/crypto.c b/block/crypto.c
index 8e7ee5e9ac..65426d3a16 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -231,6 +231,7 @@ static QemuOptsList block_crypto_create_opts_luks = {
 BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
 BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
 BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
+BLOCK_CRYPTO_OPT_DEF_LUKS_DETACHED_HEADER(""),
 { /* end of list */ }
 },
 };
@@ -405,7 +406,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, 
int64_t size,
 
 data = (struct BlockCryptoCreateData) {
 .blk = blk,
-.size = size,
+.size = flags & QCRYPTO_BLOCK_CREATE_DETACHED ? 0 : size,
 .prealloc = prealloc,
 };
 
@@ -791,6 +792,9 @@ block_crypto_co_create_opts_luks(BlockDriver *drv, const 
char *filename,
 PreallocMode prealloc;
 char *buf = NULL;
 int64_t size;
+bool detached_hdr =
+qemu_opt_get_bool(opts, "detached-header", false);
+unsigned int cflags = 0;
 int ret;
 Error *local_err = NULL;
 
@@ -830,6 +834,10 @@ block_crypto_co_create_opts_luks(BlockDriver *drv, const 
char *filename,
 goto fail;
 }
 
+if (detached_hdr) {
+cflags |= QCRYPTO_BLOCK_CREATE_DETACHED;
+}
+
 /* Create format layer */
 ret = block_crypto_co_create_generic(bs, size, create_opts,
  prealloc, 0, errp);
diff --git a/block/crypto.h b/block/crypto.h
index 72e792c9af..dc3d2d5ed9 100644
--- a/block/crypto.h
+++ b/block/crypto.h
@@ -41,6 +41,7 @@
 #define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg"
 #define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
 #define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
+#define BLOCK_CRYPTO_OPT_LUKS_DETACHED_HEADER "detached-header"
 #define BLOCK_CRYPTO_OPT_LUKS_KEYSLOT "keyslot"
 #define BLOCK_CRYPTO_OPT_LUKS_STATE "state"
 #define BLOCK_CRYPTO_OPT_LUKS_OLD_SECRET "old-secret"
@@ -100,6 +101,13 @@
 .help = "Select new state of affected keyslots (active/inactive)",\
 }
 
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_DETACHED_HEADER(prefix) \
+{ \
+.name = prefix BLOCK_CRYPTO_OPT_LUKS_DETACHED_HEADER, \
+.type = QEMU_OPT_BOOL,\
+.help = "Create a detached LUKS header",  \
+}
+
 #define BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(prefix)  \
 {  \
 .name = prefix BLOCK_CRYPTO_OPT_LUKS_KEYSLOT,  \
diff --git a/qapi/crypto.json b/qapi/crypto.json
index fd3d46ebd1..62fd145223 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -223,6 +223,8 @@
 # @iter-time: number of milliseconds to spend in PBKDF passphrase
 # processing.  Currently defaults to 2000. (since 2.8)
 #
+# @detached-header: create a detached LUKS header. (since 9.0)
+#
 # Since: 2.6
 ##
 { 'struct': 'QCryptoBlockCreateOptionsLUKS',
@@ -232,7 +234,8 @@
 '*ivgen-alg': 

Re: [PATCH] migration/docs: Explain two solutions for VMSD compatibility

2024-01-29 Thread Peter Xu
On Mon, Jan 29, 2024 at 03:51:07PM +, Peter Maydell wrote:
> On Mon, 29 Jan 2024 at 15:18, Fabiano Rosas  wrote:
> >
> > Peter Maydell  writes:
> >
> > > On Mon, 29 Jan 2024 at 13:45, Fabiano Rosas  wrote:
> > >>
> > >> Peter Xu  writes:
> > >> > Fundamentally, IMHO it's because QEMU as a project is used both in
> > >> > enterprise and personal emulations.  I think it might be too strict to
> > >> > always request backward migration capability if we know some device / 
> > >> > arch
> > >> > is only used for personal, or educational, purposes.
> > >>
> > >> Do we need migration support tiers? =)
> > >
> > > We already have them. The tier list is:
> >
> > Ah that's good. Thanks, Peter.
> >
> > >
> > >  * if the machine type is a versioned one, then we maintain
> > >forwards compatibility for the versioned machine
> > >(i.e. can migrate machine-X.Y of QEMU A.B to the
> > > machine-X.Y of a QEMU C.D which is newer than A.B).
> > >  * if the machine type is not versioned, then we do not make
> > >any guarantee of migration compatibility across QEMU versions.
> > >Instead the aim is that if the user tries it it either works
> > >or gives an error message that the migration failed
> > >(e.g. because the version field in a VMState struct was bumped).
> > >Migration breaks are generally called out in commit messages.
> > >Often for machines in this tier the user is really interested
> > >in state-save snapshots for debugging purposes, rather than
> > >in a true cross-host-machine migration.
> > >  * some machine types do not support migration/savevm/loadvm
> > >at all, because of devices missing VMState structs. This
> > >is not desirable, and for new machine models we try to
> > >ensure that they have vmstate structs as part of the minimum
> > >quality bar, but it is true of some legacy machine types.
> >
> > Hm, does this mean in some cases we're requiring new models to have
> > vmstate only to never look at them again? Or do you mean some versioned
> > machines are currently broken?
> 
> New device models have vmstate; we don't actively test that
> savevm/loadvm works, but as with most device models we fix bugs
> if anybody reports them. Some older device models simply omit
> the vmstate struct completely (which results in the guest not
> behaving right after savevm/loadvm); a few at least register a
> migration blocker. Usually if somebody's doing a refactoring
> and cleanup of an old device they'll add the vmstate while they're
> doing it.
> 
> Any device which is used by a versioned machine type is supposed
> to have the vmstate support.
> 
> > > AIUI we, in the sense of the upstream project, do not support
> > > backwards migration compatibility (i.e. migrating a machine-X.Y
> > > from QEMU C.D to QEMU A.B where A.B is an older version than C.D);
> > > though some downstreams (read: RedHat) may do so.
> >
> > Here we still need to make a distinction between migration code and
> > vmstate. If we simply ignore backwards migration then it might become
> > impossible for downstreams to provide it without major
> > modifications. But luckily this is the easy case.
> 
> Yeah, there's no reason for us to make our downstreams' lives
> harder; the "not supported upstream" part is a mix of
> (a) we don't test it so it probably doesn't work and
> (b) we're not going to insist on patch submitters tying themselves
> in knots over trying to implement a level of compatibility for
> a device when we don't advertise that it's supposed to work

(b) makes sense.  I suppose that further justified what this document
wanted to make clear of, on that we should probably allow vmsd versioning
to be used, which is already better than either migration incompatible, or
even not support migration at all on the system.

But shouldn't we still have that tier to request "backward migration"?  Yes
it's not covered yet by any test, but maybe some day we can have it.
Besides, we're more discussing the goal which can apply to suggestions to
patch submitters and reviewers.  I think that's still a fair goal so that
on extremely popular devices + architectures, we still ask for bi-direction
migration capability.

Do we have a place where such tiering is documented?  Should I add one more
patch to describe it?

I think the hard thing is still how to justify which change will require
which tier: we were discussing machine type numbers, but normally IIUC many
devices can be used in multiple machine types, in that case should we pick
the strictest rule out of those machine types that such device support?
Maybe it'll be easier we just justify that during reviews.

-- 
Peter Xu




RE: [RFC v1 3/3] hw/arm/virt-acpi-build.c: Enable CPU cache topology

2024-01-29 Thread JeeHeng Sia



> -Original Message-
> From: Jonathan Cameron 
> Sent: Monday, January 29, 2024 7:08 PM
> To: JeeHeng Sia 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; qemu-ri...@nongnu.org; 
> m...@redhat.com; imamm...@redhat.com;
> anisi...@redhat.com; shannon.zha...@gmail.com; peter.mayd...@linaro.org; 
> suni...@ventanamicro.com; pal...@dabbelt.com;
> alistair.fran...@wdc.com; bin.m...@windriver.com; liwei1...@gmail.com; 
> dbarb...@ventanamicro.com;
> zhiwei_...@linux.alibaba.com
> Subject: Re: [RFC v1 3/3] hw/arm/virt-acpi-build.c: Enable CPU cache topology
> 
> On Mon, 29 Jan 2024 00:14:23 -0800
> Sia Jee Heng  wrote:
> 
> > Introduced a 3-layer cache for the ARM virtual machine.
> >
> > Signed-off-by: Sia Jee Heng 
> 
> There are a bunch of CPU registers that also need updating to reflect the
> described cache.
> https://lore.kernel.org/qemu-devel/20230808115713.2613-3-jonathan.came...@huawei.com/
> It's called HACK for a reason ;)
> But there is some discussion about this issue in the thread.
> 
> The l1 etc also needs to reflect the CPU model.  This stuff needs to match.
> Wrong information being passed to a VM is probably worse than no information.
> 
> Whilst I plan to circle back to the MPAM support (perhaps next month) there
> is a lot more to be done here before we have useful cache descriptions for
> guests.
Thanks for the info. I will spend time to look into.
> 
> Jonathan
> 
> > ---
> >  hw/arm/virt-acpi-build.c | 44 +++-
> >  1 file changed, 43 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > index 17aeec7a6f..c57067cd63 100644
> > --- a/hw/arm/virt-acpi-build.c
> > +++ b/hw/arm/virt-acpi-build.c
> > @@ -426,6 +426,48 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
> > VirtMachineState *vms)
> >  g_array_free(its_idmaps, true);
> >  }
> >
> > +static void pptt_setup(GArray *table_data, BIOSLinker *linker, 
> > MachineState *ms,
> > +   const char *oem_id, const char *oem_table_id)
> > +{
> > +CPUCaches default_cache_info = {
> > +.l1d_cache = &(CPUCacheInfo) {
> > +.type = DATA_CACHE,
> > +.size = 64 * KiB,
> > +.line_size = 64,
> > +.associativity = 4,
> > +.sets = 256,
> > +.attributes = 0x02,
> > +},
> > +.l1i_cache = &(CPUCacheInfo) {
> > +.type = INSTRUCTION_CACHE,
> > +.size = 64 * KiB,
> > +.line_size = 64,
> > +.associativity = 4,
> > +.sets = 256,
> > +.attributes = 0x04,
> 
> This is the duplication I commented on in patch 1.
> The bit set there is the one to indicate it's an instruction
> cache and we have type doing that as well.
But this gives a great readability, no?
> 
> 
> > +},
> > +.l2_cache = &(CPUCacheInfo) {
> > +.type = UNIFIED_CACHE,
> > +.size = 2048 * KiB,
> > +.line_size = 64,
> > +.associativity = 8,
> > +.sets = 4096,
> > +.attributes = 0x0a,
> > +},
> > +.l3_cache = &(CPUCacheInfo) {
> > +.type = UNIFIED_CACHE,
> > +.size = 4096 * KiB,
> > +.line_size = 64,
> > +.associativity = 8,
> > +.sets = 8192,
> > +.attributes = 0x0a,
> > +},
> > +};
> > +
> > +build_pptt(table_data, linker, ms, oem_id, oem_table_id,
> > +   _cache_info);
> > +}
> > +
> >  /*
> >   * Serial Port Console Redirection Table (SPCR)
> >   * Rev: 1.07
> > @@ -912,7 +954,7 @@ void virt_acpi_build(VirtMachineState *vms, 
> > AcpiBuildTables *tables)
> >
> >  if (!vmc->no_cpu_topology) {
> >  acpi_add_table(table_offsets, tables_blob);
> > -build_pptt(tables_blob, tables->linker, ms,
> > +pptt_setup(tables_blob, tables->linker, ms,
> > vms->oem_id, vms->oem_table_id);
> >  }
> >




RE: [RFC v1 1/3] hw/acpi/aml-build: Add cache structure table creation for PPTT table

2024-01-29 Thread JeeHeng Sia



> -Original Message-
> From: Jonathan Cameron 
> Sent: Monday, January 29, 2024 7:03 PM
> To: JeeHeng Sia 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; qemu-ri...@nongnu.org; 
> m...@redhat.com; imamm...@redhat.com;
> anisi...@redhat.com; shannon.zha...@gmail.com; peter.mayd...@linaro.org; 
> suni...@ventanamicro.com; pal...@dabbelt.com;
> alistair.fran...@wdc.com; bin.m...@windriver.com; liwei1...@gmail.com; 
> dbarb...@ventanamicro.com;
> zhiwei_...@linux.alibaba.com
> Subject: Re: [RFC v1 1/3] hw/acpi/aml-build: Add cache structure table 
> creation for PPTT table
> 
> On Mon, 29 Jan 2024 00:14:21 -0800
> Sia Jee Heng  wrote:
> 
> > Adds cache structure table generation for the Processor Properties
> > Topology Table (PPTT) to describe cache hierarchy information for
> > ACPI guests.
> >
> > A 3-level cache topology is employed here, referring to the type 1 cache
> > structure according to ACPI spec v6.3. The L1 cache and L2 cache are
> > private resources for the core, while the L3 cache is the private
> > resource for the cluster.
> >
> > In the absence of cluster values in the QEMU command, a 2-layer cache is
> > expected. The default cache value should be passed in from the
> > architecture code.
> >
> > Examples:
> > 3-layer: -smp 4,sockets=1,clusters=2,cores=2,threads=1
> > 2-layer: -smp 4,sockets=1,cores=2,threads=2
> >
> > Signed-off-by: Sia Jee Heng 
> 
> Hi,
> 
> I'm not keen on the topology assumptions this is making.
> If were to use this on our Kunpeng 920 for guests then the description would
> be wrong as we only share the l3 tags at the cluster level, the
> L3 is die level (NUMA node). So for the physical machine we present
> a cluster with no associated caches.  For other platforms this would be
> even further from the truth.
Should you consider a file like kunpeng920.c and then pass the necessary
value to the build_pptt() function?
> 
> If we are presenting caches in PPTT (which I do want to see) then
> we need additional controls to specify the levels at which the
> appropriate caches are found.
I understood and I'm wonder if adding default value meet your needs?
> 
> There have been various proposals for how to do that description:
> https://lore.kernel.org/qemu-devel/20230808115713.2613-2-jonathan.came...@huawei.com/
> was my brief go at this (and had PPTT cache descriptions).
I can spend time to try out your patches, but it will be good for a
short command. Btw, it seems you stop for many months, do you
plan for a v2 or I will continue by update with your v2?
> 
> Maybe it's acceptable to have some defaults.
I would suggest to have some default value.
> 
> A few other review comments inline.
> 
> Give an example of the disassembled PPTT so we can see what is being
> built.  Need to clear if you are sharing descriptions across multiple
> instances of a given cache (which is allowed if no cache IDs).
> Looks like you do separate entries which is good because that's needed
> in latest definition (but wasn't in 6.3 and people built systems that
> didn't do separate entries).
Sure, here is the example output with clusters=2,core=2,thread=1
[000h  004h]   Signature : "PPTT"[Processor Properties 
Topology Table]
[004h 0004 004h]Table Length : 0208
[008h 0008 001h]Revision : 02
[009h 0009 001h]Checksum : 88
[00Ah 0010 006h]  Oem ID : "BOCHS "
[010h 0016 008h]Oem Table ID : "BXPC"
[018h 0024 004h]Oem Revision : 0001
[01Ch 0028 004h] Asl Compiler ID : "BXPC"
[020h 0032 004h]   Asl Compiler Revision : 0001


[024h 0036 001h]   Subtable Type : 00 [Processor Hierarchy Node]
[025h 0037 001h]  Length : 14
[026h 0038 002h]Reserved : 
[028h 0040 004h]   Flags (decoded below) : 0001
Physical package : 1
 ACPI Processor ID valid : 0
   Processor is a thread : 0
  Node is a leaf : 0
Identical Implementation : 0
[02Ch 0044 004h]  Parent : 
[030h 0048 004h]   ACPI Processor ID : 
[034h 0052 004h] Private Resource Number : 
[038h 0056 001h]   Subtable Type : 01 [Cache Type]
[039h 0057 001h]  Length : 18
[03Ah 0058 002h]Reserved : 
[03Ch 0060 004h]   Flags (decoded below) : 007F
  Size valid : 1
Number of Sets valid : 1
 Associativity valid : 1
   Allocation Type valid : 1
Cache Type valid : 1
  Write Policy valid : 1
 Line Size valid : 1
  Cache ID valid : 0
[040h 0064 004h] Next Level of Cache : 
[044h 0068 

Re: [PATCH] migration/docs: Explain two solutions for VMSD compatibility

2024-01-29 Thread Peter Xu
On Mon, Jan 29, 2024 at 10:44:46AM -0300, Fabiano Rosas wrote:
> > Since we're at it, I would also like to know how you think about whether we
> > should still suggest people using VMSD versioning, as we know that it won't
> > work for backward migrations.
> >
> > My current thoughts is it is still fine, as it's easier to use, and it
> > should still be applicable to the cases where a strict migration semantics
> > are not required.  However it's hard to justify which device needs that
> > strictness.
> 
> I'd prefer if we kept things strict. However I don't think we can do
> that without having enough testing and specially, clear recipes on how
> to add compatibility back once it gets lost. Think of that recent thread

If it was broken, IMHO we should just fix it and backport to stable.

I think Juan used to worry on what happens if someone already used an old
version of old release, e.g., someone using 8.2.0 may not be able to
migrate to 8.2.1 if we fix that breakage in 9.0 and backport that to 8.2.1.
My take is that maybe that's overcomplicated, and maybe we should simply
only maintain the latest stable version, rather than all.  In this case,
IMHO it will be less burden if we only guarantee 8.2.1 will be working,
e.g., when migrating from 8.1.z -> 8.2.1.  Then we should just state a
known issue in 8.2.0 that it is broken, and both:

  (1) 8.1.z -> 8.2.0, and
  (2) 8.2.0 -> 8.2.1

will expect to fail.

> were we discussed an old powerpc issue. How come we can see the fix
> today in the code but cannot tell which problem it was trying to solve?
> That's bonkers. Ideally every type of breakage would have a mapping into
> why it breaks and how to fix it.
> 
> So with testing to catch the issue early and a clear step-by-step on how
> to identify and fix compatibility, then we could require strict
> compatibility for every device.

I don't think we can guarantee no bug there, but indeed we can do better on
providing some test framework for device VMSDs.

> 
> >
> > For example, any device to be used in migration-test must be forward +
> > backward migration compatible at least, because you just added the n-1
> > regression tests to cover both directions.  Said that, only a few devices
> > are involved because currently our migration-test qemu cmdline is pretty
> > simple.
> 
> We might want to make a distinction between migration core vs. device
> state testing. I see n-1 testing more like migration core testing. It's
> bad to break migration, but it's really bad to break migration for
> everyone because we refactored something deep within migration/.
> 
> I also wouldn't mind if we had some simple way for device developers to
> add migration tests that cover their code. Currently it's infeasible to
> edit migration-test with new command lines for every device of
> interest. Maybe we could have a little framework that takes a command
> line and spits a migration stream? Something really self-contained,
> behind the device's CONFIG in meson.

I added one more todo:

https://wiki.qemu.org/ToDo/LiveMigration#Device_migration_stream_test_framework

How's that look?  Feel free to modify on your will.

-- 
Peter Xu




RE: [PATCH v3 0/4] Live Migration Acceleration with IAA Compression

2024-01-29 Thread Liu, Yuan1
> -Original Message-
> From: Peter Xu 
> Sent: Monday, January 29, 2024 6:43 PM
> To: Liu, Yuan1 
> Cc: faro...@suse.de; leob...@redhat.com; qemu-devel@nongnu.org; Zou,
> Nanhai 
> Subject: Re: [PATCH v3 0/4] Live Migration Acceleration with IAA
> Compression
> 
> On Wed, Jan 03, 2024 at 07:28:47PM +0800, Yuan Liu wrote:
> > Hi,
> 
> Hi, Yuan,
> 
> I have a few comments and questions.  Many of them can be pure questions
> as I don't know enough on these new technologies.
> 
> >
> > I am writing to submit a code change aimed at enhancing live migration
> > acceleration by leveraging the compression capability of the Intel
> > In-Memory Analytics Accelerator (IAA).
> >
> > The implementation of the IAA (de)compression code is based on Intel
> > Query Processing Library (QPL), an open-source software project
> > designed for IAA high-level software programming.
> > https://github.com/intel/qpl
> >
> > In the last version, there was some discussion about whether to
> > introduce a new compression algorithm for IAA. Because the compression
> > algorithm of IAA hardware is based on deflate, and QPL already
> > supports Zlib, so in this version, I implemented IAA as an accelerator
> > for the Zlib compression method. However, due to some reasons, QPL is
> > currently not compatible with the existing Zlib method that Zlib
> > compressed data can be decompressed by QPl and vice versa.
> >
> > I have some concerns about the existing Zlib compression
> >   1. Will you consider supporting one channel to support multi-stream
> >  compression? Of course, this may lead to a reduction in compression
> >  ratio, but it will allow the hardware to process each stream
> >  concurrently. We can have each stream process multiple pages,
> >  reducing the loss of compression ratio. For example, 128 pages are
> >  divided into 16 streams for independent compression. I will provide
> >  the a early performance data in the next version(v4).
> 
> I think Juan used to ask similar question: how much this can help if
> multifd can already achieve some form of concurrency over the pages?


> Couldn't the user specify more multifd channels if they want to grant more
> cpu resource for comp/decomp purpose?
> 
> IOW, how many concurrent channels QPL can provide?  What is the suggested
> concurrency channels there?

From the QPL software, there is no limit on the number of concurrent 
compression and decompression tasks.
From the IAA hardware, one IAA physical device can process two compressions 
concurrently or eight decompression tasks concurrently. There are up to 8 IAA 
devices on an Intel SPR Server and it will vary according to the customer’s 
product selection and deployment.

Regarding the requirement for the number of concurrent channels, I think this 
may not be a bottleneck problem.
Please allow me to introduce a little more here

1. If the compression design is based on Zlib/Deflate/Gzip streaming mode, then 
we indeed need more channels to maintain concurrent processing. Because each 
time a multifd packet is compressed (including 128 independent pages), it needs 
to be compressed page by page. These 128 pages are not concurrent. The 
concurrency is reflected in the logic of multiple channels for the multifd 
packet.

2. Through testing, we prefer concurrent processing on 4K pages, not multifd 
packet, which means that 128 pages belonging to a packet can be 
compressed/decompressed concurrently. Even one channel can also utilize all the 
resources of IAA. But this is not compatible with existing zlib.
The code is similar to the following
  for(int i = 0; i < num_pages; i++) {
job[i]->input_data = pages[i]
submit_job(job[i] //Non-block submit for compression/decompression tasks
  }
  for(int i = 0; i < num_pages; i++) {
wait_job(job[i])  //busy polling. In the future, we will make this part and 
data sending into pipeline mode.
  } 

3. Currently, the patches we provide to the community are based on streaming 
compression. This is to be compatible with the current zlib method. However, we 
found that there are still many problems with this, so we plan to provide a new 
change in the next version that the independent QPL/IAA acceleration function 
as said above.
Compatibility issues include the following
1. QPL currently does not support the z_sync_flush operation
2. IAA comp/decomp window is fixed 4K. By default, the zlib window size is 
32K. And window size should be the same for Both comp/decomp sides. 
3. At the same time, I researched the QAT compression scheme. QATzip 
currently does not support zlib, nor does it support z_sync_flush. The window 
size is 32K

In general, I think it is a good suggestion to make the accelerator compatible 
with standard compression algorithms, but also let the accelerator run 
independently, thus avoiding some compatibility and performance problems of the 
accelerator. For example, we can add the "accel" option to the compression 

RE: [RESEND v2 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location

2024-01-29 Thread JeeHeng Sia



> -Original Message-
> From: Andrew Jones 
> Sent: Monday, January 29, 2024 5:19 PM
> To: JeeHeng Sia 
> Cc: qemu-...@nongnu.org; qemu-devel@nongnu.org; qemu-ri...@nongnu.org; 
> m...@redhat.com; imamm...@redhat.com;
> anisi...@redhat.com; peter.mayd...@linaro.org; shannon.zha...@gmail.com; 
> suni...@ventanamicro.com; pal...@dabbelt.com;
> alistair.fran...@wdc.com; bin.m...@windriver.com; liwei1...@gmail.com; 
> dbarb...@ventanamicro.com;
> zhiwei_...@linux.alibaba.com
> Subject: Re: [RESEND v2 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation 
> to common location
> 
> On Sun, Jan 28, 2024 at 06:14:39PM -0800, Sia Jee Heng wrote:
> > RISC-V should also generate the SPCR in a manner similar to ARM.
> > Therefore, instead of replicating the code, relocate this function
> > to the common AML build.
> >
> > Signed-off-by: Sia Jee Heng 
> > ---
> >  hw/acpi/aml-build.c | 51 
> >  hw/arm/virt-acpi-build.c| 68 +++--
> >  include/hw/acpi/acpi-defs.h | 33 ++
> >  include/hw/acpi/aml-build.h |  4 +++
> >  4 files changed, 115 insertions(+), 41 deletions(-)
> >
> > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > index af66bde0f5..f3904650e4 100644
> > --- a/hw/acpi/aml-build.c
> > +++ b/hw/acpi/aml-build.c
> > @@ -1994,6 +1994,57 @@ static void build_processor_hierarchy_node(GArray 
> > *tbl, uint32_t flags,
> >  }
> >  }
> >
> > +void build_spcr(GArray *table_data, BIOSLinker *linker,
> > +const AcpiSpcrData *f, const uint8_t rev,
> > +const char *oem_id, const char *oem_table_id)
> > +{
> > +AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
> > +.oem_table_id = oem_table_id };
> > +
> > +acpi_table_begin(, table_data);
> > +/* Interface type */
> > +build_append_int_noprefix(table_data, f->interface_type, 1);
> > +/* Reserved */
> > +build_append_int_noprefix(table_data, 0, 3);
> > +/* Base Address */
> > +build_append_gas(table_data, f->base_addr.id, f->base_addr.width,
> > + f->base_addr.offset, f->base_addr.size,
> > + f->base_addr.addr);
> > +/* Interrupt type */
> > +build_append_int_noprefix(table_data, f->interrupt_type, 1);
> > +/* IRQ */
> > +build_append_int_noprefix(table_data, f->pc_interrupt, 1);
> > +/* Global System Interrupt */
> > +build_append_int_noprefix(table_data, f->interrupt, 4);
> > +/* Baud Rate */
> > +build_append_int_noprefix(table_data, f->baud_rate, 1);
> > +/* Parity */
> > +build_append_int_noprefix(table_data, f->parity, 1);
> > +/* Stop Bits */
> > +build_append_int_noprefix(table_data, f->stop_bits, 1);
> > +/* Flow Control */
> > +build_append_int_noprefix(table_data, f->flow_control, 1);
> > +/* Terminal Type */
> > +build_append_int_noprefix(table_data, f->terminal_type, 1);
> > +/* PCI Device ID  */
> > +build_append_int_noprefix(table_data, f->pci_device_id, 2);
> > +/* PCI Vendor ID */
> > +build_append_int_noprefix(table_data, f->pci_vendor_id, 2);
> > +/* PCI Bus Number */
> > +build_append_int_noprefix(table_data, f->pci_bus, 1);
> > +/* PCI Device Number */
> > +build_append_int_noprefix(table_data, f->pci_device, 1);
> > +/* PCI Function Number */
> > +build_append_int_noprefix(table_data, f->pci_function, 1);
> > +/* PCI Flags */
> > +build_append_int_noprefix(table_data, f->pci_flags, 4);
> > +/* PCI Segment */
> > +build_append_int_noprefix(table_data, f->pci_segment, 1);
> > +/* Reserved */
> > +build_append_int_noprefix(table_data, 0, 4);
> > +
> > +acpi_table_end(linker, );
> > +}
> >  /*
> >   * ACPI spec, Revision 6.3
> >   * 5.2.29 Processor Properties Topology Table (PPTT)
> > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > index a22a2f43a5..195767c0f0 100644
> > --- a/hw/arm/virt-acpi-build.c
> > +++ b/hw/arm/virt-acpi-build.c
> > @@ -431,48 +431,34 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
> > VirtMachineState *vms)
> >   * Rev: 1.07
> >   */
> >  static void
> > -build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> > +spcr_setup(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> >  {
> > -AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = vms->oem_id,
> > -.oem_table_id = vms->oem_table_id };
> > -
> > -acpi_table_begin(, table_data);
> > -
> > -/* Interface Type */
> > -build_append_int_noprefix(table_data, 3, 1); /* ARM PL011 UART */
> > -build_append_int_noprefix(table_data, 0, 3); /* Reserved */
> > -/* Base Address */
> > -build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 32, 0, 3,
> > - vms->memmap[VIRT_UART].base);
> > -/* Interrupt Type */
> > -build_append_int_noprefix(table_data,
> > -(1 << 3) /* 

RE: [RESEND v2 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location

2024-01-29 Thread JeeHeng Sia



> -Original Message-
> From: Sunil V L 
> Sent: Monday, January 29, 2024 1:13 PM
> To: JeeHeng Sia 
> Cc: qemu-...@nongnu.org; qemu-devel@nongnu.org; qemu-ri...@nongnu.org; 
> m...@redhat.com; imamm...@redhat.com;
> anisi...@redhat.com; peter.mayd...@linaro.org; shannon.zha...@gmail.com; 
> pal...@dabbelt.com; alistair.fran...@wdc.com;
> bin.m...@windriver.com; liwei1...@gmail.com; dbarb...@ventanamicro.com; 
> zhiwei_...@linux.alibaba.com
> Subject: Re: [RESEND v2 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation 
> to common location
> 
> Hi Jee Heng,
> 
> On Sun, Jan 28, 2024 at 06:14:39PM -0800, Sia Jee Heng wrote:
> > RISC-V should also generate the SPCR in a manner similar to ARM.
> > Therefore, instead of replicating the code, relocate this function
> > to the common AML build.
> >
> > Signed-off-by: Sia Jee Heng 
> > ---
> >  hw/acpi/aml-build.c | 51 
> >  hw/arm/virt-acpi-build.c| 68 +++--
> >  include/hw/acpi/acpi-defs.h | 33 ++
> >  include/hw/acpi/aml-build.h |  4 +++
> >  4 files changed, 115 insertions(+), 41 deletions(-)
> >
> > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > index af66bde0f5..f3904650e4 100644
> > --- a/hw/acpi/aml-build.c
> > +++ b/hw/acpi/aml-build.c
> > @@ -1994,6 +1994,57 @@ static void build_processor_hierarchy_node(GArray 
> > *tbl, uint32_t flags,
> >  }
> >  }
> >
> > +void build_spcr(GArray *table_data, BIOSLinker *linker,
> > +const AcpiSpcrData *f, const uint8_t rev,
> > +const char *oem_id, const char *oem_table_id)
> > +{
> > +AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
> > +.oem_table_id = oem_table_id };
> > +
> > +acpi_table_begin(, table_data);
> > +/* Interface type */
> > +build_append_int_noprefix(table_data, f->interface_type, 1);
> > +/* Reserved */
> > +build_append_int_noprefix(table_data, 0, 3);
> > +/* Base Address */
> > +build_append_gas(table_data, f->base_addr.id, f->base_addr.width,
> > + f->base_addr.offset, f->base_addr.size,
> > + f->base_addr.addr);
> > +/* Interrupt type */
> > +build_append_int_noprefix(table_data, f->interrupt_type, 1);
> > +/* IRQ */
> > +build_append_int_noprefix(table_data, f->pc_interrupt, 1);
> > +/* Global System Interrupt */
> > +build_append_int_noprefix(table_data, f->interrupt, 4);
> > +/* Baud Rate */
> > +build_append_int_noprefix(table_data, f->baud_rate, 1);
> > +/* Parity */
> > +build_append_int_noprefix(table_data, f->parity, 1);
> > +/* Stop Bits */
> > +build_append_int_noprefix(table_data, f->stop_bits, 1);
> > +/* Flow Control */
> > +build_append_int_noprefix(table_data, f->flow_control, 1);
> > +/* Terminal Type */
> > +build_append_int_noprefix(table_data, f->terminal_type, 1);
> > +/* PCI Device ID  */
> > +build_append_int_noprefix(table_data, f->pci_device_id, 2);
> > +/* PCI Vendor ID */
> > +build_append_int_noprefix(table_data, f->pci_vendor_id, 2);
> > +/* PCI Bus Number */
> > +build_append_int_noprefix(table_data, f->pci_bus, 1);
> > +/* PCI Device Number */
> > +build_append_int_noprefix(table_data, f->pci_device, 1);
> > +/* PCI Function Number */
> > +build_append_int_noprefix(table_data, f->pci_function, 1);
> > +/* PCI Flags */
> > +build_append_int_noprefix(table_data, f->pci_flags, 4);
> > +/* PCI Segment */
> > +build_append_int_noprefix(table_data, f->pci_segment, 1);
> > +/* Reserved */
> > +build_append_int_noprefix(table_data, 0, 4);
> > +
> I think either there should be a comment that this supports only v2 of
> SPCR spec or it should be able to create SPCR of any version. IMO, I
> think it is better to add support till v4 (latest). Since consumers like
> Linux probably doesn't support v4 yet, ARM/RISC-V can continue to create
> v2 itself for the time being but the generic build_spcr() should be able
> to create v4 also if the arch requires it.
A v4 table depends on the updated acpica. I am not aware if there is a
request from ARM to update to v4. Anyway, RISC-V BRS Spec did mentioned
on poll-based sbi console. I can check with acpica community if updating
table to v4 is the go otherwise I would suggest we cont stick to v2 because
there is no compatible ACPI guest to test the code.
> 
> Thanks,
> Sunil
> > +acpi_table_end(linker, );
> > +}
> >  /*
> >   * ACPI spec, Revision 6.3
> >   * 5.2.29 Processor Properties Topology Table (PPTT)
> > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > index a22a2f43a5..195767c0f0 100644
> > --- a/hw/arm/virt-acpi-build.c
> > +++ b/hw/arm/virt-acpi-build.c
> > @@ -431,48 +431,34 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
> > VirtMachineState *vms)
> >   * Rev: 1.07
> >   */
> >  static void
> > -build_spcr(GArray 

Re: [PATCH] target/loongarch: Fix qtest test-hmp error when KVM-only build

2024-01-29 Thread maobibo
With qemu is compiled with option "--target-list=loongarch64-softmmu 
--disable-tcg", it passes to run with "make check" command.


Also gdb debug for LoongArch kvm support depends on this.

Tested-by: Bibo Mao 

On 2024/1/25 下午2:14, Song Gao wrote:

The cc->sysemu_ops->get_phys_page_debug() is NULL when
KVM-only build. this patch fixes it.

Signed-off-by: Song Gao 
---
  target/loongarch/internals.h  |  20 ++-
  target/loongarch/cpu.c|   2 -
  target/loongarch/cpu_helper.c | 231 ++
  target/loongarch/tcg/tlb_helper.c | 230 -
  target/loongarch/meson.build  |   1 +
  5 files changed, 250 insertions(+), 234 deletions(-)
  create mode 100644 target/loongarch/cpu_helper.c

diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index 0beb034748..a2fc54c8a7 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -37,6 +37,17 @@ void restore_fp_status(CPULoongArchState *env);
  #endif
  
  #ifndef CONFIG_USER_ONLY

+enum {
+TLBRET_MATCH = 0,
+TLBRET_BADADDR = 1,
+TLBRET_NOMATCH = 2,
+TLBRET_INVALID = 3,
+TLBRET_DIRTY = 4,
+TLBRET_RI = 5,
+TLBRET_XI = 6,
+TLBRET_PE = 7,
+};
+
  extern const VMStateDescription vmstate_loongarch_cpu;
  
  void loongarch_cpu_set_irq(void *opaque, int irq, int level);

@@ -46,12 +57,17 @@ uint64_t 
cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
  uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
  void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
 uint64_t value);
+bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
+  int *index);
+int get_physical_address(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx);
+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+
  #ifdef CONFIG_TCG
  bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr);
-
-hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
  #endif
  #endif /* !CONFIG_USER_ONLY */
  
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c

index 064540397d..1e58c160ab 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -752,9 +752,7 @@ static struct TCGCPUOps loongarch_tcg_ops = {
  #include "hw/core/sysemu-cpu-ops.h"
  
  static const struct SysemuCPUOps loongarch_sysemu_ops = {

-#ifdef CONFIG_TCG
  .get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
-#endif
  };
  
  static int64_t loongarch_cpu_get_arch_id(CPUState *cs)

diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
new file mode 100644
index 00..f68d63f466
--- /dev/null
+++ b/target/loongarch/cpu_helper.c
@@ -0,0 +1,231 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch CPU helpers for qemu
+ *
+ * Copyright (c) 2024 Loongson Technology Corporation Limited
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+#include "cpu-csr.h"
+
+static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
+   int *prot, target_ulong address,
+   int access_type, int index, int mmu_idx)
+{
+LoongArchTLB *tlb = >tlb[index];
+uint64_t plv = mmu_idx;
+uint64_t tlb_entry, tlb_ppn;
+uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
+
+if (index >= LOONGARCH_STLB) {
+tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
+} else {
+tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
+}
+n = (address >> tlb_ps) & 0x1;/* Odd or even */
+
+tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
+tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
+tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
+tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
+if (is_la64(env)) {
+tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
+tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
+tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
+tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
+} else {
+tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
+tlb_nx = 0;
+tlb_nr = 0;
+tlb_rplv = 0;
+}
+
+/* Remove sw bit between bit12 -- bit PS*/
+tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) -1));
+
+/* Check access rights */
+if (!tlb_v) {
+return TLBRET_INVALID;
+}
+
+if (access_type == MMU_INST_FETCH && tlb_nx) {
+return TLBRET_XI;
+}
+
+if (access_type == MMU_DATA_LOAD && tlb_nr) {
+return TLBRET_RI;
+}
+
+if (((tlb_rplv == 0) && (plv > tlb_plv)) ||
+

Disk migration from qcow2 to SPDK

2024-01-29 Thread 陈孚
Hello everyone,

Recently, we are looking to switch the VM’s disks from the qemu driver with the 
qcow2 format to a vhost-user-blk driver based on SPDK. Currently, we are able 
to copy data into an SPDK-based target using the blockcopy method. We would 
like to inquire if there is a theoretical possibility to switch the virtio 
backend from qemu to vhost-user-blk online. If it's possible, what would need 
to be done?

Best regards


RE: [PATCH v3 11/29] target/hexagon: Prefer fast cpu_env() over slower CPU QOM cast macro

2024-01-29 Thread Brian Cain

> -Original Message-
> From: Philippe Mathieu-Daudé 
> Sent: Monday, January 29, 2024 10:45 AM
> To: qemu-devel@nongnu.org
> Cc: qemu-ri...@nongnu.org; qemu-s3...@nongnu.org; Paolo Bonzini
> ; k...@vger.kernel.org; qemu-...@nongnu.org;
> qemu-...@nongnu.org; Richard Henderson ;
> Philippe Mathieu-Daudé ; Brian Cain
> 
> Subject: [PATCH v3 11/29] target/hexagon: Prefer fast cpu_env() over slower
> CPU QOM cast macro
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> Mechanical patch produced running the command documented
> in scripts/coccinelle/cpu_env.cocci_template header.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/hexagon/cpu.c | 25 ++---
>  target/hexagon/gdbstub.c |  6 ++
>  2 files changed, 8 insertions(+), 23 deletions(-)
> 
> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
> index 085d6c0115..17a22aa7a5 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -236,10 +236,7 @@ static void hexagon_dump(CPUHexagonState *env,
> FILE *f, int flags)
> 
>  static void hexagon_dump_state(CPUState *cs, FILE *f, int flags)
>  {
> -HexagonCPU *cpu = HEXAGON_CPU(cs);
> -CPUHexagonState *env = >env;
> -
> -hexagon_dump(env, f, flags);
> +hexagon_dump(cpu_env(cs), f, flags);
>  }
> 
>  void hexagon_debug(CPUHexagonState *env)
> @@ -249,25 +246,19 @@ void hexagon_debug(CPUHexagonState *env)
> 
>  static void hexagon_cpu_set_pc(CPUState *cs, vaddr value)
>  {
> -HexagonCPU *cpu = HEXAGON_CPU(cs);
> -CPUHexagonState *env = >env;
> -env->gpr[HEX_REG_PC] = value;
> +cpu_env(cs)->gpr[HEX_REG_PC] = value;
>  }
> 
>  static vaddr hexagon_cpu_get_pc(CPUState *cs)
>  {
> -HexagonCPU *cpu = HEXAGON_CPU(cs);
> -CPUHexagonState *env = >env;
> -return env->gpr[HEX_REG_PC];
> +return cpu_env(cs)->gpr[HEX_REG_PC];
>  }
> 
>  static void hexagon_cpu_synchronize_from_tb(CPUState *cs,
>  const TranslationBlock *tb)
>  {
> -HexagonCPU *cpu = HEXAGON_CPU(cs);
> -CPUHexagonState *env = >env;
>  tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
> -env->gpr[HEX_REG_PC] = tb->pc;
> +cpu_env(cs)->gpr[HEX_REG_PC] = tb->pc;
>  }
> 
>  static bool hexagon_cpu_has_work(CPUState *cs)
> @@ -279,18 +270,14 @@ static void hexagon_restore_state_to_opc(CPUState
> *cs,
>   const TranslationBlock *tb,
>   const uint64_t *data)
>  {
> -HexagonCPU *cpu = HEXAGON_CPU(cs);
> -CPUHexagonState *env = >env;
> -
> -env->gpr[HEX_REG_PC] = data[0];
> +cpu_env(cs)->gpr[HEX_REG_PC] = data[0];
>  }
> 
>  static void hexagon_cpu_reset_hold(Object *obj)
>  {
>  CPUState *cs = CPU(obj);
> -HexagonCPU *cpu = HEXAGON_CPU(cs);
>  HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(obj);
> -CPUHexagonState *env = >env;
> +CPUHexagonState *env = cpu_env(cs);
> 
>  if (mcc->parent_phases.hold) {
>  mcc->parent_phases.hold(obj);
> diff --git a/target/hexagon/gdbstub.c b/target/hexagon/gdbstub.c
> index 54d37e006e..f773f8ea4f 100644
> --- a/target/hexagon/gdbstub.c
> +++ b/target/hexagon/gdbstub.c
> @@ -22,8 +22,7 @@
> 
>  int hexagon_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
>  {
> -HexagonCPU *cpu = HEXAGON_CPU(cs);
> -CPUHexagonState *env = >env;
> +CPUHexagonState *env = cpu_env(cs);
> 
>  if (n == HEX_REG_P3_0_ALIASED) {
>  uint32_t p3_0 = 0;
> @@ -42,8 +41,7 @@ int hexagon_gdb_read_register(CPUState *cs, GByteArray
> *mem_buf, int n)
> 
>  int hexagon_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
>  {
> -HexagonCPU *cpu = HEXAGON_CPU(cs);
> -CPUHexagonState *env = >env;
> +CPUHexagonState *env = cpu_env(cs);
> 
>  if (n == HEX_REG_P3_0_ALIASED) {
>  uint32_t p3_0 = ldtul_p(mem_buf);
> --
> 2.41.0

Reviewed-by: Brian Cain 


Re: [PATCH] Make 'uri' optional for migrate QAPI

2024-01-29 Thread Peter Xu
On Mon, Jan 29, 2024 at 11:30:53PM +0300, Michael Tokarev wrote:
> 23.01.2024 09:42, Het Gala:
> > 'uri' argument should be optional, as 'uri' and 'channels'
> > arguments are mutally exclusive in nature.
> > 
> > Fixes: 074dbce5fcce (migration: New migrate and
> > migrate-incoming argument 'channels')
> > Signed-off-by: Het Gala 
> > ---
> >   qapi/migration.json | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/qapi/migration.json b/qapi/migration.json
> > index eb2f883513..197d3faa43 100644
> > --- a/qapi/migration.json
> > +++ b/qapi/migration.json
> > @@ -1757,7 +1757,7 @@
> >   #
> >   ##
> >   { 'command': 'migrate',
> > -  'data': {'uri': 'str',
> > +  'data': {'*uri': 'str',
> >  '*channels': [ 'MigrationChannel' ],
> >  '*blk': { 'type': 'bool', 'features': [ 'deprecated' ] },
> >  '*inc': { 'type': 'bool', 'features': [ 'deprecated' ] },
> 
> This seems like a stable material too, - please let me know if it is not.

Yes it is. I used to be more careful on copying stable at least in the
commit message when I post patches, but forgot to do so when start picking
up..

Note that it's already merged in master 57fd4b4e10, while there should be a
test case to land later when ready (which won't need to copy stable).

Since at it, just to double check how stable works for us: as long as the
commit has "Cc: qemu-sta...@nongnu.org" when merge should work, even
without the need to reply the patch copying stable list, am I right?

Thanks,

-- 
Peter Xu




Re: [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method

2024-01-29 Thread Gurchetan Singh
On Mon, Jan 29, 2024 at 7:46 AM Manos Pitsidianakis <
manos.pitsidiana...@linaro.org> wrote:

> When the Rutabaga GPU device frees resources, it calls
> rutabaga_resource_unref for that resource_id. However, when the generic
> VirtIOGPU functions destroys resources, it only removes the
> virtio_gpu_simple_resource from the device's VirtIOGPU->reslist list.
> The rutabaga resource associated with that resource_id is then leaked.
>
> This commit overrides the resource_destroy class method introduced in
> the previous commit to fix this.
>
> Signed-off-by: Manos Pitsidianakis 
> ---
>  hw/display/virtio-gpu-rutabaga.c | 51 
>  1 file changed, 39 insertions(+), 12 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-rutabaga.c
> b/hw/display/virtio-gpu-rutabaga.c
> index 9e67f9bd51..6ac0776005 100644
> --- a/hw/display/virtio-gpu-rutabaga.c
> +++ b/hw/display/virtio-gpu-rutabaga.c
> @@ -148,14 +148,42 @@ rutabaga_cmd_create_resource_3d(VirtIOGPU *g,
>  }
>
>  static void
> +virtio_gpu_rutabaga_resource_unref(VirtIOGPU *g,
> +   struct virtio_gpu_simple_resource *res,
> +   Error **errp)
> +{
> +int32_t result;
> +const char *strerror = NULL;
> +VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
> +
> +result = rutabaga_resource_unref(vr->rutabaga, res->resource_id);
> +if (result) {
> +error_setg(errp, "%s: rutabaga_resource_unref returned %"PRIi32
> +   " for resource_id = %"PRIu32, __func__, result,
> +   res->resource_id);
> +strerror = strerrorname_np((int)result);
> +if (strerror != NULL) {
> +error_append_hint(errp, "%s: %s\n",
> +  strerror, strerrordesc_np((int)result) ? :
> "");
> +}
>

Can't we rely on virtio_gpu_rutabaga_debug_cb(..) to report an error when
the resource ID is not found?



> +}
> +
> +if (res->image) {
> +pixman_image_unref(res->image);
> +}
> +
> +QTAILQ_REMOVE(>reslist, res, next);
> +g_free(res);
> +}
> +
> +static void
>  rutabaga_cmd_resource_unref(VirtIOGPU *g,
>  struct virtio_gpu_ctrl_command *cmd)
>  {
> -int32_t result;
> +int32_t result = 0;
>  struct virtio_gpu_simple_resource *res;
>  struct virtio_gpu_resource_unref unref;
> -
> -VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
> +Error *local_err = NULL;
>
>  VIRTIO_GPU_FILL_CMD(unref);
>
> @@ -164,15 +192,14 @@ rutabaga_cmd_resource_unref(VirtIOGPU *g,
>  res = virtio_gpu_find_resource(g, unref.resource_id);
>  CHECK(res, cmd);
>
> -result = rutabaga_resource_unref(vr->rutabaga, unref.resource_id);
> -CHECK(!result, cmd);
> -
> -if (res->image) {
> -pixman_image_unref(res->image);
> +virtio_gpu_rutabaga_resource_unref(g, res, _err);
> +if (local_err) {
> +error_report_err(local_err);
> +/* local_err was freed, do not reuse it. */
> +local_err = NULL;
> +result = 1;
>  }
> -
> -QTAILQ_REMOVE(>reslist, res, next);
> -g_free(res);
> +CHECK(!result, cmd);
>  }
>
>  static void
> @@ -1099,7 +1126,7 @@ static void
> virtio_gpu_rutabaga_class_init(ObjectClass *klass, void *data)
>  vgc->handle_ctrl = virtio_gpu_rutabaga_handle_ctrl;
>  vgc->process_cmd = virtio_gpu_rutabaga_process_cmd;
>  vgc->update_cursor_data = virtio_gpu_rutabaga_update_cursor;
> -
> +vgc->resource_destroy = virtio_gpu_rutabaga_resource_unref;
>  vdc->realize = virtio_gpu_rutabaga_realize;
>  device_class_set_props(dc, virtio_gpu_rutabaga_properties);
>  }
> --
> γαῖα πυρί μιχθήτω
>
>


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

2024-01-29 Thread Alistair Francis
On Fri, Jan 26, 2024 at 5:54 AM Daniel Henrique Barboza
 wrote:
>
> The RVA22U64 and RVA22S64 profiles mandates certain extensions that,
> until now, we were implying that they were available.
>
> We can't do this anymore since named features also has a riscv,isa
> entry.  Let's add them to riscv_cpu_named_features[].
>
> They will also need to be explicitly enabled in both profile
> descriptions. TCG will enable the named features it already implements,
> other accelerators are free to handle it as they like.
>
> After this patch, here's the riscv,isa from a buildroot using the
> 'rva22s64' CPU:
>
>  # cat /proc/device-tree/cpus/cpu@0/riscv,isa
> rv64imafdc_zic64b_zicbom_zicbop_zicboz_ziccamoa_ziccif_zicclsm_ziccrse_
> zicntr_zicsr_zifencei_zihintpause_zihpm_za64rs_zfhmin_zca_zcd_zba_zbb_
> zbs_zkt_sscounterenw_sstvala_sstvecd_svade_svinval_svpbmt#
>
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  target/riscv/cpu.c | 41 +-
>  target/riscv/cpu_cfg.h |  9 +
>  target/riscv/tcg/tcg-cpu.c | 19 +-
>  3 files changed, 59 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 28d3cfa8ce..1ecd8a57ed 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -101,6 +101,10 @@ const RISCVIsaExtData isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
>  ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
>  ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
> +ISA_EXT_DATA_ENTRY(ziccamoa, PRIV_VERSION_1_11_0, ext_ziccamoa),
> +ISA_EXT_DATA_ENTRY(ziccif, PRIV_VERSION_1_11_0, ext_ziccif),
> +ISA_EXT_DATA_ENTRY(zicclsm, PRIV_VERSION_1_11_0, ext_zicclsm),
> +ISA_EXT_DATA_ENTRY(ziccrse, PRIV_VERSION_1_11_0, ext_ziccrse),
>  ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
>  ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
>  ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr),
> @@ -109,6 +113,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
>  ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
>  ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
> +ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, ext_za64rs),
>  ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
>  ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
>  ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
> @@ -170,8 +175,12 @@ const RISCVIsaExtData isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
>  ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
>  ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
> +ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, ext_ssccptr),
>  ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
> +ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, ext_sscounterenw),
>  ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
> +ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, ext_sstvala),
> +ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, ext_sstvecd),
>  ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
>  ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
>  ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
> @@ -1523,6 +1532,22 @@ const RISCVCPUMultiExtConfig 
> riscv_cpu_named_features[] = {
>  MULTI_EXT_CFG_BOOL("svade", ext_svade, true),
>  MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
>
> +/*
> + * cache-related extensions that are always enabled
> + * since QEMU RISC-V does not have a cache model.
> + */
> +MULTI_EXT_CFG_BOOL("za64rs", ext_za64rs, true),
> +MULTI_EXT_CFG_BOOL("ziccif", ext_ziccif, true),
> +MULTI_EXT_CFG_BOOL("ziccrse", ext_ziccrse, true),
> +MULTI_EXT_CFG_BOOL("ziccamoa", ext_ziccamoa, true),
> +MULTI_EXT_CFG_BOOL("zicclsm", ext_zicclsm, true),
> +MULTI_EXT_CFG_BOOL("ssccptr", ext_ssccptr, true),
> +
> +/* Other named features that QEMU TCG always implements */
> +MULTI_EXT_CFG_BOOL("sstvecd", ext_sstvecd, true),
> +MULTI_EXT_CFG_BOOL("sstvala", ext_sstvala, true),
> +MULTI_EXT_CFG_BOOL("sscounterenw", ext_sscounterenw, true),
> +
>  DEFINE_PROP_END_OF_LIST(),
>  };
>
> @@ -2116,13 +2141,8 @@ static const PropertyInfo prop_marchid = {
>  };
>
>  /*
> - * RVA22U64 defines some 'named features' or 'synthetic extensions'
> - * that are cache related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa
> - * and Zicclsm. We do not implement caching in QEMU so we'll consider
> - * all these named features as always enabled.
> - *
> - * There's no riscv,isa update for them (nor for zic64b, despite it
> - * having a cfg offset) at this moment.
> + * RVA22U64 defines some cache related extensions: Za64rs,
> + * Ziccif, 

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

2024-01-29 Thread Alistair Francis
On Fri, Jan 26, 2024 at 6:55 AM Daniel Henrique Barboza
 wrote:
>
> Further discussions after the introduction of rva22 support in QEMU
> revealed that what we've been calling 'named features' are actually
> regular extensions, with their respective riscv,isa DTs. This is
> clarified in [1]. [2] is a bug tracker asking for the profile spec to be
> less cryptic about it.
>
> As far as QEMU goes we understand extensions as something that the user
> can enable/disable in the command line. This isn't the case for named
> features, so we'll have to reach a middle ground.
>
> We'll keep our existing nomenclature 'named features' to refer to any
> extension that the user can't control in the command line. We'll also do
> the following:
>
> - 'svade' and 'zic64b' flags are renamed to 'ext_svade' and
>   'ext_zic64b'. 'ext_svade' and 'ext_zic64b' now have riscv,isa strings and
>   priv_spec versions;
>
> - skip name feature check in cpu_bump_multi_ext_priv_ver(). Now that
>   named features have a riscv,isa and an entry in isa_edata_arr[] we
>   don't need to gate the call to cpu_cfg_ext_get_min_version() anymore.
>
> [1] https://github.com/riscv/riscv-profiles/issues/121
> [2] https://github.com/riscv/riscv-profiles/issues/142
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

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

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

2024-01-29 Thread Alistair Francis
On Fri, Jan 26, 2024 at 5:54 AM Daniel Henrique Barboza
 wrote:
>
> Recent changes in options handling removed the 'mmu' default the bare
> CPUs had, meaning that we must enable 'mmu' by hand when using the
> rva22s64 profile CPU.
>
> Given that this profile is setting a satp mode, it already implies that
> we need a 'mmu'. Enable the 'mmu' in this case.
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

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



Re: [PATCH v10 0/3] gdbstub and TCG plugin improvements

2024-01-29 Thread Alistair Francis
On Sun, Jan 28, 2024 at 6:29 PM Akihiko Odaki  wrote:
>
> This series extracts fixes and refactorings that can be applied
> independently from "[PATCH v9 00/23] plugins: Allow to read registers".
>
> The patch "target/riscv: Move MISA limits to class" was replaced with
> patch "target/riscv: Move misa_mxl_max to class" since I found instances
> may have different misa_ext_mask.

Do you mind rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next ?

Alistair

>
> V6 -> V7:
>   Rebased.
>
> V5 -> V6:
>   Added patch "default-configs: Add TARGET_XML_FILES definition".
>   Rebased.
>
> V4 -> V5:
>   Added patch "hw/riscv: Use misa_mxl instead of misa_mxl_max".
>
> V3 -> V4:
>   Added patch "gdbstub: Check if gdb_regs is NULL".
>
> V2 -> V3:
>   Restored patch sets from the previous version.
>   Rebased to commit 800485762e6564e04e2ab315132d477069562d91.
>
> V1 -> V2:
>   Added patch "target/riscv: Do not allow MXL_RV32 for TARGET_RISCV64".
>   Added patch "target/riscv: Initialize gdb_core_xml_file only once".
>   Dropped patch "target/riscv: Remove misa_mxl validation".
>   Dropped patch "target/riscv: Move misa_mxl_max to class".
>   Dropped patch "target/riscv: Validate misa_mxl_max only once".
>
> Signed-off-by: Akihiko Odaki 
> ---
> Changes in v10:
> - Dropped patch "hw/riscv: Use misa_mxl instead of misa_mxl_max" due to
>   invalid assumption that the relevant code is only used for kernel
>   loading.
> - Link to v9: 
> https://lore.kernel.org/r/20240115-riscv-v9-0-ff171e1ae...@daynix.com
>
> Changes in v9:
> - Rebased to commit 977542ded7e6b28d2bc077bcda24568c716e393c.
> - Link to v8: 
> https://lore.kernel.org/r/20231218-riscv-v8-0-c9bf2b158...@daynix.com
>
> Changes in v8:
> - Added a more detailed explanation for patch "hw/riscv: Use misa_mxl
>   instead of misa_mxl_max". (Alistair Francis)
> - Link to v7: 
> https://lore.kernel.org/r/20231213-riscv-v7-0-a760156a3...@daynix.com
>
> ---
> Akihiko Odaki (3):
>   target/riscv: Remove misa_mxl validation
>   target/riscv: Move misa_mxl_max to class
>   target/riscv: Validate misa_mxl_max only once
>
>  target/riscv/cpu.h |   4 +-
>  hw/riscv/boot.c|   3 +-
>  target/riscv/cpu.c | 183 
> ++---
>  target/riscv/gdbstub.c |  12 ++-
>  target/riscv/kvm/kvm-cpu.c |  10 +--
>  target/riscv/machine.c |   7 +-
>  target/riscv/tcg/tcg-cpu.c |  44 ++-
>  target/riscv/translate.c   |   3 +-
>  8 files changed, 135 insertions(+), 131 deletions(-)
> ---
> base-commit: 977542ded7e6b28d2bc077bcda24568c716e393c
> change-id: 20231213-riscv-fcc9640986cf
>
> Best regards,
> --
> Akihiko Odaki 
>
>



Re: [PATCH] kconfig: use "select" to enable semihosting

2024-01-29 Thread Alistair Francis
On Mon, Jan 29, 2024 at 9:59 PM Paolo Bonzini  wrote:
>
> Just like all other dependencies, these can be expressed in Kconfig
> files rather than in the default configurations.
>
> Signed-off-by: Paolo Bonzini 

Acked-by: Alistair Francis 

Alistair

> ---
>  configs/devices/m68k-softmmu/default.mak| 2 --
>  configs/devices/mips-softmmu/common.mak | 3 ---
>  configs/devices/nios2-softmmu/default.mak   | 2 --
>  configs/devices/riscv32-softmmu/default.mak | 2 --
>  configs/devices/riscv64-softmmu/default.mak | 2 --
>  configs/devices/xtensa-softmmu/default.mak  | 2 --
>  target/m68k/Kconfig | 1 +
>  target/mips/Kconfig | 1 +
>  target/nios2/Kconfig| 1 +
>  target/riscv/Kconfig| 2 ++
>  target/xtensa/Kconfig   | 1 +
>  11 files changed, 6 insertions(+), 13 deletions(-)
>
> diff --git a/configs/devices/m68k-softmmu/default.mak 
> b/configs/devices/m68k-softmmu/default.mak
> index 7f8619e4278..8dcaa28ed38 100644
> --- a/configs/devices/m68k-softmmu/default.mak
> +++ b/configs/devices/m68k-softmmu/default.mak
> @@ -1,7 +1,5 @@
>  # Default configuration for m68k-softmmu
>
> -CONFIG_SEMIHOSTING=y
> -
>  # Boards:
>  #
>  CONFIG_AN5206=y
> diff --git a/configs/devices/mips-softmmu/common.mak 
> b/configs/devices/mips-softmmu/common.mak
> index 7da99327a77..1a853841b27 100644
> --- a/configs/devices/mips-softmmu/common.mak
> +++ b/configs/devices/mips-softmmu/common.mak
> @@ -1,8 +1,5 @@
>  # Common mips*-softmmu CONFIG defines
>
> -# CONFIG_SEMIHOSTING is always required on this architecture
> -CONFIG_SEMIHOSTING=y
> -
>  CONFIG_ISA_BUS=y
>  CONFIG_PCI=y
>  CONFIG_PCI_DEVICES=y
> diff --git a/configs/devices/nios2-softmmu/default.mak 
> b/configs/devices/nios2-softmmu/default.mak
> index 1bc4082ea99..e130d024e62 100644
> --- a/configs/devices/nios2-softmmu/default.mak
> +++ b/configs/devices/nios2-softmmu/default.mak
> @@ -1,7 +1,5 @@
>  # Default configuration for nios2-softmmu
>
> -CONFIG_SEMIHOSTING=y
> -
>  # Boards:
>  #
>  CONFIG_NIOS2_10M50=y
> diff --git a/configs/devices/riscv32-softmmu/default.mak 
> b/configs/devices/riscv32-softmmu/default.mak
> index d847bd5692e..94a236c9c25 100644
> --- a/configs/devices/riscv32-softmmu/default.mak
> +++ b/configs/devices/riscv32-softmmu/default.mak
> @@ -3,8 +3,6 @@
>  # Uncomment the following lines to disable these optional devices:
>  #
>  #CONFIG_PCI_DEVICES=n
> -CONFIG_SEMIHOSTING=y
> -CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
>
>  # Boards:
>  #
> diff --git a/configs/devices/riscv64-softmmu/default.mak 
> b/configs/devices/riscv64-softmmu/default.mak
> index bc69301fa4a..3f680594484 100644
> --- a/configs/devices/riscv64-softmmu/default.mak
> +++ b/configs/devices/riscv64-softmmu/default.mak
> @@ -3,8 +3,6 @@
>  # Uncomment the following lines to disable these optional devices:
>  #
>  #CONFIG_PCI_DEVICES=n
> -CONFIG_SEMIHOSTING=y
> -CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
>
>  # Boards:
>  #
> diff --git a/configs/devices/xtensa-softmmu/default.mak 
> b/configs/devices/xtensa-softmmu/default.mak
> index 4fe1bf00c94..49e4c9da88c 100644
> --- a/configs/devices/xtensa-softmmu/default.mak
> +++ b/configs/devices/xtensa-softmmu/default.mak
> @@ -1,7 +1,5 @@
>  # Default configuration for Xtensa
>
> -CONFIG_SEMIHOSTING=y
> -
>  # Boards:
>  #
>  CONFIG_XTENSA_SIM=y
> diff --git a/target/m68k/Kconfig b/target/m68k/Kconfig
> index 23debad519a..9eae71486ff 100644
> --- a/target/m68k/Kconfig
> +++ b/target/m68k/Kconfig
> @@ -1,2 +1,3 @@
>  config M68K
>  bool
> +select SEMIHOSTING
> diff --git a/target/mips/Kconfig b/target/mips/Kconfig
> index 6adf1453548..eb19c94c7d4 100644
> --- a/target/mips/Kconfig
> +++ b/target/mips/Kconfig
> @@ -1,5 +1,6 @@
>  config MIPS
>  bool
> +select SEMIHOSTING
>
>  config MIPS64
>  bool
> diff --git a/target/nios2/Kconfig b/target/nios2/Kconfig
> index 1529ab8950d..c65550c861a 100644
> --- a/target/nios2/Kconfig
> +++ b/target/nios2/Kconfig
> @@ -1,2 +1,3 @@
>  config NIOS2
>  bool
> +select SEMIHOSTING
> diff --git a/target/riscv/Kconfig b/target/riscv/Kconfig
> index b9e5932f13f..adb7de3f37d 100644
> --- a/target/riscv/Kconfig
> +++ b/target/riscv/Kconfig
> @@ -1,5 +1,7 @@
>  config RISCV32
>  bool
> +select ARM_COMPATIBLE_SEMIHOSTING # for do_common_semihosting()
>
>  config RISCV64
>  bool
> +select ARM_COMPATIBLE_SEMIHOSTING # for do_common_semihosting()
> diff --git a/target/xtensa/Kconfig b/target/xtensa/Kconfig
> index a3c8dc7f6d7..5e46049262d 100644
> --- a/target/xtensa/Kconfig
> +++ b/target/xtensa/Kconfig
> @@ -1,2 +1,3 @@
>  config XTENSA
>  bool
> +select SEMIHOSTING
> --
> 2.43.0
>
>



Re: [PATCH 09/10] riscv: Clean up includes

2024-01-29 Thread Alistair Francis
On Fri, Jan 26, 2024 at 2:35 AM Peter Maydell  wrote:
>
> This commit was created with scripts/clean-includes:
>  ./scripts/clean-includes --git riscv target/riscv/*.[ch]
>
> All .c should include qemu/osdep.h first.  The script performs three
> related cleanups:
>
> * Ensure .c files include qemu/osdep.h first.
> * Including it in a .h is redundant, since the .c  already includes
>   it.  Drop such inclusions.
> * Likewise, including headers qemu/osdep.h includes is redundant.
>   Drop these, too.
>
> Signed-off-by: Peter Maydell 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/vector_internals.h | 1 -
>  target/riscv/vector_internals.c | 1 +
>  2 files changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
> index 8133111e5f6..842765f6c16 100644
> --- a/target/riscv/vector_internals.h
> +++ b/target/riscv/vector_internals.h
> @@ -19,7 +19,6 @@
>  #ifndef TARGET_RISCV_VECTOR_INTERNALS_H
>  #define TARGET_RISCV_VECTOR_INTERNALS_H
>
> -#include "qemu/osdep.h"
>  #include "qemu/bitops.h"
>  #include "cpu.h"
>  #include "tcg/tcg-gvec-desc.h"
> diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
> index 9cf5c17cdea..12f5964fbbe 100644
> --- a/target/riscv/vector_internals.c
> +++ b/target/riscv/vector_internals.c
> @@ -16,6 +16,7 @@
>   * this program.  If not, see .
>   */
>
> +#include "qemu/osdep.h"
>  #include "vector_internals.h"
>
>  /* set agnostic elements to 1s */
> --
> 2.34.1
>
>



Re: [PATCH 24/33] target/riscv: Populate CPUClass.mmu_index

2024-01-29 Thread Alistair Francis
On Tue, Jan 30, 2024 at 10:03 AM Richard Henderson
 wrote:
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 8cbfc7e781..be21fa09c6 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -867,6 +867,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
>  #endif
>  }
>
> +static int riscv_cpu_mmu_index(CPUState *cs, bool ifetch)
> +{
> +return riscv_env_mmu_index(cpu_env(cs), ifetch);
> +}
> +
>  static void riscv_cpu_reset_hold(Object *obj)
>  {
>  #ifndef CONFIG_USER_ONLY
> @@ -1810,6 +1815,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
> *data)
>
>  cc->class_by_name = riscv_cpu_class_by_name;
>  cc->has_work = riscv_cpu_has_work;
> +cc->mmu_index = riscv_cpu_mmu_index;
>  cc->dump_state = riscv_cpu_dump_state;
>  cc->set_pc = riscv_cpu_set_pc;
>  cc->get_pc = riscv_cpu_get_pc;
> --
> 2.34.1
>
>



Re: [PATCH 23/33] target/riscv: Replace cpu_mmu_index with riscv_env_mmu_index

2024-01-29 Thread Alistair Francis
On Tue, Jan 30, 2024 at 9:36 AM Richard Henderson
 wrote:
>
> Use the target-specific function name in preference
> to the generic name.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_helper.c| 4 ++--
>  target/riscv/op_helper.c | 4 ++--
>  target/riscv/vector_helper.c | 9 +
>  3 files changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 15f87ecdb0..b6b23b7d03 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -106,7 +106,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
>  #else
>  flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
>
> -flags |= cpu_mmu_index(env, 0);
> +flags |= riscv_env_mmu_index(env, 0);
>  fs = get_field(env->mstatus, MSTATUS_FS);
>  vs = get_field(env->mstatus, MSTATUS_VS);
>
> @@ -1200,7 +1200,7 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, 
> vaddr addr)
>  CPURISCVState *env = >env;
>  hwaddr phys_addr;
>  int prot;
> -int mmu_idx = cpu_mmu_index(>env, false);
> +int mmu_idx = riscv_env_mmu_index(>env, false);
>
>  if (get_physical_address(env, _addr, , addr, NULL, 0, mmu_idx,
>   true, env->virt_enabled, true)) {
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index 5355225d56..f414aaebdb 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -157,7 +157,7 @@ void helper_cbo_zero(CPURISCVState *env, target_ulong 
> address)
>  {
>  RISCVCPU *cpu = env_archcpu(env);
>  uint16_t cbozlen = cpu->cfg.cboz_blocksize;
> -int mmu_idx = cpu_mmu_index(env, false);
> +int mmu_idx = riscv_env_mmu_index(env, false);
>  uintptr_t ra = GETPC();
>  void *mem;
>
> @@ -205,7 +205,7 @@ static void check_zicbom_access(CPURISCVState *env,
>  uintptr_t ra)
>  {
>  RISCVCPU *cpu = env_archcpu(env);
> -int mmu_idx = cpu_mmu_index(env, false);
> +int mmu_idx = riscv_env_mmu_index(env, false);
>  uint16_t cbomlen = cpu->cfg.cbom_blocksize;
>  void *phost;
>  int ret;
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index c1c3a4d1ea..fe0d5d053c 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -113,14 +113,15 @@ static void probe_pages(CPURISCVState *env, 
> target_ulong addr,
>  {
>  target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
>  target_ulong curlen = MIN(pagelen, len);
> +int mmu_index = riscv_env_mmu_index(env, false);
>
>  probe_access(env, adjust_addr(env, addr), curlen, access_type,
> - cpu_mmu_index(env, false), ra);
> + mmu_index, ra);
>  if (len > curlen) {
>  addr += curlen;
>  curlen = len - curlen;
>  probe_access(env, adjust_addr(env, addr), curlen, access_type,
> - cpu_mmu_index(env, false), ra);
> + mmu_index, ra);
>  }
>  }
>
> @@ -464,6 +465,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
>  uint32_t esz = 1 << log2_esz;
>  uint32_t vma = vext_vma(desc);
>  target_ulong addr, offset, remain;
> +int mmu_index = riscv_env_mmu_index(env, false);
>
>  /* probe every access */
>  for (i = env->vstart; i < env->vl; i++) {
> @@ -478,8 +480,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
>  remain = nf << log2_esz;
>  while (remain > 0) {
>  offset = -(addr | TARGET_PAGE_MASK);
> -host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD,
> - cpu_mmu_index(env, false));
> +host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD, 
> mmu_index);
>  if (host) {
>  #ifdef CONFIG_USER_ONLY
>  if (!page_check_range(addr, offset, PAGE_READ)) {
> --
> 2.34.1
>
>



Re: [PATCH 22/33] target/riscv: Rename riscv_cpu_mmu_index to riscv_env_mmu_index

2024-01-29 Thread Alistair Francis
On Tue, Jan 30, 2024 at 9:39 AM Richard Henderson
 wrote:
>
> Free up the riscv_cpu_mmu_index name for other usage;
> emphasize that the argument is 'env'.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h| 4 ++--
>  target/riscv/cpu_helper.c | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5f3955c38d..9c825c7b51 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -498,7 +498,7 @@ target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
>  void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
>  bool riscv_cpu_vector_enabled(CPURISCVState *env);
>  void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
> -int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
> +int riscv_env_mmu_index(CPURISCVState *env, bool ifetch);
>  G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
> MMUAccessType access_type,
> int mmu_idx, uintptr_t 
> retaddr);
> @@ -507,7 +507,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
> size,
>  bool probe, uintptr_t retaddr);
>  char *riscv_isa_string(RISCVCPU *cpu);
>
> -#define cpu_mmu_index riscv_cpu_mmu_index
> +#define cpu_mmu_index riscv_env_mmu_index
>
>  #ifndef CONFIG_USER_ONLY
>  void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index c7cc7eb423..15f87ecdb0 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -33,7 +33,7 @@
>  #include "debug.h"
>  #include "tcg/oversized-guest.h"
>
> -int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> +int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
>  {
>  #ifdef CONFIG_USER_ONLY
>  return 0;
> --
> 2.34.1
>
>



Re: [PATCH v3 22/29] target/riscv: Prefer fast cpu_env() over slower CPU QOM cast macro

2024-01-29 Thread Alistair Francis
On Tue, Jan 30, 2024 at 2:52 AM Philippe Mathieu-Daudé
 wrote:
>
> Mechanical patch produced running the command documented
> in scripts/coccinelle/cpu_env.cocci_template header.
>
> Reviewed-by: Richard Henderson 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/arch_dump.c   |  6 ++
>  target/riscv/cpu.c | 17 +
>  target/riscv/cpu_helper.c  | 17 +
>  target/riscv/debug.c   |  9 +++--
>  target/riscv/gdbstub.c |  6 ++
>  target/riscv/kvm/kvm-cpu.c | 11 +++
>  target/riscv/tcg/tcg-cpu.c | 10 +++---
>  target/riscv/translate.c   |  6 ++
>  8 files changed, 25 insertions(+), 57 deletions(-)
>
> diff --git a/target/riscv/arch_dump.c b/target/riscv/arch_dump.c
> index 434c8a3dbb..994709647f 100644
> --- a/target/riscv/arch_dump.c
> +++ b/target/riscv/arch_dump.c
> @@ -68,8 +68,7 @@ int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, 
> CPUState *cs,
> int cpuid, DumpState *s)
>  {
>  struct riscv64_note note;
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> +CPURISCVState *env = cpu_env(cs);
>  int ret, i = 0;
>  const char name[] = "CORE";
>
> @@ -137,8 +136,7 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, 
> CPUState *cs,
> int cpuid, DumpState *s)
>  {
>  struct riscv32_note note;
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> +CPURISCVState *env = cpu_env(cs);
>  int ret, i;
>  const char name[] = "CORE";
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 1bd99bc5c6..8af4f7a088 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -419,8 +419,7 @@ static void riscv_any_cpu_init(Object *obj)
>
>  static void riscv_max_cpu_init(Object *obj)
>  {
> -RISCVCPU *cpu = RISCV_CPU(obj);
> -CPURISCVState *env = >env;
> +CPURISCVState *env = cpu_env(CPU(obj));
>  RISCVMXL mlx = MXL_RV64;
>
>  #ifdef TARGET_RISCV32
> @@ -828,8 +827,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
> int flags)
>
>  static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
>  {
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> +CPURISCVState *env = cpu_env(cs);
>
>  if (env->xl == MXL_RV32) {
>  env->pc = (int32_t)value;
> @@ -840,8 +838,7 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
>
>  static vaddr riscv_cpu_get_pc(CPUState *cs)
>  {
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> +CPURISCVState *env = cpu_env(cs);
>
>  /* Match cpu_get_tb_cpu_state. */
>  if (env->xl == MXL_RV32) {
> @@ -853,8 +850,7 @@ static vaddr riscv_cpu_get_pc(CPUState *cs)
>  static bool riscv_cpu_has_work(CPUState *cs)
>  {
>  #ifndef CONFIG_USER_ONLY
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> +CPURISCVState *env = cpu_env(cs);
>  /*
>   * Definition of the WFI instruction requires it to ignore the privilege
>   * mode and delegation registers, but respect individual enables
> @@ -1642,10 +1638,7 @@ static void rva22s64_profile_cpu_init(Object *obj)
>
>  static const gchar *riscv_gdb_arch_name(CPUState *cs)
>  {
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> -
> -switch (riscv_cpu_mxl(env)) {
> +switch (riscv_cpu_mxl(cpu_env(cs))) {
>  case MXL_RV32:
>  return "riscv:rv32";
>  case MXL_RV64:
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 791435d628..01b32a3f83 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -493,9 +493,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
>  bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>  {
>  if (interrupt_request & CPU_INTERRUPT_HARD) {
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> -int interruptno = riscv_cpu_local_irq_pending(env);
> +int interruptno = riscv_cpu_local_irq_pending(cpu_env(cs));
>  if (interruptno >= 0) {
>  cs->exception_index = RISCV_EXCP_INT_FLAG | interruptno;
>  riscv_cpu_do_interrupt(cs);
> @@ -1196,8 +1194,7 @@ static void raise_mmu_exception(CPURISCVState *env, 
> target_ulong address,
>
>  hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>  {
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> +CPURISCVState *env = cpu_env(cs);
>  hwaddr phys_addr;
>  int prot;
>  int mmu_idx = cpu_mmu_index(env, false);
> @@ -1223,8 +1220,7 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, 
> hwaddr physaddr,
>   int mmu_idx, MemTxAttrs attrs,
>   MemTxResult response, uintptr_t retaddr)
>  {
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = >env;
> +

Re: [PATCH] smc37c669: remove useless is_enabled functions

2024-01-29 Thread Bernhard Beschow



Am 29. Januar 2024 13:34:20 UTC schrieb Paolo Bonzini :
>Calls to is_enabled are bounded to indices that actually exist in
>the SuperIO device.  Therefore, the is_enabled functions in
>smc37c669 are not doing anything and they can be removed.

Indeed isa_superio_realize() only considers .count instances respectively and 
`qemu-system-alpha -M clipper` prints something on the screen. So:

Reviewed-by: Bernhard Beschow 

>
>Signed-off-by: Paolo Bonzini 
>---
> hw/isa/smc37c669-superio.c | 18 --
> 1 file changed, 18 deletions(-)
>
>diff --git a/hw/isa/smc37c669-superio.c b/hw/isa/smc37c669-superio.c
>index 18287741cb4..388e2ed9371 100644
>--- a/hw/isa/smc37c669-superio.c
>+++ b/hw/isa/smc37c669-superio.c
>@@ -14,11 +14,6 @@
> 
> /* UARTs (compatible with NS16450 or PC16550) */
> 
>-static bool is_serial_enabled(ISASuperIODevice *sio, uint8_t index)
>-{
>-return index < 2;
>-}
>-
> static uint16_t get_serial_iobase(ISASuperIODevice *sio, uint8_t index)
> {
> return index ? 0x2f8 : 0x3f8;
>@@ -31,11 +26,6 @@ static unsigned int get_serial_irq(ISASuperIODevice *sio, 
>uint8_t index)
> 
> /* Parallel port */
> 
>-static bool is_parallel_enabled(ISASuperIODevice *sio, uint8_t index)
>-{
>-return index < 1;
>-}
>-
> static uint16_t get_parallel_iobase(ISASuperIODevice *sio, uint8_t index)
> {
> return 0x378;
>@@ -53,11 +43,6 @@ static unsigned int get_parallel_dma(ISASuperIODevice *sio, 
>uint8_t index)
> 
> /* Diskette controller (Software compatible with the Intel PC8477) */
> 
>-static bool is_fdc_enabled(ISASuperIODevice *sio, uint8_t index)
>-{
>-return index < 1;
>-}
>-
> static uint16_t get_fdc_iobase(ISASuperIODevice *sio, uint8_t index)
> {
> return 0x3f0;
>@@ -79,20 +64,17 @@ static void smc37c669_class_init(ObjectClass *klass, void 
>*data)
> 
> sc->parallel = (ISASuperIOFuncs){
> .count = 1,
>-.is_enabled = is_parallel_enabled,
> .get_iobase = get_parallel_iobase,
> .get_irq= get_parallel_irq,
> .get_dma= get_parallel_dma,
> };
> sc->serial = (ISASuperIOFuncs){
> .count = 2,
>-.is_enabled = is_serial_enabled,
> .get_iobase = get_serial_iobase,
> .get_irq= get_serial_irq,
> };
> sc->floppy = (ISASuperIOFuncs){
> .count = 1,
>-.is_enabled = is_fdc_enabled,
> .get_iobase = get_fdc_iobase,
> .get_irq= get_fdc_irq,
> .get_dma= get_fdc_dma,



[PATCH] pflash: fix sectors vs bytes confusion in blk_pread_nonzeroes()

2024-01-29 Thread Stefan Hajnoczi
The following expression is incorrect because blk_pread_nonzeroes()
deals in units of bytes, not sectors:

  bytes = MIN(size - offset, BDRV_REQUEST_MAX_SECTORS)
  ^^^

BDRV_REQUEST_MAX_BYTES is the appropriate constant.

Fixes: a4b15a8b9ef2 ("pflash: Only read non-zero parts of backend image")
Cc: Xiang Zheng 
Signed-off-by: Stefan Hajnoczi 
---
 hw/block/block.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/block/block.c b/hw/block/block.c
index 9f52ee6e72..ff503002aa 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -30,7 +30,7 @@ static int blk_pread_nonzeroes(BlockBackend *blk, hwaddr 
size, void *buf)
 BlockDriverState *bs = blk_bs(blk);
 
 for (;;) {
-bytes = MIN(size - offset, BDRV_REQUEST_MAX_SECTORS);
+bytes = MIN(size - offset, BDRV_REQUEST_MAX_BYTES);
 if (bytes <= 0) {
 return 0;
 }
-- 
2.43.0




Re: [PATCH v2 1/2] hw/core/qdev.c: add qdev_get_human_name()

2024-01-29 Thread Stefan Hajnoczi
On Tue, Jan 23, 2024 at 05:35:30PM +0200, Manos Pitsidianakis wrote:
> Add a simple method to return some kind of human readable identifier for
> use in error messages.
> 
> Signed-off-by: Manos Pitsidianakis 
> ---
>  hw/core/qdev.c |  8 
>  include/hw/qdev-core.h | 14 ++
>  2 files changed, 22 insertions(+)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH v2 2/2] hw/block/block.c: improve confusing blk_check_size_and_read_all() error

2024-01-29 Thread Stefan Hajnoczi
On Tue, Jan 23, 2024 at 05:35:31PM +0200, Manos Pitsidianakis wrote:
>  if (blk_len != size) {
> -error_setg(errp, "device requires %" HWADDR_PRIu " bytes, "
> -   "block backend provides %" PRIu64 " bytes",
> -   size, blk_len);
> +dev_id = qdev_get_human_name(dev);
> +error_setg(errp, "%s device with id='%s' requires %" HWADDR_PRIu

Since qdev_get_human_name() falls back to returning the path instead of
the id, this error message could be confusing. Perhaps avoid saying what
dev_id is and let the user interpret it:

  %s device '%s'

> +   " bytes, %s block backend provides %" PRIu64 " bytes",
> +   object_get_typename(OBJECT(dev)), dev_id, size,
> +   blk_name(blk), blk_len);
>  return false;
>  }
>  
> @@ -89,7 +90,11 @@ bool blk_check_size_and_read_all(BlockBackend *blk, void 
> *buf, hwaddr size,
>  assert(size <= BDRV_REQUEST_MAX_BYTES);
>  ret = blk_pread_nonzeroes(blk, size, buf);
>  if (ret < 0) {
> -error_setg_errno(errp, -ret, "can't read block backend");
> +dev_id = qdev_get_human_name(dev);
> +error_setg_errno(errp, -ret, "can't read %s block backend"
> + "for %s device with id='%s'",

Same here.


signature.asc
Description: PGP signature


[PATCH 33/33] include/exec: Change cpu_mmu_index argument to CPUState

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 include/exec/cpu-all.h|  2 +-
 include/exec/cpu-common.h |  3 +--
 target/sparc/cpu.h|  2 +-
 accel/tcg/cputlb.c| 22 +---
 semihosting/uaccess.c |  2 +-
 target/cris/translate.c   |  2 +-
 target/hppa/mem_helper.c  |  2 +-
 target/hppa/op_helper.c   |  8 +++---
 target/i386/tcg/translate.c   |  2 +-
 target/loongarch/tcg/tlb_helper.c |  4 +--
 target/m68k/op_helper.c   |  2 +-
 target/microblaze/helper.c|  3 +--
 target/microblaze/mmu.c   |  2 +-
 target/microblaze/translate.c |  2 +-
 target/nios2/translate.c  |  2 +-
 target/openrisc/translate.c   |  2 +-
 target/sparc/ldst_helper.c|  2 +-
 target/sparc/mmu_helper.c |  2 +-
 target/tricore/helper.c   |  2 +-
 target/tricore/translate.c|  2 +-
 target/xtensa/mmu_helper.c|  2 +-
 accel/tcg/ldst_common.c.inc   | 42 ---
 22 files changed, 65 insertions(+), 49 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 80c0d0699b..bc05dce7ab 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -311,7 +311,7 @@ CPUArchState *cpu_copy(CPUArchState *env);
 #define TLB_MMIO(1 << (TARGET_PAGE_BITS_MIN - 2))
 #define TLB_WATCHPOINT  0
 
-static inline int cpu_mmu_index(CPUArchState *env, bool ifetch)
+static inline int cpu_mmu_index(CPUState *cs, bool ifetch)
 {
 return MMU_USER_IDX;
 }
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 5a4a36a7d8..532663e81d 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -274,9 +274,8 @@ static inline CPUState *env_cpu(CPUArchState *env)
  * The user-only version of this function is inline in cpu-all.h,
  * where it always returns MMU_USER_IDX.
  */
-static inline int cpu_mmu_index(CPUArchState *env, bool ifetch)
+static inline int cpu_mmu_index(CPUState *cs, bool ifetch)
 {
-CPUState *cs = env_cpu(env);
 return cs->cc->mmu_index(cs, ifetch);
 }
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 51856152fa..1e076f6355 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -755,7 +755,7 @@ static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, 
vaddr *pc,
 uint32_t flags;
 *pc = env->pc;
 *cs_base = env->npc;
-flags = cpu_mmu_index(env, false);
+flags = cpu_mmu_index(env_cpu(env), false);
 #ifndef CONFIG_USER_ONLY
 if (cpu_supervisor_mode(env)) {
 flags |= TB_FLAG_SUPER;
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 3facfcbb24..047cd2cc0a 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1601,7 +1601,7 @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState 
*env, vaddr addr,
 void *p;
 
 (void)probe_access_internal(env_cpu(env), addr, 1, MMU_INST_FETCH,
-cpu_mmu_index(env, true), false,
+cpu_mmu_index(env_cpu(env), true), false,
 , , 0, false);
 if (p == NULL) {
 return -1;
@@ -2959,26 +2959,30 @@ static void do_st16_mmu(CPUState *cpu, vaddr addr, 
Int128 val,
 
 uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr)
 {
-MemOpIdx oi = make_memop_idx(MO_UB, cpu_mmu_index(env, true));
-return do_ld1_mmu(env_cpu(env), addr, oi, 0, MMU_INST_FETCH);
+CPUState *cs = env_cpu(env);
+MemOpIdx oi = make_memop_idx(MO_UB, cpu_mmu_index(cs, true));
+return do_ld1_mmu(cs, addr, oi, 0, MMU_INST_FETCH);
 }
 
 uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr)
 {
-MemOpIdx oi = make_memop_idx(MO_TEUW, cpu_mmu_index(env, true));
-return do_ld2_mmu(env_cpu(env), addr, oi, 0, MMU_INST_FETCH);
+CPUState *cs = env_cpu(env);
+MemOpIdx oi = make_memop_idx(MO_TEUW, cpu_mmu_index(cs, true));
+return do_ld2_mmu(cs, addr, oi, 0, MMU_INST_FETCH);
 }
 
 uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr)
 {
-MemOpIdx oi = make_memop_idx(MO_TEUL, cpu_mmu_index(env, true));
-return do_ld4_mmu(env_cpu(env), addr, oi, 0, MMU_INST_FETCH);
+CPUState *cs = env_cpu(env);
+MemOpIdx oi = make_memop_idx(MO_TEUL, cpu_mmu_index(cs, true));
+return do_ld4_mmu(cs, addr, oi, 0, MMU_INST_FETCH);
 }
 
 uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr)
 {
-MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true));
-return do_ld8_mmu(env_cpu(env), addr, oi, 0, MMU_INST_FETCH);
+CPUState *cs = env_cpu(env);
+MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(cs, true));
+return do_ld8_mmu(cs, addr, oi, 0, MMU_INST_FETCH);
 }
 
 uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr,
diff --git a/semihosting/uaccess.c b/semihosting/uaccess.c
index 5d889f9263..dc587d73bc 100644
--- a/semihosting/uaccess.c
+++ b/semihosting/uaccess.c
@@ -26,7 +26,7 @@ void *uaccess_lock_user(CPUArchState *env, 

[PATCH 31/33] target/xtensa: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/xtensa/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 62020b1f33..79f91819df 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -74,6 +74,11 @@ static bool xtensa_cpu_has_work(CPUState *cs)
 #endif
 }
 
+static int xtensa_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return xtensa_get_cring(cpu_env(cs));
+}
+
 #ifdef CONFIG_USER_ONLY
 static bool abi_call0;
 
@@ -252,6 +257,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void 
*data)
 
 cc->class_by_name = xtensa_cpu_class_by_name;
 cc->has_work = xtensa_cpu_has_work;
+cc->mmu_index = xtensa_cpu_mmu_index;
 cc->dump_state = xtensa_cpu_dump_state;
 cc->set_pc = xtensa_cpu_set_pc;
 cc->get_pc = xtensa_cpu_get_pc;
-- 
2.34.1




[PATCH 29/33] target/sparc: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/sparc/cpu.h | 34 ++
 target/sparc/cpu.c | 29 +
 2 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 12a11ecb26..92c58c92c1 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -708,34 +708,6 @@ static inline int cpu_supervisor_mode(CPUSPARCState *env1)
 }
 #endif
 
-static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
-{
-#if defined(CONFIG_USER_ONLY)
-return MMU_USER_IDX;
-#elif !defined(TARGET_SPARC64)
-if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
-return MMU_PHYS_IDX;
-} else {
-return env->psrs;
-}
-#else
-/* IMMU or DMMU disabled.  */
-if (ifetch
-? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0
-: (env->lsu & DMMU_E) == 0) {
-return MMU_PHYS_IDX;
-} else if (cpu_hypervisor_mode(env)) {
-return MMU_PHYS_IDX;
-} else if (env->tl > 0) {
-return MMU_NUCLEUS_IDX;
-} else if (cpu_supervisor_mode(env)) {
-return MMU_KERNEL_IDX;
-} else {
-return MMU_USER_IDX;
-}
-#endif
-}
-
 static inline int cpu_interrupts_enabled(CPUSPARCState *env1)
 {
 #if !defined (TARGET_SPARC64)
@@ -777,6 +749,12 @@ trap_state* cpu_tsptr(CPUSPARCState* env);
 #define TB_FLAG_HYPER(1 << 7)
 #define TB_FLAG_ASI_SHIFT24
 
+int sparc_cpu_mmu_index(CPUState *cs, bool ifetch);
+static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
+{
+return sparc_cpu_mmu_index(env_cpu(env), ifetch);
+}
+
 static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc,
 uint64_t *cs_base, uint32_t *pflags)
 {
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 7d0d629a3d..7a3b815737 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -718,6 +718,34 @@ static bool sparc_cpu_has_work(CPUState *cs)
cpu_interrupts_enabled(env);
 }
 
+int sparc_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+CPUSPARCState *env = cpu_env(cs);
+
+#ifndef TARGET_SPARC64
+if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
+return MMU_PHYS_IDX;
+} else {
+return env->psrs;
+}
+#else
+/* IMMU or DMMU disabled.  */
+if (ifetch
+? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0
+: (env->lsu & DMMU_E) == 0) {
+return MMU_PHYS_IDX;
+} else if (cpu_hypervisor_mode(env)) {
+return MMU_PHYS_IDX;
+} else if (env->tl > 0) {
+return MMU_NUCLEUS_IDX;
+} else if (cpu_supervisor_mode(env)) {
+return MMU_KERNEL_IDX;
+} else {
+return MMU_USER_IDX;
+}
+#endif
+}
+
 static char *sparc_cpu_type_name(const char *cpu_model)
 {
 char *name = g_strdup_printf(SPARC_CPU_TYPE_NAME("%s"), cpu_model);
@@ -906,6 +934,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->class_by_name = sparc_cpu_class_by_name;
 cc->parse_features = sparc_cpu_parse_features;
 cc->has_work = sparc_cpu_has_work;
+cc->mmu_index = sparc_cpu_mmu_index;
 cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
 cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
-- 
2.34.1




[PATCH 05/33] target/arm: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 6a96b245f2..1f9ea622bd 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -133,6 +133,11 @@ static bool arm_cpu_has_work(CPUState *cs)
  | CPU_INTERRUPT_EXITTB);
 }
 
+static int arm_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return arm_env_mmu_index(cpu_env(cs));
+}
+
 void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
  void *opaque)
 {
@@ -2497,6 +2502,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void 
*data)
 
 cc->class_by_name = arm_cpu_class_by_name;
 cc->has_work = arm_cpu_has_work;
+cc->mmu_index = arm_cpu_mmu_index;
 cc->dump_state = arm_cpu_dump_state;
 cc->set_pc = arm_cpu_set_pc;
 cc->get_pc = arm_cpu_get_pc;
-- 
2.34.1




[PATCH 32/33] include/exec: Implement cpu_mmu_index generically

2024-01-29 Thread Richard Henderson
For user-only mode, use MMU_USER_IDX.
For system mode, use CPUClass.mmu_index.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu-all.h|  4 
 include/exec/cpu-common.h | 19 +++
 target/alpha/cpu.h|  5 -
 target/arm/cpu.h  | 13 -
 target/avr/cpu.h  |  5 -
 target/cris/cpu.h |  4 
 target/hexagon/cpu.h  |  9 -
 target/hppa/cpu.h | 10 --
 target/i386/cpu.h |  6 --
 target/loongarch/cpu.h| 10 --
 target/m68k/cpu.h |  4 
 target/microblaze/cpu.h   |  6 --
 target/mips/cpu.h |  5 -
 target/nios2/cpu.h|  6 --
 target/openrisc/cpu.h |  6 --
 target/ppc/cpu.h  |  5 -
 target/riscv/cpu.h|  2 --
 target/rx/cpu.h   |  5 -
 target/s390x/cpu.h|  2 --
 target/sh4/cpu.h  |  6 --
 target/sparc/cpu.h|  6 --
 target/tricore/cpu.h  |  5 -
 target/xtensa/cpu.h   |  5 -
 target/hppa/cpu.c |  2 +-
 target/i386/cpu.c |  2 +-
 target/loongarch/cpu.c|  2 +-
 target/microblaze/cpu.c   |  2 +-
 target/nios2/cpu.c|  2 +-
 target/openrisc/cpu.c |  2 +-
 target/sh4/cpu.c  |  2 +-
 target/sparc/cpu.c|  2 +-
 31 files changed, 31 insertions(+), 133 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 8501a33dbf..80c0d0699b 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -311,6 +311,10 @@ CPUArchState *cpu_copy(CPUArchState *env);
 #define TLB_MMIO(1 << (TARGET_PAGE_BITS_MIN - 2))
 #define TLB_WATCHPOINT  0
 
+static inline int cpu_mmu_index(CPUArchState *env, bool ifetch)
+{
+return MMU_USER_IDX;
+}
 #else
 
 /*
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index dcbd5f5783..5a4a36a7d8 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -262,4 +262,23 @@ static inline CPUState *env_cpu(CPUArchState *env)
 return (void *)env - sizeof(CPUState);
 }
 
+#ifndef CONFIG_USER_ONLY
+/**
+ * cpu_mmu_index:
+ * @env: The cpu environment
+ * @ifetch: True for code access, false for data access.
+ *
+ * Return the core mmu index for the current translation regime.
+ * This function is used by generic TCG code paths.
+ *
+ * The user-only version of this function is inline in cpu-all.h,
+ * where it always returns MMU_USER_IDX.
+ */
+static inline int cpu_mmu_index(CPUArchState *env, bool ifetch)
+{
+CPUState *cs = env_cpu(env);
+return cs->cc->mmu_index(cs, ifetch);
+}
+#endif /* !CONFIG_USER_ONLY */
+
 #endif /* CPU_COMMON_H */
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 3beff2738a..7188a409a0 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -398,11 +398,6 @@ static inline int alpha_env_mmu_index(CPUAlphaState *env)
 return ret;
 }
 
-static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
-{
-return alpha_env_mmu_index(env);
-}
-
 enum {
 IR_V0   = 0,
 IR_T0   = 1,
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d3477b1601..63f31e0d98 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3240,19 +3240,6 @@ FIELD(TBFLAG_A64, NV2_MEM_BE, 36, 1)
 #define EX_TBFLAG_M32(IN, WHICH)   FIELD_EX32(IN.flags2, TBFLAG_M32, WHICH)
 #define EX_TBFLAG_AM32(IN, WHICH)  FIELD_EX32(IN.flags2, TBFLAG_AM32, WHICH)
 
-/**
- * cpu_mmu_index:
- * @env: The cpu environment
- * @ifetch: True for code access, false for data access.
- *
- * Return the core mmu index for the current translation regime.
- * This function is used by generic TCG code paths.
- */
-static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
-{
-return EX_TBFLAG_ANY(env->hflags, MMUIDX);
-}
-
 /**
  * sve_vq
  * @env: the cpu context
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 4595c6bb18..d185d20dcb 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -184,11 +184,6 @@ static inline void set_avr_feature(CPUAVRState *env, int 
feature)
 env->features |= (1U << feature);
 }
 
-static inline int cpu_mmu_index(CPUAVRState *env, bool ifetch)
-{
-return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX;
-}
-
 void avr_cpu_tcg_init(void);
 
 int cpu_avr_exec(CPUState *cpu);
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index d830dcac5b..3904e5448c 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -260,10 +260,6 @@ enum {
 
 /* MMU modes definitions */
 #define MMU_USER_IDX 1
-static inline int cpu_mmu_index (CPUCRISState *env, bool ifetch)
-{
-   return !!(env->pregs[PR_CCS] & U_FLAG);
-}
 
 /* Support function regs.  */
 #define SFR_RW_GC_CFG  0][0
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 5c11ae3445..3eef58fe8f 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -146,15 +146,6 @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState 
*env, vaddr *pc,
 *flags = hex_flags;
 }
 
-static inline int cpu_mmu_index(CPUHexagonState *env, bool 

[PATCH 14/33] target/microblaze: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/microblaze/cpu.h | 13 ++---
 target/microblaze/cpu.c | 18 +-
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index b5374365f5..90ab796de9 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -434,19 +434,10 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr 
physaddr, vaddr addr,
MemTxResult response, uintptr_t retaddr);
 #endif
 
+int mb_cpu_mmu_index(CPUState *cs, bool ifetch);
 static inline int cpu_mmu_index(CPUMBState *env, bool ifetch)
 {
-MicroBlazeCPU *cpu = env_archcpu(env);
-
-/* Are we in nommu mode?.  */
-if (!(env->msr & MSR_VM) || !cpu->cfg.use_mmu) {
-return MMU_NOMMU_IDX;
-}
-
-if (env->msr & MSR_UM) {
-return MMU_USER_IDX;
-}
-return MMU_KERNEL_IDX;
+return mb_cpu_mmu_index(env_cpu(env), ifetch);
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 2318ad7013..6dad11905b 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -118,6 +118,22 @@ static bool mb_cpu_has_work(CPUState *cs)
 return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
+int mb_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+CPUMBState *env = cpu_env(cs);
+MicroBlazeCPU *cpu = env_archcpu(env);
+
+/* Are we in nommu mode?.  */
+if (!(env->msr & MSR_VM) || !cpu->cfg.use_mmu) {
+return MMU_NOMMU_IDX;
+}
+
+if (env->msr & MSR_UM) {
+return MMU_USER_IDX;
+}
+return MMU_KERNEL_IDX;
+}
+
 #ifndef CONFIG_USER_ONLY
 static void mb_cpu_ns_axi_dp(void *opaque, int irq, int level)
 {
@@ -415,7 +431,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
 cc->class_by_name = mb_cpu_class_by_name;
 cc->has_work = mb_cpu_has_work;
-
+cc->mmu_index = mb_cpu_mmu_index;
 cc->dump_state = mb_cpu_dump_state;
 cc->set_pc = mb_cpu_set_pc;
 cc->get_pc = mb_cpu_get_pc;
-- 
2.34.1




[PATCH 25/33] target/rx: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/rx/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 353132dac2..5205167da1 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -64,6 +64,11 @@ static bool rx_cpu_has_work(CPUState *cs)
 (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR);
 }
 
+static int riscv_cpu_mmu_index(CPUState *cs, bool ifunc)
+{
+return 0;
+}
+
 static void rx_cpu_reset_hold(Object *obj)
 {
 RXCPU *cpu = RX_CPU(obj);
@@ -204,6 +209,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void 
*data)
 
 cc->class_by_name = rx_cpu_class_by_name;
 cc->has_work = rx_cpu_has_work;
+cc->mmu_index = riscv_cpu_mmu_index;
 cc->dump_state = rx_cpu_dump_state;
 cc->set_pc = rx_cpu_set_pc;
 cc->get_pc = rx_cpu_get_pc;
-- 
2.34.1




[PATCH 09/33] target/hppa: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h |  7 ++-
 target/hppa/cpu.c | 12 
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 6a153405d2..04439f247d 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -281,16 +281,13 @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
 return hppa_is_pa20(env) ? 0 : PA10_BTLB_FIXED + PA10_BTLB_VARIABLE;
 }
 
+int hppa_cpu_mmu_index(CPUState *cs, bool ifetch);
 static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
 return MMU_USER_IDX;
 #else
-if (env->psw & (ifetch ? PSW_C : PSW_D)) {
-return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
-}
-/* mmu disabled */
-return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
+return hppa_cpu_mmu_index(env_cpu(env), ifetch);
 #endif
 }
 
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 3c019855b4..fbb37e541e 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -94,6 +94,17 @@ static bool hppa_cpu_has_work(CPUState *cs)
 return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
+int hppa_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+CPUHPPAState *env = cpu_env(cs);
+
+if (env->psw & (ifetch ? PSW_C : PSW_D)) {
+return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
+}
+/* mmu disabled */
+return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
+}
+
 static void hppa_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
 {
 info->mach = bfd_mach_hppa20;
@@ -194,6 +205,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
 
 cc->class_by_name = hppa_cpu_class_by_name;
 cc->has_work = hppa_cpu_has_work;
+cc->mmu_index = hppa_cpu_mmu_index;
 cc->dump_state = hppa_cpu_dump_state;
 cc->set_pc = hppa_cpu_set_pc;
 cc->get_pc = hppa_cpu_get_pc;
-- 
2.34.1




[PATCH 30/33] target/tricore: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/tricore/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index e6d91c74b5..74e8a22b86 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -89,6 +89,11 @@ static bool tricore_cpu_has_work(CPUState *cs)
 return true;
 }
 
+static int tricore_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return 0;
+}
+
 static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
 {
 CPUState *cs = CPU(dev);
@@ -194,6 +199,7 @@ static void tricore_cpu_class_init(ObjectClass *c, void 
*data)
>parent_phases);
 cc->class_by_name = tricore_cpu_class_by_name;
 cc->has_work = tricore_cpu_has_work;
+cc->mmu_index = tricore_cpu_mmu_index;
 
 cc->gdb_read_register = tricore_cpu_gdb_read_register;
 cc->gdb_write_register = tricore_cpu_gdb_write_register;
-- 
2.34.1




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

2024-01-29 Thread Fabiano Rosas
Fabiano Rosas  writes:

> Peter Xu  writes:
>
>> On Fri, Jan 26, 2024 at 11:54:32AM -0300, Fabiano Rosas wrote:
>>> Peter Maydell  writes:
>>> 
>>> > On Fri, 26 Jan 2024 at 14:36, Fabiano Rosas  wrote:
>>> >>
>>> >> pet...@redhat.com writes:
>>> >>
>>> >> > From: Fabiano Rosas 
>>> >> >
>>> >> > The 'max' cpu is not expected to be stable in terms of features across
>>> >> > QEMU versions, so it should not be expected to migrate.
>>> >> >
>>> >> > While the tests currently all pass with -cpu max, that is only because
>>> >> > we're not testing across QEMU versions, which is the more common
>>> >> > use-case for migration.
>>> >> >
>>> >> > We've recently introduced compatibility tests that use two different
>>> >> > QEMU versions and the tests are now failing for aarch64. The next
>>> >> > patch adds those tests to CI, so we cannot use the 'max' cpu
>>> >> > anymore. Replace it with the 'neoverse-n1', which has a fixed set of
>>> >> > features.
>>> >> >
>>> >> > Suggested-by: Peter Maydell 
>>> >> > Signed-off-by: Fabiano Rosas 
>>> >> > Link: https://lore.kernel.org/r/20240118164951.30350-2-faro...@suse.de
>>> >> > Signed-off-by: Peter Xu 
>>> >> > ---
>>> >> >  tests/qtest/migration-test.c | 2 +-
>>> >> >  1 file changed, 1 insertion(+), 1 deletion(-)
>>> >> >
>>> >> > diff --git a/tests/qtest/migration-test.c 
>>> >> > b/tests/qtest/migration-test.c
>>> >> > index 7675519cfa..15713f3666 100644
>>> >> > --- a/tests/qtest/migration-test.c
>>> >> > +++ b/tests/qtest/migration-test.c
>>> >> > @@ -820,7 +820,7 @@ static int test_migrate_start(QTestState **from, 
>>> >> > QTestState **to,
>>> >> >  memory_size = "150M";
>>> >> >  machine_alias = "virt";
>>> >> >  machine_opts = "gic-version=max";
>>> >> > -arch_opts = g_strdup_printf("-cpu max -kernel %s", bootpath);
>>> >> > +arch_opts = g_strdup_printf("-cpu neoverse-n1 -kernel %s", 
>>> >> > bootpath);
>>> >> >  start_address = ARM_TEST_MEM_START;
>>> >> >  end_address = ARM_TEST_MEM_END;
>>> >> >  } else {
>>> >>
>>> >> This breaks the tests on an arm host with KVM support. We could drop
>>> >> this patch from the PR, it doesn't affect anything else.
>>> >>
>>> >> Or squash in:
>>> >>
>>> >> -->8--
>>> >> From b8aa5d8a2b33dcc28e4cd4ce2c4f4eacc3a3b845 Mon Sep 17 00:00:00 2001
>>> >> From: Fabiano Rosas 
>>> >> Date: Fri, 26 Jan 2024 11:33:15 -0300
>>> >> Subject: [PATCH] fixup! tests/qtest/migration: Don't use -cpu max for 
>>> >> aarch64
>>> >>
>>> >> Signed-off-by: Fabiano Rosas 
>>> >> ---
>>> >>  tests/qtest/migration-test.c | 4 +++-
>>> >>  1 file changed, 3 insertions(+), 1 deletion(-)
>>> >>
>>> >> diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
>>> >> index 15713f3666..2ba9cab684 100644
>>> >> --- a/tests/qtest/migration-test.c
>>> >> +++ b/tests/qtest/migration-test.c
>>> >> @@ -820,7 +820,9 @@ static int test_migrate_start(QTestState **from, 
>>> >> QTestState **to,
>>> >>  memory_size = "150M";
>>> >>  machine_alias = "virt";
>>> >>  machine_opts = "gic-version=max";
>>> >> -arch_opts = g_strdup_printf("-cpu neoverse-n1 -kernel %s", 
>>> >> bootpath);
>>> >> +arch_opts = g_strdup_printf("-cpu %s -kernel %s",
>>> >> +qtest_has_accel("kvm") ?
>>> >> +"host" : "neoverse-n1", bootpath);
>>> >>  start_address = ARM_TEST_MEM_START;
>>> >>  end_address = ARM_TEST_MEM_END;
>>> >>  } else {
>>> >
>>> > If you want to do that then a comment explaining why would be
>>> > helpful for future readers, I think.
>>> 
>>> Ok, let's drop this one then, I'll resend.
>>
>> I'll drop this one for now then, thanks.
>>
>> Just to double check: Fabiano, you meant that "-cpu host" won't hit the
>> same issue as what "-cpu max" would have for the new "n-1" CI test, right?
>
> Well, no. What we need here is a cpu that works with KVM. Currently
> that's 'host'. If that breaks the n-1 test, then it's a regression.
>
> We also need a cpu that works with TCG. Any of them would do. Except max
> which changes in incompatible ways (that was the original patch's
> purpose).
>
> The issue that occurs to me now is that 'cpu host' will not work with
> TCG. We might actually need to go poking /dev/kvm for this to work.

Nevermind this last part. There's not going to be a scenario where we
build with CONFIG_KVM, but run in an environment that does not support
KVM.



[PATCH 28/33] target/sh4: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/sh4/cpu.h | 16 ++--
 target/sh4/cpu.c | 16 
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 0e6fa65bae..9c5e2b349e 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -273,16 +273,6 @@ void cpu_load_tlb(CPUSH4State * env);
 
 /* MMU modes definitions */
 #define MMU_USER_IDX 1
-static inline int cpu_mmu_index (CPUSH4State *env, bool ifetch)
-{
-/* The instruction in a RTE delay slot is fetched in privileged
-   mode, but executed in user mode.  */
-if (ifetch && (env->flags & TB_FLAG_DELAY_SLOT_RTE)) {
-return 0;
-} else {
-return (env->sr & (1u << SR_MD)) == 0 ? 1 : 0;
-}
-}
 
 #include "exec/cpu-all.h"
 
@@ -380,6 +370,12 @@ static inline void cpu_write_sr(CPUSH4State *env, 
target_ulong sr)
 env->sr = sr & ~((1u << SR_M) | (1u << SR_Q) | (1u << SR_T));
 }
 
+int sh4_cpu_mmu_index(CPUState *cs, bool ifetch);
+static inline int cpu_mmu_index(CPUSH4State *env, bool ifetch)
+{
+return sh4_cpu_mmu_index(env_cpu(env), ifetch);
+}
+
 static inline void cpu_get_tb_cpu_state(CPUSH4State *env, vaddr *pc,
 uint64_t *cs_base, uint32_t *flags)
 {
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 39772955b5..6fead5655f 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -89,6 +89,21 @@ static bool superh_cpu_has_work(CPUState *cs)
 return cs->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
+int sh4_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+CPUSH4State *env = cpu_env(cs);
+
+/*
+ * The instruction in a RTE delay slot is fetched in privileged mode,
+ * but executed in user mode.
+ */
+if (ifetch && (env->flags & TB_FLAG_DELAY_SLOT_RTE)) {
+return 0;
+} else {
+return (env->sr & (1u << SR_MD)) == 0 ? 1 : 0;
+}
+}
+
 static void superh_cpu_reset_hold(Object *obj)
 {
 CPUState *s = CPU(obj);
@@ -266,6 +281,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void 
*data)
 
 cc->class_by_name = superh_cpu_class_by_name;
 cc->has_work = superh_cpu_has_work;
+cc->mmu_index = sh4_cpu_mmu_index;
 cc->dump_state = superh_cpu_dump_state;
 cc->set_pc = superh_cpu_set_pc;
 cc->get_pc = superh_cpu_get_pc;
-- 
2.34.1




[PATCH 10/33] target/i386: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/i386/cpu.h | 13 ++---
 target/i386/cpu.c | 10 ++
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 7f0786e8b9..62bdb02378 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2296,13 +2296,6 @@ uint64_t cpu_get_tsc(CPUX86State *env);
 #define MMU_NESTED_IDX  3
 #define MMU_PHYS_IDX4
 
-static inline int cpu_mmu_index(CPUX86State *env, bool ifetch)
-{
-return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
-(!(env->hflags & HF_SMAP_MASK) || (env->eflags & AC_MASK))
-? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX;
-}
-
 static inline int cpu_mmu_index_kernel(CPUX86State *env)
 {
 return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX :
@@ -2322,6 +2315,12 @@ static inline int cpu_mmu_index_kernel(CPUX86State *env)
 #include "hw/i386/apic.h"
 #endif
 
+int x86_cpu_mmu_index(CPUState *cs, bool ifetch);
+static inline int cpu_mmu_index(CPUX86State *env, bool ifetch)
+{
+return x86_cpu_mmu_index(env_cpu(env), ifetch);
+}
+
 static inline void cpu_get_tb_cpu_state(CPUX86State *env, vaddr *pc,
 uint64_t *cs_base, uint32_t *flags)
 {
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 03822d9ba8..280bcb7d00 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7720,6 +7720,15 @@ static bool x86_cpu_has_work(CPUState *cs)
 return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0;
 }
 
+int x86_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+CPUX86State *env = cpu_env(cs);
+
+return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
+(!(env->hflags & HF_SMAP_MASK) || (env->eflags & AC_MASK))
+? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX;
+}
+
 static void x86_disas_set_info(CPUState *cs, disassemble_info *info)
 {
 X86CPU *cpu = X86_CPU(cs);
@@ -7954,6 +7963,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, 
void *data)
 cc->class_by_name = x86_cpu_class_by_name;
 cc->parse_features = x86_cpu_parse_featurestr;
 cc->has_work = x86_cpu_has_work;
+cc->mmu_index = x86_cpu_mmu_index;
 cc->dump_state = x86_cpu_dump_state;
 cc->set_pc = x86_cpu_set_pc;
 cc->get_pc = x86_cpu_get_pc;
-- 
2.34.1




[PATCH 17/33] target/mips: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/mips/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index df544ab39b..d644adbc77 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -182,6 +182,11 @@ static bool mips_cpu_has_work(CPUState *cs)
 return has_work;
 }
 
+static int mips_cpu_mmu_index(CPUState *cs, bool ifunc)
+{
+return mips_env_mmu_index(cpu_env(cs));
+}
+
 #include "cpu-defs.c.inc"
 
 static void mips_cpu_reset_hold(Object *obj)
@@ -579,6 +584,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 
 cc->class_by_name = mips_cpu_class_by_name;
 cc->has_work = mips_cpu_has_work;
+cc->mmu_index = mips_cpu_mmu_index;
 cc->dump_state = mips_cpu_dump_state;
 cc->set_pc = mips_cpu_set_pc;
 cc->get_pc = mips_cpu_get_pc;
-- 
2.34.1




[PATCH 26/33] target/s390x: Split out s390x_env_mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/s390x/cpu.h|  4 +++-
 target/s390x/tcg/mem_helper.c | 34 ++
 2 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index fa3aac4f97..f0fed5d6ad 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -381,7 +381,7 @@ extern const VMStateDescription vmstate_s390_cpu;
 #define MMU_HOME_IDX2
 #define MMU_REAL_IDX3
 
-static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch)
+static inline int s390x_env_mmu_index(CPUS390XState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
 return MMU_USER_IDX;
@@ -412,6 +412,8 @@ static inline int cpu_mmu_index(CPUS390XState *env, bool 
ifetch)
 #endif
 }
 
+#define cpu_mmu_index s390x_env_mmu_index
+
 #ifdef CONFIG_TCG
 
 #include "tcg/tcg_s390x.h"
diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index 84103251b9..557831def4 100644
--- a/target/s390x/tcg/mem_helper.c
+++ b/target/s390x/tcg/mem_helper.c
@@ -358,7 +358,7 @@ static int mmu_idx_from_as(uint8_t as)
 static uint32_t do_helper_nc(CPUS390XState *env, uint32_t l, uint64_t dest,
  uint64_t src, uintptr_t ra)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 S390Access srca1, srca2, desta;
 uint32_t i;
 uint8_t c = 0;
@@ -392,7 +392,7 @@ uint32_t HELPER(nc)(CPUS390XState *env, uint32_t l, 
uint64_t dest,
 static uint32_t do_helper_xc(CPUS390XState *env, uint32_t l, uint64_t dest,
  uint64_t src, uintptr_t ra)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 S390Access srca1, srca2, desta;
 uint32_t i;
 uint8_t c = 0;
@@ -433,7 +433,7 @@ uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, 
uint64_t dest,
 static uint32_t do_helper_oc(CPUS390XState *env, uint32_t l, uint64_t dest,
  uint64_t src, uintptr_t ra)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 S390Access srca1, srca2, desta;
 uint32_t i;
 uint8_t c = 0;
@@ -467,7 +467,7 @@ uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, 
uint64_t dest,
 static uint32_t do_helper_mvc(CPUS390XState *env, uint32_t l, uint64_t dest,
   uint64_t src, uintptr_t ra)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 S390Access srca, desta;
 uint32_t i;
 
@@ -508,7 +508,7 @@ void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t 
dest, uint64_t src)
 /* move right to left */
 void HELPER(mvcrl)(CPUS390XState *env, uint64_t l, uint64_t dest, uint64_t src)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 const uint64_t ra = GETPC();
 S390Access srca, desta;
 int32_t i;
@@ -529,7 +529,7 @@ void HELPER(mvcrl)(CPUS390XState *env, uint64_t l, uint64_t 
dest, uint64_t src)
 /* move inverse  */
 void HELPER(mvcin)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 S390Access srca, desta;
 uintptr_t ra = GETPC();
 int i;
@@ -550,7 +550,7 @@ void HELPER(mvcin)(CPUS390XState *env, uint32_t l, uint64_t 
dest, uint64_t src)
 /* move numerics  */
 void HELPER(mvn)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 S390Access srca1, srca2, desta;
 uintptr_t ra = GETPC();
 int i;
@@ -572,7 +572,7 @@ void HELPER(mvn)(CPUS390XState *env, uint32_t l, uint64_t 
dest, uint64_t src)
 /* move with offset  */
 void HELPER(mvo)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 /* MVO always processes one more byte than specified - maximum is 16 */
 const int len_dest = (l >> 4) + 1;
 const int len_src = (l & 0xf) + 1;
@@ -606,7 +606,7 @@ void HELPER(mvo)(CPUS390XState *env, uint32_t l, uint64_t 
dest, uint64_t src)
 /* move zones  */
 void HELPER(mvz)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
 {
-const int mmu_idx = cpu_mmu_index(env, false);
+const int mmu_idx = s390x_env_mmu_index(env, false);
 S390Access srca1, srca2, desta;
 uintptr_t ra = GETPC();
 int i;
@@ -669,7 +669,7 @@ uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, 
uint32_t mask,
 
 if (!mask) {
 /* Recognize access exceptions for the first byte */
-probe_read(env, addr, 1, cpu_mmu_index(env, false), ra);
+probe_read(env, addr, 1, s390x_env_mmu_index(env, false), ra);
 }
 
   

[PATCH 15/33] target/mips: Pass ptw_mmu_idx down from mips_cpu_tlb_fill

2024-01-29 Thread Richard Henderson
Rather than adjust env->hflags so that the value computed
by cpu_mmu_index() changes, compute the mmu_idx that we
want directly and pass it down.

Introduce symbolic constants for MMU_{KERNEL,ERL}_IDX.

Signed-off-by: Richard Henderson 
---
 target/mips/cpu.h   |  4 +++-
 target/mips/tcg/sysemu/tlb_helper.c | 32 -
 2 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 1163a71f3c..3ba8dccd2d 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1242,12 +1242,14 @@ uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState 
*env);
  * MMU modes definitions. We carefully match the indices with our
  * hflags layout.
  */
+#define MMU_KERNEL_IDX 0
 #define MMU_USER_IDX 2
+#define MMU_ERL_IDX 3
 
 static inline int hflags_mmu_index(uint32_t hflags)
 {
 if (hflags & MIPS_HFLAG_ERL) {
-return 3; /* ERL */
+return MMU_ERL_IDX;
 } else {
 return hflags & MIPS_HFLAG_KSU;
 }
diff --git a/target/mips/tcg/sysemu/tlb_helper.c 
b/target/mips/tcg/sysemu/tlb_helper.c
index 4ede904800..b715449114 100644
--- a/target/mips/tcg/sysemu/tlb_helper.c
+++ b/target/mips/tcg/sysemu/tlb_helper.c
@@ -623,7 +623,7 @@ static uint64_t get_tlb_entry_layout(CPUMIPSState *env, 
uint64_t entry,
 static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
 int directory_index, bool *huge_page, bool *hgpg_directory_hit,
 uint64_t *pw_entrylo0, uint64_t *pw_entrylo1,
-unsigned directory_shift, unsigned leaf_shift)
+unsigned directory_shift, unsigned leaf_shift, int ptw_mmu_idx)
 {
 int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1;
 int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F;
@@ -638,8 +638,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t 
*vaddr,
 uint64_t w = 0;
 
 if (get_physical_address(env, , , *vaddr, MMU_DATA_LOAD,
- cpu_mmu_index(env, false)) !=
- TLBRET_MATCH) {
+ ptw_mmu_idx) != TLBRET_MATCH) {
 /* wrong base address */
 return 0;
 }
@@ -666,8 +665,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t 
*vaddr,
 *pw_entrylo0 = entry;
 }
 if (get_physical_address(env, , , vaddr2, MMU_DATA_LOAD,
- cpu_mmu_index(env, false)) !=
- TLBRET_MATCH) {
+ ptw_mmu_idx) != TLBRET_MATCH) {
 return 0;
 }
 if (!get_pte(env, vaddr2, leafentry_size, )) {
@@ -690,7 +688,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t 
*vaddr,
 }
 
 static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
-   int mmu_idx)
+   int ptw_mmu_idx)
 {
 int gdw = (env->CP0_PWSize >> CP0PS_GDW) & 0x3F;
 int udw = (env->CP0_PWSize >> CP0PS_UDW) & 0x3F;
@@ -776,7 +774,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr 
address,
 vaddr |= goffset;
 switch (walk_directory(env, , pf_gdw, _page, _gdhit,
_entrylo0, _entrylo1,
-   directory_shift, leaf_shift))
+   directory_shift, leaf_shift, ptw_mmu_idx))
 {
 case 0:
 return false;
@@ -793,7 +791,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr 
address,
 vaddr |= uoffset;
 switch (walk_directory(env, , pf_udw, _page, _udhit,
_entrylo0, _entrylo1,
-   directory_shift, leaf_shift))
+   directory_shift, leaf_shift, ptw_mmu_idx))
 {
 case 0:
 return false;
@@ -810,7 +808,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr 
address,
 vaddr |= moffset;
 switch (walk_directory(env, , pf_mdw, _page, _mdhit,
_entrylo0, _entrylo1,
-   directory_shift, leaf_shift))
+   directory_shift, leaf_shift, ptw_mmu_idx))
 {
 case 0:
 return false;
@@ -825,8 +823,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr 
address,
 /* Leaf Level Page Table - First half of PTE pair */
 vaddr |= ptoffset0;
 if (get_physical_address(env, , , vaddr, MMU_DATA_LOAD,
- cpu_mmu_index(env, false)) !=
- TLBRET_MATCH) {
+ ptw_mmu_idx) != TLBRET_MATCH) {
 return false;
 }
 if (!get_pte(env, vaddr, leafentry_size, _entry)) {
@@ -838,8 +835,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr 
address,
 /* Leaf Level Page Table - Second half of PTE pair */
 vaddr |= ptoffset1;
 if (get_physical_address(env, , , vaddr, 

[PATCH 04/33] target/arm: Split out arm_env_mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/internals.h  |  5 +
 target/arm/helper.c |  2 +-
 target/arm/tcg/helper-a64.c |  4 ++--
 target/arm/tcg/mte_helper.c | 18 +-
 target/arm/tcg/sve_helper.c |  8 
 target/arm/tcg/tlb_helper.c |  2 +-
 6 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 71d6c70bf3..fc337fe40e 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -40,6 +40,11 @@
 #define BANK_HYP6
 #define BANK_MON7
 
+static inline int arm_env_mmu_index(CPUARMState *env)
+{
+return EX_TBFLAG_ANY(env->hflags, MMUIDX);
+}
+
 static inline bool excp_is_internal(int excp)
 {
 /* Return true if this exception number represents a QEMU-internal
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 945d8571a6..b0488caf40 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7841,7 +7841,7 @@ static void dccvap_writefn(CPUARMState *env, const 
ARMCPRegInfo *opaque,
 uint64_t vaddr_in = (uint64_t) value;
 uint64_t vaddr = vaddr_in & ~(dline_size - 1);
 void *haddr;
-int mem_idx = cpu_mmu_index(env, false);
+int mem_idx = arm_env_mmu_index(env);
 
 /* This won't be crossing page boundaries */
 haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
index 198b975f20..ebaa7f00df 100644
--- a/target/arm/tcg/helper-a64.c
+++ b/target/arm/tcg/helper-a64.c
@@ -856,7 +856,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t 
new_pc)
 tbii = EX_TBFLAG_A64(env->hflags, TBII);
 if ((tbii >> extract64(new_pc, 55, 1)) & 1) {
 /* TBI is enabled. */
-int core_mmu_idx = cpu_mmu_index(env, false);
+int core_mmu_idx = arm_env_mmu_index(env);
 if (regime_has_2_ranges(core_to_aa64_mmu_idx(core_mmu_idx))) {
 new_pc = sextract64(new_pc, 0, 56);
 } else {
@@ -925,7 +925,7 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
  */
 int blocklen = 4 << env_archcpu(env)->dcz_blocksize;
 uint64_t vaddr = vaddr_in & ~(blocklen - 1);
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = arm_env_mmu_index(env);
 void *mem;
 
 /*
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
index ffb8ea1c34..d971b81370 100644
--- a/target/arm/tcg/mte_helper.c
+++ b/target/arm/tcg/mte_helper.c
@@ -291,7 +291,7 @@ static int load_tag1(uint64_t ptr, uint8_t *mem)
 
 uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr, uint64_t xt)
 {
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = arm_env_mmu_index(env);
 uint8_t *mem;
 int rtag = 0;
 
@@ -311,7 +311,7 @@ static void check_tag_aligned(CPUARMState *env, uint64_t 
ptr, uintptr_t ra)
 {
 if (unlikely(!QEMU_IS_ALIGNED(ptr, TAG_GRANULE))) {
 arm_cpu_do_unaligned_access(env_cpu(env), ptr, MMU_DATA_STORE,
-cpu_mmu_index(env, false), ra);
+arm_env_mmu_index(env), ra);
 g_assert_not_reached();
 }
 }
@@ -344,7 +344,7 @@ typedef void stg_store1(uint64_t, uint8_t *, int);
 static inline void do_stg(CPUARMState *env, uint64_t ptr, uint64_t xt,
   uintptr_t ra, stg_store1 store1)
 {
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = arm_env_mmu_index(env);
 uint8_t *mem;
 
 check_tag_aligned(env, ptr, ra);
@@ -371,7 +371,7 @@ void HELPER(stg_parallel)(CPUARMState *env, uint64_t ptr, 
uint64_t xt)
 
 void HELPER(stg_stub)(CPUARMState *env, uint64_t ptr)
 {
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = arm_env_mmu_index(env);
 uintptr_t ra = GETPC();
 
 check_tag_aligned(env, ptr, ra);
@@ -381,7 +381,7 @@ void HELPER(stg_stub)(CPUARMState *env, uint64_t ptr)
 static inline void do_st2g(CPUARMState *env, uint64_t ptr, uint64_t xt,
uintptr_t ra, stg_store1 store1)
 {
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = arm_env_mmu_index(env);
 int tag = allocation_tag_from_addr(xt);
 uint8_t *mem1, *mem2;
 
@@ -429,7 +429,7 @@ void HELPER(st2g_parallel)(CPUARMState *env, uint64_t ptr, 
uint64_t xt)
 
 void HELPER(st2g_stub)(CPUARMState *env, uint64_t ptr)
 {
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = arm_env_mmu_index(env);
 uintptr_t ra = GETPC();
 int in_page = -(ptr | TARGET_PAGE_MASK);
 
@@ -445,7 +445,7 @@ void HELPER(st2g_stub)(CPUARMState *env, uint64_t ptr)
 
 uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
 {
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = arm_env_mmu_index(env);
 uintptr_t ra = GETPC();
 int gm_bs = env_archcpu(env)->gm_blocksize;
 int gm_bs_bytes = 4 << gm_bs;
@@ -505,7 +505,7 @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
 
 void HELPER(stgm)(CPUARMState *env, 

[PATCH 20/33] target/ppc: Split out ppc_env_mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/ppc/cpu.h|  7 ++-
 target/ppc/cpu_init.c   |  2 +-
 target/ppc/mem_helper.c | 10 +-
 target/ppc/mmu_common.c |  4 ++--
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index f8101ffa29..5f4f52aec5 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1624,7 +1624,7 @@ int ppc_dcr_write(ppc_dcr_t *dcr_env, int dcrn, uint32_t 
val);
 
 /* MMU modes definitions */
 #define MMU_USER_IDX 0
-static inline int cpu_mmu_index(CPUPPCState *env, bool ifetch)
+static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
 return MMU_USER_IDX;
@@ -1633,6 +1633,11 @@ static inline int cpu_mmu_index(CPUPPCState *env, bool 
ifetch)
 #endif
 }
 
+static inline int cpu_mmu_index(CPUPPCState *env, bool ifetch)
+{
+return ppc_env_mmu_index(env, ifetch);
+}
+
 /* Compatibility modes */
 #if defined(TARGET_PPC64)
 bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr,
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 23eb5522b6..86c8031765 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7457,7 +7457,7 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 qemu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
  "%08x iidx %d didx %d\n",
  env->msr, env->spr[SPR_HID0], env->hflags,
- cpu_mmu_index(env, true), cpu_mmu_index(env, false));
+ ppc_env_mmu_index(env, true), ppc_env_mmu_index(env, false));
 #if !defined(CONFIG_USER_ONLY)
 if (env->tb_env) {
 qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
index c7535481d6..ea7e8443a8 100644
--- a/target/ppc/mem_helper.c
+++ b/target/ppc/mem_helper.c
@@ -83,7 +83,7 @@ static void *probe_contiguous(CPUPPCState *env, target_ulong 
addr, uint32_t nb,
 void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
 {
 uintptr_t raddr = GETPC();
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = ppc_env_mmu_index(env, false);
 void *host = probe_contiguous(env, addr, (32 - reg) * 4,
   MMU_DATA_LOAD, mmu_idx, raddr);
 
@@ -105,7 +105,7 @@ void helper_lmw(CPUPPCState *env, target_ulong addr, 
uint32_t reg)
 void helper_stmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
 {
 uintptr_t raddr = GETPC();
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = ppc_env_mmu_index(env, false);
 void *host = probe_contiguous(env, addr, (32 - reg) * 4,
   MMU_DATA_STORE, mmu_idx, raddr);
 
@@ -135,7 +135,7 @@ static void do_lsw(CPUPPCState *env, target_ulong addr, 
uint32_t nb,
 return;
 }
 
-mmu_idx = cpu_mmu_index(env, false);
+mmu_idx = ppc_env_mmu_index(env, false);
 host = probe_contiguous(env, addr, nb, MMU_DATA_LOAD, mmu_idx, raddr);
 
 if (likely(host)) {
@@ -224,7 +224,7 @@ void helper_stsw(CPUPPCState *env, target_ulong addr, 
uint32_t nb,
 return;
 }
 
-mmu_idx = cpu_mmu_index(env, false);
+mmu_idx = ppc_env_mmu_index(env, false);
 host = probe_contiguous(env, addr, nb, MMU_DATA_STORE, mmu_idx, raddr);
 
 if (likely(host)) {
@@ -276,7 +276,7 @@ static void dcbz_common(CPUPPCState *env, target_ulong addr,
 target_ulong mask, dcbz_size = env->dcache_line_size;
 uint32_t i;
 void *haddr;
-int mmu_idx = epid ? PPC_TLB_EPID_STORE : cpu_mmu_index(env, false);
+int mmu_idx = epid ? PPC_TLB_EPID_STORE : ppc_env_mmu_index(env, false);
 
 #if defined(TARGET_PPC64)
 /* Check for dcbz vs dcbzl on 970 */
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 6ca5d12207..751403f1c8 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1561,9 +1561,9 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
  * mapped by code TLBs, so we also try a MMU_INST_FETCH.
  */
 if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, , , ,
-  cpu_mmu_index(>env, false), false) ||
+  ppc_env_mmu_index(>env, false), false) ||
 ppc_xlate(cpu, addr, MMU_INST_FETCH, , , ,
-  cpu_mmu_index(>env, true), false)) {
+  ppc_env_mmu_index(>env, true), false)) {
 return raddr & TARGET_PAGE_MASK;
 }
 return -1;
-- 
2.34.1




[PATCH 02/33] target/alpha: Split out alpha_env_mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/alpha/cpu.h   | 7 ++-
 target/alpha/translate.c | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index ce806587ca..3beff2738a 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -389,7 +389,7 @@ enum {
 
 #define TB_FLAG_UNALIGN   (1u << 1)
 
-static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
+static inline int alpha_env_mmu_index(CPUAlphaState *env)
 {
 int ret = env->flags & ENV_FLAG_PS_USER ? MMU_USER_IDX : MMU_KERNEL_IDX;
 if (env->flags & ENV_FLAG_PAL_MODE) {
@@ -398,6 +398,11 @@ static inline int cpu_mmu_index(CPUAlphaState *env, bool 
ifetch)
 return ret;
 }
 
+static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
+{
+return alpha_env_mmu_index(env);
+}
+
 enum {
 IR_V0   = 0,
 IR_T0   = 1,
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 134eb7225b..4b464f8651 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -2875,7 +2875,7 @@ static void alpha_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cpu)
 int64_t bound;
 
 ctx->tbflags = ctx->base.tb->flags;
-ctx->mem_idx = cpu_mmu_index(env, false);
+ctx->mem_idx = alpha_env_mmu_index(env);
 ctx->implver = env->implver;
 ctx->amask = env->amask;
 
-- 
2.34.1




[PATCH 23/33] target/riscv: Replace cpu_mmu_index with riscv_env_mmu_index

2024-01-29 Thread Richard Henderson
Use the target-specific function name in preference
to the generic name.

Signed-off-by: Richard Henderson 
---
 target/riscv/cpu_helper.c| 4 ++--
 target/riscv/op_helper.c | 4 ++--
 target/riscv/vector_helper.c | 9 +
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 15f87ecdb0..b6b23b7d03 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -106,7 +106,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
 #else
 flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
 
-flags |= cpu_mmu_index(env, 0);
+flags |= riscv_env_mmu_index(env, 0);
 fs = get_field(env->mstatus, MSTATUS_FS);
 vs = get_field(env->mstatus, MSTATUS_VS);
 
@@ -1200,7 +1200,7 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 CPURISCVState *env = >env;
 hwaddr phys_addr;
 int prot;
-int mmu_idx = cpu_mmu_index(>env, false);
+int mmu_idx = riscv_env_mmu_index(>env, false);
 
 if (get_physical_address(env, _addr, , addr, NULL, 0, mmu_idx,
  true, env->virt_enabled, true)) {
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 5355225d56..f414aaebdb 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -157,7 +157,7 @@ void helper_cbo_zero(CPURISCVState *env, target_ulong 
address)
 {
 RISCVCPU *cpu = env_archcpu(env);
 uint16_t cbozlen = cpu->cfg.cboz_blocksize;
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = riscv_env_mmu_index(env, false);
 uintptr_t ra = GETPC();
 void *mem;
 
@@ -205,7 +205,7 @@ static void check_zicbom_access(CPURISCVState *env,
 uintptr_t ra)
 {
 RISCVCPU *cpu = env_archcpu(env);
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = riscv_env_mmu_index(env, false);
 uint16_t cbomlen = cpu->cfg.cbom_blocksize;
 void *phost;
 int ret;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index c1c3a4d1ea..fe0d5d053c 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -113,14 +113,15 @@ static void probe_pages(CPURISCVState *env, target_ulong 
addr,
 {
 target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
 target_ulong curlen = MIN(pagelen, len);
+int mmu_index = riscv_env_mmu_index(env, false);
 
 probe_access(env, adjust_addr(env, addr), curlen, access_type,
- cpu_mmu_index(env, false), ra);
+ mmu_index, ra);
 if (len > curlen) {
 addr += curlen;
 curlen = len - curlen;
 probe_access(env, adjust_addr(env, addr), curlen, access_type,
- cpu_mmu_index(env, false), ra);
+ mmu_index, ra);
 }
 }
 
@@ -464,6 +465,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
 uint32_t esz = 1 << log2_esz;
 uint32_t vma = vext_vma(desc);
 target_ulong addr, offset, remain;
+int mmu_index = riscv_env_mmu_index(env, false);
 
 /* probe every access */
 for (i = env->vstart; i < env->vl; i++) {
@@ -478,8 +480,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
 remain = nf << log2_esz;
 while (remain > 0) {
 offset = -(addr | TARGET_PAGE_MASK);
-host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD,
- cpu_mmu_index(env, false));
+host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD, mmu_index);
 if (host) {
 #ifdef CONFIG_USER_ONLY
 if (!page_check_range(addr, offset, PAGE_READ)) {
-- 
2.34.1




[PATCH 07/33] target/cris: Cache mem_index in DisasContext

2024-01-29 Thread Richard Henderson
Compute this value once for each translation.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 14 +-
 target/cris/translate_v10.c.inc |  6 ++
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index ee1402a9a3..7acea29a01 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -94,6 +94,7 @@ typedef struct DisasContext {
 
 CRISCPU *cpu;
 target_ulong pc, ppc;
+int mem_index;
 
 /* Decoder.  */
 unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
@@ -1008,37 +1009,31 @@ static inline void cris_prepare_jmp (DisasContext *dc, 
unsigned int type)
 
 static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
 {
-int mem_index = cpu_mmu_index(>cpu->env, false);
-
 /* If we get a fault on a delayslot we must keep the jmp state in
the cpu-state to be able to re-execute the jmp.  */
 if (dc->delayed_branch == 1) {
 cris_store_direct_jmp(dc);
 }
 
-tcg_gen_qemu_ld_i64(dst, addr, mem_index, MO_TEUQ);
+tcg_gen_qemu_ld_i64(dst, addr, dc->mem_index, MO_TEUQ);
 }
 
 static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
  unsigned int size, int sign)
 {
-int mem_index = cpu_mmu_index(>cpu->env, false);
-
 /* If we get a fault on a delayslot we must keep the jmp state in
the cpu-state to be able to re-execute the jmp.  */
 if (dc->delayed_branch == 1) {
 cris_store_direct_jmp(dc);
 }
 
-tcg_gen_qemu_ld_tl(dst, addr, mem_index,
+tcg_gen_qemu_ld_tl(dst, addr, dc->mem_index,
MO_TE + ctz32(size) + (sign ? MO_SIGN : 0));
 }
 
 static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
unsigned int size)
 {
-int mem_index = cpu_mmu_index(>cpu->env, false);
-
 /* If we get a fault on a delayslot we must keep the jmp state in
the cpu-state to be able to re-execute the jmp.  */
 if (dc->delayed_branch == 1) {
@@ -1055,7 +1050,7 @@ static void gen_store (DisasContext *dc, TCGv addr, TCGv 
val,
 return;
 }
 
-tcg_gen_qemu_st_tl(val, addr, mem_index, MO_TE + ctz32(size));
+tcg_gen_qemu_st_tl(val, addr, dc->mem_index, MO_TE + ctz32(size));
 
 if (dc->flags_x) {
 cris_evaluate_flags(dc);
@@ -2971,6 +2966,7 @@ static void cris_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 dc->cpu = env_archcpu(env);
 dc->ppc = pc_start;
 dc->pc = pc_start;
+dc->mem_index = cpu_mmu_index(env, false);
 dc->flags_uptodate = 1;
 dc->flags_x = tb_flags & X_FLAG;
 dc->cc_x_uptodate = 0;
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
index 6df599fdce..73fc27c15d 100644
--- a/target/cris/translate_v10.c.inc
+++ b/target/cris/translate_v10.c.inc
@@ -91,8 +91,6 @@ static void gen_store_v10_conditional(DisasContext *dc, TCGv 
addr, TCGv val,
 static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
unsigned int size)
 {
-int mem_index = cpu_mmu_index(>cpu->env, false);
-
 /* If we get a fault on a delayslot we must keep the jmp state in
the cpu-state to be able to re-execute the jmp.  */
 if (dc->delayed_branch == 1) {
@@ -101,11 +99,11 @@ static void gen_store_v10(DisasContext *dc, TCGv addr, 
TCGv val,
 
 /* Conditional writes. */
 if (dc->flags_x) {
-gen_store_v10_conditional(dc, addr, val, size, mem_index);
+gen_store_v10_conditional(dc, addr, val, size, dc->mem_index);
 return;
 }
 
-tcg_gen_qemu_st_tl(val, addr, mem_index, ctz32(size) | MO_TE);
+tcg_gen_qemu_st_tl(val, addr, dc->mem_index, ctz32(size) | MO_TE);
 }
 
 
-- 
2.34.1




[PATCH 08/33] target/cris: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/cris/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 6349148b65..163fb05d58 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -56,6 +56,11 @@ static bool cris_cpu_has_work(CPUState *cs)
 return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
+static int cris_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return !!(cpu_env(cs)->pregs[PR_CCS] & U_FLAG);
+}
+
 static void cris_cpu_reset_hold(Object *obj)
 {
 CPUState *s = CPU(obj);
@@ -274,6 +279,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 
 cc->class_by_name = cris_cpu_class_by_name;
 cc->has_work = cris_cpu_has_work;
+cc->mmu_index = cris_cpu_mmu_index;
 cc->dump_state = cris_cpu_dump_state;
 cc->set_pc = cris_cpu_set_pc;
 cc->get_pc = cris_cpu_get_pc;
-- 
2.34.1




[PATCH 06/33] target/avr: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/avr/cpu.h | 4 +---
 target/avr/cpu.c | 6 ++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 7d5dd42575..4595c6bb18 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -184,9 +184,7 @@ static inline void set_avr_feature(CPUAVRState *env, int 
feature)
 env->features |= (1U << feature);
 }
 
-#define cpu_mmu_index avr_cpu_mmu_index
-
-static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch)
+static inline int cpu_mmu_index(CPUAVRState *env, bool ifetch)
 {
 return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX;
 }
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 1c68748b24..a40f445af2 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -50,6 +50,11 @@ static bool avr_cpu_has_work(CPUState *cs)
 && cpu_interrupts_enabled(env);
 }
 
+static int avr_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX;
+}
+
 static void avr_cpu_synchronize_from_tb(CPUState *cs,
 const TranslationBlock *tb)
 {
@@ -236,6 +241,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 cc->class_by_name = avr_cpu_class_by_name;
 
 cc->has_work = avr_cpu_has_work;
+cc->mmu_index = avr_cpu_mmu_index;
 cc->dump_state = avr_cpu_dump_state;
 cc->set_pc = avr_cpu_set_pc;
 cc->get_pc = avr_cpu_get_pc;
-- 
2.34.1




[PATCH 16/33] target/mips: Split out mips_env_mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/mips/cpu.h   |  7 ++-
 target/mips/sysemu/physaddr.c   |  2 +-
 target/mips/tcg/msa_helper.c| 10 +-
 target/mips/tcg/sysemu/cp0_helper.c |  2 +-
 target/mips/tcg/sysemu/special_helper.c |  2 +-
 target/mips/tcg/sysemu/tlb_helper.c |  2 +-
 6 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3ba8dccd2d..4c15e76781 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1255,11 +1255,16 @@ static inline int hflags_mmu_index(uint32_t hflags)
 }
 }
 
-static inline int cpu_mmu_index(CPUMIPSState *env, bool ifetch)
+static inline int mips_env_mmu_index(CPUMIPSState *env)
 {
 return hflags_mmu_index(env->hflags);
 }
 
+static inline int cpu_mmu_index(CPUMIPSState *env, bool ifetch)
+{
+return mips_env_mmu_index(env);
+}
+
 #include "exec/cpu-all.h"
 
 /* Exceptions */
diff --git a/target/mips/sysemu/physaddr.c b/target/mips/sysemu/physaddr.c
index 05990aa5bb..13c8bc8f47 100644
--- a/target/mips/sysemu/physaddr.c
+++ b/target/mips/sysemu/physaddr.c
@@ -236,7 +236,7 @@ hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 int prot;
 
 if (get_physical_address(env, _addr, , addr, MMU_DATA_LOAD,
- cpu_mmu_index(env, false)) != 0) {
+ mips_env_mmu_index(env)) != 0) {
 return -1;
 }
 return phys_addr;
diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c
index 7a8dbada5d..d2181763e7 100644
--- a/target/mips/tcg/msa_helper.c
+++ b/target/mips/tcg/msa_helper.c
@@ -8214,7 +8214,7 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 #if !defined(CONFIG_USER_ONLY)
 #define MEMOP_IDX(DF)   \
 MemOpIdx oi = make_memop_idx(MO_TE | DF | MO_UNALN, \
- cpu_mmu_index(env, false));
+ mips_env_mmu_index(env));
 #else
 #define MEMOP_IDX(DF)
 #endif
@@ -8323,7 +8323,7 @@ void helper_msa_st_b(CPUMIPSState *env, uint32_t wd,
  target_ulong addr)
 {
 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = mips_env_mmu_index(env);
 uintptr_t ra = GETPC();
 
 ensure_writable_pages(env, addr, mmu_idx, ra);
@@ -8337,7 +8337,7 @@ void helper_msa_st_h(CPUMIPSState *env, uint32_t wd,
  target_ulong addr)
 {
 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = mips_env_mmu_index(env);
 uintptr_t ra = GETPC();
 uint64_t d0, d1;
 
@@ -8358,7 +8358,7 @@ void helper_msa_st_w(CPUMIPSState *env, uint32_t wd,
  target_ulong addr)
 {
 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = mips_env_mmu_index(env);
 uintptr_t ra = GETPC();
 uint64_t d0, d1;
 
@@ -8379,7 +8379,7 @@ void helper_msa_st_d(CPUMIPSState *env, uint32_t wd,
  target_ulong addr)
 {
 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
-int mmu_idx = cpu_mmu_index(env, false);
+int mmu_idx = mips_env_mmu_index(env);
 uintptr_t ra = GETPC();
 
 ensure_writable_pages(env, addr, mmu_idx, GETPC());
diff --git a/target/mips/tcg/sysemu/cp0_helper.c 
b/target/mips/tcg/sysemu/cp0_helper.c
index cc545aed9c..62f6fb4bf6 100644
--- a/target/mips/tcg/sysemu/cp0_helper.c
+++ b/target/mips/tcg/sysemu/cp0_helper.c
@@ -1202,7 +1202,7 @@ void helper_mtc0_status(CPUMIPSState *env, target_ulong 
arg1)
 old, old & env->CP0_Cause & CP0Ca_IP_mask,
 val, val & env->CP0_Cause & CP0Ca_IP_mask,
 env->CP0_Cause);
-switch (cpu_mmu_index(env, false)) {
+switch (mips_env_mmu_index(env)) {
 case 3:
 qemu_log(", ERL\n");
 break;
diff --git a/target/mips/tcg/sysemu/special_helper.c 
b/target/mips/tcg/sysemu/special_helper.c
index 93276f789d..518d3fbc34 100644
--- a/target/mips/tcg/sysemu/special_helper.c
+++ b/target/mips/tcg/sysemu/special_helper.c
@@ -68,7 +68,7 @@ static void debug_post_eret(CPUMIPSState *env)
 if (env->hflags & MIPS_HFLAG_DM) {
 qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
 }
-switch (cpu_mmu_index(env, false)) {
+switch (mips_env_mmu_index(env)) {
 case 3:
 qemu_log(", ERL\n");
 break;
diff --git a/target/mips/tcg/sysemu/tlb_helper.c 
b/target/mips/tcg/sysemu/tlb_helper.c
index b715449114..cdae42ffdd 100644
--- a/target/mips/tcg/sysemu/tlb_helper.c
+++ b/target/mips/tcg/sysemu/tlb_helper.c
@@ -973,7 +973,7 @@ hwaddr cpu_mips_translate_address(CPUMIPSState *env, 
target_ulong address,
 
 /* data access */
 ret = get_physical_address(env, , , address, access_type,
-   

[PATCH 22/33] target/riscv: Rename riscv_cpu_mmu_index to riscv_env_mmu_index

2024-01-29 Thread Richard Henderson
Free up the riscv_cpu_mmu_index name for other usage;
emphasize that the argument is 'env'.

Signed-off-by: Richard Henderson 
---
 target/riscv/cpu.h| 4 ++--
 target/riscv/cpu_helper.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5f3955c38d..9c825c7b51 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -498,7 +498,7 @@ target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
 void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
 bool riscv_cpu_vector_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
-int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
+int riscv_env_mmu_index(CPURISCVState *env, bool ifetch);
 G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr);
@@ -507,7 +507,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 bool probe, uintptr_t retaddr);
 char *riscv_isa_string(RISCVCPU *cpu);
 
-#define cpu_mmu_index riscv_cpu_mmu_index
+#define cpu_mmu_index riscv_env_mmu_index
 
 #ifndef CONFIG_USER_ONLY
 void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c7cc7eb423..15f87ecdb0 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -33,7 +33,7 @@
 #include "debug.h"
 #include "tcg/oversized-guest.h"
 
-int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
+int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
 return 0;
-- 
2.34.1




[PATCH 11/33] target/loongarch: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/loongarch/cpu.h |  6 ++
 target/loongarch/cpu.c | 11 +++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 0fa5e0ca93..5dfcfeb3a4 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -408,15 +408,13 @@ struct LoongArchCPUClass {
 #define MMU_IDX_USER MMU_PLV_USER
 #define MMU_IDX_DA   4
 
+int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch);
 static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
 return MMU_IDX_USER;
 #else
-if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
-return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
-}
-return MMU_IDX_DA;
+return loongarch_cpu_mmu_index(env_cpu(env), ifetch);
 #endif
 }
 
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index fb8dde7def..cbecc63213 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -375,6 +375,16 @@ static bool loongarch_cpu_has_work(CPUState *cs)
 #endif
 }
 
+int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+CPULoongArchState *env = cpu_env(cs);
+
+if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
+return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
+}
+return MMU_IDX_DA;
+}
+
 static void loongarch_la464_initfn(Object *obj)
 {
 LoongArchCPU *cpu = LOONGARCH_CPU(obj);
@@ -779,6 +789,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
 
 cc->class_by_name = loongarch_cpu_class_by_name;
 cc->has_work = loongarch_cpu_has_work;
+cc->mmu_index = loongarch_cpu_mmu_index;
 cc->dump_state = loongarch_cpu_dump_state;
 cc->set_pc = loongarch_cpu_set_pc;
 cc->get_pc = loongarch_cpu_get_pc;
-- 
2.34.1




[PATCH 13/33] target/m68k: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/m68k/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 44000f5869..8a8392e694 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -56,6 +56,11 @@ static bool m68k_cpu_has_work(CPUState *cs)
 return cs->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
+static int m68k_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return cpu_env(cs)->sr & SR_S ? MMU_KERNEL_IDX : MMU_USER_IDX;
+}
+
 static void m68k_set_feature(CPUM68KState *env, int feature)
 {
 env->features |= BIT_ULL(feature);
@@ -551,6 +556,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 
 cc->class_by_name = m68k_cpu_class_by_name;
 cc->has_work = m68k_cpu_has_work;
+cc->mmu_index = m68k_cpu_mmu_index;
 cc->dump_state = m68k_cpu_dump_state;
 cc->set_pc = m68k_cpu_set_pc;
 cc->get_pc = m68k_cpu_get_pc;
-- 
2.34.1




[PATCH 19/33] target/openrisc: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/openrisc/cpu.h | 10 ++
 target/openrisc/cpu.c | 13 +
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index b454014ddd..7dbed8d8be 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -361,16 +361,10 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState 
*env, vaddr *pc,
| (env->sr & (SR_SM | SR_DME | SR_IME | SR_OVE));
 }
 
+int openrisc_cpu_mmu_index(CPUState *cs, bool ifetch);
 static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
 {
-int ret = MMU_NOMMU_IDX;  /* mmu is disabled */
-
-if (env->sr & (ifetch ? SR_IME : SR_DME)) {
-/* The mmu is enabled; test supervisor state.  */
-ret = env->sr & SR_SM ? MMU_SUPERVISOR_IDX : MMU_USER_IDX;
-}
-
-return ret;
+return openrisc_cpu_mmu_index(env_cpu(env), ifetch);
 }
 
 static inline uint32_t cpu_get_sr(const CPUOpenRISCState *env)
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 477d49d4bc..8670152c84 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -68,6 +68,18 @@ static bool openrisc_cpu_has_work(CPUState *cs)
 CPU_INTERRUPT_TIMER);
 }
 
+int openrisc_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+CPUOpenRISCState *env = cpu_env(cs);
+
+if (env->sr & (ifetch ? SR_IME : SR_DME)) {
+/* The mmu is enabled; test supervisor state.  */
+return env->sr & SR_SM ? MMU_SUPERVISOR_IDX : MMU_USER_IDX;
+}
+
+return MMU_NOMMU_IDX;  /* mmu is disabled */
+}
+
 static void openrisc_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
 info->print_insn = print_insn_or1k;
@@ -239,6 +251,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void 
*data)
 
 cc->class_by_name = openrisc_cpu_class_by_name;
 cc->has_work = openrisc_cpu_has_work;
+cc->mmu_index = openrisc_cpu_mmu_index;
 cc->dump_state = openrisc_cpu_dump_state;
 cc->set_pc = openrisc_cpu_set_pc;
 cc->get_pc = openrisc_cpu_get_pc;
-- 
2.34.1




[PATCH 27/33] target/s390x: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/s390x/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 7f123863dc..49a2341acc 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -142,6 +142,11 @@ static bool s390_cpu_has_work(CPUState *cs)
 return s390_cpu_has_int(cpu);
 }
 
+static int s390x_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return s390x_env_mmu_index(cpu_env(cs), ifetch);
+}
+
 static void s390_query_cpu_fast(CPUState *cpu, CpuInfoFast *value)
 {
 S390CPU *s390_cpu = S390_CPU(cpu);
@@ -352,6 +357,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
 scc->reset = s390_cpu_reset;
 cc->class_by_name = s390_cpu_class_by_name,
 cc->has_work = s390_cpu_has_work;
+cc->mmu_index = s390x_cpu_mmu_index;
 cc->dump_state = s390_cpu_dump_state;
 cc->query_cpu_fast = s390_query_cpu_fast;
 cc->set_pc = s390_cpu_set_pc;
-- 
2.34.1




[PATCH 18/33] target/nios2: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/nios2/cpu.h | 12 ++--
 target/nios2/cpu.c |  7 +++
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index 2d79b5b298..9965ff74c1 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -270,12 +270,6 @@ void do_nios2_semihosting(CPUNios2State *env);
 #define MMU_SUPERVISOR_IDX  0
 #define MMU_USER_IDX1
 
-static inline int cpu_mmu_index(CPUNios2State *env, bool ifetch)
-{
-return (env->ctrl[CR_STATUS] & CR_STATUS_U) ? MMU_USER_IDX :
-  MMU_SUPERVISOR_IDX;
-}
-
 #ifndef CONFIG_USER_ONLY
 hwaddr nios2_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
@@ -292,6 +286,12 @@ FIELD(TBFLAGS, CRS0, 0, 1)  /* Set if CRS == 0. */
 FIELD(TBFLAGS, U, 1, 1) /* Overlaps CR_STATUS_U */
 FIELD(TBFLAGS, R0_0, 2, 1)  /* Set if R0 == 0. */
 
+int nios2_cpu_mmu_index(CPUState *cs, bool ifetch);
+static inline int cpu_mmu_index(CPUNios2State *env, bool ifetch)
+{
+return nios2_cpu_mmu_index(env_cpu(env), ifetch);
+}
+
 static inline void cpu_get_tb_cpu_state(CPUNios2State *env, vaddr *pc,
 uint64_t *cs_base, uint32_t *flags)
 {
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 596c0c5617..e42885997e 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -57,6 +57,12 @@ static bool nios2_cpu_has_work(CPUState *cs)
 return cs->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
+int nios2_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return (cpu_env(cs)->ctrl[CR_STATUS] & CR_STATUS_U
+? MMU_USER_IDX : MMU_SUPERVISOR_IDX);
+}
+
 static void nios2_cpu_reset_hold(Object *obj)
 {
 CPUState *cs = CPU(obj);
@@ -381,6 +387,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void 
*data)
 
 cc->class_by_name = nios2_cpu_class_by_name;
 cc->has_work = nios2_cpu_has_work;
+cc->mmu_index = nios2_cpu_mmu_index;
 cc->dump_state = nios2_cpu_dump_state;
 cc->set_pc = nios2_cpu_set_pc;
 cc->get_pc = nios2_cpu_get_pc;
-- 
2.34.1




[PATCH 03/33] target/alpha: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/alpha/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index de705c3703..bf70173a25 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -64,6 +64,11 @@ static bool alpha_cpu_has_work(CPUState *cs)
 | CPU_INTERRUPT_MCHK);
 }
 
+static int alpha_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return alpha_env_mmu_index(cpu_env(cs));
+}
+
 static void alpha_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
 info->mach = bfd_mach_alpha_ev6;
@@ -230,6 +235,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void 
*data)
 
 cc->class_by_name = alpha_cpu_class_by_name;
 cc->has_work = alpha_cpu_has_work;
+cc->mmu_index = alpha_cpu_mmu_index;
 cc->dump_state = alpha_cpu_dump_state;
 cc->set_pc = alpha_cpu_set_pc;
 cc->get_pc = alpha_cpu_get_pc;
-- 
2.34.1




[PATCH 21/33] target/ppc: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/ppc/cpu_init.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 86c8031765..9931372a08 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7105,6 +7105,11 @@ static bool ppc_cpu_has_work(CPUState *cs)
 return cs->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
+static int ppc_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return ppc_env_mmu_index(cpu_env(cs), ifetch);
+}
+
 static void ppc_cpu_reset_hold(Object *obj)
 {
 CPUState *s = CPU(obj);
@@ -7372,6 +7377,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
*data)
 
 cc->class_by_name = ppc_cpu_class_by_name;
 cc->has_work = ppc_cpu_has_work;
+cc->mmu_index = ppc_cpu_mmu_index;
 cc->dump_state = ppc_cpu_dump_state;
 cc->set_pc = ppc_cpu_set_pc;
 cc->get_pc = ppc_cpu_get_pc;
-- 
2.34.1




[PATCH 24/33] target/riscv: Populate CPUClass.mmu_index

2024-01-29 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/riscv/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8cbfc7e781..be21fa09c6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -867,6 +867,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
 #endif
 }
 
+static int riscv_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+return riscv_env_mmu_index(cpu_env(cs), ifetch);
+}
+
 static void riscv_cpu_reset_hold(Object *obj)
 {
 #ifndef CONFIG_USER_ONLY
@@ -1810,6 +1815,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
*data)
 
 cc->class_by_name = riscv_cpu_class_by_name;
 cc->has_work = riscv_cpu_has_work;
+cc->mmu_index = riscv_cpu_mmu_index;
 cc->dump_state = riscv_cpu_dump_state;
 cc->set_pc = riscv_cpu_set_pc;
 cc->get_pc = riscv_cpu_get_pc;
-- 
2.34.1




[PATCH 00/33] hw/core: Introduce CPUClass hook for mmu_index

2024-01-29 Thread Richard Henderson
While the primary use of mmu_index is for the softmmu index for
system-mode tcg, it has a secondary use in encoding cpu state for
the page table walker, and thus depending on the target may also
be used by memory_rw_debug with kvm et al.

This is why I placed the hook in CPUClass not TCGCPUOps.


r~


Richard Henderson (33):
  include/hw/core: Add mmu_index to CPUClass
  target/alpha: Split out alpha_env_mmu_index
  target/alpha: Populate CPUClass.mmu_index
  target/arm: Split out arm_env_mmu_index
  target/arm: Populate CPUClass.mmu_index
  target/avr: Populate CPUClass.mmu_index
  target/cris: Cache mem_index in DisasContext
  target/cris: Populate CPUClass.mmu_index
  target/hppa: Populate CPUClass.mmu_index
  target/i386: Populate CPUClass.mmu_index
  target/loongarch: Populate CPUClass.mmu_index
  target/loongarch: Rename MMU_IDX_*
  target/m68k: Populate CPUClass.mmu_index
  target/microblaze: Populate CPUClass.mmu_index
  target/mips: Pass ptw_mmu_idx down from mips_cpu_tlb_fill
  target/mips: Split out mips_env_mmu_index
  target/mips: Populate CPUClass.mmu_index
  target/nios2: Populate CPUClass.mmu_index
  target/openrisc: Populate CPUClass.mmu_index
  target/ppc: Split out ppc_env_mmu_index
  target/ppc: Populate CPUClass.mmu_index
  target/riscv: Rename riscv_cpu_mmu_index to riscv_env_mmu_index
  target/riscv: Replace cpu_mmu_index with riscv_env_mmu_index
  target/riscv: Populate CPUClass.mmu_index
  target/rx: Populate CPUClass.mmu_index
  target/s390x: Split out s390x_env_mmu_index
  target/s390x: Populate CPUClass.mmu_index
  target/sh4: Populate CPUClass.mmu_index
  target/sparc: Populate CPUClass.mmu_index
  target/tricore: Populate CPUClass.mmu_index
  target/xtensa: Populate CPUClass.mmu_index
  include/exec: Implement cpu_mmu_index generically
  include/exec: Change cpu_mmu_index argument to CPUState

 include/exec/cpu-all.h|  4 ++
 include/exec/cpu-common.h | 18 
 include/hw/core/cpu.h |  3 ++
 target/alpha/cpu.h|  2 +-
 target/arm/cpu.h  | 13 --
 target/arm/internals.h|  5 +++
 target/avr/cpu.h  |  7 
 target/cris/cpu.h |  4 --
 target/hexagon/cpu.h  |  9 
 target/hppa/cpu.h | 13 --
 target/i386/cpu.h |  7 
 target/loongarch/cpu.h| 18 ++--
 target/m68k/cpu.h |  4 --
 target/microblaze/cpu.h   | 15 ---
 target/mips/cpu.h |  6 ++-
 target/nios2/cpu.h|  6 ---
 target/openrisc/cpu.h | 12 --
 target/ppc/cpu.h  |  2 +-
 target/riscv/cpu.h|  4 +-
 target/rx/cpu.h   |  5 ---
 target/s390x/cpu.h|  2 +-
 target/sh4/cpu.h  | 10 -
 target/sparc/cpu.h| 30 +
 target/tricore/cpu.h  |  5 ---
 target/xtensa/cpu.h   |  5 ---
 accel/tcg/cputlb.c| 22 ++
 semihosting/uaccess.c |  2 +-
 target/alpha/cpu.c|  6 +++
 target/alpha/translate.c  |  2 +-
 target/arm/cpu.c  |  6 +++
 target/arm/helper.c   |  2 +-
 target/arm/tcg/helper-a64.c   |  4 +-
 target/arm/tcg/mte_helper.c   | 18 
 target/arm/tcg/sve_helper.c   |  8 ++--
 target/arm/tcg/tlb_helper.c   |  2 +-
 target/avr/cpu.c  |  6 +++
 target/cris/cpu.c |  6 +++
 target/cris/translate.c   | 14 +++
 target/hppa/cpu.c | 12 ++
 target/hppa/mem_helper.c  |  2 +-
 target/hppa/op_helper.c   |  8 ++--
 target/i386/cpu.c | 10 +
 target/i386/tcg/translate.c   |  2 +-
 target/loongarch/cpu.c| 11 +
 target/loongarch/tcg/tlb_helper.c |  8 ++--
 target/loongarch/tcg/translate.c  |  2 +-
 target/m68k/cpu.c |  6 +++
 target/m68k/op_helper.c   |  2 +-
 target/microblaze/cpu.c   | 18 +++-
 target/microblaze/helper.c|  3 +-
 target/microblaze/mmu.c   |  2 +-
 target/microblaze/translate.c |  2 +-
 target/mips/cpu.c |  6 +++
 target/mips/sysemu/physaddr.c |  2 +-
 target/mips/tcg/msa_helper.c  | 10 ++---
 

[PATCH 12/33] target/loongarch: Rename MMU_IDX_*

2024-01-29 Thread Richard Henderson
The expected form is MMU_FOO_IDX, not MMU_IDX_FOO.
Rename to match generic code.

Signed-off-by: Richard Henderson 
---
 target/loongarch/cpu.h | 8 
 target/loongarch/cpu.c | 2 +-
 target/loongarch/tcg/tlb_helper.c  | 4 ++--
 target/loongarch/tcg/translate.c   | 2 +-
 target/loongarch/tcg/insn_trans/trans_privileged.c.inc | 2 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 5dfcfeb3a4..47fd110e81 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -404,15 +404,15 @@ struct LoongArchCPUClass {
  */
 #define MMU_PLV_KERNEL   0
 #define MMU_PLV_USER 3
-#define MMU_IDX_KERNEL   MMU_PLV_KERNEL
-#define MMU_IDX_USER MMU_PLV_USER
-#define MMU_IDX_DA   4
+#define MMU_KERNEL_IDX   MMU_PLV_KERNEL
+#define MMU_USER_IDX MMU_PLV_USER
+#define MMU_DA_IDX   4
 
 int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch);
 static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
-return MMU_IDX_USER;
+return MMU_USER_IDX;
 #else
 return loongarch_cpu_mmu_index(env_cpu(env), ifetch);
 #endif
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index cbecc63213..139acfe373 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -382,7 +382,7 @@ int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch)
 if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
 return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
 }
-return MMU_IDX_DA;
+return MMU_DA_IDX;
 }
 
 static void loongarch_la464_initfn(Object *obj)
diff --git a/target/loongarch/tcg/tlb_helper.c 
b/target/loongarch/tcg/tlb_helper.c
index 449043c68b..65ffbef08e 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -188,8 +188,8 @@ static int get_physical_address(CPULoongArchState *env, 
hwaddr *physical,
 int *prot, target_ulong address,
 MMUAccessType access_type, int mmu_idx)
 {
-int user_mode = mmu_idx == MMU_IDX_USER;
-int kernel_mode = mmu_idx == MMU_IDX_KERNEL;
+int user_mode = mmu_idx == MMU_USER_IDX;
+int kernel_mode = mmu_idx == MMU_KERNEL_IDX;
 uint32_t plv, base_c, base_v;
 int64_t addr_high;
 uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c
index 235515c629..58674cb268 100644
--- a/target/loongarch/tcg/translate.c
+++ b/target/loongarch/tcg/translate.c
@@ -125,7 +125,7 @@ static void 
loongarch_tr_init_disas_context(DisasContextBase *dcbase,
 if (ctx->base.tb->flags & HW_FLAGS_CRMD_PG) {
 ctx->mem_idx = ctx->plv;
 } else {
-ctx->mem_idx = MMU_IDX_DA;
+ctx->mem_idx = MMU_DA_IDX;
 }
 
 /* Bound the number of insns to execute to those left on the page.  */
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc 
b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
index 01d457212b..7e4ec93edb 100644
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
@@ -323,7 +323,7 @@ TRANS(iocsrwr_d, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_d)
 
 static void check_mmu_idx(DisasContext *ctx)
 {
-if (ctx->mem_idx != MMU_IDX_DA) {
+if (ctx->mem_idx != MMU_DA_IDX) {
 tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
 ctx->base.is_jmp = DISAS_EXIT;
 }
-- 
2.34.1




[PATCH 01/33] include/hw/core: Add mmu_index to CPUClass

2024-01-29 Thread Richard Henderson
To be used after all targets have populated the hook.

Signed-off-by: Richard Henderson 
---
 include/hw/core/cpu.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 2c284d6397..4385ce54c9 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -103,6 +103,8 @@ struct SysemuCPUOps;
  * @parse_features: Callback to parse command line arguments.
  * @reset_dump_flags: #CPUDumpFlags to use for reset logging.
  * @has_work: Callback for checking if there is work to do.
+ * @mmu_index: Callback for choosing softmmu mmu index;
+ *   may be used internally by memory_rw_debug without TCG.
  * @memory_rw_debug: Callback for GDB memory access.
  * @dump_state: Callback for dumping state.
  * @query_cpu_fast:
@@ -150,6 +152,7 @@ struct CPUClass {
 void (*parse_features)(const char *typename, char *str, Error **errp);
 
 bool (*has_work)(CPUState *cpu);
+int (*mmu_index)(CPUState *cpu, bool ifetch);
 int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
uint8_t *buf, int len, bool is_write);
 void (*dump_state)(CPUState *cpu, FILE *, int flags);
-- 
2.34.1




[PULL 20/31] accel/tcg: Rename tcg_ss[] -> tcg_specific_ss[] in meson

2024-01-29 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

tcg_ss[] source set contains target-specific units.
Rename it as 'tcg_specific_ss[]' for clarity.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Anton Johansson 
Message-Id: <20240124101639.30056-2-phi...@linaro.org>
Signed-off-by: Richard Henderson 
---
 accel/tcg/meson.build | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
index 46f7d53eeb..aef80de967 100644
--- a/accel/tcg/meson.build
+++ b/accel/tcg/meson.build
@@ -1,8 +1,8 @@
-tcg_ss = ss.source_set()
 common_ss.add(when: 'CONFIG_TCG', if_true: files(
   'cpu-exec-common.c',
 ))
-tcg_ss.add(files(
+tcg_specific_ss = ss.source_set()
+tcg_specific_ss.add(files(
   'tcg-all.c',
   'cpu-exec.c',
   'tb-maint.c',
@@ -11,12 +11,12 @@ tcg_ss.add(files(
   'translate-all.c',
   'translator.c',
 ))
-tcg_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
-tcg_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_false: files('user-exec-stub.c'))
+tcg_specific_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
+tcg_specific_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_false: 
files('user-exec-stub.c'))
 if get_option('plugins')
-  tcg_ss.add(files('plugin-gen.c'))
+  tcg_specific_ss.add(files('plugin-gen.c'))
 endif
-specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
+specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_specific_ss)
 
 specific_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files(
   'cputlb.c',
-- 
2.34.1




[PULL 30/31] accel/tcg: Introduce TCGCPUOps::cpu_exec_halt() handler

2024-01-29 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

In order to make accel/tcg/ target agnostic,
introduce the cpu_exec_halt() handler.

Reviewed-by: Anton Johansson 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240124101639.30056-9-phi...@linaro.org>
Signed-off-by: Richard Henderson 
---
 include/hw/core/tcg-cpu-ops.h | 2 ++
 accel/tcg/cpu-exec.c  | 5 +
 2 files changed, 7 insertions(+)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 013867b890..bf8ff8e3ee 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -112,6 +112,8 @@ struct TCGCPUOps {
 void (*do_interrupt)(CPUState *cpu);
 /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
 bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
+/** @cpu_exec_halt: Callback for handling halt in cpu_exec */
+void (*cpu_exec_halt)(CPUState *cpu);
 /**
  * @tlb_fill: Handle a softmmu tlb miss
  *
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 75f7ba7bed..82627b12b8 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -664,6 +664,8 @@ static inline bool cpu_handle_halt(CPUState *cpu)
 {
 #ifndef CONFIG_USER_ONLY
 if (cpu->halted) {
+const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
+
 #if defined(TARGET_I386)
 if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
 X86CPU *x86_cpu = X86_CPU(cpu);
@@ -673,6 +675,9 @@ static inline bool cpu_handle_halt(CPUState *cpu)
 bql_unlock();
 }
 #endif /* TARGET_I386 */
+if (tcg_ops->cpu_exec_halt) {
+tcg_ops->cpu_exec_halt(cpu);
+}
 if (!cpu_has_work(cpu)) {
 return true;
 }
-- 
2.34.1




[PULL 23/31] accel/tcg: Un-inline icount_exit_request() for clarity

2024-01-29 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

Convert packed logic to dumb icount_exit_request() helper.
No functional change intended.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Anton Johansson 
Message-Id: <20240124101639.30056-5-phi...@linaro.org>
Signed-off-by: Richard Henderson 
---
 accel/tcg/cpu-exec.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 950dad63cb..f2535a2991 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -777,6 +777,17 @@ static inline bool need_replay_interrupt(int 
interrupt_request)
 }
 #endif /* !CONFIG_USER_ONLY */
 
+static inline bool icount_exit_request(CPUState *cpu)
+{
+if (!icount_enabled()) {
+return false;
+}
+if (cpu->cflags_next_tb != -1 && !(cpu->cflags_next_tb & CF_USE_ICOUNT)) {
+return false;
+}
+return cpu->neg.icount_decr.u16.low + cpu->icount_extra == 0;
+}
+
 static inline bool cpu_handle_interrupt(CPUState *cpu,
 TranslationBlock **last_tb)
 {
@@ -882,10 +893,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
 }
 
 /* Finally, check if we need to exit to the main loop.  */
-if (unlikely(qatomic_read(>exit_request))
-|| (icount_enabled()
-&& (cpu->cflags_next_tb == -1 || cpu->cflags_next_tb & 
CF_USE_ICOUNT)
-&& cpu->neg.icount_decr.u16.low + cpu->icount_extra == 0)) {
+if (unlikely(qatomic_read(>exit_request)) || 
icount_exit_request(cpu)) {
 qatomic_set(>exit_request, 0);
 if (cpu->exception_index == -1) {
 cpu->exception_index = EXCP_INTERRUPT;
-- 
2.34.1




  1   2   3   4   >