[PATCH v2 06/11] ppc/spapr: remove deprecated machine pseries-2.6

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.6 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 18 --
 1 file changed, 18 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a38d4e098a..d317387b7f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5297,24 +5297,6 @@ static void spapr_machine_2_7_class_options(MachineClass 
*mc)
 
 DEFINE_SPAPR_MACHINE(2, 7);
 
-/*
- * pseries-2.6
- */
-
-static void spapr_machine_2_6_class_options(MachineClass *mc)
-{
-static GlobalProperty compat[] = {
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "ddw", "off" },
-};
-
-spapr_machine_2_7_class_options(mc);
-mc->has_hotpluggable_cpus = false;
-compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-}
-
-DEFINE_SPAPR_MACHINE(2, 6);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




[PATCH v2 07/11] ppc/spapr: remove deprecated machine pseries-2.7

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.7 specific code with this patch for now.

While at it, also remove pre-2.8-migration hacks introduced for backward
migration compatibility.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 include/hw/pci-host/spapr.h |  4 --
 target/ppc/cpu.h|  5 ---
 hw/ppc/spapr.c  | 75 -
 hw/ppc/spapr_pci.c  | 28 --
 target/ppc/cpu_init.c   |  1 -
 target/ppc/machine.c| 52 -
 6 files changed, 165 deletions(-)

diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 3778aac27b..0d40bf48f6 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -84,10 +84,6 @@ struct SpaprPhbState {
 bool pcie_ecs; /* Allow access to PCIe extended config space? */
 
 /* Fields for migration compatibility hacks */
-bool pre_2_8_migration;
-uint32_t mig_liobn;
-hwaddr mig_mem_win_addr, mig_mem_win_size;
-hwaddr mig_io_win_addr, mig_io_win_size;
 bool pre_5_1_assoc;
 };
 
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 321ed2da75..cab4a46fc1 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1456,11 +1456,6 @@ struct ArchCPU {
 opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN];
 
 /* Fields related to migration compatibility hacks */
-bool pre_2_8_migration;
-target_ulong mig_msr_mask;
-uint64_t mig_insns_flags;
-uint64_t mig_insns_flags2;
-uint32_t mig_nb_BATs;
 bool pre_2_10_migration;
 bool pre_3_0_migration;
 int32_t mig_slb_nr;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d317387b7f..4e8f2a5d8e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5222,81 +5222,6 @@ static void spapr_machine_2_8_class_options(MachineClass 
*mc)
 
 DEFINE_SPAPR_MACHINE(2, 8);
 
-/*
- * pseries-2.7
- */
-
-static bool phb_placement_2_7(SpaprMachineState *spapr, uint32_t index,
-  uint64_t *buid, hwaddr *pio,
-  hwaddr *mmio32, hwaddr *mmio64,
-  unsigned n_dma, uint32_t *liobns, Error **errp)
-{
-/* Legacy PHB placement for pseries-2.7 and earlier machine types */
-const uint64_t base_buid = 0x8002000ULL;
-const hwaddr phb_spacing = 0x10ULL; /* 64 GiB */
-const hwaddr mmio_offset = 0xa000; /* 2 GiB + 512 MiB */
-const hwaddr pio_offset = 0x8000; /* 2 GiB */
-const uint32_t max_index = 255;
-const hwaddr phb0_alignment = 0x100ULL; /* 1 TiB */
-
-uint64_t ram_top = MACHINE(spapr)->ram_size;
-hwaddr phb0_base, phb_base;
-int i;
-
-/* Do we have device memory? */
-if (MACHINE(spapr)->device_memory) {
-/* Can't just use maxram_size, because there may be an
- * alignment gap between normal and device memory regions
- */
-ram_top = MACHINE(spapr)->device_memory->base +
-memory_region_size(&MACHINE(spapr)->device_memory->mr);
-}
-
-phb0_base = QEMU_ALIGN_UP(ram_top, phb0_alignment);
-
-if (index > max_index) {
-error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
-   max_index);
-return false;
-}
-
-*buid = base_buid + index;
-for (i = 0; i < n_dma; ++i) {
-liobns[i] = SPAPR_PCI_LIOBN(index, i);
-}
-
-phb_base = phb0_base + index * phb_spacing;
-*pio = phb_base + pio_offset;
-*mmio32 = phb_base + mmio_offset;
-/*
- * We don't set the 64-bit MMIO window, relying on the PHB's
- * fallback behaviour of automatically splitting a large "32-bit"
- * window into contiguous 32-bit and 64-bit windows
- */
-
-return true;
-}
-
-static void spapr_machine_2_7_class_options(MachineClass *mc)
-{
-SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-static GlobalProperty compat[] = {
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem_win_size", "0xf8000", },
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem64_win_size", "0", },
-{ TYPE_POWERPC_CPU, "pre-2.8-migration", "on", },
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "pre-2.8-migration", "on", },
-};
-
-spapr_machine_2_8_class_options(mc);
-mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power7_v2.3");
-mc->default_machine_opts = "modern-hotplug-events=off";
-compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-smc->phb_placement = phb_placement_2_7;
-}
-
-DEFINE_SPAPR_MACHINE(2, 7);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
diff 

[PATCH v2 00/11] ppc/spapr: remove deprecated machines specific code

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing the arch specific code for the now deprecated machine types.

v2: Addressed review comments from Cedric
v1: <20240917060300.943496-1-hars...@linux.ibm.com>
 
Harsh Prateek Bora (11):
  ppc/spapr: remove deprecated machine pseries-2.1
  ppc/spapr: remove deprecated machine pseries-2.2
  ppc/spapr: remove deprecated machine pseries-2.3
  ppc/spapr: remove deprecated machine pseries-2.4
  ppc/spapr: remove deprecated machine pseries-2.5
  ppc/spapr: remove deprecated machine pseries-2.6
  ppc/spapr: remove deprecated machine pseries-2.7
  ppc/spapr: remove deprecated machine pseries-2.8
  ppc/spapr: remove deprecated machine pseries-2.9
  ppc/spapr: remove deprecated machine pseries-2.10
  ppc/spapr: remove deprecated machine pseries-2.11

 include/hw/pci-host/spapr.h |   4 -
 target/ppc/cpu.h|   6 -
 hw/ppc/spapr.c  | 235 
 hw/ppc/spapr_pci.c  |  28 -
 target/ppc/cpu_init.c   |   3 -
 target/ppc/machine.c|  54 +
 6 files changed, 1 insertion(+), 329 deletions(-)

-- 
2.45.2




[PATCH v2 04/11] ppc/spapr: remove deprecated machine pseries-2.4

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.4 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f2f20aa5b5..9e78f94ec2 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5334,21 +5334,6 @@ static void spapr_machine_2_5_class_options(MachineClass 
*mc)
 
 DEFINE_SPAPR_MACHINE(2, 5);
 
-/*
- * pseries-2.4
- */
-
-static void spapr_machine_2_4_class_options(MachineClass *mc)
-{
-SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-
-spapr_machine_2_5_class_options(mc);
-smc->dr_lmb_enabled = false;
-compat_props_add(mc->compat_props, hw_compat_2_4, hw_compat_2_4_len);
-}
-
-DEFINE_SPAPR_MACHINE(2, 4);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




[PATCH v2 09/11] ppc/spapr: remove deprecated machine pseries-2.9

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.9 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/cpu.h  |  1 -
 hw/ppc/spapr.c| 20 
 target/ppc/cpu_init.c |  2 --
 target/ppc/machine.c  |  2 +-
 4 files changed, 1 insertion(+), 24 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index cab4a46fc1..74a0ab768d 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1456,7 +1456,6 @@ struct ArchCPU {
 opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN];
 
 /* Fields related to migration compatibility hacks */
-bool pre_2_10_migration;
 bool pre_3_0_migration;
 int32_t mig_slb_nr;
 };
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 97ab253fcc..84da4ece77 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5184,26 +5184,6 @@ static void 
spapr_machine_2_10_class_options(MachineClass *mc)
 
 DEFINE_SPAPR_MACHINE(2, 10);
 
-/*
- * pseries-2.9
- */
-
-static void spapr_machine_2_9_class_options(MachineClass *mc)
-{
-SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-static GlobalProperty compat[] = {
-{ TYPE_POWERPC_CPU, "pre-2.10-migration", "on" },
-};
-
-spapr_machine_2_10_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-smc->pre_2_10_has_unused_icps = true;
-smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
-}
-
-DEFINE_SPAPR_MACHINE(2, 9);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 7768392986..39c19e6674 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7452,8 +7452,6 @@ static void ppc_disas_set_info(CPUState *cs, 
disassemble_info *info)
 }
 
 static Property ppc_cpu_properties[] = {
-DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
- false),
 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
  false),
 DEFINE_PROP_END_OF_LIST(),
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 21bed7c7c8..47495b68b1 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -630,7 +630,7 @@ static bool compat_needed(void *opaque)
 PowerPCCPU *cpu = opaque;
 
 assert(!(cpu->compat_pvr && !cpu->vhyp));
-return !cpu->pre_2_10_migration && cpu->compat_pvr != 0;
+return cpu->compat_pvr != 0;
 }
 
 static const VMStateDescription vmstate_compat = {
-- 
2.45.2




[PATCH v2 10/11] ppc/spapr: remove deprecated machine pseries-2.10

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.10 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 84da4ece77..cb6bf219bf 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5172,18 +5172,6 @@ static void 
spapr_machine_2_11_class_options(MachineClass *mc)
 
 DEFINE_SPAPR_MACHINE(2, 11);
 
-/*
- * pseries-2.10
- */
-
-static void spapr_machine_2_10_class_options(MachineClass *mc)
-{
-spapr_machine_2_11_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
-}
-
-DEFINE_SPAPR_MACHINE(2, 10);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




[PATCH v2 02/11] ppc/spapr: remove deprecated machine pseries-2.2

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.2 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 17 -
 1 file changed, 17 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ec906e1d77..3c7d251356 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5364,23 +5364,6 @@ static void spapr_machine_2_3_class_options(MachineClass 
*mc)
 }
 DEFINE_SPAPR_MACHINE(2, 3);
 
-/*
- * pseries-2.2
- */
-
-static void spapr_machine_2_2_class_options(MachineClass *mc)
-{
-static GlobalProperty compat[] = {
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem_win_size", "0x2000" },
-};
-
-spapr_machine_2_3_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_2, hw_compat_2_2_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-mc->default_machine_opts = "modern-hotplug-events=off,suppress-vmdesc=on";
-}
-DEFINE_SPAPR_MACHINE(2, 2);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




[PATCH v2 11/11] ppc/spapr: remove deprecated machine pseries-2.11

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.11 specific code with this patch.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index cb6bf219bf..04f06377b4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5157,21 +5157,6 @@ static void 
spapr_machine_2_12_sxxm_class_options(MachineClass *mc)
 
 DEFINE_SPAPR_MACHINE_TAGGED(2, 12, sxxm);
 
-/*
- * pseries-2.11
- */
-
-static void spapr_machine_2_11_class_options(MachineClass *mc)
-{
-SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-
-spapr_machine_2_12_class_options(mc);
-smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
-compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
-}
-
-DEFINE_SPAPR_MACHINE(2, 11);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




[PATCH v2 08/11] ppc/spapr: remove deprecated machine pseries-2.8

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.8 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 18 --
 1 file changed, 18 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4e8f2a5d8e..97ab253fcc 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5204,24 +5204,6 @@ static void spapr_machine_2_9_class_options(MachineClass 
*mc)
 
 DEFINE_SPAPR_MACHINE(2, 9);
 
-/*
- * pseries-2.8
- */
-
-static void spapr_machine_2_8_class_options(MachineClass *mc)
-{
-static GlobalProperty compat[] = {
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "pcie-extended-configuration-space", 
"off" },
-};
-
-spapr_machine_2_9_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-mc->numa_mem_align_shift = 23;
-}
-
-DEFINE_SPAPR_MACHINE(2, 8);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




[PATCH v2 01/11] ppc/spapr: remove deprecated machine pseries-2.1

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.1 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8aa3ce7449..ec906e1d77 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5381,17 +5381,6 @@ static void spapr_machine_2_2_class_options(MachineClass 
*mc)
 }
 DEFINE_SPAPR_MACHINE(2, 2);
 
-/*
- * pseries-2.1
- */
-
-static void spapr_machine_2_1_class_options(MachineClass *mc)
-{
-spapr_machine_2_2_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_1, hw_compat_2_1_len);
-}
-DEFINE_SPAPR_MACHINE(2, 1);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




[PATCH v2 05/11] ppc/spapr: remove deprecated machine pseries-2.5

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.5 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9e78f94ec2..a38d4e098a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5315,25 +5315,6 @@ static void spapr_machine_2_6_class_options(MachineClass 
*mc)
 
 DEFINE_SPAPR_MACHINE(2, 6);
 
-/*
- * pseries-2.5
- */
-
-static void spapr_machine_2_5_class_options(MachineClass *mc)
-{
-SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-static GlobalProperty compat[] = {
-{ "spapr-vlan", "use-rx-buffer-pools", "off" },
-};
-
-spapr_machine_2_6_class_options(mc);
-smc->use_ohci_by_default = true;
-compat_props_add(mc->compat_props, hw_compat_2_5, hw_compat_2_5_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-}
-
-DEFINE_SPAPR_MACHINE(2, 5);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




[PATCH v2 03/11] ppc/spapr: remove deprecated machine pseries-2.3

2024-10-01 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing pseries-2.3 specific code with this patch for now.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3c7d251356..f2f20aa5b5 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5349,21 +5349,6 @@ static void spapr_machine_2_4_class_options(MachineClass 
*mc)
 
 DEFINE_SPAPR_MACHINE(2, 4);
 
-/*
- * pseries-2.3
- */
-
-static void spapr_machine_2_3_class_options(MachineClass *mc)
-{
-static GlobalProperty compat[] = {
-{ "spapr-pci-host-bridge", "dynamic-reconfiguration", "off" },
-};
-spapr_machine_2_4_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_3, hw_compat_2_3_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-}
-DEFINE_SPAPR_MACHINE(2, 3);
-
 static void spapr_machine_register_types(void)
 {
 type_register_static(&spapr_machine_info);
-- 
2.45.2




Re: [PATCH v16 02/13] hw/ppc/spapr_pci: Do not create DT for disabled PCI device

2024-09-18 Thread Harsh Prateek Bora




On 9/18/24 19:57, Cédric Le Goater wrote:

Hello,

Adding :

   Harsh for QEMU/PPC pseries machine,
   Shivaprasad for KVM/PPC VFIO and IOMMU support.

Could you please give us your feedback on these changes ?

Thanks,

C.



  On 9/13/24 05:44, Akihiko Odaki wrote:

Disabled means it is a disabled SR-IOV VF or it is powered off, and
hidden from the guest.

Signed-off-by: Akihiko Odaki 
---
  hw/ppc/spapr_pci.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7cf9904c3546..f63182a03c41 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1296,6 +1296,10 @@ static void spapr_dt_pci_device_cb(PCIBus *bus, 
PCIDevice *pdev,

  return;
  }
+    if (!pdev->enabled) {
+    return;
+    }
+


While I will let Shivaprasad comment from IO perspective, I would like 
to suggest merging this condition with the error condition check 
preceding it.


regards,
Harsh


  err = spapr_dt_pci_device(p->sphb, pdev, p->fdt, p->offset);
  if (err < 0) {
  p->err = err;








Re: [PATCH] ppc/spapr: remove deprecated machines specific code

2024-09-18 Thread Harsh Prateek Bora

Hi Cedric,

On 9/17/24 12:31, Cédric Le Goater wrote:

Hello Harsh,

On 9/17/24 08:03, Harsh Prateek Bora wrote:

Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing the arch specific code for the now deprecated machine types.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 


There is more to it :/

Some machine versions have their own set of properties, like the
"pre-*-migration" ones, and the associated code should be removed
also. It impacts more models than just the machine model.

I suggest one patch per machine version, or one patch per complex
machine version and a combo patch for the simple ones.


Sure, I shall post v2 as a patchset addressing your inputs.

regards,
Harsh



Thanks,

C.



---
  hw/ppc/spapr.c | 235 -
  1 file changed, 235 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8aa3ce7449..04f06377b4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5157,241 +5157,6 @@ static void 
spapr_machine_2_12_sxxm_class_options(MachineClass *mc)

  DEFINE_SPAPR_MACHINE_TAGGED(2, 12, sxxm);
-/*
- * pseries-2.11
- */
-
-static void spapr_machine_2_11_class_options(MachineClass *mc)
-{
-    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-
-    spapr_machine_2_12_class_options(mc);
-    smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
-    compat_props_add(mc->compat_props, hw_compat_2_11, 
hw_compat_2_11_len);

-}
-
-DEFINE_SPAPR_MACHINE(2, 11);
-
-/*
- * pseries-2.10
- */
-
-static void spapr_machine_2_10_class_options(MachineClass *mc)
-{
-    spapr_machine_2_11_class_options(mc);
-    compat_props_add(mc->compat_props, hw_compat_2_10, 
hw_compat_2_10_len);

-}
-
-DEFINE_SPAPR_MACHINE(2, 10);
-
-/*
- * pseries-2.9
- */
-
-static void spapr_machine_2_9_class_options(MachineClass *mc)
-{
-    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-    static GlobalProperty compat[] = {
-    { TYPE_POWERPC_CPU, "pre-2.10-migration", "on" },
-    };
-
-    spapr_machine_2_10_class_options(mc);
-    compat_props_add(mc->compat_props, hw_compat_2_9, 
hw_compat_2_9_len);

-    compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-    smc->pre_2_10_has_unused_icps = true;
-    smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
-}
-
-DEFINE_SPAPR_MACHINE(2, 9);
-
-/*
- * pseries-2.8
- */
-
-static void spapr_machine_2_8_class_options(MachineClass *mc)
-{
-    static GlobalProperty compat[] = {
-    { TYPE_SPAPR_PCI_HOST_BRIDGE, 
"pcie-extended-configuration-space", "off" },

-    };
-
-    spapr_machine_2_9_class_options(mc);
-    compat_props_add(mc->compat_props, hw_compat_2_8, 
hw_compat_2_8_len);

-    compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-    mc->numa_mem_align_shift = 23;
-}
-
-DEFINE_SPAPR_MACHINE(2, 8);
-
-/*
- * pseries-2.7
- */
-
-static bool phb_placement_2_7(SpaprMachineState *spapr, uint32_t index,
-  uint64_t *buid, hwaddr *pio,
-  hwaddr *mmio32, hwaddr *mmio64,
-  unsigned n_dma, uint32_t *liobns, Error 
**errp)

-{
-    /* Legacy PHB placement for pseries-2.7 and earlier machine types */
-    const uint64_t base_buid = 0x8002000ULL;
-    const hwaddr phb_spacing = 0x10ULL; /* 64 GiB */
-    const hwaddr mmio_offset = 0xa000; /* 2 GiB + 512 MiB */
-    const hwaddr pio_offset = 0x8000; /* 2 GiB */
-    const uint32_t max_index = 255;
-    const hwaddr phb0_alignment = 0x100ULL; /* 1 TiB */
-
-    uint64_t ram_top = MACHINE(spapr)->ram_size;
-    hwaddr phb0_base, phb_base;
-    int i;
-
-    /* Do we have device memory? */
-    if (MACHINE(spapr)->device_memory) {
-    /* Can't just use maxram_size, because there may be an
- * alignment gap between normal and device memory regions
- */
-    ram_top = MACHINE(spapr)->device_memory->base +
-    memory_region_size(&MACHINE(spapr)->device_memory->mr);
-    }
-
-    phb0_base = QEMU_ALIGN_UP(ram_top, phb0_alignment);
-
-    if (index > max_index) {
-    error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
-   max_index);
-    return false;
-    }
-
-    *buid = base_buid + index;
-    for (i = 0; i < n_dma; ++i) {
-    liobns[i] = SPAPR_PCI_LIOBN(index, i);
-    }
-
-    phb_base = phb0_base + index * phb_spacing;
-    *pio = phb_base + pio_offset;
-    *mmio32 = phb_base + mmio_offset;
-    /*
- * We don't set the 64-bit MMIO window, relying on the PHB's
- * fallback behaviour of automatically splitting a large "32-bit"
- * window into contiguous 32-bit and 64-bit windows
- */
-
-    return true;
-}
-
-static void spapr_machine_2_7_class_options(MachineClass *mc)
-{
-    Spap

[PATCH] ppc/spapr: remove deprecated machines specific code

2024-09-16 Thread Harsh Prateek Bora
Commit 1392617d3576 intended to tag pseries-2.1 - 2.11 machines as
deprecated with reasons mentioned in its commit log.
Removing the arch specific code for the now deprecated machine types.

Suggested-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
---
 hw/ppc/spapr.c | 235 -
 1 file changed, 235 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8aa3ce7449..04f06377b4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -5157,241 +5157,6 @@ static void 
spapr_machine_2_12_sxxm_class_options(MachineClass *mc)
 
 DEFINE_SPAPR_MACHINE_TAGGED(2, 12, sxxm);
 
-/*
- * pseries-2.11
- */
-
-static void spapr_machine_2_11_class_options(MachineClass *mc)
-{
-SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-
-spapr_machine_2_12_class_options(mc);
-smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
-compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
-}
-
-DEFINE_SPAPR_MACHINE(2, 11);
-
-/*
- * pseries-2.10
- */
-
-static void spapr_machine_2_10_class_options(MachineClass *mc)
-{
-spapr_machine_2_11_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
-}
-
-DEFINE_SPAPR_MACHINE(2, 10);
-
-/*
- * pseries-2.9
- */
-
-static void spapr_machine_2_9_class_options(MachineClass *mc)
-{
-SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-static GlobalProperty compat[] = {
-{ TYPE_POWERPC_CPU, "pre-2.10-migration", "on" },
-};
-
-spapr_machine_2_10_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-smc->pre_2_10_has_unused_icps = true;
-smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
-}
-
-DEFINE_SPAPR_MACHINE(2, 9);
-
-/*
- * pseries-2.8
- */
-
-static void spapr_machine_2_8_class_options(MachineClass *mc)
-{
-static GlobalProperty compat[] = {
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "pcie-extended-configuration-space", 
"off" },
-};
-
-spapr_machine_2_9_class_options(mc);
-compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
-compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-mc->numa_mem_align_shift = 23;
-}
-
-DEFINE_SPAPR_MACHINE(2, 8);
-
-/*
- * pseries-2.7
- */
-
-static bool phb_placement_2_7(SpaprMachineState *spapr, uint32_t index,
-  uint64_t *buid, hwaddr *pio,
-  hwaddr *mmio32, hwaddr *mmio64,
-  unsigned n_dma, uint32_t *liobns, Error **errp)
-{
-/* Legacy PHB placement for pseries-2.7 and earlier machine types */
-const uint64_t base_buid = 0x8002000ULL;
-const hwaddr phb_spacing = 0x10ULL; /* 64 GiB */
-const hwaddr mmio_offset = 0xa000; /* 2 GiB + 512 MiB */
-const hwaddr pio_offset = 0x8000; /* 2 GiB */
-const uint32_t max_index = 255;
-const hwaddr phb0_alignment = 0x100ULL; /* 1 TiB */
-
-uint64_t ram_top = MACHINE(spapr)->ram_size;
-hwaddr phb0_base, phb_base;
-int i;
-
-/* Do we have device memory? */
-if (MACHINE(spapr)->device_memory) {
-/* Can't just use maxram_size, because there may be an
- * alignment gap between normal and device memory regions
- */
-ram_top = MACHINE(spapr)->device_memory->base +
-memory_region_size(&MACHINE(spapr)->device_memory->mr);
-}
-
-phb0_base = QEMU_ALIGN_UP(ram_top, phb0_alignment);
-
-if (index > max_index) {
-error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
-   max_index);
-return false;
-}
-
-*buid = base_buid + index;
-for (i = 0; i < n_dma; ++i) {
-liobns[i] = SPAPR_PCI_LIOBN(index, i);
-}
-
-phb_base = phb0_base + index * phb_spacing;
-*pio = phb_base + pio_offset;
-*mmio32 = phb_base + mmio_offset;
-/*
- * We don't set the 64-bit MMIO window, relying on the PHB's
- * fallback behaviour of automatically splitting a large "32-bit"
- * window into contiguous 32-bit and 64-bit windows
- */
-
-return true;
-}
-
-static void spapr_machine_2_7_class_options(MachineClass *mc)
-{
-SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
-static GlobalProperty compat[] = {
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem_win_size", "0xf8000", },
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem64_win_size", "0", },
-{ TYPE_POWERPC_CPU, "pre-2.8-migration", "on", },
-{ TYPE_SPAPR_PCI_HOST_BRIDGE, "pre-2.8-migration", "on", },
-};
-
-spapr_machine_2_8_class_options(mc);
-mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power7_v2.3&qu

Re: [PATCH] target/ppc: Fix inequality check in do_lstxv_X

2024-09-16 Thread Harsh Prateek Bora

Hi Fabiano,

On 9/13/24 17:02, Fabiano Rosas wrote:

Harsh Prateek Bora  writes:


This fix was earlier introduced for do_lstxv_D form with 2cc0e449d173
however got missed for _X form. This patch fixes the same.

Cc: qemu-sta...@nongnu.org
Suggested-by: Fabiano Rosas 
Fixes: 70426b5bb738 ("target/ppc: moved stxvx and lxvx from legacy to 
decodtree")
Signed-off-by: Harsh Prateek Bora 
---
  target/ppc/translate/vsx-impl.c.inc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/translate/vsx-impl.c.inc 
b/target/ppc/translate/vsx-impl.c.inc
index 40a87ddc4a..a869f30e86 100644
--- a/target/ppc/translate/vsx-impl.c.inc
+++ b/target/ppc/translate/vsx-impl.c.inc
@@ -2244,7 +2244,7 @@ static bool do_lstxv_PLS_D(DisasContext *ctx, arg_PLS_D 
*a,
  
  static bool do_lstxv_X(DisasContext *ctx, arg_X *a, bool store, bool paired)

  {
-if (paired || a->rt >= 32) {
+if (paired || a->rt < 32) {
  REQUIRE_VSX(ctx);
  } else {
  REQUIRE_VECTOR(ctx);


Hi Harsh,

Seems I was quicker than you =)

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

I'll give my RB and leave up to the maintainers which patch to take:

Reviewed-by: Fabiano Rosas 


Thanks, I missed looking at your patch earlier.
I would vote for your patch though.

regards,
Harsh



Re: [PATCH v3 09/10] target/ppc: simplify var usage in ppc_next_unmasked_interrupt

2024-09-16 Thread Harsh Prateek Bora




On 9/13/24 18:20, BALATON Zoltan wrote:

On Fri, 13 Sep 2024, Harsh Prateek Bora wrote:

As previously done for arch specific handlers, simplify var usage in
ppc_next_unmasked_interrupt by caching the env->pending_interrupts and
env->spr[SPR_LPCR] in local vars and using it later at multiple places.

Signed-off-by: Harsh Prateek Bora 
---
target/ppc/excp_helper.c | 54 
1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index d0e0f609a0..4dff5b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -2022,31 +2022,31 @@ static int 
p9_next_unmasked_interrupt(CPUPPCState *env,


static int ppc_next_unmasked_interrupt(CPUPPCState *env)
{
+    uint32_t pending_interrupts = env->pending_interrupts;
+    target_ulong lpcr = env->spr[SPR_LPCR];
+    bool async_deliver;


Maybe easier to review if split into one patch for each variable added 
so it's easier to see what's replaced and that nothing is missed.




Thanks for the reviews. I shall split as suggested in v4.

regards,
Harsh


Regards,
BALATON Zoltan


+
#ifdef TARGET_PPC64
    switch (env->excp_model) {
    case POWERPC_EXCP_POWER7:
-    return p7_next_unmasked_interrupt(env, env->pending_interrupts,
-  env->spr[SPR_LPCR]);
+    return p7_next_unmasked_interrupt(env, pending_interrupts, 
lpcr);

    case POWERPC_EXCP_POWER8:
-    return p8_next_unmasked_interrupt(env, env->pending_interrupts,
-  env->spr[SPR_LPCR]);
+    return p8_next_unmasked_interrupt(env, pending_interrupts, 
lpcr);

    case POWERPC_EXCP_POWER9:
    case POWERPC_EXCP_POWER10:
    case POWERPC_EXCP_POWER11:
-    return p9_next_unmasked_interrupt(env, env->pending_interrupts,
-  env->spr[SPR_LPCR]);
+    return p9_next_unmasked_interrupt(env, pending_interrupts, 
lpcr);

    default:
    break;
    }
#endif
-    bool async_deliver;

    /* External reset */
-    if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+    if (pending_interrupts & PPC_INTERRUPT_RESET) {
    return PPC_INTERRUPT_RESET;
    }
    /* Machine check exception */
-    if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+    if (pending_interrupts & PPC_INTERRUPT_MCK) {
    return PPC_INTERRUPT_MCK;
    }
#if 0 /* TODO */
@@ -2065,9 +2065,9 @@ static int 
ppc_next_unmasked_interrupt(CPUPPCState *env)
    async_deliver = FIELD_EX64(env->msr, MSR, EE) || 
env->resume_as_sreset;


    /* Hypervisor decrementer exception */
-    if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
+    if (pending_interrupts & PPC_INTERRUPT_HDECR) {
    /* LPCR will be clear when not supported so this will work */
-    bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
+    bool hdice = !!(lpcr & LPCR_HDICE);
    if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) {
    /* HDEC clears on delivery */
    return PPC_INTERRUPT_HDECR;
@@ -2075,18 +2075,18 @@ static int 
ppc_next_unmasked_interrupt(CPUPPCState *env)

    }

    /* Hypervisor virtualization interrupt */
-    if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) {
+    if (pending_interrupts & PPC_INTERRUPT_HVIRT) {
    /* LPCR will be clear when not supported so this will work */
-    bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
+    bool hvice = !!(lpcr & LPCR_HVICE);
    if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) {
    return PPC_INTERRUPT_HVIRT;
    }
    }

    /* External interrupt can ignore MSR:EE under some circumstances */
-    if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
-    bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
-    bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+    if (pending_interrupts & PPC_INTERRUPT_EXT) {
+    bool lpes0 = !!(lpcr & LPCR_LPES0);
+    bool heic = !!(lpcr & LPCR_HEIC);
    /* HEIC blocks delivery to the hypervisor */
    if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) &&
    !FIELD_EX64(env->msr, MSR, PR))) ||
@@ -2096,45 +2096,45 @@ static int 
ppc_next_unmasked_interrupt(CPUPPCState *env)

    }
    if (FIELD_EX64(env->msr, MSR, CE)) {
    /* External critical interrupt */
-    if (env->pending_interrupts & PPC_INTERRUPT_CEXT) {
+    if (pending_interrupts & PPC_INTERRUPT_CEXT) {
    return PPC_INTERRUPT_CEXT;
    }
    }
    if (async_deliver != 0) {
    /* Watchdog timer on embedded PowerPC */
-    if (env->pending_interrupts & PPC_INTERRUPT_WDT) {
+    if (pending_interrupts & PPC_INTERRUPT_WDT) {
    return PPC_INTERRUPT_WDT;
    }
-    if (env->pendin

Re: [PULL 20/49] spapr: Tag pseries-2.1 - 2.11 machines as deprecated

2024-09-16 Thread Harsh Prateek Bora

Hi Cedric,

On 9/16/24 18:44, Cédric Le Goater wrote:

Hello Harsh,

On 2/19/24 09:29, Nicholas Piggin wrote:

From: Cédric Le Goater 

pseries machines before version 2.11 have undergone many changes to
correct issues, mostly regarding migration compatibility. This is
obfuscating the code uselessly and makes maintenance more difficult.
Remove them and only keep the last version of the 2.x series, 2.12,
still in use by old distros.

Reviewed-by: Thomas Huth 
Reviewed-by: Daniel Henrique Barboza 
Signed-off-by: Cédric Le Goater 
Signed-off-by: Nicholas Piggin 
---
  docs/about/deprecated.rst | 8 
  hw/ppc/spapr.c    | 1 +
  roms/skiboot  | 2 +-
  3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 5a2305ccd6..36bd3e15ef 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -229,6 +229,14 @@ The Nios II architecture is orphan.
  The machine is no longer in existence and has been long unmaintained
  in QEMU. This also holds for the TC51828 16MiB flash that it uses.
+``pseries-2.1`` up to ``pseries-2.11`` (since 9.0)
+''
+
+Older pseries machines before version 2.12 have undergone many changes
+to correct issues, mostly regarding migration compatibility. These are
+no longer maintained and removing them will make the code easier to
+read and maintain. Use versions 2.12 and above as a replacement.
+


Would you have time, or a KVM PPC team member, to start removing
the now deprecated pseries machines in the QEMU 9.2 cycle ?



Sure, I can take a look at that.

regards,
Harsh


Thanks,

C.






Re: [PATCH] target/ppc: Fix lxv/stxv MSR facility check

2024-09-12 Thread Harsh Prateek Bora

Hi Fabiano,

On 9/10/24 04:36, Fabiano Rosas wrote:

Nicholas Piggin  writes:


The move to decodetree flipped the inequality test for the VEC / VSX
MSR facility check.

This caused application crashes under Linux, where these facility
unavailable interrupts are used for lazy-switching of VEC/VSX register
sets. Getting the incorrect interrupt would result in wrong registers
being loaded, potentially overwriting live values and/or exposing
stale ones.

Cc: qemu-sta...@nongnu.org
Reported-by: Joel Stanley 
Fixes: 70426b5bb738 ("target/ppc: moved stxvx and lxvx from legacy to 
decodtree")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1769
Tested-by: Harsh Prateek Bora 
Signed-off-by: Nicholas Piggin 
---
  target/ppc/translate/vsx-impl.c.inc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/translate/vsx-impl.c.inc 
b/target/ppc/translate/vsx-impl.c.inc
index 6db87ab336..0266f09119 100644
--- a/target/ppc/translate/vsx-impl.c.inc
+++ b/target/ppc/translate/vsx-impl.c.inc
@@ -2268,7 +2268,7 @@ static bool do_lstxv(DisasContext *ctx, int ra, TCGv 
displ,
  
  static bool do_lstxv_D(DisasContext *ctx, arg_D *a, bool store, bool paired)

  {
-if (paired || a->rt >= 32) {
+if (paired || a->rt < 32) {
  REQUIRE_VSX(ctx);
  } else {
  REQUIRE_VECTOR(ctx);


What about the X-form down below?

static bool do_lstxv_X(DisasContext *ctx, arg_X *a, bool store, bool paired)
{
 if (paired || a->rt >= 32) {
 REQUIRE_VSX(ctx);
 } else {
 REQUIRE_VECTOR(ctx);
 }

 return do_lstxv(ctx, a->ra, cpu_gpr[a->rb], a->rt, store, paired);
}


Thanks for catching this. I have posted the fix here:
https://lore.kernel.org/qemu-devel/20240913043827.914457-1-hars...@linux.ibm.com/T/#u

regards,
Harsh




[PATCH] target/ppc: Fix inequality check in do_lstxv_X

2024-09-12 Thread Harsh Prateek Bora
This fix was earlier introduced for do_lstxv_D form with 2cc0e449d173
however got missed for _X form. This patch fixes the same.

Cc: qemu-sta...@nongnu.org
Suggested-by: Fabiano Rosas 
Fixes: 70426b5bb738 ("target/ppc: moved stxvx and lxvx from legacy to 
decodtree")
Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/translate/vsx-impl.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/translate/vsx-impl.c.inc 
b/target/ppc/translate/vsx-impl.c.inc
index 40a87ddc4a..a869f30e86 100644
--- a/target/ppc/translate/vsx-impl.c.inc
+++ b/target/ppc/translate/vsx-impl.c.inc
@@ -2244,7 +2244,7 @@ static bool do_lstxv_PLS_D(DisasContext *ctx, arg_PLS_D 
*a,
 
 static bool do_lstxv_X(DisasContext *ctx, arg_X *a, bool store, bool paired)
 {
-if (paired || a->rt >= 32) {
+if (paired || a->rt < 32) {
 REQUIRE_VSX(ctx);
 } else {
 REQUIRE_VECTOR(ctx);
-- 
2.45.2




Re: [PATCH v2 5/7] target/ppc: optimize p9 exception handling routines for lpcr

2024-09-12 Thread Harsh Prateek Bora

Hi Nick,

On 7/4/24 13:13, Nicholas Piggin wrote:

On Thu May 23, 2024 at 3:14 PM AEST, Harsh Prateek Bora wrote:

Like pending_interrupts, env->spr[SPR_LPCR] is being used at multiple
places across p9 exception handlers. Pass the value during entry and
avoid multiple indirect accesses.


Ditto for this (does it help code, other CPU functions should
be converted similarly).


Thanks for your review comments and apologies for a late response.
I have posted v3 with suggested updates and some additional patches.
Patch 7/7 of this series had been picked by Aditya and updated in his
patchset for P11 support so I have excluded that in v3 and just rebased
on top of his v6 series.

v3: 
https://lore.kernel.org/qemu-devel/20240913041337.912876-1-hars...@linux.ibm.com/T/#t


regards,
Harsh


Thanks,
Nick



Signed-off-by: Harsh Prateek Bora 
---
  target/ppc/excp_helper.c | 33 ++---
  1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 704eddac63..d3db81e6ae 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1843,13 +1843,14 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
   PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
  
  static int p9_interrupt_powersave(CPUPPCState *env,

-  uint32_t pending_interrupts)
+  uint32_t pending_interrupts,
+  target_ulong lpcr)
  {
  
  /* External Exception */

  if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
-(env->spr[SPR_LPCR] & LPCR_EEE)) {
-bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+(lpcr & LPCR_EEE)) {
+bool heic = !!(lpcr & LPCR_HEIC);
  if (!heic || !FIELD_EX64_HV(env->msr) ||
  FIELD_EX64(env->msr, MSR, PR)) {
  return PPC_INTERRUPT_EXT;
@@ -1857,11 +1858,11 @@ static int p9_interrupt_powersave(CPUPPCState *env,
  }
  /* Decrementer Exception */
  if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
-(env->spr[SPR_LPCR] & LPCR_DEE)) {
+(lpcr & LPCR_DEE)) {
  return PPC_INTERRUPT_DECR;
  }
  /* Machine Check or Hypervisor Maintenance Exception */
-if (env->spr[SPR_LPCR] & LPCR_OEE) {
+if (lpcr & LPCR_OEE) {
  if (pending_interrupts & PPC_INTERRUPT_MCK) {
  return PPC_INTERRUPT_MCK;
  }
@@ -1871,17 +1872,17 @@ static int p9_interrupt_powersave(CPUPPCState *env,
  }
  /* Privileged Doorbell Exception */
  if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
-(env->spr[SPR_LPCR] & LPCR_PDEE)) {
+(lpcr & LPCR_PDEE)) {
  return PPC_INTERRUPT_DOORBELL;
  }
  /* Hypervisor Doorbell Exception */
  if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
-(env->spr[SPR_LPCR] & LPCR_HDEE)) {
+(lpcr & LPCR_HDEE)) {
  return PPC_INTERRUPT_HDOORBELL;
  }
  /* Hypervisor virtualization exception */
  if ((pending_interrupts & PPC_INTERRUPT_HVIRT) &&
-(env->spr[SPR_LPCR] & LPCR_HVEE)) {
+(lpcr & LPCR_HVEE)) {
  return PPC_INTERRUPT_HVIRT;
  }
  if (pending_interrupts & PPC_INTERRUPT_RESET) {
@@ -1891,7 +1892,8 @@ static int p9_interrupt_powersave(CPUPPCState *env,
  }
  
  static int p9_next_unmasked_interrupt(CPUPPCState *env,

-  uint32_t pending_interrupts)
+  uint32_t pending_interrupts,
+  target_ulong lpcr)
  {
  CPUState *cs = env_cpu(env);
  
@@ -1906,7 +1908,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,

   * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can
   * wakeup the processor
   */
-return p9_interrupt_powersave(env, pending_interrupts);
+return p9_interrupt_powersave(env, pending_interrupts, lpcr);
  } else {
  /*
   * When it's clear, any system-caused exception exits power-saving
@@ -1924,7 +1926,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
  /* Hypervisor decrementer exception */
  if (pending_interrupts & PPC_INTERRUPT_HDECR) {
  /* LPCR will be clear when not supported so this will work */
-bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
+bool hdice = !!(lpcr & LPCR_HDICE);
  if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
  /* HDEC clears on delivery */
  return PPC_INTERRUPT_HDECR;
@@ -1934,7 +1936,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
  /* Hypervisor virtualization interrupt */
  if (pending_interrupts & PPC_INTERRUPT_HVIRT) {

[PATCH v3 09/10] target/ppc: simplify var usage in ppc_next_unmasked_interrupt

2024-09-12 Thread Harsh Prateek Bora
As previously done for arch specific handlers, simplify var usage in
ppc_next_unmasked_interrupt by caching the env->pending_interrupts and
env->spr[SPR_LPCR] in local vars and using it later at multiple places.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 54 
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index d0e0f609a0..4dff5b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -2022,31 +2022,31 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
 
 static int ppc_next_unmasked_interrupt(CPUPPCState *env)
 {
+uint32_t pending_interrupts = env->pending_interrupts;
+target_ulong lpcr = env->spr[SPR_LPCR];
+bool async_deliver;
+
 #ifdef TARGET_PPC64
 switch (env->excp_model) {
 case POWERPC_EXCP_POWER7:
-return p7_next_unmasked_interrupt(env, env->pending_interrupts,
-  env->spr[SPR_LPCR]);
+return p7_next_unmasked_interrupt(env, pending_interrupts, lpcr);
 case POWERPC_EXCP_POWER8:
-return p8_next_unmasked_interrupt(env, env->pending_interrupts,
-  env->spr[SPR_LPCR]);
+return p8_next_unmasked_interrupt(env, pending_interrupts, lpcr);
 case POWERPC_EXCP_POWER9:
 case POWERPC_EXCP_POWER10:
 case POWERPC_EXCP_POWER11:
-return p9_next_unmasked_interrupt(env, env->pending_interrupts,
- env->spr[SPR_LPCR]);
+return p9_next_unmasked_interrupt(env, pending_interrupts, lpcr);
 default:
 break;
 }
 #endif
-bool async_deliver;
 
 /* External reset */
-if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+if (pending_interrupts & PPC_INTERRUPT_RESET) {
 return PPC_INTERRUPT_RESET;
 }
 /* Machine check exception */
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
 #if 0 /* TODO */
@@ -2065,9 +2065,9 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env)
 async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
 
 /* Hypervisor decrementer exception */
-if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
+if (pending_interrupts & PPC_INTERRUPT_HDECR) {
 /* LPCR will be clear when not supported so this will work */
-bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
+bool hdice = !!(lpcr & LPCR_HDICE);
 if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) {
 /* HDEC clears on delivery */
 return PPC_INTERRUPT_HDECR;
@@ -2075,18 +2075,18 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* Hypervisor virtualization interrupt */
-if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) {
+if (pending_interrupts & PPC_INTERRUPT_HVIRT) {
 /* LPCR will be clear when not supported so this will work */
-bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
+bool hvice = !!(lpcr & LPCR_HVICE);
 if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) {
 return PPC_INTERRUPT_HVIRT;
 }
 }
 
 /* External interrupt can ignore MSR:EE under some circumstances */
-if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
-bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
-bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+if (pending_interrupts & PPC_INTERRUPT_EXT) {
+bool lpes0 = !!(lpcr & LPCR_LPES0);
+bool heic = !!(lpcr & LPCR_HEIC);
 /* HEIC blocks delivery to the hypervisor */
 if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) &&
 !FIELD_EX64(env->msr, MSR, PR))) ||
@@ -2096,45 +2096,45 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env)
 }
 if (FIELD_EX64(env->msr, MSR, CE)) {
 /* External critical interrupt */
-if (env->pending_interrupts & PPC_INTERRUPT_CEXT) {
+if (pending_interrupts & PPC_INTERRUPT_CEXT) {
 return PPC_INTERRUPT_CEXT;
 }
 }
 if (async_deliver != 0) {
 /* Watchdog timer on embedded PowerPC */
-if (env->pending_interrupts & PPC_INTERRUPT_WDT) {
+if (pending_interrupts & PPC_INTERRUPT_WDT) {
 return PPC_INTERRUPT_WDT;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) {
+if (pending_interrupts & PPC_INTERRUPT_CDOORBELL) {
 return PPC_INTERRUPT_CDOORBELL;
 }
 /* Fixed interval timer on embedded PowerPC */
-if (env->pending_interrupts & PPC_INTERRUPT_FIT) {
+ 

[PATCH v3 02/10] target/ppc: optimize hreg_compute_pmu_hflags_value

2024-09-12 Thread Harsh Prateek Bora
Cache env->spr[SPR_POWER_MMCR0] in a local variable as used in multiple
conditions to avoid multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
Reviewed-by: Nicholas Piggin 
---
 target/ppc/helper_regs.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index fe543ab3b8..7b23e5ef0e 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -83,15 +83,16 @@ static bool hreg_check_bhrb_enable(CPUPPCState *env)
 static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState *env)
 {
 uint32_t hflags = 0;
-
 #if defined(TARGET_PPC64)
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC0) {
+target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
+
+if (mmcr0 & MMCR0_PMCC0) {
 hflags |= 1 << HFLAGS_PMCC0;
 }
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) {
+if (mmcr0 & MMCR0_PMCC1) {
 hflags |= 1 << HFLAGS_PMCC1;
 }
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) {
+if (mmcr0 & MMCR0_PMCjCE) {
 hflags |= 1 << HFLAGS_PMCJCE;
 }
 if (hreg_check_bhrb_enable(env)) {
-- 
2.45.2




[PATCH v3 04/10] target/ppc: optimize p9 exception handling routines

2024-09-12 Thread Harsh Prateek Bora
Currently, p9 exception handling has multiple if-condition checks where
it does an indirect access to pending_interrupts via env. Pass the
value during entry to avoid multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 47 +---
 1 file changed, 25 insertions(+), 22 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 2029144622..31c1653e2b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1872,10 +1872,12 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
  PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT |  \
  PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
 
-static int p9_interrupt_powersave(CPUPPCState *env)
+static int p9_interrupt_powersave(CPUPPCState *env,
+  uint32_t pending_interrupts)
 {
+
 /* External Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
+if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
 (env->spr[SPR_LPCR] & LPCR_EEE)) {
 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
 if (!heic || !FIELD_EX64_HV(env->msr) ||
@@ -1884,48 +1886,49 @@ static int p9_interrupt_powersave(CPUPPCState *env)
 }
 }
 /* Decrementer Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
+if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
 (env->spr[SPR_LPCR] & LPCR_DEE)) {
 return PPC_INTERRUPT_DECR;
 }
 /* Machine Check or Hypervisor Maintenance Exception */
 if (env->spr[SPR_LPCR] & LPCR_OEE) {
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_HMI) {
+if (pending_interrupts & PPC_INTERRUPT_HMI) {
 return PPC_INTERRUPT_HMI;
 }
 }
 /* Privileged Doorbell Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
+if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
 return PPC_INTERRUPT_DOORBELL;
 }
 /* Hypervisor Doorbell Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
+if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
 return PPC_INTERRUPT_HDOORBELL;
 }
 /* Hypervisor virtualization exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) &&
+if ((pending_interrupts & PPC_INTERRUPT_HVIRT) &&
 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
 return PPC_INTERRUPT_HVIRT;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+if (pending_interrupts & PPC_INTERRUPT_RESET) {
 return PPC_INTERRUPT_RESET;
 }
 return 0;
 }
 
-static int p9_next_unmasked_interrupt(CPUPPCState *env)
+static int p9_next_unmasked_interrupt(CPUPPCState *env,
+  uint32_t pending_interrupts)
 {
 CPUState *cs = env_cpu(env);
 
 /* Ignore MSR[EE] when coming out of some power management states */
 bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
 
-assert((env->pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
+assert((pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
 
 if (cs->halted) {
 if (env->spr[SPR_PSSCR] & PSSCR_EC) {
@@ -1933,7 +1936,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
  * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can
  * wakeup the processor
  */
-return p9_interrupt_powersave(env);
+return p9_interrupt_powersave(env, pending_interrupts);
 } else {
 /*
  * When it's clear, any system-caused exception exits power-saving
@@ -1944,12 +1947,12 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* Machine check exception */
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
 
 /* Hypervisor decrementer exception */
-if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
+if (pending_interrupts & PPC_INTERRUPT_HDECR) {
 /* LPCR will be clear when not supported so this will work */
 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
@@ -1959,7 +1962,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* Hypervisor virtualization interrupt */
-if (env->pending_inte

[PATCH v3 10/10] target/ppc: combine multiple ail checks into one

2024-09-12 Thread Harsh Prateek Bora
ppc_excp_apply_ail has multiple if-checks for ail which is un-necessary.
Combine them as appropriate.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 4dff5b..a8bd537a18 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -324,10 +324,7 @@ static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp, 
target_ulong msr,
 }
 
 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
-if (ail == 0) {
-return;
-}
-if (ail == 1) {
+if (ail == 0 || ail == 1) {
 /* AIL=1 is reserved, treat it like AIL=0 */
 return;
 }
@@ -351,10 +348,7 @@ static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp, 
target_ulong msr,
 } else {
 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
 }
-if (ail == 0) {
-return;
-}
-if (ail == 1 || ail == 2) {
+if (ail == 0 || ail == 1 || ail == 2) {
 /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */
 return;
 }
-- 
2.45.2




[PATCH v3 05/10] target/ppc: optimize p9 exception handling routines for lpcr

2024-09-12 Thread Harsh Prateek Bora
Like pending_interrupts, env->spr[SPR_LPCR] is being used at multiple
places across p9 exception handlers. Pass the value during entry and
avoid multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 33 ++---
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 31c1653e2b..c7641898ca 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1873,13 +1873,14 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
  PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
 
 static int p9_interrupt_powersave(CPUPPCState *env,
-  uint32_t pending_interrupts)
+  uint32_t pending_interrupts,
+  target_ulong lpcr)
 {
 
 /* External Exception */
 if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
-(env->spr[SPR_LPCR] & LPCR_EEE)) {
-bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+(lpcr & LPCR_EEE)) {
+bool heic = !!(lpcr & LPCR_HEIC);
 if (!heic || !FIELD_EX64_HV(env->msr) ||
 FIELD_EX64(env->msr, MSR, PR)) {
 return PPC_INTERRUPT_EXT;
@@ -1887,11 +1888,11 @@ static int p9_interrupt_powersave(CPUPPCState *env,
 }
 /* Decrementer Exception */
 if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
-(env->spr[SPR_LPCR] & LPCR_DEE)) {
+(lpcr & LPCR_DEE)) {
 return PPC_INTERRUPT_DECR;
 }
 /* Machine Check or Hypervisor Maintenance Exception */
-if (env->spr[SPR_LPCR] & LPCR_OEE) {
+if (lpcr & LPCR_OEE) {
 if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
@@ -1901,17 +1902,17 @@ static int p9_interrupt_powersave(CPUPPCState *env,
 }
 /* Privileged Doorbell Exception */
 if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
-(env->spr[SPR_LPCR] & LPCR_PDEE)) {
+(lpcr & LPCR_PDEE)) {
 return PPC_INTERRUPT_DOORBELL;
 }
 /* Hypervisor Doorbell Exception */
 if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
-(env->spr[SPR_LPCR] & LPCR_HDEE)) {
+(lpcr & LPCR_HDEE)) {
 return PPC_INTERRUPT_HDOORBELL;
 }
 /* Hypervisor virtualization exception */
 if ((pending_interrupts & PPC_INTERRUPT_HVIRT) &&
-(env->spr[SPR_LPCR] & LPCR_HVEE)) {
+(lpcr & LPCR_HVEE)) {
 return PPC_INTERRUPT_HVIRT;
 }
 if (pending_interrupts & PPC_INTERRUPT_RESET) {
@@ -1921,7 +1922,8 @@ static int p9_interrupt_powersave(CPUPPCState *env,
 }
 
 static int p9_next_unmasked_interrupt(CPUPPCState *env,
-  uint32_t pending_interrupts)
+  uint32_t pending_interrupts,
+  target_ulong lpcr)
 {
 CPUState *cs = env_cpu(env);
 
@@ -1936,7 +1938,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
  * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can
  * wakeup the processor
  */
-return p9_interrupt_powersave(env, pending_interrupts);
+return p9_interrupt_powersave(env, pending_interrupts, lpcr);
 } else {
 /*
  * When it's clear, any system-caused exception exits power-saving
@@ -1954,7 +1956,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
 /* Hypervisor decrementer exception */
 if (pending_interrupts & PPC_INTERRUPT_HDECR) {
 /* LPCR will be clear when not supported so this will work */
-bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
+bool hdice = !!(lpcr & LPCR_HDICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
 /* HDEC clears on delivery */
 return PPC_INTERRUPT_HDECR;
@@ -1964,7 +1966,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
 /* Hypervisor virtualization interrupt */
 if (pending_interrupts & PPC_INTERRUPT_HVIRT) {
 /* LPCR will be clear when not supported so this will work */
-bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
+bool hvice = !!(lpcr & LPCR_HVICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hvice) {
 return PPC_INTERRUPT_HVIRT;
 }
@@ -1972,8 +1974,8 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
 
 /* External interrupt can ignore MSR:EE under some circumstances */
 if (pending_interrupts & PPC_INTERRUPT_EXT) {
-bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
-bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+bool lpes0 = !!(lpcr & LPCR_LPES0);
+ 

[PATCH v3 01/10] target/ppc: use locally stored msr and avoid indirect access

2024-09-12 Thread Harsh Prateek Bora
hreg_compute_hflags_value already stores msr locally to be used in most
of the logic in the routine however some instances are still using
env->msr which is unnecessary. Use locally stored value as available.

Reviewed-by: Nicholas Piggin 
Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/helper_regs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 02076e96fb..fe543ab3b8 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -143,10 +143,10 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState 
*env)
 
 if (ppc_flags & POWERPC_FLAG_DE) {
 target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0];
-if ((dbcr0 & DBCR0_ICMP) && FIELD_EX64(env->msr, MSR, DE)) {
+if ((dbcr0 & DBCR0_ICMP) && FIELD_EX64(msr, MSR, DE)) {
 hflags |= 1 << HFLAGS_SE;
 }
-if ((dbcr0 & DBCR0_BRT) && FIELD_EX64(env->msr, MSR, DE)) {
+if ((dbcr0 & DBCR0_BRT) && FIELD_EX64(msr, MSR, DE)) {
 hflags |= 1 << HFLAGS_BE;
 }
 } else {
-- 
2.45.2




[PATCH v3 06/10] target/ppc: reduce duplicate code between init_proc_POWER{9, 10}

2024-09-12 Thread Harsh Prateek Bora
Historically, the registration of sprs have been inherited alongwith
every new Power arch support being added leading to a lot of code
duplication. It's time to do necessary cleanups now to avoid further
duplication with newer arch support being added.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/cpu_init.c | 58 +--
 1 file changed, 12 insertions(+), 46 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 9cb5dd4596..de1dd63bf7 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6410,7 +6410,7 @@ static struct ppc_radix_page_info POWER9_radix_page_info 
= {
 #endif /* CONFIG_USER_ONLY */
 
 #define POWER9_BHRB_ENTRIES_LOG2 5
-static void init_proc_POWER9(CPUPPCState *env)
+static void register_power9_common_sprs(CPUPPCState *env)
 {
 /* Common Registers */
 init_proc_book3s_common(env);
@@ -6429,7 +6429,6 @@ static void init_proc_POWER9(CPUPPCState *env)
 register_power5p_ear_sprs(env);
 register_power5p_tb_sprs(env);
 register_power6_common_sprs(env);
-register_HEIR32_spr(env);
 register_power6_dbg_sprs(env);
 register_power7_common_sprs(env);
 register_power8_tce_address_control_sprs(env);
@@ -6447,16 +6446,21 @@ static void init_proc_POWER9(CPUPPCState *env)
 register_power8_rpr_sprs(env);
 register_power9_mmu_sprs(env);
 
-/* POWER9 Specific registers */
-spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
- spr_read_generic, spr_write_generic,
- KVM_REG_PPC_TIDR, 0);
-
 /* FIXME: Filter fields properly based on privilege level */
 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
 spr_read_generic, spr_write_generic,
 KVM_REG_PPC_PSSCR, 0);
 
+}
+
+static void init_proc_POWER9(CPUPPCState *env)
+{
+register_power9_common_sprs(env);
+register_HEIR32_spr(env);
+/* POWER9 Specific registers */
+spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
+ spr_read_generic, spr_write_generic,
+ KVM_REG_PPC_TIDR, 0);
 /* env variables */
 env->dcache_line_size = 128;
 env->icache_line_size = 128;
@@ -6562,50 +6566,12 @@ static struct ppc_radix_page_info 
POWER10_radix_page_info = {
 #define POWER10_BHRB_ENTRIES_LOG2 5
 static void init_proc_POWER10(CPUPPCState *env)
 {
-/* Common Registers */
-init_proc_book3s_common(env);
-register_book3s_207_dbg_sprs(env);
-
-/* Common TCG PMU */
-init_tcg_pmu_power8(env);
-
-/* POWER8 Specific Registers */
-register_book3s_ids_sprs(env);
-register_amr_sprs(env);
-register_iamr_sprs(env);
-register_book3s_purr_sprs(env);
-register_power5p_common_sprs(env);
-register_power5p_lpar_sprs(env);
-register_power5p_ear_sprs(env);
-register_power5p_tb_sprs(env);
-register_power6_common_sprs(env);
+register_power9_common_sprs(env);
 register_HEIR64_spr(env);
-register_power6_dbg_sprs(env);
-register_power7_common_sprs(env);
-register_power8_tce_address_control_sprs(env);
-register_power8_ids_sprs(env);
-register_power8_ebb_sprs(env);
-register_power8_fscr_sprs(env);
-register_power8_pmu_sup_sprs(env);
-register_power8_pmu_user_sprs(env);
-register_power8_tm_sprs(env);
-register_power8_pspb_sprs(env);
-register_power8_dpdes_sprs(env);
-register_vtb_sprs(env);
-register_power8_ic_sprs(env);
-register_power9_book4_sprs(env);
-register_power8_rpr_sprs(env);
-register_power9_mmu_sprs(env);
 register_power10_hash_sprs(env);
 register_power10_dexcr_sprs(env);
 register_power10_pmu_sup_sprs(env);
 register_power10_pmu_user_sprs(env);
-
-/* FIXME: Filter fields properly based on privilege level */
-spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
-spr_read_generic, spr_write_generic,
-KVM_REG_PPC_PSSCR, 0);
-
 /* env variables */
 env->dcache_line_size = 128;
 env->icache_line_size = 128;
-- 
2.45.2




[PATCH v3 03/10] target/ppc: optimize hreg_compute_pmu_hflags_value

2024-09-12 Thread Harsh Prateek Bora
The second if-condition can be true only if the first one above is true.
Enclose the latter into the former to avoid un-necessary check if first
condition fails.

Reviewed-by: BALATON Zoltan 
Reviewed-by: Nicholas Piggin 
Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/helper_regs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 7b23e5ef0e..42c681ca4a 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -102,9 +102,9 @@ static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState 
*env)
 #ifndef CONFIG_USER_ONLY
 if (env->pmc_ins_cnt) {
 hflags |= 1 << HFLAGS_INSN_CNT;
-}
-if (env->pmc_ins_cnt & 0x1e) {
-hflags |= 1 << HFLAGS_PMC_OTHER;
+if (env->pmc_ins_cnt & 0x1e) {
+hflags |= 1 << HFLAGS_PMC_OTHER;
+}
 }
 #endif
 #endif
-- 
2.45.2




[PATCH v3 07/10] target/ppc: optimize p8 exception handling routines

2024-09-12 Thread Harsh Prateek Bora
Most of the p8 exception handling accesses env->pending_interrupts and
env->spr[SPR_LPCR] at multiple places. Passing it directly as local
variables simplifies the code and avoids multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 60 +---
 1 file changed, 32 insertions(+), 28 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index c7641898ca..c0828aac88 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1765,39 +1765,42 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env)
 PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL |  \
 PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
 
-static int p8_interrupt_powersave(CPUPPCState *env)
+static int p8_interrupt_powersave(uint32_t pending_interrupts,
+  target_ulong lpcr)
 {
-if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
-(env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
+if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
+(lpcr & LPCR_P8_PECE2)) {
 return PPC_INTERRUPT_EXT;
 }
-if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
-(env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
+if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
+(lpcr & LPCR_P8_PECE3)) {
 return PPC_INTERRUPT_DECR;
 }
-if ((env->pending_interrupts & PPC_INTERRUPT_MCK) &&
-(env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+if ((pending_interrupts & PPC_INTERRUPT_MCK) &&
+(lpcr & LPCR_P8_PECE4)) {
 return PPC_INTERRUPT_MCK;
 }
-if ((env->pending_interrupts & PPC_INTERRUPT_HMI) &&
-(env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+if ((pending_interrupts & PPC_INTERRUPT_HMI) &&
+(lpcr & LPCR_P8_PECE4)) {
 return PPC_INTERRUPT_HMI;
 }
-if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
-(env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
+if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
+(lpcr & LPCR_P8_PECE0)) {
 return PPC_INTERRUPT_DOORBELL;
 }
-if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
-(env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
+if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
+(lpcr & LPCR_P8_PECE1)) {
 return PPC_INTERRUPT_HDOORBELL;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+if (pending_interrupts & PPC_INTERRUPT_RESET) {
 return PPC_INTERRUPT_RESET;
 }
 return 0;
 }
 
-static int p8_next_unmasked_interrupt(CPUPPCState *env)
+static int p8_next_unmasked_interrupt(CPUPPCState *env,
+  uint32_t pending_interrupts,
+  target_ulong lpcr)
 {
 CPUState *cs = env_cpu(env);
 
@@ -1808,18 +1811,18 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
 
 if (cs->halted) {
 /* LPCR[PECE] controls which interrupts can exit power-saving mode */
-return p8_interrupt_powersave(env);
+return p8_interrupt_powersave(pending_interrupts, lpcr);
 }
 
 /* Machine check exception */
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
 
 /* Hypervisor decrementer exception */
-if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
+if (pending_interrupts & PPC_INTERRUPT_HDECR) {
 /* LPCR will be clear when not supported so this will work */
-bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
+bool hdice = !!(lpcr & LPCR_HDICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
 /* HDEC clears on delivery */
 return PPC_INTERRUPT_HDECR;
@@ -1827,9 +1830,9 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* External interrupt can ignore MSR:EE under some circumstances */
-if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
-bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
-bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+if (pending_interrupts & PPC_INTERRUPT_EXT) {
+bool lpes0 = !!(lpcr & LPCR_LPES0);
+bool heic = !!(lpcr & LPCR_HEIC);
 /* HEIC blocks delivery to the hypervisor */
 if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
 !FIELD_EX64(env->msr, MSR, PR))) ||
@@ -1839,20 +1842,20 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
 }
 if (msr_ee != 0) {
 /* Decrementer exception */
-if (env->pending_

[PATCH v3 00/10] misc ppc improvements/optimizations

2024-09-12 Thread Harsh Prateek Bora
This a set of misc ppc arch specific code improvements/optimizations.
This version of series extended improvements to p7 and p8 alongwith
additional minor improvements.

Since patch 7/7 of v2 series have been picked by Aditya in his patchset
for P11 support, I have excluded that patch in this series and based on
top of his v6 series which contains the required patch as 1/5.
Based on: <20240731055022.696051-1-adit...@linux.ibm.com>

Changelog:
v3: extended improvements to other Power arch p7, p8 (Nick)
other minor improvements
v2: addressed review comments from BALATON Zoltan
v1: Initial patch

Harsh Prateek Bora (10):
  target/ppc: use locally stored msr and avoid indirect access
  target/ppc: optimize hreg_compute_pmu_hflags_value
  target/ppc: optimize hreg_compute_pmu_hflags_value
  target/ppc: optimize p9 exception handling routines
  target/ppc: optimize p9 exception handling routines for lpcr
  target/ppc: reduce duplicate code between init_proc_POWER{9, 10}
  target/ppc: optimize p8 exception handling routines
  target/ppc: optimize p7 exception handling routines
  target/ppc: simplify var usage in ppc_next_unmasked_interrupt
  target/ppc: combine multiple ail checks into one

 target/ppc/cpu_init.c|  58 ++
 target/ppc/excp_helper.c | 230 ---
 target/ppc/helper_regs.c |  19 ++--
 3 files changed, 141 insertions(+), 166 deletions(-)

-- 
2.45.2




[PATCH v3 08/10] target/ppc: optimize p7 exception handling routines

2024-09-12 Thread Harsh Prateek Bora
Like p8 and p9, simplifying p7 exception handling rotuines to avoid
un-necessary multiple indirect accesses to env->pending_interrupts and
env->spr[SPR_LPCR].

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 46 ++--
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index c0828aac88..d0e0f609a0 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1683,51 +1683,54 @@ void ppc_cpu_do_interrupt(CPUState *cs)
  PPC_INTERRUPT_PIT | PPC_INTERRUPT_DOORBELL | PPC_INTERRUPT_HDOORBELL | \
  PPC_INTERRUPT_THERM | PPC_INTERRUPT_EBB)
 
-static int p7_interrupt_powersave(CPUPPCState *env)
+static int p7_interrupt_powersave(uint32_t pending_interrupts,
+  target_ulong lpcr)
 {
-if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
-(env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
+if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
+(lpcr & LPCR_P7_PECE0)) {
 return PPC_INTERRUPT_EXT;
 }
-if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
-(env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
+if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
+(lpcr & LPCR_P7_PECE1)) {
 return PPC_INTERRUPT_DECR;
 }
-if ((env->pending_interrupts & PPC_INTERRUPT_MCK) &&
-(env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
+if ((pending_interrupts & PPC_INTERRUPT_MCK) &&
+(lpcr & LPCR_P7_PECE2)) {
 return PPC_INTERRUPT_MCK;
 }
-if ((env->pending_interrupts & PPC_INTERRUPT_HMI) &&
-(env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
+if ((pending_interrupts & PPC_INTERRUPT_HMI) &&
+(lpcr & LPCR_P7_PECE2)) {
 return PPC_INTERRUPT_HMI;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+if (pending_interrupts & PPC_INTERRUPT_RESET) {
 return PPC_INTERRUPT_RESET;
 }
 return 0;
 }
 
-static int p7_next_unmasked_interrupt(CPUPPCState *env)
+static int p7_next_unmasked_interrupt(CPUPPCState *env,
+  uint32_t pending_interrupts,
+  target_ulong lpcr)
 {
 CPUState *cs = env_cpu(env);
 
 /* Ignore MSR[EE] when coming out of some power management states */
 bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
 
-assert((env->pending_interrupts & P7_UNUSED_INTERRUPTS) == 0);
+assert((pending_interrupts & P7_UNUSED_INTERRUPTS) == 0);
 
 if (cs->halted) {
 /* LPCR[PECE] controls which interrupts can exit power-saving mode */
-return p7_interrupt_powersave(env);
+return p7_interrupt_powersave(pending_interrupts, lpcr);
 }
 
 /* Machine check exception */
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
 
 /* Hypervisor decrementer exception */
-if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
+if (pending_interrupts & PPC_INTERRUPT_HDECR) {
 /* LPCR will be clear when not supported so this will work */
 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
@@ -1737,9 +1740,9 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* External interrupt can ignore MSR:EE under some circumstances */
-if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
-bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
-bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+if (pending_interrupts & PPC_INTERRUPT_EXT) {
+bool lpes0 = !!(lpcr & LPCR_LPES0);
+bool heic = !!(lpcr & LPCR_HEIC);
 /* HEIC blocks delivery to the hypervisor */
 if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
 !FIELD_EX64(env->msr, MSR, PR))) ||
@@ -1749,10 +1752,10 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env)
 }
 if (msr_ee != 0) {
 /* Decrementer exception */
-if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
+if (pending_interrupts & PPC_INTERRUPT_DECR) {
 return PPC_INTERRUPT_DECR;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
+if (pending_interrupts & PPC_INTERRUPT_PERFM) {
 return PPC_INTERRUPT_PERFM;
 }
 }
@@ -2022,7 +2025,8 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env)
 #ifdef TARGET_PPC64
 switch (env->excp_model) {
 case POWERPC_EXCP_POWER7:
-return p7_next_unmasked_interrupt(env);
+return p7_next_unmasked_interrupt(env, env->pending_interrupts,
+  env->spr[SPR_LPCR]);
 case POWERPC_EXCP_POWER8:
 return p8_next_unmasked_interrupt(env, env->pending_interrupts,
   env->spr[SPR_LPCR]);
-- 
2.45.2




Re: [PATCH v5 1/5] target/ppc: reduce code duplication across Power9/10 init code

2024-07-23 Thread Harsh Prateek Bora

Hi Aditya,

On 7/23/24 20:43, Aditya Gupta wrote:

Hi Harsh,


Is it okay if I do, the changes in your patch ?



Sure, feel free to update as suggested and add your sob mentioning the 
summary of updates.


Thanks
Harsh



Thanks,

Aditya Gupta


On 23/07/24 10:52, Nicholas Piggin wrote:

On Thu Jun 6, 2024 at 10:16 PM AEST, Aditya Gupta wrote:

From: Harsh Prateek Bora 

Power9/10 initialization code consists of a lot of logical OR of
various flag bits as supported by respective Power platform during its
initialization, most of which is duplicated and only selected bits are
added or removed as needed with each new platform support being added.
Remove the duplicate code and share using common macros.

Signed-off-by: Harsh Prateek Bora 
---
  target/ppc/cpu_init.c | 124 +-
  target/ppc/cpu_init.h |  78 ++
  2 files changed, 93 insertions(+), 109 deletions(-)
  create mode 100644 target/ppc/cpu_init.h

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 01e358a4a5ac..3d8a112935ae 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -51,6 +51,7 @@
  #include "kvm_ppc.h"
  #endif
+#include "cpu_init.h"
  /* #define PPC_DEBUG_SPR */
  /* #define USE_APPLE_GDB */
@@ -6508,58 +6509,15 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void 
*data)

  dc->fw_name = "PowerPC,POWER9";
  dc->desc = "POWER9";
  pcc->pvr_match = ppc_pvr_match_power9;
-    pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | 
PCR_COMPAT_2_07;
-    pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | 
PCR_COMPAT_2_06 |

- PCR_COMPAT_2_05;
+    pcc->pcr_mask = POWERPC_POWER9_PCC_PCR_MASK;
+    pcc->pcr_supported = POWERPC_POWER9_PCC_PCR_SUPPORTED;
  pcc->init_proc = init_proc_POWER9;
  pcc->check_pow = check_pow_nocheck;
  pcc->check_attn = check_attn_hid0_power9;
-    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | 
PPC_MFTB |

-   PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
-   PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
-   PPC_FLOAT_FRSQRTES |
-   PPC_FLOAT_STFIWX |
-   PPC_FLOAT_EXT |
-   PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
-   PPC_MEM_SYNC | PPC_MEM_EIEIO |
-   PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-   PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
-   PPC_SEGMENT_64B | PPC_SLBI |
-   PPC_POPCNTB | PPC_POPCNTWD |
-   PPC_CILDST;
-    pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
-    PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
-    PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
-    PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
-    PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
-    PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
-    PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | 
PPC2_MEM_LWSYNC |

-    PPC2_BCDA_ISA206;
-    pcc->msr_mask = (1ull << MSR_SF) |
-    (1ull << MSR_HV) |
-    (1ull << MSR_TM) |
-    (1ull << MSR_VR) |
-    (1ull << MSR_VSX) |
-    (1ull << MSR_EE) |
-    (1ull << MSR_PR) |
-    (1ull << MSR_FP) |
-    (1ull << MSR_ME) |
-    (1ull << MSR_FE0) |
-    (1ull << MSR_SE) |
-    (1ull << MSR_DE) |
-    (1ull << MSR_FE1) |
-    (1ull << MSR_IR) |
-    (1ull << MSR_DR) |
-    (1ull << MSR_PMM) |
-    (1ull << MSR_RI) |
-    (1ull << MSR_LE);
-    pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
-    (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
-    LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
-    (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
- LPCR_DEE | LPCR_OEE))
-    | LPCR_MER | LPCR_GTSE | LPCR_TC |
-    LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
+    pcc->insns_flags = POWERPC_FAMILY_POWER9_INSNS_FLAGS;
+    pcc->insns_flags2 = POWERPC_FAMILY_POWER9_INSNS_FLAGS2;
+    pcc->msr_mask = POWERPC_POWER9_PCC_MSR_MASK;
+    pcc->lpcr_mask = POWERPC_POWER9_PCC_LPCR_MASK;
  pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | 
LPCR_OEE;

  pcc->mmu_model = POWERPC_MMU_3_00;
  #if !defined(CONFIG_USER_ONLY)
@@ -6572,10 +6530,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void 
*data)

  pcc->excp_mo

Re: [PATCH V13 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-06-24 Thread Harsh Prateek Bora

+qemu-devel, qemu-ppc

Ping!

On 6/17/24 15:18, Harsh Prateek Bora wrote:


+ MST, Igor - to help with early review/merge. TIA.

On 6/14/24 16:06, Salil Mehta wrote:

Hello


  From: Harsh Prateek Bora 
  Sent: Friday, June 14, 2024 6:24 AM
  Hi Paolo, Nick,
  Can this patch 1/8 be merged earlier provided we have got 
sufficient R-bys

  for it and the review of entire series may take a longer time?
  We have some ppc64 patches based on it, hence the ask.
  Hi Salil,
  I am hoping we are not expecting anymore changes to this patch, please
  confirm.



I do not expect any change. I had requested Michael to merge the complete
series as it is stranding other users. He then requested Igor to take 
a final look but
he has not reverted yet. I'll remind Michael again. BTW, can you reply 
to below
patch explicitly indicating your interest in the series so that MST 
knows who else

are the stake holders here

https://lore.kernel.org/qemu-devel/20240605160327.3c71f...@imammedo.users.ipa.redhat.com/


Hi Paolo,

A request, would it be possible to skim through this series from KVM 
perspective?
(although nothing has changed which will affect the KVM and this is 
architecture

agnostic patch-set)

Many thanks!

Best
Salil.



  regards,
  Harsh
  On 6/7/24 17:26, Salil Mehta wrote:
  > KVM vCPU creation is done once during the vCPU realization when Qemu
  > vCPU thread is spawned. This is common to all the architectures 
as of now.

  >
  > Hot-unplug of vCPU results in destruction of the vCPU object in QOM
  > but the corresponding KVM vCPU object in the Host KVM is not 
destroyed
  > as KVM doesn't support vCPU removal. Therefore, its 
representative KVM

  > vCPU object/context in Qemu is parked.
  >
  > Refactor architecture common logic so that some APIs could be reused
  > by vCPU Hotplug code of some architectures likes ARM, Loongson etc.
  > Update new/old APIs with trace events. No functional change is 
intended

  here.
  >
  > Signed-off-by: Salil Mehta 
  > Reviewed-by: Gavin Shan 
  > Tested-by: Vishnu Pajjuri 
  > Reviewed-by: Jonathan Cameron 
  > Tested-by: Xianglai Li 
  > Tested-by: Miguel Luis 
  > Reviewed-by: Shaoqin Huang 
  > Reviewed-by: Vishnu Pajjuri 
  > Reviewed-by: Nicholas Piggin 
  > Tested-by: Zhao Liu 
  > Reviewed-by: Zhao Liu 
  > Reviewed-by: Harsh Prateek Bora 
  > ---
  >   accel/kvm/kvm-all.c    | 95 


  --
  >   accel/kvm/kvm-cpus.h   |  1 -
  >   accel/kvm/trace-events |  5 ++-
  >   include/sysemu/kvm.h   | 25 +++
  >   4 files changed, 92 insertions(+), 34 deletions(-)
  >
  > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
  > c0be9f5eed..8f9128bb92 100644
  > --- a/accel/kvm/kvm-all.c
  > +++ b/accel/kvm/kvm-all.c
  > @@ -340,14 +340,71 @@ err:
  >   return ret;
  >   }
  >
  > +void kvm_park_vcpu(CPUState *cpu)
  > +{
  > +    struct KVMParkedVcpu *vcpu;
  > +
  > +    trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
  > +
  > +    vcpu = g_malloc0(sizeof(*vcpu));
  > +    vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
  > +    vcpu->kvm_fd = cpu->kvm_fd;
  > +    QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node); }
  > +
  > +int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id) {
  > +    struct KVMParkedVcpu *cpu;
  > +    int kvm_fd = -ENOENT;
  > +
  > +    QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
  > +    if (cpu->vcpu_id == vcpu_id) {
  > +    QLIST_REMOVE(cpu, node);
  > +    kvm_fd = cpu->kvm_fd;
  > +    g_free(cpu);
  > +    }
  > +    }
  > +
  > +    trace_kvm_unpark_vcpu(vcpu_id, kvm_fd > 0 ? "unparked" : "not
  > + found parked");
  > +
  > +    return kvm_fd;
  > +}
  > +
  > +int kvm_create_vcpu(CPUState *cpu)
  > +{
  > +    unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
  > +    KVMState *s = kvm_state;
  > +    int kvm_fd;
  > +
  > +    /* check if the KVM vCPU already exist but is parked */
  > +    kvm_fd = kvm_unpark_vcpu(s, vcpu_id);
  > +    if (kvm_fd < 0) {
  > +    /* vCPU not parked: create a new KVM vCPU */
  > +    kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
  > +    if (kvm_fd < 0) {
  > +    error_report("KVM_CREATE_VCPU IOCTL failed for vCPU 
%lu",

  vcpu_id);
  > +    return kvm_fd;
  > +    }
  > +    }
  > +
  > +    cpu->kvm_fd = kvm_fd;
  > +    cpu->kvm_state = s;
  > +    cpu->vcpu_dirty = true;
  > +    cpu->dirty_pages = 0;
  > +    cpu->throttle_us_per_full = 0;
  > +
  > +    trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
  > +
  > +    return 0;
  > +}
  > +
  >   static 

Re: [PATCH 2/2] target/ppc/arch_dump: set prstatus pid to cpuid

2024-06-24 Thread Harsh Prateek Bora

Hi Omar,

On 6/19/24 10:30, Omar Sandoval wrote:

Every other architecture does this, and debuggers need it to be able to
identify which prstatus note corresponds to which CPU.

Signed-off-by: Omar Sandoval 
---
  target/ppc/arch_dump.c | 21 -
  1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
index a8315659d9..78b4205319 100644
--- a/target/ppc/arch_dump.c
+++ b/target/ppc/arch_dump.c
@@ -47,9 +47,11 @@ struct PPCUserRegStruct {
  } QEMU_PACKED;
  
  struct PPCElfPrstatus {

-char pad1[112];
+char pad1[32];
+uint32_t pid;
+uint8_t pad2[76];
  struct PPCUserRegStruct pr_reg;
-char pad2[40];
+char pad3[40];
  } QEMU_PACKED;
  


Could you please add a comment above the struct providing reference to 
the spec being referred here for member position across the status bits?


With that,

Reviewed-by: Harsh Prateek Bora 

  
@@ -96,7 +98,7 @@ typedef struct NoteFuncArg {

  DumpState *state;
  } NoteFuncArg;
  
-static void ppc_write_elf_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)

+static void ppc_write_elf_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu, int id)
  {
  int i;
  reg_t cr;
@@ -109,6 +111,7 @@ static void ppc_write_elf_prstatus(NoteFuncArg *arg, 
PowerPCCPU *cpu)
  
  prstatus = ¬e->contents.prstatus;

  memset(prstatus, 0, sizeof(*prstatus));
+prstatus->pid = cpu_to_dump32(s, id);
  reg = &prstatus->pr_reg;
  
  for (i = 0; i < 32; i++) {

@@ -127,7 +130,7 @@ static void ppc_write_elf_prstatus(NoteFuncArg *arg, 
PowerPCCPU *cpu)
  reg->ccr = cpu_to_dump_reg(s, cr);
  }
  
-static void ppc_write_elf_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)

+static void ppc_write_elf_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu, int id)
  {
  int i;
  struct PPCElfFpregset  *fpregset;
@@ -146,7 +149,7 @@ static void ppc_write_elf_fpregset(NoteFuncArg *arg, 
PowerPCCPU *cpu)
  fpregset->fpscr = cpu_to_dump_reg(s, cpu->env.fpscr);
  }
  
-static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)

+static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu, int id)
  {
  int i;
  struct PPCElfVmxregset *vmxregset;
@@ -178,7 +181,7 @@ static void ppc_write_elf_vmxregset(NoteFuncArg *arg, 
PowerPCCPU *cpu)
  vmxregset->vscr.u32[3] = cpu_to_dump32(s, ppc_get_vscr(&cpu->env));
  }
  
-static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)

+static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu, int id)
  {
  int i;
  struct PPCElfVsxregset *vsxregset;
@@ -195,7 +198,7 @@ static void ppc_write_elf_vsxregset(NoteFuncArg *arg, 
PowerPCCPU *cpu)
  }
  }
  
-static void ppc_write_elf_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)

+static void ppc_write_elf_speregset(NoteFuncArg *arg, PowerPCCPU *cpu, int id)
  {
  struct PPCElfSperegset *speregset;
  Note *note = &arg->note;
@@ -211,7 +214,7 @@ static void ppc_write_elf_speregset(NoteFuncArg *arg, 
PowerPCCPU *cpu)
  
  static const struct NoteFuncDescStruct {

  int contents_size;
-void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu);
+void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu, int id);
  } note_func[] = {
  {sizeof_field(Note, contents.prstatus),  ppc_write_elf_prstatus},
  {sizeof_field(Note, contents.fpregset),  ppc_write_elf_fpregset},
@@ -282,7 +285,7 @@ static int ppc_write_all_elf_notes(const char *note_name,
  arg.note.hdr.n_descsz = cpu_to_dump32(s, nf->contents_size);
  strncpy(arg.note.name, note_name, sizeof(arg.note.name));
  
-(*nf->note_contents_func)(&arg, cpu);

+(*nf->note_contents_func)(&arg, cpu, id);
  
  note_size =

  sizeof(arg.note) - sizeof(arg.note.contents) + nf->contents_size;




[PATCH v4 0/3] target/ppc: vcpu hotplug failure handling fixes

2024-06-18 Thread Harsh Prateek Bora
On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating and parking vcpu on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.

This series adds another helper to create and park vcpu, based on [1],
exports cpu_get_free_index to be reused later and adds ppc arch specfic
handling for vcpu hotplug failure using kvm accel helper cpu_target_realize.

[1] <20240607115649.214622-1-salil.me...@huawei.com> 

Changelog:
v4: rebased, comment update in patch 3, added R-bys.
v3: Addressed review comments from Nick
v2: Addressed review comments from Nick
v1: Initial patch

Harsh Prateek Bora (3):
  accel/kvm: Introduce kvm_create_and_park_vcpu() helper
  cpu-common.c: export cpu_get_free_index to be reused later
  target/ppc: handle vcpu hotplug failure gracefully

 include/exec/cpu-common.h |  2 ++
 include/sysemu/kvm.h  |  8 +++
 accel/kvm/kvm-all.c   | 12 ++
 cpu-common.c  |  7 +++---
 target/ppc/kvm.c  | 46 +++
 5 files changed, 72 insertions(+), 3 deletions(-)

-- 
2.45.1




[PATCH v4 1/3] accel/kvm: Introduce kvm_create_and_park_vcpu() helper

2024-06-18 Thread Harsh Prateek Bora
There are distinct helpers for creating and parking a KVM vCPU.
However, there can be cases where a platform needs to create and
immediately park the vCPU during early stages of vcpu init which
can later be reused when vcpu thread gets initialized. This would
help detect failures with kvm_create_vcpu at an early stage.

Suggested-by: Nicholas Piggin 
Reviewed-by: Nicholas Piggin 
Signed-off-by: Harsh Prateek Bora 

---
Based on: <20240607115649.214622-1-salil.me...@huawei.com>
---
---
 include/sysemu/kvm.h |  8 
 accel/kvm/kvm-all.c  | 12 
 2 files changed, 20 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index c4a914b3d8..9cf14ca3d5 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -338,6 +338,14 @@ void kvm_park_vcpu(CPUState *cpu);
  */
 int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
 
+/**
+ * kvm_create_and_park_vcpu - Create and park a KVM vCPU
+ * @cpu: QOM CPUState object for which KVM vCPU has to be created and parked.
+ *
+ * @returns: 0 when success, errno (<0) when failed.
+ */
+int kvm_create_and_park_vcpu(CPUState *cpu);
+
 /* Arch specific hooks */
 
 extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 4c5f521583..c0cbb6d480 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -398,6 +398,18 @@ int kvm_create_vcpu(CPUState *cpu)
 return 0;
 }
 
+int kvm_create_and_park_vcpu(CPUState *cpu)
+{
+int ret = 0;
+
+ret = kvm_create_vcpu(cpu);
+if (!ret) {
+kvm_park_vcpu(cpu);
+}
+
+return ret;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
-- 
2.45.1




[PATCH v4 2/3] cpu-common.c: export cpu_get_free_index to be reused later

2024-06-18 Thread Harsh Prateek Bora
This helper provides an easy way to identify the next available free cpu
index which can be used for vcpu creation. Until now, this is being
called at a very later stage and there is a need to be able to call it
earlier (for now, with ppc64) hence the need to export.

Suggested-by: Nicholas Piggin 
Reviewed-by: Nicholas Piggin 
Signed-off-by: Harsh Prateek Bora 
---
 include/exec/cpu-common.h | 2 ++
 cpu-common.c  | 7 ---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 240ee04369..2e1b499cb7 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -35,6 +35,8 @@ void cpu_list_lock(void);
 void cpu_list_unlock(void);
 unsigned int cpu_list_generation_id_get(void);
 
+int cpu_get_free_index(void);
+
 void tcg_iommu_init_notifier_list(CPUState *cpu);
 void tcg_iommu_free_notifier_list(CPUState *cpu);
 
diff --git a/cpu-common.c b/cpu-common.c
index ce78273af5..82bd1b432d 100644
--- a/cpu-common.c
+++ b/cpu-common.c
@@ -57,14 +57,12 @@ void cpu_list_unlock(void)
 qemu_mutex_unlock(&qemu_cpu_list_lock);
 }
 
-static bool cpu_index_auto_assigned;
 
-static int cpu_get_free_index(void)
+int cpu_get_free_index(void)
 {
 CPUState *some_cpu;
 int max_cpu_index = 0;
 
-cpu_index_auto_assigned = true;
 CPU_FOREACH(some_cpu) {
 if (some_cpu->cpu_index >= max_cpu_index) {
 max_cpu_index = some_cpu->cpu_index + 1;
@@ -83,8 +81,11 @@ unsigned int cpu_list_generation_id_get(void)
 
 void cpu_list_add(CPUState *cpu)
 {
+static bool cpu_index_auto_assigned;
+
 QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
 if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) {
+cpu_index_auto_assigned = true;
 cpu->cpu_index = cpu_get_free_index();
 assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX);
 } else {
-- 
2.45.1




[PATCH v4 3/3] target/ppc: handle vcpu hotplug failure gracefully

2024-06-18 Thread Harsh Prateek Bora
On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating and parking vcpu on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.

Also introducing KVM AccelCPUClass to init cpu_target_realize for kvm.

Tested OK by repeatedly doing a hotplug/unplug of vcpus as below:

 #virsh setvcpus hotplug 40
 #virsh setvcpus hotplug 70
error: internal error: unable to execute QEMU command 'device_add':
kvmppc_cpu_realize: vcpu hotplug failed with -12

Reported-by: Anushree Mathur 
Suggested-by: Shivaprasad G Bhat 
Suggested-by: Vaibhav Jain 
Tested-by: Anushree Mathur 
Reviewed-by: Nicholas Piggin 
Signed-off by: Harsh Prateek Bora 
---
 target/ppc/kvm.c | 46 ++
 1 file changed, 46 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 005f2239f3..77a3ebae22 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -48,6 +48,8 @@
 #include "qemu/mmap-alloc.h"
 #include "elf.h"
 #include "sysemu/kvm_int.h"
+#include "sysemu/kvm.h"
+#include "hw/core/accel-cpu.h"
 
 #include CONFIG_DEVICES
 
@@ -2346,6 +2348,30 @@ static void alter_insns(uint64_t *word, uint64_t flags, 
bool on)
 }
 }
 
+static bool kvmppc_cpu_realize(CPUState *cs, Error **errp)
+{
+int ret;
+const char *vcpu_str = (cs->parent_obj.hotplugged == true) ?
+   "hotplug" : "create";
+cs->cpu_index = cpu_get_free_index();
+
+POWERPC_CPU(cs)->vcpu_id = cs->cpu_index;
+
+/* create and park to fail gracefully in case vcpu hotplug fails */
+ret = kvm_create_and_park_vcpu(cs);
+if (ret) {
+/*
+ * This causes QEMU to terminate if initial CPU creation
+ * fails, and only CPU hotplug failure if the error happens
+ * there.
+ */
+error_setg(errp, "%s: vcpu %s failed with %d",
+ __func__, vcpu_str, ret);
+return false;
+}
+return true;
+}
+
 static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
 {
 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
@@ -2966,3 +2992,23 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t 
tb_offset)
 void kvm_arch_accel_class_init(ObjectClass *oc)
 {
 }
+
+static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data)
+{
+AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
+
+acc->cpu_target_realize = kvmppc_cpu_realize;
+}
+
+static const TypeInfo kvm_cpu_accel_type_info = {
+.name = ACCEL_CPU_NAME("kvm"),
+
+.parent = TYPE_ACCEL_CPU,
+.class_init = kvm_cpu_accel_class_init,
+.abstract = true,
+};
+static void kvm_cpu_accel_register_types(void)
+{
+type_register_static(&kvm_cpu_accel_type_info);
+}
+type_init(kvm_cpu_accel_register_types);
-- 
2.45.1




Re: [PATCH 00/26] hw/ppc: Prefer HumanReadableText over Monitor

2024-06-17 Thread Harsh Prateek Bora




On 6/10/24 11:50, Philippe Mathieu-Daudé wrote:

Hi,

This series remove uses of Monitor in hw/ppc/,
replacing by the more generic HumanReadableText.
Care is taken to keep the commit bisectables by
updating functions one by one, also easing review.

For rationale see previous series from Daniel:
https://lore.kernel.org/qemu-devel/20211028155457.967291-1-berra...@redhat.com/

Regards,

Phil.



For the series:

Reviewed-by: Harsh Prateek Bora 


Philippe Mathieu-Daudé (26):
   hw/ppc: Avoid using Monitor in pnv_phb3_msi_pic_print_info()
   hw/ppc: Avoid using Monitor in icp_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_tctx_pic_print_info()
   hw/ppc: Avoid using Monitor in ics_pic_print_info()
   hw/ppc: Avoid using Monitor in PnvChipClass::intc_print_info()
   hw/ppc: Avoid using Monitor in xive_end_queue_pic_print_info()
   hw/ppc: Avoid using Monitor in spapr_xive_end_pic_print_info()
   hw/ppc: Avoid using Monitor in spapr_xive_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_source_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_phb4_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_end_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_end_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_nvt_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_xive_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_psi_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_queue_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_nvp_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_xive2_pic_print_info()
   hw/ppc: Avoid using Monitor in
 SpaprInterruptControllerClass::print_info()
   hw/ppc: Avoid using Monitor in spapr_irq_print_info()
   hw/ppc: Avoid using Monitor in pnv_chip_power9_pic_print_info_child()
   hw/ppc: Avoid using Monitor in pic_print_info()

  include/hw/pci-host/pnv_phb3.h |   2 +-
  include/hw/pci-host/pnv_phb4.h |   2 +-
  include/hw/ppc/pnv_chip.h  |   4 +-
  include/hw/ppc/pnv_psi.h   |   2 +-
  include/hw/ppc/pnv_xive.h  |   4 +-
  include/hw/ppc/spapr_irq.h |   4 +-
  include/hw/ppc/xics.h  |   4 +-
  include/hw/ppc/xive.h  |   4 +-
  include/hw/ppc/xive2_regs.h|   8 +--
  include/hw/ppc/xive_regs.h |   8 +--
  hw/intc/pnv_xive.c |  38 ++--
  hw/intc/pnv_xive2.c|  48 +++
  hw/intc/spapr_xive.c   |  41 ++---
  hw/intc/xics.c |  25 
  hw/intc/xics_spapr.c   |   7 +--
  hw/intc/xive.c | 108 -
  hw/intc/xive2.c|  87 +-
  hw/pci-host/pnv_phb3_msi.c |  21 +++
  hw/pci-host/pnv_phb4.c |  17 +++---
  hw/ppc/pnv.c   |  52 
  hw/ppc/pnv_psi.c   |   9 ++-
  hw/ppc/spapr.c |  11 +++-
  hw/ppc/spapr_irq.c |   4 +-
  23 files changed, 256 insertions(+), 254 deletions(-)





Re: [PATCH 08/26] hw/ppc: Avoid using Monitor in spapr_xive_pic_print_info()

2024-06-17 Thread Harsh Prateek Bora




On 6/10/24 11:50, Philippe Mathieu-Daudé wrote:

@@ -203,10 +201,8 @@ static void spapr_xive_pic_print_info(SpaprXive *xive, 
Monitor *mon)
  spapr_xive_end_pic_print_info(xive, end, buf);
  }
  
-info = human_readable_text_from_str(buf);

-monitor_puts(mon, info->human_readable_text);
  }
-monitor_printf(mon, "\n");
+g_string_append_c(buf, '\n');


Ok, I see caller specific changes are done in separate patches.
Ideally one call flow could be squashed into a single patch, which would
help avoid addition, followed by removal of common logic like above.
However, assuming that would be increasing the patch size, I understand
smaller patches are easier to review.

Thanks
Harsh


  }
  }




Re: [PATCH 07/26] hw/ppc: Avoid using Monitor in spapr_xive_end_pic_print_info()

2024-06-17 Thread Harsh Prateek Bora




On 6/10/24 11:50, Philippe Mathieu-Daudé wrote:

@@ -198,13 +193,18 @@ static void spapr_xive_pic_print_info(SpaprXive *xive, 
Monitor *mon)
  if (!xive_eas_is_masked(eas)) {
  uint32_t end_idx = xive_get_field64(EAS_END_INDEX, eas->w);
  XiveEND *end;
+g_autoptr(GString) buf = g_string_new("");
+g_autoptr(HumanReadableText) info = NULL;
  
  assert(end_idx < xive->nr_ends);

  end = &xive->endt[end_idx];
  
  if (xive_end_is_valid(end)) {

-spapr_xive_end_pic_print_info(xive, end, mon);
+spapr_xive_end_pic_print_info(xive, end, buf);
  }
+
+info = human_readable_text_from_str(buf);
+monitor_puts(mon, info->human_readable_text);
  }
  monitor_printf(mon, "\n");


Similarly, this monitor_printf could be g_stringified before doing the 
human_readable logic ?


Thanks
Harsh

  }




Re: [PATCH 06/26] hw/ppc: Avoid using Monitor in xive_end_queue_pic_print_info()

2024-06-17 Thread Harsh Prateek Bora




On 6/10/24 11:50, Philippe Mathieu-Daudé wrote:

@@ -1389,8 +1392,10 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t 
end_idx, Monitor *mon)
  if (qaddr_base) {
  monitor_printf(mon, " eq:@%08"PRIx64"% 6d/%5d ^%d",
 qaddr_base, qindex, qentries, qgen);
-xive_end_queue_pic_print_info(end, 6, mon);
+xive_end_queue_pic_print_info(end, 6, buf);
  }
+info = human_readable_text_from_str(buf);
+monitor_puts(mon, info->human_readable_text);
  monitor_printf(mon, "\n");


This monitor_printf could also be folded in buf before info assignment ?


  }
  




Re: [PATCH 01/26] hw/ppc: Avoid using Monitor in pnv_phb3_msi_pic_print_info()

2024-06-17 Thread Harsh Prateek Bora




On 6/17/24 15:49, Harsh Prateek Bora wrote:

Hi Phillipe,

One query below:

On 6/17/24 15:41, Harsh Prateek Bora wrote:



On 6/10/24 11:50, Philippe Mathieu-Daudé wrote:

Replace Monitor API by HumanReadableText one.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Harsh Prateek Bora 


---
  include/hw/pci-host/pnv_phb3.h |  2 +-
  hw/pci-host/pnv_phb3_msi.c | 21 ++---
  hw/ppc/pnv.c   |  8 +++-
  3 files changed, 18 insertions(+), 13 deletions(-)






diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6e3a5ccdec..5356a4e295 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -38,6 +38,7 @@
  #include "hw/loader.h"
  #include "hw/nmi.h"
  #include "qapi/visitor.h"
+#include "qapi/type-helpers.h"
  #include "monitor/monitor.h"
  #include "hw/intc/intc.h"
  #include "hw/ipmi/ipmi.h"
@@ -774,8 +775,13 @@ static void 
pnv_chip_power8_pic_print_info(PnvChip *chip, Monitor *mon)

  for (i = 0; i < chip8->num_phbs; i++) {
  PnvPHB *phb = chip8->phbs[i];
  PnvPHB3 *phb3 = PNV_PHB3(phb->backend);
+    g_autoptr(GString) buf = g_string_new("");
+    g_autoptr(HumanReadableText) info = NULL;
+
+    pnv_phb3_msi_pic_print_info(&phb3->msis, buf);
+    info = human_readable_text_from_str(buf);
+    monitor_puts(mon, info->human_readable_text);
-    pnv_phb3_msi_pic_print_info(&phb3->msis, mon);
  ics_pic_print_info(&phb3->lsis, mon);


How is the memory allocated to info in human_readable_text_from_str 
being reclaimed here? Isnt it a mem leak ?



Ok, I see, g_autoptr takes care of auto cleanup. Please ignore.


Thanks
Harsh


  }
  }






Re: [PATCH 03/26] hw/ppc: Avoid using Monitor in xive_tctx_pic_print_info()

2024-06-17 Thread Harsh Prateek Bora

Hi Phillipe,

On 6/10/24 11:50, Philippe Mathieu-Daudé wrote:

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index fa23b27a2b..5854358f65 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1223,7 +1223,13 @@ static void pnv_chip_power9_intc_destroy(PnvChip *chip, 
PowerPCCPU *cpu)
  static void pnv_chip_power9_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
  Monitor *mon)
  {
-xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), mon);
+g_autoptr(GString) buf = g_string_new("");
+g_autoptr(HumanReadableText) info = NULL;
+
+xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), buf);
+
+info = human_readable_text_from_str(buf);
+monitor_puts(mon, info->human_readable_text);
  }
  
  static void pnv_chip_power10_intc_create(PnvChip *chip, PowerPCCPU *cpu,

@@ -1267,7 +1273,13 @@ static void pnv_chip_power10_intc_destroy(PnvChip *chip, 
PowerPCCPU *cpu)
  static void pnv_chip_power10_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
   Monitor *mon)
  {
-xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), mon);
+g_autoptr(GString) buf = g_string_new("");
+g_autoptr(HumanReadableText) info = NULL;
+
+xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), buf);
+
+info = human_readable_text_from_str(buf);
+monitor_puts(mon, info->human_readable_text);
  }
  


We have an existing code duplication in above two routines which is 
getting worse with these multi-lines getting duplicated. Could _power9_ 
be changed to inline and called from _power10_ as well?


Thanks
Harsh



Re: [PATCH 01/26] hw/ppc: Avoid using Monitor in pnv_phb3_msi_pic_print_info()

2024-06-17 Thread Harsh Prateek Bora

Hi Phillipe,

One query below:

On 6/17/24 15:41, Harsh Prateek Bora wrote:



On 6/10/24 11:50, Philippe Mathieu-Daudé wrote:

Replace Monitor API by HumanReadableText one.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Harsh Prateek Bora 


---
  include/hw/pci-host/pnv_phb3.h |  2 +-
  hw/pci-host/pnv_phb3_msi.c | 21 ++---
  hw/ppc/pnv.c   |  8 +++-
  3 files changed, 18 insertions(+), 13 deletions(-)






diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6e3a5ccdec..5356a4e295 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -38,6 +38,7 @@
  #include "hw/loader.h"
  #include "hw/nmi.h"
  #include "qapi/visitor.h"
+#include "qapi/type-helpers.h"
  #include "monitor/monitor.h"
  #include "hw/intc/intc.h"
  #include "hw/ipmi/ipmi.h"
@@ -774,8 +775,13 @@ static void 
pnv_chip_power8_pic_print_info(PnvChip *chip, Monitor *mon)

  for (i = 0; i < chip8->num_phbs; i++) {
  PnvPHB *phb = chip8->phbs[i];
  PnvPHB3 *phb3 = PNV_PHB3(phb->backend);
+    g_autoptr(GString) buf = g_string_new("");
+    g_autoptr(HumanReadableText) info = NULL;
+
+    pnv_phb3_msi_pic_print_info(&phb3->msis, buf);
+    info = human_readable_text_from_str(buf);
+    monitor_puts(mon, info->human_readable_text);
-    pnv_phb3_msi_pic_print_info(&phb3->msis, mon);
  ics_pic_print_info(&phb3->lsis, mon);


How is the memory allocated to info in human_readable_text_from_str 
being reclaimed here? Isnt it a mem leak ?


Thanks
Harsh


  }
  }






Re: [PATCH 01/26] hw/ppc: Avoid using Monitor in pnv_phb3_msi_pic_print_info()

2024-06-17 Thread Harsh Prateek Bora




On 6/10/24 11:50, Philippe Mathieu-Daudé wrote:

Replace Monitor API by HumanReadableText one.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Harsh Prateek Bora 


---
  include/hw/pci-host/pnv_phb3.h |  2 +-
  hw/pci-host/pnv_phb3_msi.c | 21 ++---
  hw/ppc/pnv.c   |  8 +++-
  3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/include/hw/pci-host/pnv_phb3.h b/include/hw/pci-host/pnv_phb3.h
index d62b3091ac..24ca3dddaa 100644
--- a/include/hw/pci-host/pnv_phb3.h
+++ b/include/hw/pci-host/pnv_phb3.h
@@ -40,7 +40,7 @@ void pnv_phb3_msi_update_config(Phb3MsiState *msis, uint32_t 
base,
  void pnv_phb3_msi_send(Phb3MsiState *msis, uint64_t addr, uint16_t data,
 int32_t dev_pe);
  void pnv_phb3_msi_ffi(Phb3MsiState *msis, uint64_t val);
-void pnv_phb3_msi_pic_print_info(Phb3MsiState *msis, Monitor *mon);
+void pnv_phb3_msi_pic_print_info(Phb3MsiState *msis, GString *buf);
  
  
  /*

diff --git a/hw/pci-host/pnv_phb3_msi.c b/hw/pci-host/pnv_phb3_msi.c
index a6d827f903..77d673da54 100644
--- a/hw/pci-host/pnv_phb3_msi.c
+++ b/hw/pci-host/pnv_phb3_msi.c
@@ -13,7 +13,6 @@
  #include "hw/pci-host/pnv_phb3.h"
  #include "hw/ppc/pnv.h"
  #include "hw/pci/msi.h"
-#include "monitor/monitor.h"
  #include "hw/irq.h"
  #include "hw/qdev-properties.h"
  #include "sysemu/reset.h"
@@ -316,13 +315,13 @@ static void pnv_phb3_msi_register_types(void)
  
  type_init(pnv_phb3_msi_register_types);
  
-void pnv_phb3_msi_pic_print_info(Phb3MsiState *msi, Monitor *mon)

+void pnv_phb3_msi_pic_print_info(Phb3MsiState *msi, GString *buf)
  {
  ICSState *ics = ICS(msi);
  int i;
  
-monitor_printf(mon, "ICS %4x..%4x %p\n",

-   ics->offset, ics->offset + ics->nr_irqs - 1, ics);
+g_string_append_printf(buf, "ICS %4x..%4x %p\n",
+   ics->offset, ics->offset + ics->nr_irqs - 1, ics);
  
  for (i = 0; i < ics->nr_irqs; i++) {

  uint64_t ive;
@@ -335,12 +334,12 @@ void pnv_phb3_msi_pic_print_info(Phb3MsiState *msi, 
Monitor *mon)
  continue;
  }
  
-monitor_printf(mon, "  %4x %c%c server=%04x prio=%02x gen=%d\n",

-   ics->offset + i,
-   GETFIELD(IODA2_IVT_P, ive) ? 'P' : '-',
-   GETFIELD(IODA2_IVT_Q, ive) ? 'Q' : '-',
-   (uint32_t) GETFIELD(IODA2_IVT_SERVER, ive) >> 2,
-   (uint32_t) GETFIELD(IODA2_IVT_PRIORITY, ive),
-   (uint32_t) GETFIELD(IODA2_IVT_GEN, ive));
+g_string_append_printf(buf, "  %4x %c%c server=%04x prio=%02x 
gen=%d\n",
+   ics->offset + i,
+   GETFIELD(IODA2_IVT_P, ive) ? 'P' : '-',
+   GETFIELD(IODA2_IVT_Q, ive) ? 'Q' : '-',
+   (uint32_t) GETFIELD(IODA2_IVT_SERVER, ive) >> 2,
+   (uint32_t) GETFIELD(IODA2_IVT_PRIORITY, ive),
+   (uint32_t) GETFIELD(IODA2_IVT_GEN, ive));
  }
  }
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6e3a5ccdec..5356a4e295 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -38,6 +38,7 @@
  #include "hw/loader.h"
  #include "hw/nmi.h"
  #include "qapi/visitor.h"
+#include "qapi/type-helpers.h"
  #include "monitor/monitor.h"
  #include "hw/intc/intc.h"
  #include "hw/ipmi/ipmi.h"
@@ -774,8 +775,13 @@ static void pnv_chip_power8_pic_print_info(PnvChip *chip, 
Monitor *mon)
  for (i = 0; i < chip8->num_phbs; i++) {
  PnvPHB *phb = chip8->phbs[i];
  PnvPHB3 *phb3 = PNV_PHB3(phb->backend);
+g_autoptr(GString) buf = g_string_new("");
+g_autoptr(HumanReadableText) info = NULL;
+
+pnv_phb3_msi_pic_print_info(&phb3->msis, buf);
+info = human_readable_text_from_str(buf);
+monitor_puts(mon, info->human_readable_text);
  
-pnv_phb3_msi_pic_print_info(&phb3->msis, mon);

  ics_pic_print_info(&phb3->lsis, mon);
  }
  }




Re: [PATCH v4 01/11] ppc: Add Power11 DD2.0 processor

2024-05-30 Thread Harsh Prateek Bora




On 5/30/24 12:18, Aditya Gupta wrote:

Hello Harsh,

On Thu, May 30, 2024 at 10:57:31AM GMT, Harsh Prateek Bora wrote:

Hi Aditya,

On 5/28/24 12:35, Aditya Gupta wrote:

Add CPU target code to add support for new Power11 Processor.

Power11 core is same as Power10, hence reuse functions defined for
Power10.

Cc: Cédric Le Goater 
Cc: Daniel Henrique Barboza 
Cc: Frédéric Barrat 
Cc: Mahesh J Salgaonkar 
Cc: Madhavan Srinivasan 
Cc: Nicholas Piggin 
Signed-off-by: Aditya Gupta 
---
   target/ppc/compat.c |   7 +++
   target/ppc/cpu-models.c |   3 ++
   target/ppc/cpu-models.h |   3 ++
   target/ppc/cpu_init.c   | 102 
   4 files changed, 115 insertions(+)

diff --git a/target/ppc/compat.c b/target/ppc/compat.c
index ebef2cccecf3..12dd8ae290ca 100644
--- a/target/ppc/compat.c
+++ b/target/ppc/compat.c
@@ -100,6 +100,13 @@ static const CompatInfo compat_table[] = {
   .pcr_level = PCR_COMPAT_3_10,
   .max_vthreads = 8,
   },
+{ /* POWER11, ISA3.10 */
+.name = "power11",
+.pvr = CPU_POWERPC_LOGICAL_3_10_PLUS,
+.pcr = PCR_COMPAT_3_10,
+.pcr_level = PCR_COMPAT_3_10,
+.max_vthreads = 8,
+},
   };
   static const CompatInfo *compat_by_pvr(uint32_t pvr)
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index f2301b43f78b..ece348178188 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -734,6 +734,8 @@
   "POWER9 v2.2")
   POWERPC_DEF("power10_v2.0",  CPU_POWERPC_POWER10_DD20,   POWER10,
   "POWER10 v2.0")
+POWERPC_DEF("power11_v2.0",  CPU_POWERPC_POWER11_DD20,   POWER11,
+"POWER11_v2.0")
   #endif /* defined (TARGET_PPC64) */
   /***/
@@ -909,6 +911,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
   { "power8nvl", "power8nvl_v1.0" },
   { "power9", "power9_v2.2" },
   { "power10", "power10_v2.0" },
+{ "power11", "power11_v2.0" },
   #endif
   /* Generic PowerPCs */
diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
index 0229ef3a9a5c..ef74e387b047 100644
--- a/target/ppc/cpu-models.h
+++ b/target/ppc/cpu-models.h
@@ -354,6 +354,8 @@ enum {
   CPU_POWERPC_POWER10_BASE   = 0x0080,
   CPU_POWERPC_POWER10_DD1= 0x00801100,
   CPU_POWERPC_POWER10_DD20   = 0x00801200,
+CPU_POWERPC_POWER11_BASE   = 0x0082,
+CPU_POWERPC_POWER11_DD20   = 0x00821200,
   CPU_POWERPC_970_v22= 0x00390202,
   CPU_POWERPC_970FX_v10  = 0x00391100,
   CPU_POWERPC_970FX_v20  = 0x003C0200,
@@ -391,6 +393,7 @@ enum {
   CPU_POWERPC_LOGICAL_2_07   = 0x0F04,
   CPU_POWERPC_LOGICAL_3_00   = 0x0F05,
   CPU_POWERPC_LOGICAL_3_10   = 0x0F06,
+CPU_POWERPC_LOGICAL_3_10_PLUS  = 0x0F07,
   };
   /* System version register (used on MPC 8xxx)
*/
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 01e358a4a5ac..82d700382cdd 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6763,6 +6763,108 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
   pcc->l1_icache_size = 0x8000;
   }
+static bool ppc_pvr_match_power11(PowerPCCPUClass *pcc, uint32_t pvr, bool 
best)
+{
+uint32_t base = pvr & CPU_POWERPC_POWER_SERVER_MASK;
+uint32_t pcc_base = pcc->pvr & CPU_POWERPC_POWER_SERVER_MASK;
+
+if (!best && (base == CPU_POWERPC_POWER11_BASE)) {


Also, this helper is almost same as that of power10 except for the base 
check against respective value. This entire logic can be shared by 
passing respective base value to the another low level routine which 
takes this base value as arg. Let's try to avoid code duplication by 
resharing as much as possible.


Thanks
Harsh


+return true;
+}
+
+if (base != pcc_base) {
+return false;
+}
+
+if ((pvr & 0x0f00) == (pcc->pvr & 0x0f00)) {
+return true;
+}
+
+return false;
+}
+
+POWERPC_FAMILY(POWER11)(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+dc->fw_name = "PowerPC,POWER11";
+dc->desc = "POWER11";
+pcc->pvr_match = ppc_pvr_match_power11;
+pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
+PCR_COMPAT_3_00;
+pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
+ PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
+pcc->init_proc = init_proc_POWER10;
+pcc->check_pow = check_pow_nocheck;
+pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MF

Re: [PATCH 1/2] hw/acpi: Remove the deprecated QAPI MEM_UNPLUG_ERROR event

2024-05-30 Thread Harsh Prateek Bora




On 5/30/24 12:45, Philippe Mathieu-Daudé wrote:

The MEM_UNPLUG_ERROR event is deprecated since commit d43f1670c7
("qapi/qdev.json: add DEVICE_UNPLUG_GUEST_ERROR QAPI event"),
time to remove it.

Signed-off-by: Philippe Mathieu-Daudé 
---
  docs/about/deprecated.rst   |  5 -
  docs/about/removed-features.rst |  9 +
  qapi/machine.json   | 28 
  hw/acpi/memory_hotplug.c|  8 
  hw/ppc/spapr.c  | 11 +--
  5 files changed, 10 insertions(+), 51 deletions(-)



For spapr:
Reviewed-by: Harsh Prateek Bora 


diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 40585ca7d5..4a61894db6 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -151,11 +151,6 @@ property types.
  QEMU Machine Protocol (QMP) events
  --
  
-``MEM_UNPLUG_ERROR`` (since 6.2)

-''''''''''''''''''''''''''''''''''''''''''''''''''''''''
-
-Use the more generic event ``DEVICE_UNPLUG_GUEST_ERROR`` instead.
-
  ``vcpu`` trace events (since 8.1)
  '''''''''''''''''''''''''''''''''
  
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst

index fba0cfb0b0..f1e70263e2 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -671,6 +671,15 @@ Use ``multifd-channels`` instead.
  
  Use ``multifd-compression`` instead.
  
+QEMU Machine Protocol (QMP) events

+--
+
+``MEM_UNPLUG_ERROR`` (removed in 9.1)
+'''''''''''''''''''''''''''''''''''''
+
+MEM_UNPLUG_ERROR has been replaced by the more generic 
``DEVICE_UNPLUG_GUEST_ERROR`` event.
+
+
  Human Monitor Protocol (HMP) commands
  -
  
diff --git a/qapi/machine.json b/qapi/machine.json

index bce6e1bbc4..453feb9347 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1607,34 +1607,6 @@
  { 'event': 'MEMORY_DEVICE_SIZE_CHANGE',
'data': { '*id': 'str', 'size': 'size', 'qom-path' : 'str'} }
  
-##

-# @MEM_UNPLUG_ERROR:
-#
-# Emitted when memory hot unplug error occurs.
-#
-# @device: device name
-#
-# @msg: Informative message
-#
-# Features:
-#
-# @deprecated: This event is deprecated.  Use
-# @DEVICE_UNPLUG_GUEST_ERROR instead.
-#
-# Since: 2.4
-#
-# Example:
-#
-# <- { "event": "MEM_UNPLUG_ERROR",
-#  "data": { "device": "dimm1",
-#"msg": "acpi: device unplug for unsupported device"
-#  },
-#  "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-##
-{ 'event': 'MEM_UNPLUG_ERROR',
-  'data': { 'device': 'str', 'msg': 'str' },
-  'features': ['deprecated'] }
-
  ##
  # @BootConfiguration:
  #
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index de6f974ebb..9b974b7274 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -178,14 +178,6 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr 
addr, uint64_t data,
  hotplug_handler_unplug(hotplug_ctrl, dev, &local_err);
  if (local_err) {
  trace_mhp_acpi_pc_dimm_delete_failed(mem_st->selector);
-
-/*
- * Send both MEM_UNPLUG_ERROR and DEVICE_UNPLUG_GUEST_ERROR
- * while the deprecation of MEM_UNPLUG_ERROR is
- * pending.
- */
-qapi_event_send_mem_unplug_error(dev->id ? : "",
- error_get_pretty(local_err));
  qapi_event_send_device_unplug_guest_error(dev->id,

dev->canonical_path);
  error_free(local_err);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4345764bce..81a187f126 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3786,7 +3786,6 @@ void spapr_memory_unplug_rollback(SpaprMachineState 
*spapr, DeviceState *dev)
  SpaprDrc *drc;
  uint32_t nr_lmbs;
  uint64_t size, addr_start, addr;
-g_autofree char *qapi_error = NULL;
  int i;
  
  if (!dev) {

@@ -3823,16 +3822,8 @@ void spapr_memory_unplug_rollback(SpaprMachineState 
*spapr, DeviceState *dev)
  
  /*

   * Tell QAPI that something happened and the memory
- * hotunplug wasn't successful. Keep sending
- * MEM_UNPLUG_ERROR even while sending
- * DEVICE_UNPLUG_GUEST_ERROR until the deprecation of
- * MEM_UNPLUG_ERROR is due.
+ * hotunplug wasn't successful.
   */
-qapi_error = g_strdup_printf("Memory hotunplug rejected by the guest "
- "for device %s", dev->id);
-
-qapi_event_send_mem_unplug_error(dev->id ? : "", qapi_error);
-
  qapi_event_send_device_unplug_guest_error(dev->id,
dev->canonical_path);
  }




Re: [PATCH v4 02/11] ppc/pseries: Add Power11 cpu type

2024-05-30 Thread Harsh Prateek Bora




On 5/28/24 12:35, Aditya Gupta wrote:

Add sPAPR CPU Core definition for Power11

Cc: David Gibson  (reviewer:sPAPR (pseries))
Cc: Harsh Prateek Bora  (reviewer:sPAPR (pseries))
Cc: Cédric Le Goater 
Cc: Daniel Henrique Barboza 
Cc: Frédéric Barrat 
Cc: Mahesh J Salgaonkar 
Cc: Madhavan Srinivasan 
Cc: Nicholas Piggin 
Signed-off-by: Aditya Gupta 
---
  docs/system/ppc/pseries.rst | 6 +++---
  hw/ppc/spapr_cpu_core.c | 1 +
  2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/docs/system/ppc/pseries.rst b/docs/system/ppc/pseries.rst
index a876d897b6e4..3277564b34c2 100644
--- a/docs/system/ppc/pseries.rst
+++ b/docs/system/ppc/pseries.rst
@@ -15,9 +15,9 @@ Supported devices
  =
  
   * Multi processor support for many Power processors generations: POWER7,

-   POWER7+, POWER8, POWER8NVL, POWER9, and Power10. Support for POWER5+ exists,
-   but its state is unknown.
- * Interrupt Controller, XICS (POWER8) and XIVE (POWER9 and Power10)
+   POWER7+, POWER8, POWER8NVL, POWER9, Power10 and Power11. Support for POWER5+
+   exists, but its state is unknown.
+ * Interrupt Controller, XICS (POWER8) and XIVE (POWER9, Power10, Power11)


I think it would look more cleaner to rephrase as below:

 * Multi processor support for many Power processors generations:
   - POWER7, POWER7+
   - POWER8, POWER8NVL
   - POWER9
   - Power10
   - Power11.
   - Support for POWER5+ exists, but its state is unknown.
 * Interrupt Controller
- XICS (POWER8)
- XIVE (Supported by below:)
- POWER9
- Power10
- Power11

So, that every next platform just need to add one line for itself.

With that,
Reviewed-by: Harsh Prateek Bora 

Thanks
Harsh

   * vPHB PCIe Host bridge.
   * vscsi and vnet devices, compatible with the same devices available on a
 PowerVM hypervisor with VIOS managing LPARs.
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index e7c9edd033c8..62416b7e0a7e 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -401,6 +401,7 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
  DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"),
  DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.2"),
  DEFINE_SPAPR_CPU_CORE_TYPE("power10_v2.0"),
+DEFINE_SPAPR_CPU_CORE_TYPE("power11_v2.0"),
  #ifdef CONFIG_KVM
  DEFINE_SPAPR_CPU_CORE_TYPE("host"),
  #endif




Re: [PATCH v4 01/11] ppc: Add Power11 DD2.0 processor

2024-05-29 Thread Harsh Prateek Bora

Hi Aditya,

On 5/28/24 12:35, Aditya Gupta wrote:

Add CPU target code to add support for new Power11 Processor.

Power11 core is same as Power10, hence reuse functions defined for
Power10.

Cc: Cédric Le Goater 
Cc: Daniel Henrique Barboza 
Cc: Frédéric Barrat 
Cc: Mahesh J Salgaonkar 
Cc: Madhavan Srinivasan 
Cc: Nicholas Piggin 
Signed-off-by: Aditya Gupta 
---
  target/ppc/compat.c |   7 +++
  target/ppc/cpu-models.c |   3 ++
  target/ppc/cpu-models.h |   3 ++
  target/ppc/cpu_init.c   | 102 
  4 files changed, 115 insertions(+)

diff --git a/target/ppc/compat.c b/target/ppc/compat.c
index ebef2cccecf3..12dd8ae290ca 100644
--- a/target/ppc/compat.c
+++ b/target/ppc/compat.c
@@ -100,6 +100,13 @@ static const CompatInfo compat_table[] = {
  .pcr_level = PCR_COMPAT_3_10,
  .max_vthreads = 8,
  },
+{ /* POWER11, ISA3.10 */
+.name = "power11",
+.pvr = CPU_POWERPC_LOGICAL_3_10_PLUS,
+.pcr = PCR_COMPAT_3_10,
+.pcr_level = PCR_COMPAT_3_10,
+.max_vthreads = 8,
+},
  };
  
  static const CompatInfo *compat_by_pvr(uint32_t pvr)

diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index f2301b43f78b..ece348178188 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -734,6 +734,8 @@
  "POWER9 v2.2")
  POWERPC_DEF("power10_v2.0",  CPU_POWERPC_POWER10_DD20,   POWER10,
  "POWER10 v2.0")
+POWERPC_DEF("power11_v2.0",  CPU_POWERPC_POWER11_DD20,   POWER11,
+"POWER11_v2.0")
  #endif /* defined (TARGET_PPC64) */
  
  /***/

@@ -909,6 +911,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
  { "power8nvl", "power8nvl_v1.0" },
  { "power9", "power9_v2.2" },
  { "power10", "power10_v2.0" },
+{ "power11", "power11_v2.0" },
  #endif
  
  /* Generic PowerPCs */

diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
index 0229ef3a9a5c..ef74e387b047 100644
--- a/target/ppc/cpu-models.h
+++ b/target/ppc/cpu-models.h
@@ -354,6 +354,8 @@ enum {
  CPU_POWERPC_POWER10_BASE   = 0x0080,
  CPU_POWERPC_POWER10_DD1= 0x00801100,
  CPU_POWERPC_POWER10_DD20   = 0x00801200,
+CPU_POWERPC_POWER11_BASE   = 0x0082,
+CPU_POWERPC_POWER11_DD20   = 0x00821200,
  CPU_POWERPC_970_v22= 0x00390202,
  CPU_POWERPC_970FX_v10  = 0x00391100,
  CPU_POWERPC_970FX_v20  = 0x003C0200,
@@ -391,6 +393,7 @@ enum {
  CPU_POWERPC_LOGICAL_2_07   = 0x0F04,
  CPU_POWERPC_LOGICAL_3_00   = 0x0F05,
  CPU_POWERPC_LOGICAL_3_10   = 0x0F06,
+CPU_POWERPC_LOGICAL_3_10_PLUS  = 0x0F07,
  };
  
  /* System version register (used on MPC 8xxx)*/

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 01e358a4a5ac..82d700382cdd 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6763,6 +6763,108 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
  pcc->l1_icache_size = 0x8000;
  }
  
+static bool ppc_pvr_match_power11(PowerPCCPUClass *pcc, uint32_t pvr, bool best)

+{
+uint32_t base = pvr & CPU_POWERPC_POWER_SERVER_MASK;
+uint32_t pcc_base = pcc->pvr & CPU_POWERPC_POWER_SERVER_MASK;
+
+if (!best && (base == CPU_POWERPC_POWER11_BASE)) {
+return true;
+}
+
+if (base != pcc_base) {
+return false;
+}
+
+if ((pvr & 0x0f00) == (pcc->pvr & 0x0f00)) {
+return true;
+}
+
+return false;
+}
+
+POWERPC_FAMILY(POWER11)(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+dc->fw_name = "PowerPC,POWER11";
+dc->desc = "POWER11";
+pcc->pvr_match = ppc_pvr_match_power11;
+pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
+PCR_COMPAT_3_00;
+pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
+ PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
+pcc->init_proc = init_proc_POWER10;
+pcc->check_pow = check_pow_nocheck;
+pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
+   PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+   PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+   PPC_FLOAT_FRSQRTES |
+   PPC_FLOAT_STFIWX |
+   PPC_FLOAT_EXT |
+   PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+   PPC_MEM_SYNC | PPC_MEM_EIEIO |
+   PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+   PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
+   PPC_SEGMENT_64B | PPC_SLBI |
+   PPC_POPCNTB | PPC_POPCNTWD |
+   PPC_CILDST;
+pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | 

Re: [PATCH V12 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-29 Thread Harsh Prateek Bora




On 5/30/24 05:12, Salil Mehta wrote:

KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
Reviewed-by: Nicholas Piggin 
Tested-by: Zhao Liu 
Reviewed-by: Zhao Liu 
---
  accel/kvm/kvm-all.c| 95 --
  accel/kvm/kvm-cpus.h   | 23 ++
  accel/kvm/trace-events |  5 ++-
  3 files changed, 90 insertions(+), 33 deletions(-)



Since there are no functional changes intended here and we have a
different patch series (ppc64 vcpu hotplug failure fixes) depending on
this patch as well, it will be nice to see this patch getting merged
soon.

Reviewed-by: Harsh Prateek Bora 


diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c0be9f5eed..8f9128bb92 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -340,14 +340,71 @@ err:
  return ret;
  }
  
+void kvm_park_vcpu(CPUState *cpu)

+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
+{
+struct KVMParkedVcpu *cpu;
+int kvm_fd = -ENOENT;
+
+QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
+if (cpu->vcpu_id == vcpu_id) {
+QLIST_REMOVE(cpu, node);
+kvm_fd = cpu->kvm_fd;
+g_free(cpu);
+}
+}
+
+trace_kvm_unpark_vcpu(vcpu_id, kvm_fd > 0 ? "unparked" : "not found 
parked");
+
+return kvm_fd;
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_unpark_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
+
+return 0;
+}
+
  static int do_kvm_destroy_vcpu(CPUState *cpu)
  {
  KVMState *s = kvm_state;
  long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
  int ret = 0;
  
-trace_kvm_destroy_vcpu();

+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
  
  ret = kvm_arch_destroy_vcpu(cpu);

  if (ret < 0) {
@@ -373,10 +430,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
  }
  }
  
-vcpu = g_malloc0(sizeof(*vcpu));

-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
  err:
  return ret;
  }
@@ -389,24 +443,6 @@ void kvm_destroy_vcpu(CPUState *cpu)
  }
  }
  
-static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)

-{
-struct KVMParkedVcpu *cpu;
-
-QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
-if (cpu->vcpu_id == vcpu_id) {
-int kvm_fd;
-
-QLIST_REMOVE(cpu, node);
-kvm_fd = cpu->kvm_fd;
-g_free(cpu);
-return kvm_fd;
-}
-}
-
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
-}
-
  int kvm_init_vcpu(CPUState *cpu, Error **errp)
  {
  KVMState *s = kvm_state;
@@ -415,19 +451,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
  
  trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
  
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));

+ret = kvm_create_vcpu(cpu);
  if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  

Re: [RFC PATCH 08/10] ppc/pnv: Invert the design for big-core machine modelling

2024-05-29 Thread Harsh Prateek Bora

Hi Nick,

On 5/26/24 17:56, Nicholas Piggin wrote:

POWER9 and POWER10 machines come in two variants, "big-core" and
"small-core".

Big core machines are SMT8 from the software point of view, but in the
low level platform topology ("xscom registers and pervasive
addressing"), these look more like a pair of small cores ganged
together.

Presently, the way this is modelled is to create an SMT8 PnvCore and
add special cases to xscom and pervasive for big-core mode. This is
becoming too complicated to manage as more of the machine is modelled.
The better approach looks like the inverse, which is creating 2xPnvCore
ganging them together to look like an SMT8 core in TCG. The TCG SMT code
is quite simple to do that, and then the xscom and pervasive modelling
does not need to differentiate big and small core modes for the most
part.

device-tree building does need a special case to only build one
CPU node for each big-core because that's what the firmware expects.
And so does a special case workaround in the ChipTOD model.

A big-core machine option is added for powernv9 and 10 machines.

Signed-off-by: Nicholas Piggin 
---
  include/hw/ppc/pnv.h |   3 +
  include/hw/ppc/pnv_core.h|   8 ++
  target/ppc/cpu.h |   4 +-
  hw/ppc/pnv.c | 183 ---
  hw/ppc/pnv_core.c|  20 +++-
  hw/ppc/spapr_cpu_core.c  |   6 +-
  target/ppc/misc_helper.c |   6 +-
  target/ppc/timebase_helper.c |   9 ++
  8 files changed, 197 insertions(+), 42 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 476b136146..93ecb062b4 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -100,6 +100,9 @@ struct PnvMachineState {
  PnvPnor  *pnor;
  
  hwaddr   fw_load_addr;

+
+bool big_core;
+bool big_core_tbst_quirk;
  };
  
  PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id);

diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index 21297262c1..39f8f33e6c 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -27,6 +27,13 @@
  
  /* ChipTOD and TimeBase State Machine */

  struct pnv_tod_tbst {
+/*
+ * POWER10 DD2.0 - big core TFMR drives the state machine on the even
+ * small core. Skiboot has a workaround that targets the even small core
+ * for CHIPTOD_TO_TB ops.
+ */
+bool big_core_quirk;
+
  int tb_ready_for_tod; /* core TB ready to receive TOD from chiptod */
  int tod_sent_to_tb;   /* chiptod sent TOD to the core TB */
  
@@ -49,6 +56,7 @@ struct PnvCore {
  
  /*< public >*/

  PowerPCCPU **threads;
+bool big_core;
  uint32_t pir;
  uint32_t hwid;
  uint64_t hrmor;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 8fd6ade471..de15e38af8 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1248,6 +1248,7 @@ struct CPUArchState {
  int access_type;
  
  /* For SMT processors */

+int has_smt_siblings;


   bool ?


  int core_index;
  
  #if !defined(CONFIG_USER_ONLY)

@@ -1276,7 +1277,6 @@ struct CPUArchState {
  uint32_t tlb_need_flush; /* Delayed flush needed */
  #define TLB_NEED_LOCAL_FLUSH   0x1
  #define TLB_NEED_GLOBAL_FLUSH  0x2
-
  #endif
  
  /* Other registers */

@@ -1407,7 +1407,7 @@ struct CPUArchState {
  };
  
  #define PPC_CPU_HAS_CORE_SIBLINGS(cs)   \

-(cs->nr_threads > 1)
+(POWERPC_CPU(cs)->env.has_smt_siblings)
  
  #define PPC_CPU_HAS_LPAR_SIBLINGS(cs)   \

  ((POWERPC_CPU(cs)->env.flags & POWERPC_FLAG_SMT_1LPAR) &&   \
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 7d062ec16c..5364c55bbb 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -142,7 +142,7 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  CPUPPCState *env = &cpu->env;
  PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
  PnvChipClass *pnv_cc = PNV_CHIP_GET_CLASS(chip);
-g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
+uint32_t *servers_prop;
  int i;
  uint32_t pir, tir;
  uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
@@ -157,6 +157,14 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  
  pnv_cc->processor_id(chip, pc->hwid, 0, &pir, &tir);
  
+/* Only one DT node per (big) core */

+if (tir != 0) {
+g_assert(pc->big_core);
+g_assert(tir == 1);
+g_assert(pc->hwid & 1) > +return -1;
+}
+
  nodename = g_strdup_printf("%s@%x", dc->fw_name, pir);
  offset = fdt_add_subnode(fdt, cpus_offset, nodename);
  _FDT(offset);
@@ -236,12 +244,28 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  }
  
  /* Build interrupt servers properties */

-for (i = 0; i < smt_threads; i++) {
-pnv_cc->processor_id(chip, pc->hwid, i, &pir, &tir);
-servers_prop[i] = cpu_to_be32(pir);
+if (pc->big_core) {
+servers_prop = g_ne

Re: [RFC PATCH 07/10] target/ppc: Add helpers to check for SMT sibling threads

2024-05-28 Thread Harsh Prateek Bora




On 5/26/24 17:56, Nicholas Piggin wrote:

Add helpers for TCG code to determine if there are SMT siblings
sharing per-core and per-lpar registers. This simplifies the
callers and makes SMT register topology simpler to modify with
later changes.

Signed-off-by: Nicholas Piggin 
---
  target/ppc/cpu.h |  7 +++
  target/ppc/cpu_init.c|  2 +-
  target/ppc/excp_helper.c | 16 +++-
  target/ppc/misc_helper.c | 27 ++-
  target/ppc/timebase_helper.c | 20 +++-
  5 files changed, 28 insertions(+), 44 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 9a89083932..8fd6ade471 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1406,6 +1406,13 @@ struct CPUArchState {
  uint64_t pmu_base_time;
  };
  
+#define PPC_CPU_HAS_CORE_SIBLINGS(cs)   \

+(cs->nr_threads > 1)
+
+#define PPC_CPU_HAS_LPAR_SIBLINGS(cs)   \
+((POWERPC_CPU(cs)->env.flags & POWERPC_FLAG_SMT_1LPAR) &&   \
+ PPC_CPU_HAS_CORE_SIBLINGS(cs))
+
  #define _CORE_ID(cs)\
  (POWERPC_CPU(cs)->env.core_index)
  
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c

index ae483e20c4..e71ee008ed 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6975,7 +6975,7 @@ static void ppc_cpu_realize(DeviceState *dev, Error 
**errp)
  
  pcc->parent_realize(dev, errp);
  
-if (env_cpu(env)->nr_threads > 1) {

+if (PPC_CPU_HAS_CORE_SIBLINGS(cs)) {
  env->flags |= POWERPC_FLAG_SMT;
  }
  
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c

index 0cd542675f..fd45da0f2b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -3029,7 +3029,7 @@ void helper_book3s_msgsnd(CPUPPCState *env, target_ulong 
rb)
  brdcast = true;
  }
  
-if (cs->nr_threads == 1 || !brdcast) {

+if (!PPC_CPU_HAS_CORE_SIBLINGS(cs) || !brdcast) {


Since there are multiple usage of above macro in negation below as well, 
we may probably want to introduce another macro PPC_CPU_HAS_SINGLE_CORE

which checks only for nr_threads == 1. Anyways,

Reviewed-by: Harsh Prateek Bora 



  ppc_set_irq(cpu, PPC_INTERRUPT_HDOORBELL, 1);
  return;
  }
@@ -3067,21 +3067,19 @@ void helper_book3s_msgsndp(CPUPPCState *env, 
target_ulong rb)
  CPUState *cs = env_cpu(env);
  PowerPCCPU *cpu = env_archcpu(env);
  CPUState *ccs;
-uint32_t nr_threads = cs->nr_threads;
  int ttir = rb & PPC_BITMASK(57, 63);
  
  helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
  
-if (!(env->flags & POWERPC_FLAG_SMT_1LPAR)) {

-nr_threads = 1; /* msgsndp behaves as 1-thread in LPAR-per-thread 
mode*/
-}
-
-if (!dbell_type_server(rb) || ttir >= nr_threads) {
+if (!dbell_type_server(rb)) {
  return;
  }
  
-if (nr_threads == 1) {

-ppc_set_irq(cpu, PPC_INTERRUPT_DOORBELL, 1);
+/* msgsndp behaves as 1-thread in LPAR-per-thread mode*/
+if (!PPC_CPU_HAS_LPAR_SIBLINGS(cs)) {
+if (ttir == 0) {
+ppc_set_irq(cpu, PPC_INTERRUPT_DOORBELL, 1);
+}
  return;
  }
  
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c

index 46ba3a5584..598c956cdd 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -49,9 +49,8 @@ void helper_spr_core_write_generic(CPUPPCState *env, uint32_t 
sprn,
  {
  CPUState *cs = env_cpu(env);
  CPUState *ccs;
-uint32_t nr_threads = cs->nr_threads;
  
-if (nr_threads == 1) {

+if (!PPC_CPU_HAS_CORE_SIBLINGS(cs)) {
  env->spr[sprn] = val;
  return;
  }
@@ -196,7 +195,7 @@ void helper_store_ptcr(CPUPPCState *env, target_ulong val)
  return;
  }
  
-if (cs->nr_threads == 1 || !(env->flags & POWERPC_FLAG_SMT_1LPAR)) {

+if (!PPC_CPU_HAS_LPAR_SIBLINGS(cs)) {
  env->spr[SPR_PTCR] = val;
  tlb_flush(cs);
  } else {
@@ -243,16 +242,12 @@ target_ulong helper_load_dpdes(CPUPPCState *env)
  {
  CPUState *cs = env_cpu(env);
  CPUState *ccs;
-uint32_t nr_threads = cs->nr_threads;
  target_ulong dpdes = 0;
  
  helper_hfscr_facility_check(env, HFSCR_MSGP, "load DPDES", HFSCR_IC_MSGP);
  
-if (!(env->flags & POWERPC_FLAG_SMT_1LPAR)) {

-nr_threads = 1; /* DPDES behaves as 1-thread in LPAR-per-thread mode */
-}
-
-if (nr_threads == 1) {
+/* DPDES behaves as 1-thread in LPAR-per-thread mode */
+if (!PPC_CPU_HAS_LPAR_SIBLINGS(cs)) {
  if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
  dpdes = 1;
  }
@@ -279,21 +274,11 @@ void helper_store_dpdes(CPUPPCState *env, target_ulong 
val)
  PowerPCCPU *cpu = env_archcpu(env);
  CPUState *cs = env_cp

Re: [RFC PATCH 06/10] ppc: Add a core_index to CPUPPCState for SMT vCPUs

2024-05-28 Thread Harsh Prateek Bora

corrected typo, it's bitwise.

On 5/28/24 14:18, Harsh Prateek Bora wrote:
-    (POWERPC_CPU(cs)->env.spr_cb[SPR_PIR].default_value & 
~(cs->nr_threads - 1))

+    (POWERPC_CPU(cs)->env.core_index)


Dont we want to keep the bitwise & with ~(cs->nr_threads - 1) ?
How's it taken care ?




Re: [RFC PATCH 06/10] ppc: Add a core_index to CPUPPCState for SMT vCPUs

2024-05-28 Thread Harsh Prateek Bora




On 5/26/24 17:56, Nicholas Piggin wrote:

The way SMT thread siblings are matched is clunky, using hard-coded
logic that checks the PIR SPR.

Change that to use a new core_index variable in the CPUPPCState,
where all siblings have the same core_index. CPU realize routines have
flexibility in setting core/sibling topology.

Signed-off-by: Nicholas Piggin 
---
  target/ppc/cpu.h| 5 -
  hw/ppc/pnv_core.c   | 2 ++
  hw/ppc/spapr_cpu_core.c | 3 +++
  3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index dac13d4dac..9a89083932 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1247,6 +1247,9 @@ struct CPUArchState {
  /* when a memory exception occurs, the access type is stored here */
  int access_type;
  
+/* For SMT processors */

+int core_index;
+
  #if !defined(CONFIG_USER_ONLY)
  /* MMU context, only relevant for full system emulation */
  #if defined(TARGET_PPC64)
@@ -1404,7 +1407,7 @@ struct CPUArchState {
  };
  
  #define _CORE_ID(cs)\

-(POWERPC_CPU(cs)->env.spr_cb[SPR_PIR].default_value & ~(cs->nr_threads - 
1))
+(POWERPC_CPU(cs)->env.core_index)


Dont we want to keep the logical & with ~(cs->nr_threads - 1) ?
How's it taken care ?

  
  #define THREAD_SIBLING_FOREACH(cs, cs_sibling)  \

  CPU_FOREACH(cs_sibling) \
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 9b5edd9e48..0f61aabb77 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -252,6 +252,8 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU 
*cpu, Error **errp,
  pir_spr->default_value = pir;
  tir_spr->default_value = tir;
  
+env->core_index = core_hwid;

+
  /* Set time-base frequency to 512 MHz */
  cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ);
  }
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index e7c9edd033..059d372c8a 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -300,16 +300,19 @@ static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, 
int i, Error **errp)
  g_autofree char *id = NULL;
  CPUState *cs;
  PowerPCCPU *cpu;
+CPUPPCState *env;
  
  obj = object_new(scc->cpu_type);
  
  cs = CPU(obj);

  cpu = POWERPC_CPU(obj);
+env = &cpu->env;
  /*
   * All CPUs start halted. CPU0 is unhalted from the machine level reset 
code
   * and the rest are explicitly started up by the guest using an RTAS call.
   */
  qdev_prop_set_bit(DEVICE(obj), "start-powered-off", true);
+env->core_index = cc->core_id;


We could just do cpu->env.core_index and avoid creating local var env.

regards,
Harsh


  cs->cpu_index = cc->core_id + i;
  if (!spapr_set_vcpu_id(cpu, cs->cpu_index, errp)) {
  return NULL;




Re: [RFC PATCH 05/10] ppc/pnv: Extend chip_pir class method to TIR as well

2024-05-28 Thread Harsh Prateek Bora




On 5/26/24 17:56, Nicholas Piggin wrote:

The chip_pir chip class method allows the platform to set the PIR
processor identification register. Extend this to a more general
ID function which also allows the TIR to be set. This is in
preparation for "big core", which is a more complicated topology
of cores and threads.

Signed-off-by: Nicholas Piggin 
---
  include/hw/ppc/pnv_chip.h |  3 +-
  hw/ppc/pnv.c  | 61 ---
  hw/ppc/pnv_core.c | 10 ---
  3 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 8589f3291e..679723926a 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -147,7 +147,8 @@ struct PnvChipClass {
  
  DeviceRealize parent_realize;
  
-uint32_t (*chip_pir)(PnvChip *chip, uint32_t core_id, uint32_t thread_id);

+void (*processor_id)(PnvChip *chip, uint32_t core_id, uint32_t thread_id,
+ uint32_t *pir, uint32_t *tir);


Should it be named get_chip_core_thread_regs() ?


  void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp);
  void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu);
  void (*intc_destroy)(PnvChip *chip, PowerPCCPU *cpu);
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index a706de2e36..7d062ec16c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -144,7 +144,7 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  PnvChipClass *pnv_cc = PNV_CHIP_GET_CLASS(chip);
  g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
  int i;
-uint32_t pir;
+uint32_t pir, tir;
  uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
 0x, 0x};
  uint32_t tbfreq = PNV_TIMEBASE_FREQ;
@@ -155,7 +155,7 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  char *nodename;
  int cpus_offset = get_cpus_node(fdt);
  
-pir = pnv_cc->chip_pir(chip, pc->hwid, 0);

+pnv_cc->processor_id(chip, pc->hwid, 0, &pir, &tir);


As a generic helper API and potentially expandable, it should allow 
passing NULL for registers whose values are not really sought to avoid 
having to create un-necessary local variables by the caller.


regards,
Harsh
  
  nodename = g_strdup_printf("%s@%x", dc->fw_name, pir);

  offset = fdt_add_subnode(fdt, cpus_offset, nodename);
@@ -237,7 +237,8 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  
  /* Build interrupt servers properties */

  for (i = 0; i < smt_threads; i++) {
-servers_prop[i] = cpu_to_be32(pnv_cc->chip_pir(chip, pc->hwid, i));
+pnv_cc->processor_id(chip, pc->hwid, i, &pir, &tir);
+servers_prop[i] = cpu_to_be32(pir);
  }
  _FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
 servers_prop, sizeof(*servers_prop) * smt_threads)));
@@ -249,14 +250,17 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t 
hwid,
 uint32_t nr_threads)
  {
  PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
-uint32_t pir = pcc->chip_pir(chip, hwid, 0);
-uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12);
+uint32_t pir, tir;
+uint64_t addr;
  char *name;
  const char compat[] = "IBM,power8-icp\0IBM,ppc-xicp";
  uint32_t irange[2], i, rsize;
  uint64_t *reg;
  int offset;
  
+pcc->processor_id(chip, hwid, 0, &pir, &tir);

+addr = PNV_ICP_BASE(chip) | (pir << 12);
+
  irange[0] = cpu_to_be32(pir);
  irange[1] = cpu_to_be32(nr_threads);
  
@@ -1104,10 +1108,12 @@ static void pnv_power10_init(MachineState *machine)

   *   25:28  Core number
   *   29:31  Thread ID
   */
-static uint32_t pnv_chip_pir_p8(PnvChip *chip, uint32_t core_id,
-uint32_t thread_id)
+static void pnv_processor_id_p8(PnvChip *chip,
+uint32_t core_id, uint32_t thread_id,
+uint32_t *pir, uint32_t *tir)
  {
-return (chip->chip_id << 7) | (core_id << 3) | thread_id;
+*pir = (chip->chip_id << 7) | (core_id << 3) | thread_id;
+*tir = thread_id;
  }
  
  static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu,

@@ -1159,15 +1165,17 @@ static void pnv_chip_power8_intc_print_info(PnvChip 
*chip, PowerPCCPU *cpu,
   *
   * We only care about the lower bits. uint32_t is fine for the moment.
   */
-static uint32_t pnv_chip_pir_p9(PnvChip *chip, uint32_t core_id,
-uint32_t thread_id)
+static void pnv_processor_id_p9(PnvChip *chip,
+uint32_t core_id, uint32_t thread_id,
+uint32_t *pir, uint32_t *tir)
  {
  if (chip->nr_threads == 8) {
-return (chip->chip_id << 8) | ((thread_id & 1) << 2) | (core_id << 3) |
+*pir = (chip->chip_id << 8) | ((thread_id & 1) << 2) | (core_id << 3) |
 (thread_id >> 1);
   

Re: [RFC PATCH 04/10] ppc/pnv: specialise init for powernv8/9/10 machines

2024-05-28 Thread Harsh Prateek Bora

Hi Nick,

On 5/26/24 17:56, Nicholas Piggin wrote:

This will allow different settings and checks for different
machine types with later changes.

Signed-off-by: Nicholas Piggin 
---
  hw/ppc/pnv.c | 35 ++-
  1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6e3a5ccdec..a706de2e36 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -976,11 +976,6 @@ static void pnv_init(MachineState *machine)
  pnv->num_chips =
  machine->smp.max_cpus / (machine->smp.cores * machine->smp.threads);
  
-if (machine->smp.threads > 8) {

-error_report("Cannot support more than 8 threads/core "
- "on a powernv machine");
-exit(1);
-}
  if (!is_power_of_2(machine->smp.threads)) {
  error_report("Cannot support %d threads/core on a powernv"
   "machine because it must be a power of 2",
@@ -1076,6 +1071,33 @@ static void pnv_init(MachineState *machine)
  }
  }
  
+static void pnv_power8_init(MachineState *machine)

+{
+if (machine->smp.threads > 8) {
+error_report("Cannot support more than 8 threads/core "
+ "on a powernv POWER8 machine");


We could use mc->desc for machine name above, so that ..


+exit(1);
+}


with this patch, we can reuse p8 init for both p9 and p10 (and not just 
reuse p9 for p10 with hard coded string?).


With that,
Reviewed-by: Harsh Prateek Bora 


+
+pnv_init(machine);
+}
+
+static void pnv_power9_init(MachineState *machine)
+{
+if (machine->smp.threads > 8) {
+error_report("Cannot support more than 8 threads/core "
+ "on a powernv9/10 machine");
+exit(1);
+}
+
+pnv_init(machine);
+}
+
+static void pnv_power10_init(MachineState *machine)
+{
+pnv_power9_init(machine);
+}
+
  /*
   *0:21  Reserved - Read as zeros
   *   22:24  Chip ID
@@ -2423,6 +2445,7 @@ static void pnv_machine_power8_class_init(ObjectClass 
*oc, void *data)
  };
  
  mc->desc = "IBM PowerNV (Non-Virtualized) POWER8";

+mc->init = pnv_power8_init;
  mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
  compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
  
@@ -2449,6 +2472,7 @@ static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)

  };
  
  mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";

+mc->init = pnv_power9_init;
  mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.2");
  compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
  
@@ -2473,6 +2497,7 @@ static void pnv_machine_p10_common_class_init(ObjectClass *oc, void *data)

  { TYPE_PNV_PHB_ROOT_PORT, "version", "5" },
  };
  
+mc->init = pnv_power10_init;

  mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v2.0");
  compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
  




Re: [RFC PATCH 03/10] target/ppc: Improve SPR indirect registers

2024-05-27 Thread Harsh Prateek Bora



Hi Nick,

On 5/26/24 17:56, Nicholas Piggin wrote:

SPRC/SPRD were recently added to all BookS CPUs supported, but
they are only tested on POWER9 and POWER10, so restrict them to
those CPUs.



Hope you mean to restrict to P9/10 for both spapr and pnv or just pnv ?


SPR indirect scratch registers presently replicated per-CPU like
SMT SPRs, but the PnvCore is a better place for them since they
are restricted to P9/P10.

Also add SPR indirect read access to core thread state for POWER9
since skiboot accesses that when booting to check for big-core
mode.

Signed-off-by: Nicholas Piggin 
---
  include/hw/ppc/pnv_core.h |  1 +
  target/ppc/cpu.h  |  3 --
  target/ppc/cpu_init.c | 21 ++--
  target/ppc/misc_helper.c  | 67 ---
  4 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index f434c71547..21297262c1 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -53,6 +53,7 @@ struct PnvCore {
  uint32_t hwid;
  uint64_t hrmor;
  
+target_ulong scratch[8]; /* SCRATCH registers */

  struct pnv_tod_tbst pnv_tod_tbst;
  
  PnvChip *chip;

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 1e86658da6..dac13d4dac 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1253,9 +1253,6 @@ struct CPUArchState {
  ppc_slb_t slb[MAX_SLB_ENTRIES]; /* PowerPC 64 SLB area */
  struct CPUBreakpoint *ciabr_breakpoint;
  struct CPUWatchpoint *dawr0_watchpoint;
-
-/* POWER CPU regs/state */
-target_ulong scratch[8]; /* SCRATCH registers (shared across core) */
  #endif
  target_ulong sr[32];   /* segment registers */
  uint32_t nb_BATs;  /* number of BATs */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 01e358a4a5..ae483e20c4 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -5759,16 +5759,6 @@ static void register_power_common_book4_sprs(CPUPPCState 
*env)
   SPR_NOACCESS, SPR_NOACCESS,
   &spr_read_generic, &spr_core_write_generic,
   0x);
-spr_register_hv(env, SPR_POWER_SPRC, "SPRC",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_sprc,
- 0x);
-spr_register_hv(env, SPR_POWER_SPRD, "SPRD",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_sprd, &spr_write_sprd,
- 0x);
  #endif
  }
  
@@ -5781,6 +5771,17 @@ static void register_power9_book4_sprs(CPUPPCState *env)

   SPR_NOACCESS, SPR_NOACCESS,
   &spr_read_generic, &spr_write_generic,
   KVM_REG_PPC_WORT, 0);
+/* SPRC/SPRD exist in earlier CPUs but only tested on POWER9/10 */
+spr_register_hv(env, SPR_POWER_SPRC, "SPRC",
+ SPR_NOACCESS, SPR_NOACCESS,
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_sprc,
+ 0x);
+spr_register_hv(env, SPR_POWER_SPRD, "SPRD",
+ SPR_NOACCESS, SPR_NOACCESS,
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_sprd, &spr_write_sprd,
+ 0x);
  #endif
  }
  
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c

index fa47be2298..46ba3a5584 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -26,6 +26,7 @@
  #include "qemu/main-loop.h"
  #include "mmu-book3s-v3.h"
  #include "hw/ppc/ppc.h"
+#include "hw/ppc/pnv_core.h"
  
  #include "helper_regs.h"
  
@@ -321,11 +322,25 @@ void helper_store_sprc(CPUPPCState *env, target_ulong val)
  
  target_ulong helper_load_sprd(CPUPPCState *env)

  {
+PowerPCCPU *cpu = env_archcpu(env);
+PnvCore *pc = pnv_cpu_state(cpu)->core;


We may want to avoid creating local variable cpu here also like previous 
patches.


However, is this helper meant to be accessible for spapr as well ?


  target_ulong sprc = env->spr[SPR_POWER_SPRC];
  
-switch (sprc & 0x3c0) {

-case 0: /* SCRATCH0-7 */
-return env->scratch[(sprc >> 3) & 0x7];
+switch (sprc & 0x3e0) {
+case 0: /* SCRATCH0-3 */
+case 1: /* SCRATCH4-7 */
+return pc->scratch[(sprc >> 3) & 0x7];


If so, will pc be uninitialized in case of spapr ?


+case 0x1e0: /* core thread state */
+if (env->excp_model == POWERPC_EXCP_POWER9) {
+/*
+ * Only implement for POWER9 because skiboot uses it to check
+ * big-core mode. Other bits are unimplemented so we would
+ * prefer to get unimplemented message on POWER10 if it were
+ * used.
+ */
+return 0;
+}
+/* fallthru */
  default:
  qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"

Re: [RFC PATCH 02/10] ppc/pnv: Move timebase state into PnvCore

2024-05-27 Thread Harsh Prateek Bora
(PowerPCCPU *cpu)

+{
+PnvCore *pc = pnv_cpu_state(cpu)->core;
+
+return &pc->pnv_tod_tbst;
+}
+
  static void tb_state_machine_step(CPUPPCState *env)
  {
+PowerPCCPU *cpu = env_archcpu(env);
+struct pnv_tod_tbst *pnv_tod_tbst = cpu_get_tbst(cpu);


Since cpu is not used anywhere later, we could just do 
cpu_get_tbst(env_archcpu(env)) ?



  uint64_t tfmr = env->spr[SPR_TFMR];
  unsigned int tbst = tfmr_get_tb_state(tfmr);
  
@@ -307,15 +317,15 @@ static void tb_state_machine_step(CPUPPCState *env)

  return;
  }
  
-if (env->pnv_tod_tbst.tb_sync_pulse_timer) {

-env->pnv_tod_tbst.tb_sync_pulse_timer--;
+if (pnv_tod_tbst->tb_sync_pulse_timer) {
+pnv_tod_tbst->tb_sync_pulse_timer--;
  } else {
  tfmr |= TFMR_TB_SYNC_OCCURED;
  write_tfmr(env, tfmr);
  }
  
-if (env->pnv_tod_tbst.tb_state_timer) {

-env->pnv_tod_tbst.tb_state_timer--;
+if (pnv_tod_tbst->tb_state_timer) {
+pnv_tod_tbst->tb_state_timer--;
  return;
  }
  
@@ -332,20 +342,20 @@ static void tb_state_machine_step(CPUPPCState *env)

  } else if (tfmr & TFMR_MOVE_CHIP_TOD_TO_TB) {
  if (tbst == TBST_SYNC_WAIT) {
  tfmr = tfmr_new_tb_state(tfmr, TBST_GET_TOD);
-env->pnv_tod_tbst.tb_state_timer = 3;
+pnv_tod_tbst->tb_state_timer = 3;
  } else if (tbst == TBST_GET_TOD) {
-if (env->pnv_tod_tbst.tod_sent_to_tb) {
+if (pnv_tod_tbst->tod_sent_to_tb) {
  tfmr = tfmr_new_tb_state(tfmr, TBST_TB_RUNNING);
  tfmr &= ~TFMR_MOVE_CHIP_TOD_TO_TB;
-env->pnv_tod_tbst.tb_ready_for_tod = 0;
-env->pnv_tod_tbst.tod_sent_to_tb = 0;
+pnv_tod_tbst->tb_ready_for_tod = 0;
+pnv_tod_tbst->tod_sent_to_tb = 0;
  }
  } else {
  qemu_log_mask(LOG_GUEST_ERROR, "TFMR error: MOVE_CHIP_TOD_TO_TB "
"state machine in invalid state 0x%x\n", tbst);
  tfmr = tfmr_new_tb_state(tfmr, TBST_TB_ERROR);
  tfmr |= TFMR_FIRMWARE_CONTROL_ERROR;
-env->pnv_tod_tbst.tb_ready_for_tod = 0;
+pnv_tod_tbst->tb_ready_for_tod = 0;
  }
  }
  
@@ -361,6 +371,8 @@ target_ulong helper_load_tfmr(CPUPPCState *env)
  
  void helper_store_tfmr(CPUPPCState *env, target_ulong val)

  {
+PowerPCCPU *cpu = env_archcpu(env);
+struct pnv_tod_tbst *pnv_tod_tbst = cpu_get_tbst(cpu);


... similarly here as well.

With suggested minor improvements,
Reviewed-by: Harsh Prateek Bora 


  uint64_t tfmr = env->spr[SPR_TFMR];
  uint64_t clear_on_write;
  unsigned int tbst = tfmr_get_tb_state(tfmr);
@@ -384,14 +396,7 @@ void helper_store_tfmr(CPUPPCState *env, target_ulong val)
   * after the second mfspr.
   */
  tfmr &= ~TFMR_TB_SYNC_OCCURED;
-env->pnv_tod_tbst.tb_sync_pulse_timer = 1;
-
-if (ppc_cpu_tir(env_archcpu(env)) != 0 &&
-(val & (TFMR_LOAD_TOD_MOD | TFMR_MOVE_CHIP_TOD_TO_TB))) {
-qemu_log_mask(LOG_UNIMP, "TFMR timebase state machine can only be "
- "driven by thread 0\n");
-goto out;
-}
+pnv_tod_tbst->tb_sync_pulse_timer = 1;
  
  if (((tfmr | val) & (TFMR_LOAD_TOD_MOD | TFMR_MOVE_CHIP_TOD_TO_TB)) ==

  (TFMR_LOAD_TOD_MOD | TFMR_MOVE_CHIP_TOD_TO_TB)) {
@@ -399,7 +404,7 @@ void helper_store_tfmr(CPUPPCState *env, target_ulong val)
 "MOVE_CHIP_TOD_TO_TB both set\n");
  tfmr = tfmr_new_tb_state(tfmr, TBST_TB_ERROR);
  tfmr |= TFMR_FIRMWARE_CONTROL_ERROR;
-env->pnv_tod_tbst.tb_ready_for_tod = 0;
+pnv_tod_tbst->tb_ready_for_tod = 0;
  goto out;
  }
  
@@ -413,8 +418,8 @@ void helper_store_tfmr(CPUPPCState *env, target_ulong val)

  tfmr &= ~TFMR_LOAD_TOD_MOD;
  tfmr &= ~TFMR_MOVE_CHIP_TOD_TO_TB;
  tfmr &= ~TFMR_FIRMWARE_CONTROL_ERROR; /* XXX: should this be cleared? 
*/
-env->pnv_tod_tbst.tb_ready_for_tod = 0;
-env->pnv_tod_tbst.tod_sent_to_tb = 0;
+pnv_tod_tbst->tb_ready_for_tod = 0;
+pnv_tod_tbst->tod_sent_to_tb = 0;
  goto out;
  }
  
@@ -427,19 +432,19 @@ void helper_store_tfmr(CPUPPCState *env, target_ulong val)
  
  if (tfmr & TFMR_LOAD_TOD_MOD) {

  /* Wait for an arbitrary 3 mfspr until the next state transition. */
-env->pnv_tod_tbst.tb_state_timer = 3;
+pnv_tod_tbst->tb_state_timer = 3;
  } else if (tfmr & TFMR_MOVE_CHIP_TOD_TO_TB) {
  if (tbst == TBST_NOT_SET) {
  tfmr = tfmr_new_tb_state(tfmr, TBST_SYNC_WAIT);
-env->pnv_tod_tbst.tb_ready_for_tod = 1;
-env->p

Re: [RFC PATCH 01/10] ppc/pnv: Add pointer from PnvCPUState to PnvCore

2024-05-27 Thread Harsh Prateek Bora




On 5/26/24 17:56, Nicholas Piggin wrote:

This helps move core state from CPU to core structures.

Signed-off-by: Nicholas Piggin 
---
  include/hw/ppc/pnv_core.h | 1 +
  hw/ppc/pnv_core.c | 3 +++
  2 files changed, 4 insertions(+)

diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index c6d62fd145..30c1e5b1a3 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -54,6 +54,7 @@ struct PnvCoreClass {
  #define PNV_CORE_TYPE_NAME(cpu_model) cpu_model PNV_CORE_TYPE_SUFFIX
  
  typedef struct PnvCPUState {

+PnvCore *core;


Naming it *pc might be more intuitive with the most of its usage, 
although I see few usage as "pnv_core" as well.


Reviewed-by: Harsh Prateek Bora 


  Object *intc;
  } PnvCPUState;
  
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c

index f40ab721d6..7b0ea7812b 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -225,6 +225,7 @@ static const MemoryRegionOps pnv_core_power10_xscom_ops = {
  static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp,
   int thread_index)
  {
+PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
  CPUPPCState *env = &cpu->env;
  int core_hwid;
  ppc_spr_t *pir = &env->spr_cb[SPR_PIR];
@@ -232,6 +233,8 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU 
*cpu, Error **errp,
  Error *local_err = NULL;
  PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);
  
+pnv_cpu->core = pc;

+
  if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
  return;
  }




[PATCH v3 2/3] cpu-common.c: export cpu_get_free_index to be reused later

2024-05-23 Thread Harsh Prateek Bora
This helper provides an easy way to identify the next available free cpu
index which can be used for vcpu creation. Until now, this is being
called at a very later stage and there is a need to be able to call it
earlier (for now, with ppc64) hence the need to export.

Suggested-by: Nicholas Piggin 
Signed-off-by: Harsh Prateek Bora 
---
 include/exec/cpu-common.h | 2 ++
 cpu-common.c  | 7 ---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 6d5318895a..0386f1ab29 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -29,6 +29,8 @@ void cpu_list_lock(void);
 void cpu_list_unlock(void);
 unsigned int cpu_list_generation_id_get(void);
 
+int cpu_get_free_index(void);
+
 void tcg_iommu_init_notifier_list(CPUState *cpu);
 void tcg_iommu_free_notifier_list(CPUState *cpu);
 
diff --git a/cpu-common.c b/cpu-common.c
index ce78273af5..82bd1b432d 100644
--- a/cpu-common.c
+++ b/cpu-common.c
@@ -57,14 +57,12 @@ void cpu_list_unlock(void)
 qemu_mutex_unlock(&qemu_cpu_list_lock);
 }
 
-static bool cpu_index_auto_assigned;
 
-static int cpu_get_free_index(void)
+int cpu_get_free_index(void)
 {
 CPUState *some_cpu;
 int max_cpu_index = 0;
 
-cpu_index_auto_assigned = true;
 CPU_FOREACH(some_cpu) {
 if (some_cpu->cpu_index >= max_cpu_index) {
 max_cpu_index = some_cpu->cpu_index + 1;
@@ -83,8 +81,11 @@ unsigned int cpu_list_generation_id_get(void)
 
 void cpu_list_add(CPUState *cpu)
 {
+static bool cpu_index_auto_assigned;
+
 QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
 if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) {
+cpu_index_auto_assigned = true;
 cpu->cpu_index = cpu_get_free_index();
 assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX);
 } else {
-- 
2.39.3




[PATCH v3 1/3] accel/kvm: Introduce kvm_create_and_park_vcpu() helper

2024-05-23 Thread Harsh Prateek Bora
There are distinct helpers for creating and parking a KVM vCPU.
However, there can be cases where a platform needs to create and
immediately park the vCPU during early stages of vcpu init which
can later be reused when vcpu thread gets initialized. This would
help detect failures with kvm_create_vcpu at an early stage.

Based on api refactoring to create/park vcpus introduced in 1/8 of patch series:
https://lore.kernel.org/qemu-devel/2024052221.232114-1-salil.me...@huawei.com/

Suggested-by: Nicholas Piggin 
Signed-off-by: Harsh Prateek Bora 
---
 accel/kvm/kvm-cpus.h |  8 
 accel/kvm/kvm-all.c  | 12 
 2 files changed, 20 insertions(+)

diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h
index 2e6bb38b5d..00e534b3b9 100644
--- a/accel/kvm/kvm-cpus.h
+++ b/accel/kvm/kvm-cpus.h
@@ -46,4 +46,12 @@ void kvm_park_vcpu(CPUState *cpu);
  * @returns: KVM fd
  */
 int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
+
+/**
+ *  * kvm_create_and_park_vcpu - Create and park a KVM vCPU
+ *   * @cpu: QOM CPUState object for which KVM vCPU has to be created and 
parked.
+ **
+ * * @returns: 0 when success, errno (<0) when failed.
+ *  */
+int kvm_create_and_park_vcpu(CPUState *cpu);
 #endif /* KVM_CPUS_H */
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index fc30e5d5b8..d70ca62ff5 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -398,6 +398,18 @@ int kvm_create_vcpu(CPUState *cpu)
 return 0;
 }
 
+int kvm_create_and_park_vcpu(CPUState *cpu)
+{
+int ret = 0;
+
+ret = kvm_create_vcpu(cpu);
+if (!ret) {
+kvm_park_vcpu(cpu);
+}
+
+return ret;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
-- 
2.39.3




[PATCH v3 0/3] target/ppc: vcpu hotplug failure handling fixes

2024-05-23 Thread Harsh Prateek Bora
On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating and parking vcpu on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.

This series adds another helper to create and park vcpu (based on below
patch by Salil), exports cpu_get_free_index to be reused later and adds
ppc arch specfic handling for vcpu hotplug failure using kvm accel
helper cpu_target_realize.

Based on api refactoring to create/park vcpus introduced in 1/8 of patch series:
https://lore.kernel.org/qemu-devel/2024052221.232114-1-salil.me...@huawei.com/

Changelog:
v3: Addressed review comments from Nick
v2: Addressed review comments from Nick
v1: Initial patch

Harsh Prateek Bora (3):
  accel/kvm: Introduce kvm_create_and_park_vcpu() helper
  cpu-common.c: export cpu_get_free_index to be reused later
  target/ppc: handle vcpu hotplug failure gracefully

 accel/kvm/kvm-cpus.h  |  8 
 include/exec/cpu-common.h |  2 ++
 accel/kvm/kvm-all.c   | 12 
 cpu-common.c  |  7 ---
 target/ppc/kvm.c  | 41 +++
 5 files changed, 67 insertions(+), 3 deletions(-)

-- 
2.39.3




[PATCH v3 3/3] target/ppc: handle vcpu hotplug failure gracefully

2024-05-23 Thread Harsh Prateek Bora
On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating and parking vcpu on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.

Also introducing KVM AccelCPUClass to init cpu_target_realize for kvm.

Tested OK by repeatedly doing a hotplug/unplug of vcpus as below:

 #virsh setvcpus hotplug 40
 #virsh setvcpus hotplug 70
error: internal error: unable to execute QEMU command 'device_add':
kvmppc_cpu_realize: vcpu hotplug failed with -12

Reported-by: Anushree Mathur 
Suggested-by: Shivaprasad G Bhat 
Suggested-by: Vaibhav Jain 
Signed-off by: Harsh Prateek Bora 
Tested-by: Anushree Mathur 
---
 target/ppc/kvm.c | 41 +
 1 file changed, 41 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 63930d4a77..8e5a7c3d2d 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -48,6 +48,8 @@
 #include "qemu/mmap-alloc.h"
 #include "elf.h"
 #include "sysemu/kvm_int.h"
+#include "accel/kvm/kvm-cpus.h"
+#include "hw/core/accel-cpu.h"
 
 #define PROC_DEVTREE_CPU  "/proc/device-tree/cpus/"
 
@@ -2339,6 +2341,25 @@ static void alter_insns(uint64_t *word, uint64_t flags, 
bool on)
 }
 }
 
+static bool kvmppc_cpu_realize(CPUState *cs, Error **errp)
+{
+int ret;
+const char *vcpu_str = (cs->parent_obj.hotplugged == true) ?
+   "hotplug" : "create";
+cs->cpu_index = cpu_get_free_index();
+
+POWERPC_CPU(cs)->vcpu_id = cs->cpu_index;
+
+/* create and park to fail gracefully in case vcpu hotplug fails */
+ret = kvm_create_and_park_vcpu(cs);
+if (ret) {
+error_setg(errp, "%s: vcpu %s failed with %d",
+ __func__, vcpu_str, ret);
+return false;
+}
+return true;
+}
+
 static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
 {
 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
@@ -2959,3 +2980,23 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t 
tb_offset)
 void kvm_arch_accel_class_init(ObjectClass *oc)
 {
 }
+
+static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data)
+{
+AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
+
+acc->cpu_target_realize = kvmppc_cpu_realize;
+}
+
+static const TypeInfo kvm_cpu_accel_type_info = {
+.name = ACCEL_CPU_NAME("kvm"),
+
+.parent = TYPE_ACCEL_CPU,
+.class_init = kvm_cpu_accel_class_init,
+.abstract = true,
+};
+static void kvm_cpu_accel_register_types(void)
+{
+type_register_static(&kvm_cpu_accel_type_info);
+}
+type_init(kvm_cpu_accel_register_types);
-- 
2.39.3




Re: [PATCH V11 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-23 Thread Harsh Prateek Bora

Hi Salil,

On 5/23/24 02:41, Salil Mehta wrote:

+void kvm_park_vcpu(CPUState *cpu);
+
+/**
+ * kvm_unpark_vcpu - unpark QEMU KVM vCPU context
+ * @s: KVM State
+ * @cpu: Architecture vCPU ID of the parked vCPU


s/@cpu/@vcpuid ?

Thanks
Harsh

+ *
+ * @returns: KVM fd
+ */
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
  #endif /* KVM_CPUS_H */




[PATCH v2 3/7] target/ppc: optimize hreg_compute_pmu_hflags_value

2024-05-22 Thread Harsh Prateek Bora
The second if-condition can be true only if the first one above is true.
Enclose the latter into the former to avoid un-necessary check if first
condition fails.

Signed-off-by: Harsh Prateek Bora 
Reviewed-by: BALATON Zoltan 
---
 target/ppc/helper_regs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index d09dcacd5e..261a8ba79f 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -66,9 +66,9 @@ static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState 
*env)
 #ifndef CONFIG_USER_ONLY
 if (env->pmc_ins_cnt) {
 hflags |= 1 << HFLAGS_INSN_CNT;
-}
-if (env->pmc_ins_cnt & 0x1e) {
-hflags |= 1 << HFLAGS_PMC_OTHER;
+if (env->pmc_ins_cnt & 0x1e) {
+hflags |= 1 << HFLAGS_PMC_OTHER;
+}
 }
 #endif
 #endif
-- 
2.39.3




Re: [PATCH 6/6] target/ppc: redue code duplication across Power9/10 init code

2024-05-22 Thread Harsh Prateek Bora

Hi BALATON,

On 5/20/24 17:22, BALATON Zoltan wrote:

On Mon, 20 May 2024, Harsh Prateek Bora wrote:

Power9/10 initialization code consists of a lot of logical OR of
various flag bits as supported by respective Power platform during its
initialization, most of which is duplicated and only selected bits are
added or removed as needed with each new platform support being added.
Remove the duplicate code and share using common macros.

Signed-off-by: Harsh Prateek Bora 
---
target/ppc/cpu_init.h |  79 +++
target/ppc/cpu_init.c | 123 ++
2 files changed, 94 insertions(+), 108 deletions(-)
create mode 100644 target/ppc/cpu_init.h

diff --git a/target/ppc/cpu_init.h b/target/ppc/cpu_init.h
new file mode 100644
index 00..29358bfdf6
--- /dev/null
+++ b/target/ppc/cpu_init.h
@@ -0,0 +1,79 @@
+#ifndef TARGET_PPC_CPU_INIT_H
+#define TARGET_PPC_CPU_INIT_H
+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS   \
+    PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | \
+    PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |   \
+    PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES |  \
+    PPC_FLOAT_STFIWX | PPC_FLOAT_EXT |PPC_CACHE | PPC_CACHE_ICBI |  \
+    PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | \
+    PPC_MEM_TLBSYNC | PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |  \
+    PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD |   \
+    PPC_CILDST
+#define POWERPC_FAMILY_POWER10_INSNS_FLAGS \
+    POWERPC_FAMILY_POWER9_INSNS_FLAGS


It's a good idea to make the cpu inits more readable but I'm not sure 
about having two names for the same thing. If these are the same could 
POWER10 also just use POWERPC_FAMILY_POWER9_INSNS_FLAGS (or if you 
really want to may call it POWERPC_FAMILY_POWER9_10_INSNS_FLAGS or 
similar but I think using earlier features where unchanged in newer CPU 
models would be OK and show these are the same).


Thanks for your valuable review comments on this series. I have 
addressed them and posted in v2.


regards,
Harsh


Regards,
BALATON Zoltan


+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON   \
+    PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | \
+    PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 |  \
+    PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |   \
+    PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 |  \
+    PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_ISA300 | PPC2_PRCNTL |    \
+    PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206
+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS2  \
+    POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON | PPC2_TM
+#define POWERPC_FAMILY_POWER10_INSNS_FLAGS2 \
+    POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON | PPC2_ISA310
+
+#define POWERPC_POWER9_COMMON_PCC_MSR_MASK \
+    (1ull << MSR_SF) | \
+    (1ull << MSR_HV) | \
+    (1ull << MSR_VR) | \
+    (1ull << MSR_VSX) |    \
+    (1ull << MSR_EE) | \
+    (1ull << MSR_PR) | \
+    (1ull << MSR_FP) | \
+    (1ull << MSR_ME) | \
+    (1ull << MSR_FE0) |    \
+    (1ull << MSR_SE) | \
+    (1ull << MSR_DE) | \
+    (1ull << MSR_FE1) |    \
+    (1ull << MSR_IR) | \
+    (1ull << MSR_DR) | \
+    (1ull << MSR_PMM) |    \
+    (1ull << MSR_RI) | \
+    (1ull << MSR_LE)
+
+#define POWERPC_POWER9_PCC_MSR_MASK \
+    POWERPC_POWER9_COMMON_PCC_MSR_MASK | (1ull << MSR_TM)
+#define POWERPC_POWER10_PCC_MSR_MASK \
+    POWERPC_POWER9_COMMON_PCC_MSR_MASK
+#define POWERPC_POWER9_PCC_PCR_MASK \
+    PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07
+#define POWERPC_POWER10_PCC_PCR_MASK \
+    POWERPC_POWER9_PCC_PCR_MASK | PCR_COMPAT_3_00
+#define POWERPC_POWER9_PCC_PCR_SUPPORTED \
+    PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | 
PCR_COMPAT_2_05

+#define POWERPC_POWER10_PCC_PCR_SUPPORTED \
+    POWERPC_POWER9_PCC_PCR_SUPPORTED | PCR_COMPAT_3_10
+#define 
POWERPC_POWER9_PCC_LPCR_MASK    \
+    LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD 
|   \
+    (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL 
|  \
+    LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD 
| \
+    (LPCR_PECE_L_MASK & 
(LPCR_PDEE|LPCR_HDEE|LPCR_EEE|LPCR_DEE|LPCR_OEE)) | \
+    LPCR_MER | LPCR_GTSE | LPCR_TC | LPCR_HEIC | LPCR_LPES0 | 
LPCR_HVICE |  \

+    LPCR_HDICE
+/* DD2 adds an extra HAIL bit */
+#define POWERPC_POWER10_PCC_LPCR_MASK \
+    POWERPC_POWE

[PATCH v2 2/7] target/ppc: optimize hreg_compute_pmu_hflags_value

2024-05-22 Thread Harsh Prateek Bora
Cache env->spr[SPR_POWER_MMCR0] in a local variable as used in multiple
conditions to avoid multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/helper_regs.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 945fa1a596..d09dcacd5e 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -50,15 +50,16 @@ void hreg_swap_gpr_tgpr(CPUPPCState *env)
 static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState *env)
 {
 uint32_t hflags = 0;
-
 #if defined(TARGET_PPC64)
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC0) {
+target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
+
+if (mmcr0 & MMCR0_PMCC0) {
 hflags |= 1 << HFLAGS_PMCC0;
 }
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) {
+if (mmcr0 & MMCR0_PMCC1) {
 hflags |= 1 << HFLAGS_PMCC1;
 }
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) {
+if (mmcr0 & MMCR0_PMCjCE) {
 hflags |= 1 << HFLAGS_PMCJCE;
 }
 
-- 
2.39.3




[PATCH v2 6/7] target/ppc: reduce duplicate code between init_proc_POWER{9, 10}

2024-05-22 Thread Harsh Prateek Bora
Historically, the registration of sprs have been inherited alongwith
every new Power arch support being added leading to a lot of code
duplication. It's time to do necessary cleanups now to avoid further
duplication with newer arch support being added.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/cpu_init.c | 43 +--
 1 file changed, 9 insertions(+), 34 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 6d82f24c87..5fb9a0583e 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6307,7 +6307,7 @@ static struct ppc_radix_page_info POWER9_radix_page_info 
= {
 };
 #endif /* CONFIG_USER_ONLY */
 
-static void init_proc_POWER9(CPUPPCState *env)
+static void register_power9_common_sprs(CPUPPCState *env)
 {
 /* Common Registers */
 init_proc_book3s_common(env);
@@ -6326,7 +6326,6 @@ static void init_proc_POWER9(CPUPPCState *env)
 register_power5p_ear_sprs(env);
 register_power5p_tb_sprs(env);
 register_power6_common_sprs(env);
-register_HEIR32_spr(env);
 register_power6_dbg_sprs(env);
 register_power8_tce_address_control_sprs(env);
 register_power8_ids_sprs(env);
@@ -6342,6 +6341,12 @@ static void init_proc_POWER9(CPUPPCState *env)
 register_power9_book4_sprs(env);
 register_power8_rpr_sprs(env);
 register_power9_mmu_sprs(env);
+}
+
+static void init_proc_POWER9(CPUPPCState *env)
+{
+register_power9_common_sprs(env);
+register_HEIR32_spr(env);
 
 /* POWER9 Specific registers */
 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
@@ -6499,39 +6504,9 @@ static struct ppc_radix_page_info 
POWER10_radix_page_info = {
 
 static void init_proc_POWER10(CPUPPCState *env)
 {
-/* Common Registers */
-init_proc_book3s_common(env);
-register_book3s_207_dbg_sprs(env);
-
-/* Common TCG PMU */
-init_tcg_pmu_power8(env);
-
-/* POWER8 Specific Registers */
-register_book3s_ids_sprs(env);
-register_amr_sprs(env);
-register_iamr_sprs(env);
-register_book3s_purr_sprs(env);
-register_power5p_common_sprs(env);
-register_power5p_lpar_sprs(env);
-register_power5p_ear_sprs(env);
-register_power5p_tb_sprs(env);
-register_power6_common_sprs(env);
+register_power9_common_sprs(env);
 register_HEIR64_spr(env);
-register_power6_dbg_sprs(env);
-register_power8_tce_address_control_sprs(env);
-register_power8_ids_sprs(env);
-register_power8_ebb_sprs(env);
-register_power8_fscr_sprs(env);
-register_power8_pmu_sup_sprs(env);
-register_power8_pmu_user_sprs(env);
-register_power8_tm_sprs(env);
-register_power8_pspb_sprs(env);
-register_power8_dpdes_sprs(env);
-register_vtb_sprs(env);
-register_power8_ic_sprs(env);
-register_power9_book4_sprs(env);
-register_power8_rpr_sprs(env);
-register_power9_mmu_sprs(env);
+
 register_power10_hash_sprs(env);
 register_power10_dexcr_sprs(env);
 register_power10_pmu_sup_sprs(env);
-- 
2.39.3




[PATCH v2 7/7] target/ppc: redue code duplication across Power9/10 init code

2024-05-22 Thread Harsh Prateek Bora
Power9/10 initialization code consists of a lot of logical OR of
various flag bits as supported by respective Power platform during its
initialization, most of which is duplicated and only selected bits are
added or removed as needed with each new platform support being added.
Remove the duplicate code and share using common macros.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/cpu_init.h |  77 ++
 target/ppc/cpu_init.c | 123 ++
 2 files changed, 92 insertions(+), 108 deletions(-)
 create mode 100644 target/ppc/cpu_init.h

diff --git a/target/ppc/cpu_init.h b/target/ppc/cpu_init.h
new file mode 100644
index 00..53909987b0
--- /dev/null
+++ b/target/ppc/cpu_init.h
@@ -0,0 +1,77 @@
+#ifndef TARGET_PPC_CPU_INIT_H
+#define TARGET_PPC_CPU_INIT_H
+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS   \
+PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | \
+PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |   \
+PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES |  \
+PPC_FLOAT_STFIWX | PPC_FLOAT_EXT |PPC_CACHE | PPC_CACHE_ICBI |  \
+PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | \
+PPC_MEM_TLBSYNC | PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |  \
+PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD |   \
+PPC_CILDST
+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON   \
+PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | \
+PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 |  \
+PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |   \
+PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 |  \
+PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_ISA300 | PPC2_PRCNTL |\
+PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206
+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS2  \
+POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON | PPC2_TM
+#define POWERPC_FAMILY_POWER10_INSNS_FLAGS2 \
+POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON | PPC2_ISA310
+
+#define POWERPC_POWER9_COMMON_PCC_MSR_MASK \
+(1ull << MSR_SF) | \
+(1ull << MSR_HV) | \
+(1ull << MSR_VR) | \
+(1ull << MSR_VSX) |\
+(1ull << MSR_EE) | \
+(1ull << MSR_PR) | \
+(1ull << MSR_FP) | \
+(1ull << MSR_ME) | \
+(1ull << MSR_FE0) |\
+(1ull << MSR_SE) | \
+(1ull << MSR_DE) | \
+(1ull << MSR_FE1) |\
+(1ull << MSR_IR) | \
+(1ull << MSR_DR) | \
+(1ull << MSR_PMM) |\
+(1ull << MSR_RI) | \
+(1ull << MSR_LE)
+
+#define POWERPC_POWER9_PCC_MSR_MASK \
+POWERPC_POWER9_COMMON_PCC_MSR_MASK | (1ull << MSR_TM)
+#define POWERPC_POWER10_PCC_MSR_MASK \
+POWERPC_POWER9_COMMON_PCC_MSR_MASK
+#define POWERPC_POWER9_PCC_PCR_MASK \
+PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07
+#define POWERPC_POWER10_PCC_PCR_MASK \
+POWERPC_POWER9_PCC_PCR_MASK | PCR_COMPAT_3_00
+#define POWERPC_POWER9_PCC_PCR_SUPPORTED \
+PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05
+#define POWERPC_POWER10_PCC_PCR_SUPPORTED \
+POWERPC_POWER9_PCC_PCR_SUPPORTED | PCR_COMPAT_3_10
+#define POWERPC_POWER9_PCC_LPCR_MASK\
+LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |   \
+(LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |  \
+LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD | \
+(LPCR_PECE_L_MASK & (LPCR_PDEE|LPCR_HDEE|LPCR_EEE|LPCR_DEE|LPCR_OEE)) | \
+LPCR_MER | LPCR_GTSE | LPCR_TC | LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE |  \
+LPCR_HDICE
+/* DD2 adds an extra HAIL bit */
+#define POWERPC_POWER10_PCC_LPCR_MASK \
+POWERPC_POWER9_PCC_LPCR_MASK | LPCR_HAIL
+#define POWERPC_POWER9_PCC_FLAGS_COMMON \
+POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE |  \
+POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |   \
+POWERPC_FLAG_VSX | POWERPC_FLAG_SCV
+
+#define POWERPC_POWER9_PCC_FLAGS  \
+POWERPC_POWER9_PCC_FLAGS_COMMON | POWERPC_FLAG_TM
+#define POWERPC_POWER10_PCC_FLAGS POWERPC_POWER9_PCC_FLAGS_COMMON
+
+#endif /* TARGET_PPC_CPU_INIT_H */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 5fb9a0583e..e4f6ad2399 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -51,6 +51,7 @@
 #include "kvm_ppc.h"
 #endif
 
+#include "cpu_init.h"
 /* #define PPC_

[PATCH v2 0/7] target/ppc: misc ppc improvements/optimizations

2024-05-22 Thread Harsh Prateek Bora
This a set of misc ppc arch specific code improvements/optimizations.
Although there exists similar instances for potential improvements in
the legacy ppc code, however, that can be taken up later as well.

Changelog:
v2: addressed review comments from BALATON Zoltan
v1: Initial patch

Harsh Prateek Bora (7):
  target/ppc: use locally stored msr and avoid indirect access
  target/ppc: optimize hreg_compute_pmu_hflags_value
  target/ppc: optimize hreg_compute_pmu_hflags_value
  target/ppc: optimize p9 exception handling routines
  target/ppc: optimize p9 exception handling routines for lpcr
  target/ppc: reduce duplicate code between init_proc_POWER{9,10}
  target/ppc: redue code duplication across Power9/10 init code

 target/ppc/cpu_init.h|  77 ++
 target/ppc/cpu_init.c| 166 ++-
 target/ppc/excp_helper.c |  72 +
 target/ppc/helper_regs.c |  19 ++---
 4 files changed, 150 insertions(+), 184 deletions(-)
 create mode 100644 target/ppc/cpu_init.h

-- 
2.39.3




[PATCH v2 4/7] target/ppc: optimize p9 exception handling routines

2024-05-22 Thread Harsh Prateek Bora
Currently, p9 exception handling has multiple if-condition checks where
it does an indirect access to pending_interrupts via env. Pass the
value during entry to avoid multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 47 +---
 1 file changed, 25 insertions(+), 22 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 0712098cf7..704eddac63 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1842,10 +1842,12 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
  PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT |  \
  PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
 
-static int p9_interrupt_powersave(CPUPPCState *env)
+static int p9_interrupt_powersave(CPUPPCState *env,
+  uint32_t pending_interrupts)
 {
+
 /* External Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
+if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
 (env->spr[SPR_LPCR] & LPCR_EEE)) {
 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
 if (!heic || !FIELD_EX64_HV(env->msr) ||
@@ -1854,48 +1856,49 @@ static int p9_interrupt_powersave(CPUPPCState *env)
 }
 }
 /* Decrementer Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
+if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
 (env->spr[SPR_LPCR] & LPCR_DEE)) {
 return PPC_INTERRUPT_DECR;
 }
 /* Machine Check or Hypervisor Maintenance Exception */
 if (env->spr[SPR_LPCR] & LPCR_OEE) {
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_HMI) {
+if (pending_interrupts & PPC_INTERRUPT_HMI) {
 return PPC_INTERRUPT_HMI;
 }
 }
 /* Privileged Doorbell Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
+if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
 return PPC_INTERRUPT_DOORBELL;
 }
 /* Hypervisor Doorbell Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
+if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
 return PPC_INTERRUPT_HDOORBELL;
 }
 /* Hypervisor virtualization exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) &&
+if ((pending_interrupts & PPC_INTERRUPT_HVIRT) &&
 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
 return PPC_INTERRUPT_HVIRT;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+if (pending_interrupts & PPC_INTERRUPT_RESET) {
 return PPC_INTERRUPT_RESET;
 }
 return 0;
 }
 
-static int p9_next_unmasked_interrupt(CPUPPCState *env)
+static int p9_next_unmasked_interrupt(CPUPPCState *env,
+  uint32_t pending_interrupts)
 {
 CPUState *cs = env_cpu(env);
 
 /* Ignore MSR[EE] when coming out of some power management states */
 bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
 
-assert((env->pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
+assert((pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
 
 if (cs->halted) {
 if (env->spr[SPR_PSSCR] & PSSCR_EC) {
@@ -1903,7 +1906,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
  * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can
  * wakeup the processor
  */
-return p9_interrupt_powersave(env);
+return p9_interrupt_powersave(env, pending_interrupts);
 } else {
 /*
  * When it's clear, any system-caused exception exits power-saving
@@ -1914,12 +1917,12 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* Machine check exception */
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
 
 /* Hypervisor decrementer exception */
-if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
+if (pending_interrupts & PPC_INTERRUPT_HDECR) {
 /* LPCR will be clear when not supported so this will work */
 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
@@ -1929,7 +1932,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* Hypervisor virtualization interrupt */
-if (env->pending_inte

[PATCH v2 5/7] target/ppc: optimize p9 exception handling routines for lpcr

2024-05-22 Thread Harsh Prateek Bora
Like pending_interrupts, env->spr[SPR_LPCR] is being used at multiple
places across p9 exception handlers. Pass the value during entry and
avoid multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 33 ++---
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 704eddac63..d3db81e6ae 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1843,13 +1843,14 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
  PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
 
 static int p9_interrupt_powersave(CPUPPCState *env,
-  uint32_t pending_interrupts)
+  uint32_t pending_interrupts,
+  target_ulong lpcr)
 {
 
 /* External Exception */
 if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
-(env->spr[SPR_LPCR] & LPCR_EEE)) {
-bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+(lpcr & LPCR_EEE)) {
+bool heic = !!(lpcr & LPCR_HEIC);
 if (!heic || !FIELD_EX64_HV(env->msr) ||
 FIELD_EX64(env->msr, MSR, PR)) {
 return PPC_INTERRUPT_EXT;
@@ -1857,11 +1858,11 @@ static int p9_interrupt_powersave(CPUPPCState *env,
 }
 /* Decrementer Exception */
 if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
-(env->spr[SPR_LPCR] & LPCR_DEE)) {
+(lpcr & LPCR_DEE)) {
 return PPC_INTERRUPT_DECR;
 }
 /* Machine Check or Hypervisor Maintenance Exception */
-if (env->spr[SPR_LPCR] & LPCR_OEE) {
+if (lpcr & LPCR_OEE) {
 if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
@@ -1871,17 +1872,17 @@ static int p9_interrupt_powersave(CPUPPCState *env,
 }
 /* Privileged Doorbell Exception */
 if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
-(env->spr[SPR_LPCR] & LPCR_PDEE)) {
+(lpcr & LPCR_PDEE)) {
 return PPC_INTERRUPT_DOORBELL;
 }
 /* Hypervisor Doorbell Exception */
 if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
-(env->spr[SPR_LPCR] & LPCR_HDEE)) {
+(lpcr & LPCR_HDEE)) {
 return PPC_INTERRUPT_HDOORBELL;
 }
 /* Hypervisor virtualization exception */
 if ((pending_interrupts & PPC_INTERRUPT_HVIRT) &&
-(env->spr[SPR_LPCR] & LPCR_HVEE)) {
+(lpcr & LPCR_HVEE)) {
 return PPC_INTERRUPT_HVIRT;
 }
 if (pending_interrupts & PPC_INTERRUPT_RESET) {
@@ -1891,7 +1892,8 @@ static int p9_interrupt_powersave(CPUPPCState *env,
 }
 
 static int p9_next_unmasked_interrupt(CPUPPCState *env,
-  uint32_t pending_interrupts)
+  uint32_t pending_interrupts,
+  target_ulong lpcr)
 {
 CPUState *cs = env_cpu(env);
 
@@ -1906,7 +1908,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
  * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can
  * wakeup the processor
  */
-return p9_interrupt_powersave(env, pending_interrupts);
+return p9_interrupt_powersave(env, pending_interrupts, lpcr);
 } else {
 /*
  * When it's clear, any system-caused exception exits power-saving
@@ -1924,7 +1926,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
 /* Hypervisor decrementer exception */
 if (pending_interrupts & PPC_INTERRUPT_HDECR) {
 /* LPCR will be clear when not supported so this will work */
-bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
+bool hdice = !!(lpcr & LPCR_HDICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
 /* HDEC clears on delivery */
 return PPC_INTERRUPT_HDECR;
@@ -1934,7 +1936,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
 /* Hypervisor virtualization interrupt */
 if (pending_interrupts & PPC_INTERRUPT_HVIRT) {
 /* LPCR will be clear when not supported so this will work */
-bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
+bool hvice = !!(lpcr & LPCR_HVICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hvice) {
 return PPC_INTERRUPT_HVIRT;
 }
@@ -1942,8 +1944,8 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
 
 /* External interrupt can ignore MSR:EE under some circumstances */
 if (pending_interrupts & PPC_INTERRUPT_EXT) {
-bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
-bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+bool lpes0 = !!(lpcr & LPCR_LPES0);
+ 

[PATCH v2 1/7] target/ppc: use locally stored msr and avoid indirect access

2024-05-22 Thread Harsh Prateek Bora
hreg_compute_hflags_value already stores msr locally to be used in most
of the logic in the routine however some instances are still using
env->msr which is unnecessary. Use locally stored value as available.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/helper_regs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 25258986e3..945fa1a596 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -106,10 +106,10 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState 
*env)
 
 if (ppc_flags & POWERPC_FLAG_DE) {
 target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0];
-if ((dbcr0 & DBCR0_ICMP) && FIELD_EX64(env->msr, MSR, DE)) {
+if ((dbcr0 & DBCR0_ICMP) && FIELD_EX64(msr, MSR, DE)) {
 hflags |= 1 << HFLAGS_SE;
 }
-if ((dbcr0 & DBCR0_BRT) && FIELD_EX64(env->msr, MSR, DE)) {
+if ((dbcr0 & DBCR0_BRT) && FIELD_EX64(msr, MSR, DE)) {
 hflags |= 1 << HFLAGS_BE;
 }
 } else {
-- 
2.39.3




[PATCH 6/6] target/ppc: redue code duplication across Power9/10 init code

2024-05-20 Thread Harsh Prateek Bora
Power9/10 initialization code consists of a lot of logical OR of
various flag bits as supported by respective Power platform during its
initialization, most of which is duplicated and only selected bits are
added or removed as needed with each new platform support being added.
Remove the duplicate code and share using common macros.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/cpu_init.h |  79 +++
 target/ppc/cpu_init.c | 123 ++
 2 files changed, 94 insertions(+), 108 deletions(-)
 create mode 100644 target/ppc/cpu_init.h

diff --git a/target/ppc/cpu_init.h b/target/ppc/cpu_init.h
new file mode 100644
index 00..29358bfdf6
--- /dev/null
+++ b/target/ppc/cpu_init.h
@@ -0,0 +1,79 @@
+#ifndef TARGET_PPC_CPU_INIT_H
+#define TARGET_PPC_CPU_INIT_H
+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS   \
+PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | \
+PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |   \
+PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES |  \
+PPC_FLOAT_STFIWX | PPC_FLOAT_EXT |PPC_CACHE | PPC_CACHE_ICBI |  \
+PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | \
+PPC_MEM_TLBSYNC | PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |  \
+PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD |   \
+PPC_CILDST
+#define POWERPC_FAMILY_POWER10_INSNS_FLAGS \
+POWERPC_FAMILY_POWER9_INSNS_FLAGS
+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON   \
+PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | \
+PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 |  \
+PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |   \
+PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 |  \
+PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_ISA300 | PPC2_PRCNTL |\
+PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206
+
+#define POWERPC_FAMILY_POWER9_INSNS_FLAGS2  \
+POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON | PPC2_TM
+#define POWERPC_FAMILY_POWER10_INSNS_FLAGS2 \
+POWERPC_FAMILY_POWER9_INSNS_FLAGS2_COMMON | PPC2_ISA310
+
+#define POWERPC_POWER9_COMMON_PCC_MSR_MASK \
+(1ull << MSR_SF) | \
+(1ull << MSR_HV) | \
+(1ull << MSR_VR) | \
+(1ull << MSR_VSX) |\
+(1ull << MSR_EE) | \
+(1ull << MSR_PR) | \
+(1ull << MSR_FP) | \
+(1ull << MSR_ME) | \
+(1ull << MSR_FE0) |\
+(1ull << MSR_SE) | \
+(1ull << MSR_DE) | \
+(1ull << MSR_FE1) |\
+(1ull << MSR_IR) | \
+(1ull << MSR_DR) | \
+(1ull << MSR_PMM) |\
+(1ull << MSR_RI) | \
+(1ull << MSR_LE)
+
+#define POWERPC_POWER9_PCC_MSR_MASK \
+POWERPC_POWER9_COMMON_PCC_MSR_MASK | (1ull << MSR_TM)
+#define POWERPC_POWER10_PCC_MSR_MASK \
+POWERPC_POWER9_COMMON_PCC_MSR_MASK
+#define POWERPC_POWER9_PCC_PCR_MASK \
+PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07
+#define POWERPC_POWER10_PCC_PCR_MASK \
+POWERPC_POWER9_PCC_PCR_MASK | PCR_COMPAT_3_00
+#define POWERPC_POWER9_PCC_PCR_SUPPORTED \
+PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05
+#define POWERPC_POWER10_PCC_PCR_SUPPORTED \
+POWERPC_POWER9_PCC_PCR_SUPPORTED | PCR_COMPAT_3_10
+#define POWERPC_POWER9_PCC_LPCR_MASK\
+LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |   \
+(LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |  \
+LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD | \
+(LPCR_PECE_L_MASK & (LPCR_PDEE|LPCR_HDEE|LPCR_EEE|LPCR_DEE|LPCR_OEE)) | \
+LPCR_MER | LPCR_GTSE | LPCR_TC | LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE |  \
+LPCR_HDICE
+/* DD2 adds an extra HAIL bit */
+#define POWERPC_POWER10_PCC_LPCR_MASK \
+POWERPC_POWER9_PCC_LPCR_MASK | LPCR_HAIL
+#define POWERPC_POWER9_PCC_FLAGS_COMMON \
+POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE |  \
+POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |   \
+POWERPC_FLAG_VSX | POWERPC_FLAG_SCV
+
+#define POWERPC_POWER9_PCC_FLAGS  \
+POWERPC_POWER9_PCC_FLAGS_COMMON | POWERPC_FLAG_TM
+#define POWERPC_POWER10_PCC_FLAGS POWERPC_POWER9_PCC_FLAGS_COMMON
+
+#endif /* TARGET_PPC_CPU_INIT_H */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 636e12ba7a..48773ec831 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -51,6 +5

[PATCH 3/6] target/ppc: optimize hreg_compute_pmu_hflags_value

2024-05-20 Thread Harsh Prateek Bora
The second if-condition can be true only if the first one above is true.
Enclose the latter into the former to avoid un-necessary check if first
condition fails.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/helper_regs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 5de0df5795..89aacdf212 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -66,9 +66,9 @@ static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState 
*env)
 #ifndef CONFIG_USER_ONLY
 if (env->pmc_ins_cnt) {
 hflags |= 1 << HFLAGS_INSN_CNT;
-}
-if (env->pmc_ins_cnt & 0x1e) {
-hflags |= 1 << HFLAGS_PMC_OTHER;
+if (env->pmc_ins_cnt & 0x1e) {
+hflags |= 1 << HFLAGS_PMC_OTHER;
+}
 }
 #endif
 #endif
-- 
2.39.3




[PATCH 4/6] target/ppc: optimize p9 exception handling routines

2024-05-20 Thread Harsh Prateek Bora
Currently, p9 exception handling has multiple if-condition checks where
it does an indirect access to pending_interrupts via env. Cache the
value during entry and reuse later to avoid multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/excp_helper.c | 39 +--
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 0712098cf7..4f158196bb 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1844,8 +1844,10 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
 
 static int p9_interrupt_powersave(CPUPPCState *env)
 {
+uint32_t pending_interrupts = env->pending_interrupts;
+
 /* External Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
+if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
 (env->spr[SPR_LPCR] & LPCR_EEE)) {
 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
 if (!heic || !FIELD_EX64_HV(env->msr) ||
@@ -1854,35 +1856,35 @@ static int p9_interrupt_powersave(CPUPPCState *env)
 }
 }
 /* Decrementer Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
+if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
 (env->spr[SPR_LPCR] & LPCR_DEE)) {
 return PPC_INTERRUPT_DECR;
 }
 /* Machine Check or Hypervisor Maintenance Exception */
 if (env->spr[SPR_LPCR] & LPCR_OEE) {
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_HMI) {
+if (pending_interrupts & PPC_INTERRUPT_HMI) {
 return PPC_INTERRUPT_HMI;
 }
 }
 /* Privileged Doorbell Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
+if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
 return PPC_INTERRUPT_DOORBELL;
 }
 /* Hypervisor Doorbell Exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
+if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
 return PPC_INTERRUPT_HDOORBELL;
 }
 /* Hypervisor virtualization exception */
-if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) &&
+if ((pending_interrupts & PPC_INTERRUPT_HVIRT) &&
 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
 return PPC_INTERRUPT_HVIRT;
 }
-if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+if (pending_interrupts & PPC_INTERRUPT_RESET) {
 return PPC_INTERRUPT_RESET;
 }
 return 0;
@@ -1891,11 +1893,12 @@ static int p9_interrupt_powersave(CPUPPCState *env)
 static int p9_next_unmasked_interrupt(CPUPPCState *env)
 {
 CPUState *cs = env_cpu(env);
+uint32_t pending_interrupts = env->pending_interrupts;
 
 /* Ignore MSR[EE] when coming out of some power management states */
 bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
 
-assert((env->pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
+assert((pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
 
 if (cs->halted) {
 if (env->spr[SPR_PSSCR] & PSSCR_EC) {
@@ -1914,12 +1917,12 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* Machine check exception */
-if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+if (pending_interrupts & PPC_INTERRUPT_MCK) {
 return PPC_INTERRUPT_MCK;
 }
 
 /* Hypervisor decrementer exception */
-if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
+if (pending_interrupts & PPC_INTERRUPT_HDECR) {
 /* LPCR will be clear when not supported so this will work */
 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
@@ -1929,7 +1932,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* Hypervisor virtualization interrupt */
-if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) {
+if (pending_interrupts & PPC_INTERRUPT_HVIRT) {
 /* LPCR will be clear when not supported so this will work */
 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hvice) {
@@ -1938,7 +1941,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env)
 }
 
 /* External interrupt can ignore MSR:EE under some circumstances */
-if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
+if (pending_interrupts & PPC_INTERRUPT_EXT) {
 bool lpes0 =

[PATCH 2/6] target/ppc: optimize hreg_compute_pmu_hflags_value

2024-05-20 Thread Harsh Prateek Bora
Cache env->spr[SPR_POWER_MMCR0] in a local variable as used in multiple
conditions to avoid multiple indirect accesses.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/helper_regs.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 945fa1a596..5de0df5795 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -50,15 +50,16 @@ void hreg_swap_gpr_tgpr(CPUPPCState *env)
 static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState *env)
 {
 uint32_t hflags = 0;
-
 #if defined(TARGET_PPC64)
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC0) {
+target_ulong spr_power_mmcr0 = env->spr[SPR_POWER_MMCR0];
+
+if (spr_power_mmcr0 & MMCR0_PMCC0) {
 hflags |= 1 << HFLAGS_PMCC0;
 }
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) {
+if (spr_power_mmcr0 & MMCR0_PMCC1) {
 hflags |= 1 << HFLAGS_PMCC1;
 }
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) {
+if (spr_power_mmcr0 & MMCR0_PMCjCE) {
 hflags |= 1 << HFLAGS_PMCJCE;
 }
 
-- 
2.39.3




[PATCH 1/6] target/ppc: use locally stored msr and avoid indirect access

2024-05-20 Thread Harsh Prateek Bora
hreg_compute_hflags_value already stores msr locally to be used in most
of the logic in the routine however some instances are still using
env->msr which is unnecessary. Use locally stored value as available.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/helper_regs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 25258986e3..945fa1a596 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -106,10 +106,10 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState 
*env)
 
 if (ppc_flags & POWERPC_FLAG_DE) {
 target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0];
-if ((dbcr0 & DBCR0_ICMP) && FIELD_EX64(env->msr, MSR, DE)) {
+if ((dbcr0 & DBCR0_ICMP) && FIELD_EX64(msr, MSR, DE)) {
 hflags |= 1 << HFLAGS_SE;
 }
-if ((dbcr0 & DBCR0_BRT) && FIELD_EX64(env->msr, MSR, DE)) {
+if ((dbcr0 & DBCR0_BRT) && FIELD_EX64(msr, MSR, DE)) {
 hflags |= 1 << HFLAGS_BE;
 }
 } else {
-- 
2.39.3




[PATCH 0/6] target/ppc: misc ppc improvements/optimizations

2024-05-20 Thread Harsh Prateek Bora
This a set of misc ppc arch specific code improvements/optimizations.
Although there exists similar instances for potential improvements in
the legacy ppc code, however, that can be taken up later as well.

Harsh Prateek Bora (6):
  target/ppc: use locally stored msr and avoid indirect access
  target/ppc: optimize hreg_compute_pmu_hflags_value
  target/ppc: optimize hreg_compute_pmu_hflags_value
  target/ppc: optimize p9 exception handling routines
  target/ppc: reduce duplicate code between init_proc_POWER{9,10}
  target/ppc: redue code duplication across Power9/10 init code

 target/ppc/cpu_init.h|  79 +++
 target/ppc/cpu_init.c| 166 ++-
 target/ppc/excp_helper.c |  39 -
 target/ppc/helper_regs.c |  19 ++---
 4 files changed, 134 insertions(+), 169 deletions(-)
 create mode 100644 target/ppc/cpu_init.h

-- 
2.39.3




[PATCH 5/6] target/ppc: reduce duplicate code between init_proc_POWER{9, 10}

2024-05-20 Thread Harsh Prateek Bora
Historically, the registration of sprs have been inherited alongwith
every new Power arch support being added leading to a lot of code
duplication. It's time to do necessary cleanups now to avoid further
duplication with newer arch support being added.

Signed-off-by: Harsh Prateek Bora 
---
 target/ppc/cpu_init.c | 43 +--
 1 file changed, 9 insertions(+), 34 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 6d82f24c87..636e12ba7a 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6307,7 +6307,7 @@ static struct ppc_radix_page_info POWER9_radix_page_info 
= {
 };
 #endif /* CONFIG_USER_ONLY */
 
-static void init_proc_POWER9(CPUPPCState *env)
+static inline void register_power9_common_sprs(CPUPPCState *env)
 {
 /* Common Registers */
 init_proc_book3s_common(env);
@@ -6326,7 +6326,6 @@ static void init_proc_POWER9(CPUPPCState *env)
 register_power5p_ear_sprs(env);
 register_power5p_tb_sprs(env);
 register_power6_common_sprs(env);
-register_HEIR32_spr(env);
 register_power6_dbg_sprs(env);
 register_power8_tce_address_control_sprs(env);
 register_power8_ids_sprs(env);
@@ -6342,6 +6341,12 @@ static void init_proc_POWER9(CPUPPCState *env)
 register_power9_book4_sprs(env);
 register_power8_rpr_sprs(env);
 register_power9_mmu_sprs(env);
+}
+
+static void init_proc_POWER9(CPUPPCState *env)
+{
+register_power9_common_sprs(env);
+register_HEIR32_spr(env);
 
 /* POWER9 Specific registers */
 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
@@ -6499,39 +6504,9 @@ static struct ppc_radix_page_info 
POWER10_radix_page_info = {
 
 static void init_proc_POWER10(CPUPPCState *env)
 {
-/* Common Registers */
-init_proc_book3s_common(env);
-register_book3s_207_dbg_sprs(env);
-
-/* Common TCG PMU */
-init_tcg_pmu_power8(env);
-
-/* POWER8 Specific Registers */
-register_book3s_ids_sprs(env);
-register_amr_sprs(env);
-register_iamr_sprs(env);
-register_book3s_purr_sprs(env);
-register_power5p_common_sprs(env);
-register_power5p_lpar_sprs(env);
-register_power5p_ear_sprs(env);
-register_power5p_tb_sprs(env);
-register_power6_common_sprs(env);
+register_power9_common_sprs(env);
 register_HEIR64_spr(env);
-register_power6_dbg_sprs(env);
-register_power8_tce_address_control_sprs(env);
-register_power8_ids_sprs(env);
-register_power8_ebb_sprs(env);
-register_power8_fscr_sprs(env);
-register_power8_pmu_sup_sprs(env);
-register_power8_pmu_user_sprs(env);
-register_power8_tm_sprs(env);
-register_power8_pspb_sprs(env);
-register_power8_dpdes_sprs(env);
-register_vtb_sprs(env);
-register_power8_ic_sprs(env);
-register_power9_book4_sprs(env);
-register_power8_rpr_sprs(env);
-register_power9_mmu_sprs(env);
+
 register_power10_hash_sprs(env);
 register_power10_dexcr_sprs(env);
 register_power10_pmu_sup_sprs(env);
-- 
2.39.3




Re: [PATCH] target/ppc: handle vcpu hotplug failure gracefully

2024-05-20 Thread Harsh Prateek Bora




On 5/17/24 09:30, Nicholas Piggin wrote:

On Thu May 16, 2024 at 2:31 PM AEST, Harsh Prateek Bora wrote:

Hi Nick,

On 5/14/24 08:39, Nicholas Piggin wrote:

On Tue Apr 23, 2024 at 4:30 PM AEST, Harsh Prateek Bora wrote:

+ qemu-devel

On 4/23/24 11:40, Harsh Prateek Bora wrote:

On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating vcpu and parking it on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.


So this puts in on the park list so when kvm_init_vcpu() later runs it
will just take it off the park list instead of issuing another
KVM_CREATE_VCPU ioctl.

And kvm_init_vcpu() runs in the vcpu thread function, which does not
have a good way to indicate failure to the caller.

I'm don't know a lot about this part of qemu but it seems like a good
idea to move fail-able initialisation out of the vcpu thread in that
case. So the general idea seems good to me.



Yeh ..



Based on api refactoring to create/park vcpus introduced in 1/8 of patch series:
https://lore.kernel.org/qemu-devel/2024031202.12992-2-salil.me...@huawei.com/


So from this series AFAIKS you're just using kvm_create / kvm_park
routines? You could easily pull that patch 1 out ahead of that larger
series if progress is slow on it, it's a decent cleanup by itself by
the looks.



Yeh, patch 1 of that series is only we need but the author mentioned on
the list that he is about to post next version soon.



Tested OK by repeatedly doing a hotplug/unplug of vcpus as below:

#virsh setvcpus hotplug 40
#virsh setvcpus hotplug 70
error: internal error: unable to execute QEMU command 'device_add':
kvmppc_cpu_realize: vcpu hotplug failed with -12

Reported-by: Anushree Mathur 
Suggested-by: Shivaprasad G Bhat 
Suggested-by: Vaibhav Jain 
Signed-off by: Harsh Prateek Bora 
---
---
target/ppc/kvm.c | 42 ++
1 file changed, 42 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 8231feb2d4..c887f6dfa0 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -48,6 +48,8 @@
#include "qemu/mmap-alloc.h"
#include "elf.h"
#include "sysemu/kvm_int.h"
+#include "sysemu/kvm.h"
+#include "hw/core/accel-cpu.h"

#define PROC_DEVTREE_CPU  "/proc/device-tree/cpus/"

@@ -2339,6 +2341,43 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on)

}
}

+static int max_cpu_index = 0;

+
+static bool kvmppc_cpu_realize(CPUState *cs, Error **errp)
+{
+int ret;
+
+cs->cpu_index = max_cpu_index++;
+
+POWERPC_CPU(cs)->vcpu_id = cs->cpu_index;


So you're overriding the cpu_get_free_index() allocator here.
And you need to because vcpu_id needs to be assigned before
the KVM create, I guess.



Yes ..


I guess it works. I would add a comment like s390x has.


Not sure which comment you were referring to but with exporting
cpu_get_free_index as suggested later, not sure if we still need any
comment.


Yeah that's true.


+
+if (cs->parent_obj.hotplugged) {


Can _all_ kvm cpu creation go via this path? Why just limit it to
hotplugged?


For the initial bootup, we actually want to abort if the requested vCPUs
cant be allocated so that user can retry until the requested vCPUs are
allocated. For hotplug failure, bringing down entire guest isn't fair,
hence the fix.


But you could make the error handling depend on hotplugged, no?
Perhaps put that error handling decision in common code so policy
is the same for all targets and back ends.


Hmm, I think just setting errp appropriately would suffice for both
cases as existing behaviour takes care of the rest of handling.
Something like below:

+static bool kvmppc_cpu_realize(CPUState *cs, Error **errp)
+{
+int ret;
+const char *vcpu_str = (cs->parent_obj.hotplugged == true) ?
+   "hotplug" : "create";
+cs->cpu_index = cpu_get_free_index();
+
+POWERPC_CPU(cs)->vcpu_id = cs->cpu_index;
+
+/* create and park to fail gracefully in case vcpu hotplug fails */
+ret = kvm_create_and_park_vcpu(cs);
+if (ret) {
+error_setg(errp, "%s: vcpu %s failed with %d",
+ __func__, vcpu_str, ret);
+return false;
+}
+return true;
+}




[...]


+}
+
static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
{
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
@@ -2963,4 +3002,7 @@ bool kvm_arch_cpu_check_are_resettable(void)

void kvm_arch_accel_class_init(ObjectClass *oc)

{
+AccelCla

Re: [PATCH] ppc/spapr: Add ibm,pi-features

2024-05-20 Thread Harsh Prateek Bora




On 5/18/24 15:26, Nicholas Piggin wrote:

The ibm,pi-features property has a bit to say whether or not
msgsndp should be used. Linux checks if it is being run under
KVM and avoids msgsndp anyway, but it would be preferable to
rely on this bit.

Signed-off-by: Nicholas Piggin 


Reviewed-by: Harsh Prateek Bora 


---
  hw/ppc/spapr.c | 27 +++
  1 file changed, 27 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 611a9e5184..6891d91e6e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -353,6 +353,31 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
  _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
  }
  
+static void spapr_dt_pi_features(SpaprMachineState *spapr,

+ PowerPCCPU *cpu,
+ void *fdt, int offset)
+{
+uint8_t pi_features[] = { 1, 0,
+0x00 };
+
+if (kvm_enabled() && ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00,
+  0, cpu->compat_pvr)) {
+/*
+ * POWER9 and later CPUs with KVM run in LPAR-per-thread mode where
+ * all threads are essentially independent CPUs, and msgsndp does not
+ * work (because it is physically-addressed) and therefore is
+ * emulated by KVM, so disable it here to ensure XIVE will be used.
+ * This is both KVM and CPU implementation-specific behaviour so a KVM
+ * cap would be cleanest, but for now this works. If KVM ever permits
+ * native msgsndp execution by guests, a cap could be added at that
+ * time.
+ */
+pi_features[2] |= 0x08; /* 4: No msgsndp */
+}
+
+_FDT((fdt_setprop(fdt, offset, "ibm,pi-features", pi_features, 
sizeof(pi_features;
+}
+
  static hwaddr spapr_node0_size(MachineState *machine)
  {
  if (machine->numa_state->num_nodes) {
@@ -815,6 +840,8 @@ static void spapr_dt_cpu(CPUState *cs, void *fdt, int 
offset,
  
  spapr_dt_pa_features(spapr, cpu, fdt, offset);
  
+spapr_dt_pi_features(spapr, cpu, fdt, offset);

+
  _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
 cs->cpu_index / vcpus_per_socket)));
  




Re: [PATCH v2 1/4] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-16 Thread Harsh Prateek Bora

Hi Salil,

On 5/16/24 19:05, Salil Mehta wrote:



  From: Harsh Prateek Bora 
  Sent: Thursday, May 16, 2024 2:07 PM
  
  Hi Salil,
  
  On 5/16/24 17:42, Salil Mehta wrote:

  > Hi Harsh,
  >
  >>   From: Harsh Prateek Bora 
  >>   Sent: Thursday, May 16, 2024 11:15 AM
  >>
  >>   Hi Salil,
  >>
  >>   Thanks for your email.
  >>   Your patch 1/8 is included here based on review comments on my  previous
  >>   patch from one of the maintainers in the community and therefore I  had
  >>   kept you in CC to be aware of the desire of having this independent 
patch to
  >>   get merged earlier even if your other patches in the series may go 
through
  >>   further reviews.
  >
  > I really don’t know which discussion are  you pointing at? Please
  > understand you are fixing a bug and we are pushing a feature which has got 
large series.
  > It will break the patch-set  which is about t be merged.
  >
  > There will be significant overhead of testing on us for the work we
  > have been carrying forward for large time. This will be disruptive. Please 
dont!
  >
  
  I was referring to the review discussion on my prev patch here:

  https://lore.kernel.org/qemu-devel/d191d2jfar7l.2eh4s445m4...@gmail.com/



Sure, I'm, not sure what this means.



No worries. If you had followed the conversation on the review
link I shared, I had made it clear that we are expecting a patch update
from you and it is included here just to facilitate review of additional
patches on the top.





  Although your patch was included with this series only to facilitate review of
  the additional patches depending on just one of your patch.



Generally you rebase your patch-set over the other and clearly state on the 
cover
letter that this patch-set is dependent upon such and such patch-set. Just 
imagine
if everyone starts to unilaterally pick up patches from each other's patch-set 
it will
create a chaos not only for the feature owners but also for the maintainers.



Please go through the review discussion on the link I shared above. It
was included on the suggestion of one of the maintainers. However, if
you are going to send v9 soon, everyone would be happy to wait.



  
  I am not sure what is appearing disruptive here. It is a common practive in

  the community that maintainer(s) can pick individual patches from the
  series if it has been vetted by siginificant number of reviewers.



Don’t you think this patch-set is asking for acceptance for a patch already
part of another patch-set which is about to be accepted and is a bigger feature?
Will it cause maintenance overhead at the last moment? Yes, of course!


No, I dont think so.





  However, in this case, since you have mentioned to post next version soon,
  you need not worry about it as that would be the preferred version for both
  of the series.



Yes, but please understand we are working for the benefit of overall community.
Please cooperate here.



Hope I cleared your confusion. We are waiting to see your v9 soon.

  
  >

  >>
  >>   I am hoping to see your v9 soon and thereafter maintainer(s) may
  choose to
  >>   pick the latest independent patch if needs to be merged earlier.
  >
  >
  > I don’t think you are understanding what problem it is causing. For
  > your small bug fix you are causing significant delays at our end.
  >
  
  I hope I clarfied above that including your patch here doesnt delay anything.

  Hoping to see your v9 soon!
  
  Thanks

  Harsh
  >
  > Thanks
  > Salil.
  >>
  >>   Thanks for your work and let's be hopeful it gets merged soon.
  >>
  >>   regards,
  >>   Harsh
  >>
  >>   On 5/16/24 14:00, Salil Mehta wrote:
  >>   > Hi Harsh,
  >>   >
  >>   > Thanks for your interest in the patch-set but taking away patches like
  >>   > this from other series without any discussion can disrupt others work
  >>   > and its acceptance on time. This is because we will have to put lot of
  >>   > effort in rebasing bigger series and then testing overhead comes
  along
  >>   > with it.
  >>   >
  >>   > The patch-set (from where this  patch has been taken) is part of even
  >>   > bigger series and there have been many people and companies toiling
  to
  >>   > fix the bugs collectively in that series and for years.
  >>   >
  >>   > I'm about float the V9 version of the Arch agnostic series which this
  >>   > patch is part of and you can rebase your patch-set from there. I'm
  >>   > hopeful that it will get accepted in this cycle.
  >>   >
  >>   >
  >>   > Many thanks
  >>   > Salil.
  >>   >
  >>   >>   From: Harsh Prateek Bora 
  

Re: [PATCH v2 1/4] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-16 Thread Harsh Prateek Bora

Hi Salil,

On 5/16/24 17:42, Salil Mehta wrote:

Hi Harsh,


  From: Harsh Prateek Bora 
  Sent: Thursday, May 16, 2024 11:15 AM
  
  Hi Salil,
  
  Thanks for your email.

  Your patch 1/8 is included here based on review comments on my previous
  patch from one of the maintainers in the community and therefore I had
  kept you in CC to be aware of the desire of having this independent patch to
  get merged earlier even if your other patches in the series may go through
  further reviews.


I really don’t know which discussion are  you pointing at? Please understand
you are fixing a bug and we are pushing a feature which has got large series.
It will break the patch-set  which is about t be merged.

There will be significant overhead of testing on us for the work we have been
carrying forward for large time. This will be disruptive. Please dont!



I was referring to the review discussion on my prev patch here:
https://lore.kernel.org/qemu-devel/d191d2jfar7l.2eh4s445m4...@gmail.com/

Although your patch was included with this series only to facilitate
review of the additional patches depending on just one of your patch.

I am not sure what is appearing disruptive here. It is a common practive
in the community that maintainer(s) can pick individual patches from the
series if it has been vetted by siginificant number of reviewers.

However, in this case, since you have mentioned to post next version
soon, you need not worry about it as that would be the preferred version
for both of the series.



  
  I am hoping to see your v9 soon and thereafter maintainer(s) may choose to

  pick the latest independent patch if needs to be merged earlier.



I don’t think you are understanding what problem it is causing. For your
small bug fix you are causing significant delays at our end.



I hope I clarfied above that including your patch here doesnt delay
anything. Hoping to see your v9 soon!

Thanks
Harsh


Thanks
Salil.
  
  Thanks for your work and let's be hopeful it gets merged soon.
  
  regards,

  Harsh
  
  On 5/16/24 14:00, Salil Mehta wrote:

  > Hi Harsh,
  >
  > Thanks for your interest in the patch-set but taking away patches like
  > this from other series without any discussion can disrupt others work
  > and its acceptance on time. This is because we will have to put lot of
  > effort in rebasing bigger series and then testing overhead comes along
  > with it.
  >
  > The patch-set (from where this  patch has been taken) is part of even
  > bigger series and there have been many people and companies toiling to
  > fix the bugs collectively in that series and for years.
  >
  > I'm about float the V9 version of the Arch agnostic series which this
  > patch is part of and you can rebase your patch-set from there. I'm
  > hopeful that it will get accepted in this cycle.
  >
  >
  > Many thanks
  > Salil.
  >
  >>   From: Harsh Prateek Bora 
  >>   Sent: Thursday, May 16, 2024 6:32 AM
  >>
  >>   From: Salil Mehta 
  >>
  >>   KVM vCPU creation is done once during the vCPU realization when
  Qemu
  >>   vCPU thread is spawned. This is common to all the architectures as of
  now.
  >>
  >>   Hot-unplug of vCPU results in destruction of the vCPU object in QOM
  but
  >>   the corresponding KVM vCPU object in the Host KVM is not destroyed
  as
  >>   KVM doesn't support vCPU removal. Therefore, its representative KVM
  >>   vCPU object/context in Qemu is parked.
  >>
  >>   Refactor architecture common logic so that some APIs could be reused
  by
  >>   vCPU Hotplug code of some architectures likes ARM, Loongson etc.
  Update
  >>   new/old APIs with trace events instead of DPRINTF. No functional
  change is
  >>   intended here.
  >>
  >>   Signed-off-by: Salil Mehta 
  >>   Reviewed-by: Gavin Shan 
  >>   Tested-by: Vishnu Pajjuri 
  >>   Reviewed-by: Jonathan Cameron 
  >>   Tested-by: Xianglai Li 
  >>   Tested-by: Miguel Luis 
  >>   Reviewed-by: Shaoqin Huang 
  >>   [harshpb: fixed rebase failures in include/sysemu/kvm.h]
  >>   Signed-off-by: Harsh Prateek Bora 
  >>   ---
  >>include/sysemu/kvm.h   | 15 ++
  >>accel/kvm/kvm-all.c| 64 ---
  -
  >>   --
  >>accel/kvm/trace-events |  5 +++-
  >>3 files changed, 68 insertions(+), 16 deletions(-)
  >>
  >>   diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index
  >>   eaf801bc93..fa3ec74442 100644
  >>   --- a/include/sysemu/kvm.h
  >>   +++ b/include/sysemu/kvm.h
  >>   @@ -434,6 +434,21 @@ void kvm_set_sigmask_len(KVMState *s,
  unsigned
  >>   int sigmask_len);
  >>
  >>int kvm_physical_memory_addr_from_host(KVMState *s, void
 

Re: [PATCH v2 1/4] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-16 Thread Harsh Prateek Bora

Hi Salil,

Thanks for your email.
Your patch 1/8 is included here based on review comments on my previous 
patch from one of the maintainers in the community and therefore I had 
kept you in CC to be aware of the desire of having this independent 
patch to get merged earlier even if your other patches in the series may 
go through further reviews.


I am hoping to see your v9 soon and thereafter maintainer(s) may choose 
to pick the latest independent patch if needs to be merged earlier.


Thanks for your work and let's be hopeful it gets merged soon.

regards,
Harsh

On 5/16/24 14:00, Salil Mehta wrote:

Hi Harsh,

Thanks for your interest in the patch-set but taking away patches like
this from other series without any discussion can disrupt others work
and its acceptance on time. This is because we will have to put lot of
effort in rebasing bigger series and then testing overhead comes along
with it.

The patch-set (from where this  patch has been taken) is part of even
bigger series and there have been many people and companies toiling
to fix the bugs collectively in that series and for years.

I'm about float the V9 version of the Arch agnostic series which this
patch is part of and you can rebase your patch-set from there. I'm
hopeful that it will get accepted in this cycle.


Many thanks
Salil.


  From: Harsh Prateek Bora 
  Sent: Thursday, May 16, 2024 6:32 AM
  
  From: Salil Mehta 
  
  KVM vCPU creation is done once during the vCPU realization when Qemu

  vCPU thread is spawned. This is common to all the architectures as of now.
  
  Hot-unplug of vCPU results in destruction of the vCPU object in QOM but

  the corresponding KVM vCPU object in the Host KVM is not destroyed as
  KVM doesn't support vCPU removal. Therefore, its representative KVM
  vCPU object/context in Qemu is parked.
  
  Refactor architecture common logic so that some APIs could be reused by

  vCPU Hotplug code of some architectures likes ARM, Loongson etc. Update
  new/old APIs with trace events instead of DPRINTF. No functional change is
  intended here.
  
  Signed-off-by: Salil Mehta 

  Reviewed-by: Gavin Shan 
  Tested-by: Vishnu Pajjuri 
  Reviewed-by: Jonathan Cameron 
  Tested-by: Xianglai Li 
  Tested-by: Miguel Luis 
  Reviewed-by: Shaoqin Huang 
  [harshpb: fixed rebase failures in include/sysemu/kvm.h]
  Signed-off-by: Harsh Prateek Bora 
  ---
   include/sysemu/kvm.h   | 15 ++
   accel/kvm/kvm-all.c| 64 
  --
   accel/kvm/trace-events |  5 +++-
   3 files changed, 68 insertions(+), 16 deletions(-)
  
  diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index

  eaf801bc93..fa3ec74442 100644
  --- a/include/sysemu/kvm.h
  +++ b/include/sysemu/kvm.h
  @@ -434,6 +434,21 @@ void kvm_set_sigmask_len(KVMState *s, unsigned
  int sigmask_len);
  
   int kvm_physical_memory_addr_from_host(KVMState *s, void

  *ram_addr,
  hwaddr *phys_addr);
  +/**
  + * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM vCPU
  + * @cpu: QOM CPUState object for which KVM vCPU has to be
  fetched/created.
  + *
  + * @returns: 0 when success, errno (<0) when failed.
  + */
  +int kvm_create_vcpu(CPUState *cpu);
  +
  +/**
  + * kvm_park_vcpu - Park QEMU KVM vCPU context
  + * @cpu: QOM CPUState object for which QEMU KVM vCPU context has to
  be parked.
  + *
  + * @returns: none
  + */
  +void kvm_park_vcpu(CPUState *cpu);
  
   #endif /* COMPILING_PER_TARGET */
  
  diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index

  d7281b93f3..30d42847de 100644
  --- a/accel/kvm/kvm-all.c
  +++ b/accel/kvm/kvm-all.c
  @@ -128,6 +128,7 @@ static QemuMutex kml_slots_lock;  #define
  kvm_slots_unlock()  qemu_mutex_unlock(&kml_slots_lock)
  
   static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);

  +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
  
   static inline void kvm_resample_fd_remove(int gsi)  { @@ -340,14 +341,53

  @@ err:
   return ret;
   }
  
  +void kvm_park_vcpu(CPUState *cpu)

  +{
  +struct KVMParkedVcpu *vcpu;
  +
  +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
  +
  +vcpu = g_malloc0(sizeof(*vcpu));
  +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
  +vcpu->kvm_fd = cpu->kvm_fd;
  +QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node); }
  +
  +int kvm_create_vcpu(CPUState *cpu)
  +{
  +unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
  +KVMState *s = kvm_state;
  +int kvm_fd;
  +
  +trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
  +
  +/* check if the KVM vCPU already exist but is parked */
  +kvm_fd = kvm_get_vcpu(s, vcpu_id);
  +if (kvm_fd < 0) {
  +/* vCPU not parked: create a new KVM vCPU */
  +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
  +if (kvm_fd < 0) {
  +error_report("KVM_CREATE_VCPU IOCTL fa

[PATCH v2 2/4] accel/kvm: Introduce kvm_create_and_park_vcpu() helper

2024-05-15 Thread Harsh Prateek Bora
There are distinct helpers for creating and parking a KVM vCPU.
However, there can be cases where a platform needs to create and
immediately park the vCPU during early stages of vcpu init which
can later be reused when vcpu thread gets initialized. This would
help detect failures with kvm_create_vcpu at an early stage.

Based on api refactoring to create/park vcpus introduced in 1/8 of patch series:
https://lore.kernel.org/qemu-devel/2024031202.12992-2-salil.me...@huawei.com/

Suggested-by: Nicholas Piggin 
Signed-off-by: Harsh Prateek Bora 
---
 include/sysemu/kvm.h |  8 
 accel/kvm/kvm-all.c  | 12 
 2 files changed, 20 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index fa3ec74442..221e6bd55b 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -450,6 +450,14 @@ int kvm_create_vcpu(CPUState *cpu);
  */
 void kvm_park_vcpu(CPUState *cpu);
 
+/**
+ * kvm_create_and_park_vcpu - Create and park a KVM vCPU
+ * @cpu: QOM CPUState object for which KVM vCPU has to be created and parked.
+ *
+ * @returns: 0 when success, errno (<0) when failed.
+ */
+int kvm_create_and_park_vcpu(CPUState *cpu);
+
 #endif /* COMPILING_PER_TARGET */
 
 void kvm_cpu_synchronize_state(CPUState *cpu);
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 30d42847de..3d7e5eaf0b 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -381,6 +381,18 @@ int kvm_create_vcpu(CPUState *cpu)
 return 0;
 }
 
+int kvm_create_and_park_vcpu(CPUState *cpu)
+{
+int ret = 0;
+
+ret = kvm_create_vcpu(cpu);
+if (!ret) {
+kvm_park_vcpu(cpu);
+}
+
+return ret;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
-- 
2.39.3




[PATCH v2 3/4] cpu-common.c: export cpu_get_free_index to be reused later

2024-05-15 Thread Harsh Prateek Bora
This helper provides an easy way to identify the next available free cpu
index which can be used for vcpu creation. Until now, this is being
called at a very later stage and there is a need to be able to call it
earlier (for now, with ppc64) hence the need to export.

Suggested-by: Nicholas Piggin 
Signed-off-by: Harsh Prateek Bora 
---
 include/exec/cpu-common.h | 2 ++
 cpu-common.c  | 7 ---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 6d5318895a..0386f1ab29 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -29,6 +29,8 @@ void cpu_list_lock(void);
 void cpu_list_unlock(void);
 unsigned int cpu_list_generation_id_get(void);
 
+int cpu_get_free_index(void);
+
 void tcg_iommu_init_notifier_list(CPUState *cpu);
 void tcg_iommu_free_notifier_list(CPUState *cpu);
 
diff --git a/cpu-common.c b/cpu-common.c
index ce78273af5..82bd1b432d 100644
--- a/cpu-common.c
+++ b/cpu-common.c
@@ -57,14 +57,12 @@ void cpu_list_unlock(void)
 qemu_mutex_unlock(&qemu_cpu_list_lock);
 }
 
-static bool cpu_index_auto_assigned;
 
-static int cpu_get_free_index(void)
+int cpu_get_free_index(void)
 {
 CPUState *some_cpu;
 int max_cpu_index = 0;
 
-cpu_index_auto_assigned = true;
 CPU_FOREACH(some_cpu) {
 if (some_cpu->cpu_index >= max_cpu_index) {
 max_cpu_index = some_cpu->cpu_index + 1;
@@ -83,8 +81,11 @@ unsigned int cpu_list_generation_id_get(void)
 
 void cpu_list_add(CPUState *cpu)
 {
+static bool cpu_index_auto_assigned;
+
 QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
 if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) {
+cpu_index_auto_assigned = true;
 cpu->cpu_index = cpu_get_free_index();
 assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX);
 } else {
-- 
2.39.3




[PATCH v2 1/4] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-15 Thread Harsh Prateek Bora
From: Salil Mehta 

KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events instead of DPRINTF. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
[harshpb: fixed rebase failures in include/sysemu/kvm.h]
Signed-off-by: Harsh Prateek Bora 
---
 include/sysemu/kvm.h   | 15 ++
 accel/kvm/kvm-all.c| 64 --
 accel/kvm/trace-events |  5 +++-
 3 files changed, 68 insertions(+), 16 deletions(-)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index eaf801bc93..fa3ec74442 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -434,6 +434,21 @@ void kvm_set_sigmask_len(KVMState *s, unsigned int 
sigmask_len);
 
 int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
hwaddr *phys_addr);
+/**
+ * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM vCPU
+ * @cpu: QOM CPUState object for which KVM vCPU has to be fetched/created.
+ *
+ * @returns: 0 when success, errno (<0) when failed.
+ */
+int kvm_create_vcpu(CPUState *cpu);
+
+/**
+ * kvm_park_vcpu - Park QEMU KVM vCPU context
+ * @cpu: QOM CPUState object for which QEMU KVM vCPU context has to be parked.
+ *
+ * @returns: none
+ */
+void kvm_park_vcpu(CPUState *cpu);
 
 #endif /* COMPILING_PER_TARGET */
 
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index d7281b93f3..30d42847de 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -128,6 +128,7 @@ static QemuMutex kml_slots_lock;
 #define kvm_slots_unlock()  qemu_mutex_unlock(&kml_slots_lock)
 
 static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
+static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
 
 static inline void kvm_resample_fd_remove(int gsi)
 {
@@ -340,14 +341,53 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_get_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-trace_kvm_destroy_vcpu();
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -373,10 +413,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -397,6 +434,8 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 if (cpu->vcpu_id == vcpu_id) {
 int kvm_fd;
 
+trace_kvm_get_vcpu(vcpu_id);
+
 QLIST_REMOVE(cpu, node);
 kvm_fd = cpu->kvm_fd;
 g_free(cpu);
@@ -404,7 +443,7 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 }
 }
 
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
+return -ENOENT;
 }
 
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
@@ -415,19 +454,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_ar

[PATCH v2 4/4] target/ppc: handle vcpu hotplug failure gracefully

2024-05-15 Thread Harsh Prateek Bora
On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating and parking vcpu on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.

Based on api refactoring to create/park vcpus introduced in 1/8 of patch series:
https://lore.kernel.org/qemu-devel/2024031202.12992-2-salil.me...@huawei.com/

Tested OK by repeatedly doing a hotplug/unplug of vcpus as below:

 #virsh setvcpus hotplug 40
 #virsh setvcpus hotplug 70
error: internal error: unable to execute QEMU command 'device_add':
kvmppc_cpu_realize: vcpu hotplug failed with -12

Reported-by: Anushree Mathur 
Suggested-by: Shivaprasad G Bhat 
Suggested-by: Vaibhav Jain 
Signed-off by: Harsh Prateek Bora 
Tested-by: Anushree Mathur 
---
 target/ppc/kvm.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 63930d4a77..25f0cf0ba8 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -48,6 +48,8 @@
 #include "qemu/mmap-alloc.h"
 #include "elf.h"
 #include "sysemu/kvm_int.h"
+#include "sysemu/kvm.h"
+#include "hw/core/accel-cpu.h"
 
 #define PROC_DEVTREE_CPU  "/proc/device-tree/cpus/"
 
@@ -2339,6 +2341,26 @@ static void alter_insns(uint64_t *word, uint64_t flags, 
bool on)
 }
 }
 
+static bool kvmppc_cpu_realize(CPUState *cs, Error **errp)
+{
+int ret;
+
+cs->cpu_index = cpu_get_free_index();
+
+POWERPC_CPU(cs)->vcpu_id = cs->cpu_index;
+
+if (cs->parent_obj.hotplugged) {
+/* create and park to fail gracefully in case vcpu hotplug fails */
+ret = kvm_create_and_park_vcpu(cs);
+if (ret) {
+error_setg(errp, "%s: vcpu hotplug failed with %d",
+ __func__, ret);
+return false;
+}
+}
+return true;
+}
+
 static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
 {
 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
@@ -2958,4 +2980,6 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t 
tb_offset)
 
 void kvm_arch_accel_class_init(ObjectClass *oc)
 {
+AccelClass *ac = ACCEL_CLASS(oc);
+ac->cpu_common_realize = kvmppc_cpu_realize;
 }
-- 
2.39.3




[PATCH v2 0/4] target/ppc: vcpu hotplug failure handling fixes

2024-05-15 Thread Harsh Prateek Bora
On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating and parking vcpu on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.

This series adds another helper to create and park vcpu (based on below
patch by Salil), exports cpu_get_free_index to be reused later and adds
ppc arch specfic handling for vcpu hotplug failure.

Based on api refactoring to create/park vcpus introduced in 1/8 of patch series:
https://lore.kernel.org/qemu-devel/2024031202.12992-2-salil.me...@huawei.com/

PS: I have just included patch 1 of above series after fixing a rebase
failure along with this series for better review purpose only.

Changelog:

v2: Addressed review comments from Nick
v1: Initial patch

Harsh Prateek Bora (3):
  accel/kvm: Introduce kvm_create_and_park_vcpu() helper
  cpu-common.c: export cpu_get_free_index to be reused later
  target/ppc: handle vcpu hotplug failure gracefully

Salil Mehta (1):
  accel/kvm: Extract common KVM vCPU {creation, parking} code

 include/exec/cpu-common.h |  2 ++
 include/sysemu/kvm.h  | 23 
 accel/kvm/kvm-all.c   | 76 +++
 cpu-common.c  |  7 ++--
 target/ppc/kvm.c  | 24 +
 accel/kvm/trace-events|  5 ++-
 6 files changed, 118 insertions(+), 19 deletions(-)

-- 
2.39.3




Re: [PATCH] target/ppc: handle vcpu hotplug failure gracefully

2024-05-15 Thread Harsh Prateek Bora

Hi Nick,

On 5/14/24 08:39, Nicholas Piggin wrote:

On Tue Apr 23, 2024 at 4:30 PM AEST, Harsh Prateek Bora wrote:

+ qemu-devel

On 4/23/24 11:40, Harsh Prateek Bora wrote:

On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating vcpu and parking it on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.


So this puts in on the park list so when kvm_init_vcpu() later runs it
will just take it off the park list instead of issuing another
KVM_CREATE_VCPU ioctl.

And kvm_init_vcpu() runs in the vcpu thread function, which does not
have a good way to indicate failure to the caller.

I'm don't know a lot about this part of qemu but it seems like a good
idea to move fail-able initialisation out of the vcpu thread in that
case. So the general idea seems good to me.



Yeh ..



Based on api refactoring to create/park vcpus introduced in 1/8 of patch series:
https://lore.kernel.org/qemu-devel/2024031202.12992-2-salil.me...@huawei.com/


So from this series AFAIKS you're just using kvm_create / kvm_park
routines? You could easily pull that patch 1 out ahead of that larger
series if progress is slow on it, it's a decent cleanup by itself by
the looks.



Yeh, patch 1 of that series is only we need but the author mentioned on 
the list that he is about to post next version soon.




Tested OK by repeatedly doing a hotplug/unplug of vcpus as below:

   #virsh setvcpus hotplug 40
   #virsh setvcpus hotplug 70
error: internal error: unable to execute QEMU command 'device_add':
kvmppc_cpu_realize: vcpu hotplug failed with -12

Reported-by: Anushree Mathur 
Suggested-by: Shivaprasad G Bhat 
Suggested-by: Vaibhav Jain 
Signed-off by: Harsh Prateek Bora 
---
---
   target/ppc/kvm.c | 42 ++
   1 file changed, 42 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 8231feb2d4..c887f6dfa0 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -48,6 +48,8 @@
   #include "qemu/mmap-alloc.h"
   #include "elf.h"
   #include "sysemu/kvm_int.h"
+#include "sysemu/kvm.h"
+#include "hw/core/accel-cpu.h"
   
   #define PROC_DEVTREE_CPU  "/proc/device-tree/cpus/"
   
@@ -2339,6 +2341,43 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on)

   }
   }
   
+static int max_cpu_index = 0;

+
+static bool kvmppc_cpu_realize(CPUState *cs, Error **errp)
+{
+int ret;
+
+cs->cpu_index = max_cpu_index++;
+
+POWERPC_CPU(cs)->vcpu_id = cs->cpu_index;


So you're overriding the cpu_get_free_index() allocator here.
And you need to because vcpu_id needs to be assigned before
the KVM create, I guess.



Yes ..


I guess it works. I would add a comment like s390x has.


Not sure which comment you were referring to but with exporting
cpu_get_free_index as suggested later, not sure if we still need any
comment.


+
+if (cs->parent_obj.hotplugged) {


Can _all_ kvm cpu creation go via this path? Why just limit it to
hotplugged?


For the initial bootup, we actually want to abort if the requested vCPUs
cant be allocated so that user can retry until the requested vCPUs are
allocated. For hotplug failure, bringing down entire guest isn't fair,
hence the fix.




+/* create and park to fail gracefully in case vcpu hotplug fails */
+ret = kvm_create_vcpu(cs);
+if (!ret) {
+kvm_park_vcpu(cs);


Seems like a small thing, but I would add a new core kvm function
that creates and parks the vcpu, so the target code doesn't have
to know about the parking internals, just that it needs to be
called.


Make sense, I will add another kvm helper: kvm_create_and_park_vcpu()



Unless I'm missing something, we could get all targets to move their kvm
create to here and remove it removed from kvm_init_vcpu(), that would
just expect it to be on the parked list. But that could be done
incrementally.


Hmm ..




+} else {
+max_cpu_index--;
+error_setg(errp, "%s: vcpu hotplug failed with %d",
+ __func__, ret);
+return false;
+}
+}
+return true;
+}
+
+static void kvmppc_cpu_unrealize(CPUState *cpu)
+{
+if (POWERPC_CPU(cpu)->vcpu_id == (max_cpu_index - 1)) {
+/* only reclaim vcpuid if its the last one assigned
+ * as reclaiming random vcpuid for parked vcpus may lead
+ * to unexpected behaviour due to an existing kernel bug
+ * when drc_index doesnt get reclaimed as expected.
+ */
+max_cpu_index--;
+}


This looks like a fairly lossy allocator. Using cpu_get_free_index

Re: [PATCH] spapr: Migrate ail-mode-3 spapr cap

2024-05-06 Thread Harsh Prateek Bora




On 5/6/24 17:26, Nicholas Piggin wrote:

This cap did not add the migration code when it was introduced. This
results in migration failure when changing the default using the
command line.

Cc: qemu-sta...@nongnu.org
Fixes: ccc5a4c5e10 ("spapr: Add SPAPR_CAP_AIL_MODE_3 for AIL mode 3 support for 
H_SET_MODE hcall")
Signed-off-by: Nicholas Piggin 


Reviewed-by: Harsh Prateek Bora 


---
  include/hw/ppc/spapr.h | 1 +
  hw/ppc/spapr.c | 1 +
  hw/ppc/spapr_caps.c| 1 +
  3 files changed, 3 insertions(+)

diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 4aaf23d28f..f6de3e9972 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -1004,6 +1004,7 @@ extern const VMStateDescription 
vmstate_spapr_cap_large_decr;
  extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
  extern const VMStateDescription vmstate_spapr_cap_fwnmi;
  extern const VMStateDescription vmstate_spapr_cap_rpt_invalidate;
+extern const VMStateDescription vmstate_spapr_cap_ail_mode_3;
  extern const VMStateDescription vmstate_spapr_wdt;
  
  static inline uint8_t spapr_get_cap(SpaprMachineState *spapr, int cap)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d2d1e310a3..065f58ec93 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2169,6 +2169,7 @@ static const VMStateDescription vmstate_spapr = {
  &vmstate_spapr_cap_fwnmi,
  &vmstate_spapr_fwnmi,
  &vmstate_spapr_cap_rpt_invalidate,
+&vmstate_spapr_cap_ail_mode_3,
  &vmstate_spapr_cap_nested_papr,
  NULL
  }
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 0a15415a1d..2f74923560 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -974,6 +974,7 @@ SPAPR_CAP_MIG_STATE(large_decr, 
SPAPR_CAP_LARGE_DECREMENTER);
  SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
  SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI);
  SPAPR_CAP_MIG_STATE(rpt_invalidate, SPAPR_CAP_RPT_INVALIDATE);
+SPAPR_CAP_MIG_STATE(ail_mode_3, SPAPR_CAP_AIL_MODE_3);
  
  void spapr_caps_init(SpaprMachineState *spapr)

  {




Re: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-04-22 Thread Harsh Prateek Bora

+ Nick

Hi Salil,
I have posted a patch [1] for ppc which based on this refactoring patch.
I see there were some comments from Vishnu on this patch.
Are we expecting any further updates on this patch before merge?

Thanks
Harsh

[1] 
https://lore.kernel.org/qemu-devel/a0f9b2fc-4c8a-4c37-bc36-26bbaa627...@linux.ibm.com/T/#u


On 3/22/24 13:45, Harsh Prateek Bora wrote:

+ Vaibhav, Shiva

Hi Salil,

I came across your patch while trying to solve a related problem on 
spapr. One query below ..


On 3/12/24 07:29, Salil Mehta via wrote:
KVM vCPU creation is done once during the vCPU realization when Qemu 
vCPU thread

is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM 
but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM 
doesn't
support vCPU removal. Therefore, its representative KVM vCPU 
object/context in

Qemu is parked.

Refactor architecture common logic so that some APIs could be reused 
by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update 
new/old APIs
with trace events instead of DPRINTF. No functional change is intended 
here.


Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
  accel/kvm/kvm-all.c    | 64 --
  accel/kvm/trace-events |  5 +++-
  include/sysemu/kvm.h   | 16 +++
  3 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index a8cecd040e..3bc3207bda 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -126,6 +126,7 @@ static QemuMutex kml_slots_lock;
  #define kvm_slots_unlock()  qemu_mutex_unlock(&kml_slots_lock)
  static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
+static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
  static inline void kvm_resample_fd_remove(int gsi)
  {
@@ -314,14 +315,53 @@ err:
  return ret;
  }
+void kvm_park_vcpu(CPUState *cpu)
+{
+    struct KVMParkedVcpu *vcpu;
+
+    trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+    vcpu = g_malloc0(sizeof(*vcpu));
+    vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+    vcpu->kvm_fd = cpu->kvm_fd;
+    QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+    unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+    KVMState *s = kvm_state;
+    int kvm_fd;
+
+    trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+    /* check if the KVM vCPU already exist but is parked */
+    kvm_fd = kvm_get_vcpu(s, vcpu_id);
+    if (kvm_fd < 0) {
+    /* vCPU not parked: create a new KVM vCPU */
+    kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+    if (kvm_fd < 0) {
+    error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", 
vcpu_id);

+    return kvm_fd;
+    }
+    }
+
+    cpu->kvm_fd = kvm_fd;
+    cpu->kvm_state = s;
+    cpu->vcpu_dirty = true;
+    cpu->dirty_pages = 0;
+    cpu->throttle_us_per_full = 0;
+
+    return 0;
+}
+
  static int do_kvm_destroy_vcpu(CPUState *cpu)
  {
  KVMState *s = kvm_state;
  long mmap_size;
-    struct KVMParkedVcpu *vcpu = NULL;
  int ret = 0;
-    trace_kvm_destroy_vcpu();
+    trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
  ret = kvm_arch_destroy_vcpu(cpu);
  if (ret < 0) {
@@ -347,10 +387,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
  }
  }
-    vcpu = g_malloc0(sizeof(*vcpu));
-    vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-    vcpu->kvm_fd = cpu->kvm_fd;
-    QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
+    kvm_park_vcpu(cpu);
  err:
  return ret;
  }
@@ -371,6 +408,8 @@ static int kvm_get_vcpu(KVMState *s, unsigned long 
vcpu_id)

  if (cpu->vcpu_id == vcpu_id) {
  int kvm_fd;
+    trace_kvm_get_vcpu(vcpu_id);
+
  QLIST_REMOVE(cpu, node);
  kvm_fd = cpu->kvm_fd;
  g_free(cpu);
@@ -378,7 +417,7 @@ static int kvm_get_vcpu(KVMState *s, unsigned long 
vcpu_id)

  }
  }
-    return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
+    return -ENOENT;
  }
  int kvm_init_vcpu(CPUState *cpu, Error **errp)
@@ -389,19 +428,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
  trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
-    ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+    ret = kvm_create_vcpu(cpu);
  if (ret < 0) {
-    error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu 
failed (%lu)",

+    error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
   kvm_arch_vcpu_id(cpu));


If a vcpu hotplug fails due to failure with kvm_crea

Re: [PATCH] target/ppc: handle vcpu hotplug failure gracefully

2024-04-22 Thread Harsh Prateek Bora

+ qemu-devel

On 4/23/24 11:40, Harsh Prateek Bora wrote:

On ppc64, the PowerVM hypervisor runs with limited memory and a VCPU
creation during hotplug may fail during kvm_ioctl for KVM_CREATE_VCPU,
leading to termination of guest since errp is set to &error_fatal while
calling kvm_init_vcpu. This unexpected behaviour can be avoided by
pre-creating vcpu and parking it on success or return error otherwise.
This enables graceful error delivery for any vcpu hotplug failures while
the guest can keep running.

Based on api refactoring to create/park vcpus introduced in 1/8 of patch series:
https://lore.kernel.org/qemu-devel/2024031202.12992-2-salil.me...@huawei.com/

Tested OK by repeatedly doing a hotplug/unplug of vcpus as below:

  #virsh setvcpus hotplug 40
  #virsh setvcpus hotplug 70
error: internal error: unable to execute QEMU command 'device_add':
kvmppc_cpu_realize: vcpu hotplug failed with -12

Reported-by: Anushree Mathur 
Suggested-by: Shivaprasad G Bhat 
Suggested-by: Vaibhav Jain 
Signed-off by: Harsh Prateek Bora 
---
---
  target/ppc/kvm.c | 42 ++
  1 file changed, 42 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 8231feb2d4..c887f6dfa0 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -48,6 +48,8 @@
  #include "qemu/mmap-alloc.h"
  #include "elf.h"
  #include "sysemu/kvm_int.h"
+#include "sysemu/kvm.h"
+#include "hw/core/accel-cpu.h"
  
  #define PROC_DEVTREE_CPU  "/proc/device-tree/cpus/"
  
@@ -2339,6 +2341,43 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on)

  }
  }
  
+static int max_cpu_index = 0;

+
+static bool kvmppc_cpu_realize(CPUState *cs, Error **errp)
+{
+int ret;
+
+cs->cpu_index = max_cpu_index++;
+
+POWERPC_CPU(cs)->vcpu_id = cs->cpu_index;
+
+if (cs->parent_obj.hotplugged) {
+/* create and park to fail gracefully in case vcpu hotplug fails */
+ret = kvm_create_vcpu(cs);
+if (!ret) {
+kvm_park_vcpu(cs);
+} else {
+max_cpu_index--;
+error_setg(errp, "%s: vcpu hotplug failed with %d",
+ __func__, ret);
+return false;
+}
+}
+return true;
+}
+
+static void kvmppc_cpu_unrealize(CPUState *cpu)
+{
+if (POWERPC_CPU(cpu)->vcpu_id == (max_cpu_index - 1)) {
+/* only reclaim vcpuid if its the last one assigned
+ * as reclaiming random vcpuid for parked vcpus may lead
+ * to unexpected behaviour due to an existing kernel bug
+ * when drc_index doesnt get reclaimed as expected.
+ */
+max_cpu_index--;
+}
+}
+
  static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
  {
  PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
@@ -2963,4 +3002,7 @@ bool kvm_arch_cpu_check_are_resettable(void)
  
  void kvm_arch_accel_class_init(ObjectClass *oc)

  {
+AccelClass *ac = ACCEL_CLASS(oc);
+ac->cpu_common_realize = kvmppc_cpu_realize;
+ac->cpu_common_unrealize = kvmppc_cpu_unrealize;
  }




Re: [PATCH 22/24] exec: Remove 'exec/tswap.h' from 'exec/cpu-all.h'

2024-04-18 Thread Harsh Prateek Bora




On 4/19/24 00:55, Philippe Mathieu-Daudé wrote:

"exec/cpu-all.h" doesn't require "exec/tswap.h". Remove it,
including it in the sources when required.

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/xtensa/bootparam.h   | 1 +
  include/exec/cpu-all.h  | 1 -
  accel/tcg/translator.c  | 1 +
  hw/arm/boot.c   | 1 +
  hw/arm/npcm7xx.c| 1 +
  hw/mips/fuloong2e.c | 1 +
  hw/mips/malta.c | 1 +
  hw/ppc/sam460ex.c   | 1 +
  hw/ppc/spapr.c  | 1 +


For spapr:
Reviewed-by: Harsh Prateek Bora 


  hw/ppc/virtex_ml507.c   | 1 +
  hw/sh4/r2d.c| 1 +
  target/arm/gdbstub.c| 1 +
  target/xtensa/xtensa-semi.c | 1 +
  13 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/hw/xtensa/bootparam.h b/hw/xtensa/bootparam.h
index f57ff850bc..e1d47b503c 100644
--- a/hw/xtensa/bootparam.h
+++ b/hw/xtensa/bootparam.h
@@ -1,6 +1,7 @@
  #ifndef HW_XTENSA_BOOTPARAM_H
  #define HW_XTENSA_BOOTPARAM_H
  
+#include "exec/tswap.h"

  #include "exec/cpu-common.h"
  
  #define BP_TAG_COMMAND_LINE 0x1001  /* command line (0-terminated string)*/

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 554b937ddb..cfbf51822c 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -21,7 +21,6 @@
  
  #include "exec/cpu-common.h"

  #include "exec/memory.h"
-#include "exec/tswap.h"
  #include "hw/core/cpu.h"
  
  /* some important defines:

diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 6832e55135..85950377d9 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -12,6 +12,7 @@
  #include "qemu/error-report.h"
  #include "exec/exec-all.h"
  #include "exec/translator.h"
+#include "exec/tswap.h"
  #include "exec/cpu_ldst.h"
  #include "exec/plugin-gen.h"
  #include "tcg/tcg-op-common.h"
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 84ea6a807a..93945a1a15 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -22,6 +22,7 @@
  #include "sysemu/reset.h"
  #include "hw/loader.h"
  #include "elf.h"
+#include "exec/tswap.h"
  #include "sysemu/device_tree.h"
  #include "qemu/config-file.h"
  #include "qemu/option.h"
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index cc68b5d8f1..1ef303415b 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -27,6 +27,7 @@
  #include "qemu/units.h"
  #include "sysemu/sysemu.h"
  #include "target/arm/cpu-qom.h"
+#include "exec/tswap.h"
  
  /*

   * This covers the whole MMIO space. We'll use this to catch any MMIO accesses
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index a45aac368c..1d0613a76f 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -40,6 +40,7 @@
  #include "sysemu/reset.h"
  #include "sysemu/sysemu.h"
  #include "qemu/error-report.h"
+#include "exec/tswap.h"
  
  #define ENVP_PADDR  0x2000

  #define ENVP_VADDR  cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR)
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index af74008c82..3dca0f100c 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -56,6 +56,7 @@
  #include "semihosting/semihost.h"
  #include "hw/mips/cps.h"
  #include "hw/qdev-clock.h"
+#include "exec/tswap.h"
  #include "target/mips/internal.h"
  #include "trace.h"
  #include "cpu.h"
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index d42b677898..abc02f0817 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -24,6 +24,7 @@
  #include "hw/loader.h"
  #include "elf.h"
  #include "exec/memory.h"
+#include "exec/tswap.h"
  #include "ppc440.h"
  #include "hw/pci-host/ppc4xx.h"
  #include "hw/block/flash.h"
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e9bc97fee0..b4b1f43983 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -74,6 +74,7 @@
  #include "hw/virtio/virtio-scsi.h"
  #include "hw/virtio/vhost-scsi-common.h"
  
+#include "exec/tswap.h"

  #include "exec/ram_addr.h"
  #include "hw/usb.h"
  #include "qemu/config-file.h"
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index d02f330650..fd23afebf5 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -38,6 +38,7 @@
  #include "qapi/error.h"
  #include "qemu/error-report.h"
  #include "qemu/option.h"
+#include "exec/tswap.h"
  
  #include "hw/intc/ppc-uic.h"

  #include "hw/ppc/ppc.h"
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index e5ac6751bd..5f4420f534 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -43,6 +43,7 @@
  #include "hw/l

Re: [PATCH v2 03/13] hw/ppc/spapr: Replace sprintf() by snprintf()

2024-04-14 Thread Harsh Prateek Bora




On 4/11/24 15:45, Philippe Mathieu-Daudé wrote:

sprintf() is deprecated on Darwin since macOS 13.0 / XCode 14.1,
resulting in painful developper experience.


s/developper/developer ?



Replace sprintf() by snprintf() in order to avoid:

   hw/ppc/spapr.c:385:5: warning: 'sprintf' is deprecated:
 This function is provided for compatibility reasons only.
 Due to security concerns inherent in the design of sprintf(3),
 it is highly recommended that you use snprintf(3) instead.
 [-Wdeprecated-declarations]
   sprintf(mem_name, "memory@%" HWADDR_PRIx, start);
   ^
   1 warning generated.

Signed-off-by: Philippe Mathieu-Daudé 


With the typo fixed,

Reviewed-by: Harsh Prateek Bora 


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

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e9bc97fee0..9e97992c79 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -382,7 +382,7 @@ static int spapr_dt_memory_node(SpaprMachineState *spapr, 
void *fdt, int nodeid,
  mem_reg_property[0] = cpu_to_be64(start);
  mem_reg_property[1] = cpu_to_be64(size);
  
-sprintf(mem_name, "memory@%" HWADDR_PRIx, start);

+snprintf(mem_name, sizeof(mem_name), "memory@%" HWADDR_PRIx, start);
  off = fdt_add_subnode(fdt, 0, mem_name);
  _FDT(off);
  _FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));




[PATCH] spapr: nested: use bitwise NOT operator for flags check

2024-03-28 Thread Harsh Prateek Bora
Check for flag bit in H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE need to use
bitwise NOT operator to ensure no other flag bits are set.
Reported by Coverity as CID 1540008, 1540009.

Reported-by: Peter Maydell 
Signed-off by: Harsh Prateek Bora 
---
 hw/ppc/spapr_nested.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_nested.c b/hw/ppc/spapr_nested.c
index 936659b4c0..c02785756c 100644
--- a/hw/ppc/spapr_nested.c
+++ b/hw/ppc/spapr_nested.c
@@ -1511,7 +1511,7 @@ static target_ulong h_guest_getset_state(PowerPCCPU *cpu,
 if (flags & H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE) {
 gsr.flags |= GUEST_STATE_REQUEST_GUEST_WIDE;
 }
-if (flags & !H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE) {
+if (flags & ~H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE) {
 return H_PARAMETER; /* flag not supported yet */
 }
 
-- 
2.39.3




Re: [PULL 35/38] spapr: nested: Introduce H_GUEST_[GET|SET]_STATE hcalls.

2024-03-28 Thread Harsh Prateek Bora




On 3/28/24 20:55, Peter Maydell wrote:

On Wed, 27 Mar 2024 at 05:41, Harsh Prateek Bora  wrote:




On 3/26/24 21:32, Peter Maydell wrote:

On Tue, 12 Mar 2024 at 17:11, Nicholas Piggin  wrote:


From: Harsh Prateek Bora 

Introduce the nested PAPR hcalls:
  - H_GUEST_GET_STATE which is used to get state of a nested guest or
a guest VCPU. The value field for each element in the request is
destination to be updated to reflect current state on success.
  - H_GUEST_SET_STATE which is used to modify the state of a guest or
a guest VCPU. On success, guest (or its VCPU) state shall be
updated as per the value field for the requested element(s).

Reviewed-by: Nicholas Piggin 
Signed-off-by: Michael Neuling 
Signed-off-by: Harsh Prateek Bora 
Signed-off-by: Nicholas Piggin 


Hi; Coverity points out a problem with this code (CID 1540008, 1540009):




+static target_ulong h_guest_getset_state(PowerPCCPU *cpu,
+ SpaprMachineState *spapr,
+ target_ulong *args,
+ bool set)
+{
+target_ulong flags = args[0];
+target_ulong lpid = args[1];
+target_ulong vcpuid = args[2];
+target_ulong buf = args[3];
+target_ulong buflen = args[4];
+struct guest_state_request gsr;
+SpaprMachineStateNestedGuest *guest;
+
+guest = spapr_get_nested_guest(spapr, lpid);
+if (!guest) {
+return H_P2;
+}
+gsr.buf = buf;
+assert(buflen <= GSB_MAX_BUF_SIZE);
+gsr.len = buflen;
+gsr.flags = 0;
+if (flags & H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE) {


flags is a target_ulong, which means it might only be 32 bits.
But H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE has a bit set in the
upper 32 bits only. So Coverity complains about this condition
being always-zero and the body of the if being dead code.

What was the intention here?


Hi Peter,
Ideally this is intended to be running on a ppc64 where target_ulong
should be uint64_t. I guess same holds true for existing nested-hv code
as well.


Sorry, I'm afraid I misread the Coverity report here;
sorry for the confusion. The 32-vs-64 bits question is a red
herring.

What Coverity is actually pointing out is in this next bit:


+gsr.flags |= GUEST_STATE_REQUEST_GUEST_WIDE;
+}
+if (flags & !H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE) {


The C operator ! is the logical-NOT operator; since
H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE is a non-zero value
that means that !H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE is 0;
so we're testing (flags & 0), which is always false, and this
is the if() body which is dead-code as a result.

Should this be the bitwise-NOT ~  (ie "if any flag other
than this one is set"), or should this be an else clause
to the previous if() (ie "if this flag is not set") ?


Oh, this should have been bitwise-NOT, I shall send a follow-up patch 
for the fix.


regards,
Harsh



+return H_PARAMETER; /* flag not supported yet */
+}
+
+if (set) {
+gsr.flags |= GUEST_STATE_REQUEST_SET;
+}
+return map_and_getset_state(cpu, guest, vcpuid, &gsr);
+}




thanks
-- PMM




  1   2   3   4   5   >