All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests
@ 2014-09-04  6:06 Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 01/15] ppc: Store dr entity state bits at the right bit offset Bharata B Rao
                   ` (14 more replies)
  0 siblings, 15 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Hi,

This is an early RFC patchset that adds CPU hotplug support for sPAPR guests.
The patchset applies on top of spapr-pci-hotplug-ppc-next-cleanup4 branch
of Michael Roth's tree (git://github.com/mdroth/qemu). I realize that Michael's
branch is a fast moving target and is under review now, but my patchset
depends on the hotplug framework that Michael is adding.

The division of the patches might look artificial at places, that's because
I have tried to separate the cleanup vs the actual changes I am adding. Also
there are a few fixes (like endianness fixes) that probably could be part
of Michael's patchset itself.

With the current patchset, I am able to hotplug CPUs to a BE guest successfully.
There are issues with LE guest which I still need to resolve. The hotplug
semantics (adding CPU vs adding core) hasn't yet been finalized and I have
described this issue in the patch 15/15. Also this needs a few endian
fixes to PowerPC kernel (in the CPU hotplug code path), which I will be
posting later separately.

Bharata B Rao (15):
  ppc: Store dr entity state bits at the right bit offset
  ppc: Rename SPAPR_DRC_TABLE_SIZE to SPAPR_DRC_PHB_TABLE_SIZE
  ppc: Rename sPAPRDrcEntry.phb_buid to sPAPRDrcEntry.id
  ppc: Make creation of DRC entries in FDT endian safe
  ppc: Accommodate CPU DRC entries in DRC table
  ppc: stop after getting first unused DR slot in DRC table
  ppc: Initialize DRC table before initializing CPUs
  ppc: Add CPU dynamic reconfiguration (DR) support
  ppc: Consider max_cpus during xics initialization
  ppc: Factor out CPU initialization code to a new routine
  ppc: Move RTAS indicator defines to a header file
  ppc: Support ibm,lrdr-capacity device tree property
  ppc: Make ibm,configure-connector endian-safe
  ppc: Add CPU hotplug support for sPAPR guests
  ppc: Allow hotplugging of CPU cores only

 hw/ppc/spapr.c              | 550 +++++++++++++++++++++++++++++++++++++++-----
 hw/ppc/spapr_events.c       |  35 ++-
 hw/ppc/spapr_pci.c          |  40 +---
 hw/ppc/spapr_rtas.c         |  28 ++-
 include/hw/ppc/spapr.h      |  55 ++++-
 target-ppc/translate_init.c |   5 +
 6 files changed, 603 insertions(+), 110 deletions(-)

-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 01/15] ppc: Store dr entity state bits at the right bit offset
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 02/15] ppc: Rename SPAPR_DRC_TABLE_SIZE to SPAPR_DRC_PHB_TABLE_SIZE Bharata B Rao
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 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 c65b13a..47fc21d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -367,7 +367,7 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
 
     if (empty_drc) {
         empty_drc->phb_buid = buid;
-        empty_drc->state = state;
+        empty_drc->state = state << INDICATOR_ENTITY_SENSE_SHIFT;
         empty_drc->cc_state.fdt = NULL;
         empty_drc->cc_state.offset = 0;
         empty_drc->cc_state.depth = 0;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 02/15] ppc: Rename SPAPR_DRC_TABLE_SIZE to SPAPR_DRC_PHB_TABLE_SIZE
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 01/15] ppc: Store dr entity state bits at the right bit offset Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 03/15] ppc: Rename sPAPRDrcEntry.phb_buid to sPAPRDrcEntry.id Bharata B Rao
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

DRC table could contain entries for both PHB and CPU types. The existing
size of this table is only for PHB entries, reflect the same in the code.

This patch doesn't change the code functionality.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c         | 26 +++++++++++++-------------
 include/hw/ppc/spapr.h |  8 ++++----
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 47fc21d..071d65b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -300,7 +300,7 @@ sPAPRDrcEntry *spapr_phb_to_drc_entry(uint64_t buid)
 {
     int i;
 
-    for (i = 0; i < SPAPR_DRC_TABLE_SIZE; i++) {
+    for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         if (spapr->drc_table[i].phb_buid == buid) {
             return &spapr->drc_table[i];
         }
@@ -313,7 +313,7 @@ sPAPRDrcEntry *spapr_find_drc_entry(int drc_index)
 {
     int i, j;
 
-    for (i = 0; i < SPAPR_DRC_TABLE_SIZE; i++) {
+    for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         sPAPRDrcEntry *phb_entry = &spapr->drc_table[i];
         if (phb_entry->drc_index == drc_index) {
             return phb_entry;
@@ -339,7 +339,7 @@ static void spapr_init_drc_table(void)
     memset(spapr->drc_table, 0, sizeof(spapr->drc_table));
 
     /* For now we only care about PHB entries */
-    for (i = 0; i < SPAPR_DRC_TABLE_SIZE; i++) {
+    for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         spapr->drc_table[i].drc_index = 0x2000001 + i;
     }
 }
@@ -350,7 +350,7 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
     sPAPRDrcEntry *found_drc = NULL;
     int i, phb_index;
 
-    for (i = 0; i < SPAPR_DRC_TABLE_SIZE; i++) {
+    for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         if (spapr->drc_table[i].phb_buid == 0) {
             empty_drc = &spapr->drc_table[i];
         }
@@ -388,7 +388,7 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
 static void spapr_create_drc_dt_entries(void *fdt)
 {
     char char_buf[1024];
-    uint32_t int_buf[SPAPR_DRC_TABLE_SIZE + 1];
+    uint32_t int_buf[SPAPR_DRC_PHB_TABLE_SIZE + 1];
     uint32_t *entries;
     int offset, fdt_offset;
     int i, ret;
@@ -397,9 +397,9 @@ static void spapr_create_drc_dt_entries(void *fdt)
 
     /* ibm,drc-indexes */
     memset(int_buf, 0, sizeof(int_buf));
-    int_buf[0] = SPAPR_DRC_TABLE_SIZE;
+    int_buf[0] = SPAPR_DRC_PHB_TABLE_SIZE;
 
-    for (i = 1; i <= SPAPR_DRC_TABLE_SIZE; i++) {
+    for (i = 1; i <= SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         int_buf[i] = spapr->drc_table[i-1].drc_index;
     }
 
@@ -411,9 +411,9 @@ static void spapr_create_drc_dt_entries(void *fdt)
 
     /* ibm,drc-power-domains */
     memset(int_buf, 0, sizeof(int_buf));
-    int_buf[0] = SPAPR_DRC_TABLE_SIZE;
+    int_buf[0] = SPAPR_DRC_PHB_TABLE_SIZE;
 
-    for (i = 1; i <= SPAPR_DRC_TABLE_SIZE; i++) {
+    for (i = 1; i <= SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         int_buf[i] = 0xffffffff;
     }
 
@@ -426,10 +426,10 @@ static void spapr_create_drc_dt_entries(void *fdt)
     /* ibm,drc-names */
     memset(char_buf, 0, sizeof(char_buf));
     entries = (uint32_t *)&char_buf[0];
-    *entries = SPAPR_DRC_TABLE_SIZE;
+    *entries = SPAPR_DRC_PHB_TABLE_SIZE;
     offset = sizeof(*entries);
 
-    for (i = 0; i < SPAPR_DRC_TABLE_SIZE; i++) {
+    for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         offset += sprintf(char_buf + offset, "PHB %d", i + 1);
         char_buf[offset++] = '\0';
     }
@@ -442,10 +442,10 @@ static void spapr_create_drc_dt_entries(void *fdt)
     /* ibm,drc-types */
     memset(char_buf, 0, sizeof(char_buf));
     entries = (uint32_t *)&char_buf[0];
-    *entries = SPAPR_DRC_TABLE_SIZE;
+    *entries = SPAPR_DRC_PHB_TABLE_SIZE;
     offset = sizeof(*entries);
 
-    for (i = 0; i < SPAPR_DRC_TABLE_SIZE; i++) {
+    for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         offset += sprintf(char_buf + offset, "PHB");
         char_buf[offset++] = '\0';
     }
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index aab627f..9631aeb 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -11,9 +11,9 @@ struct sPAPRNVRAM;
 #define HPTE64_V_HPTE_DIRTY     0x0000000000000040ULL
 
 /* For dlparable/hotpluggable slots */
-#define SPAPR_DRC_TABLE_SIZE    32
-#define SPAPR_DRC_PHB_SLOT_MAX  32
-#define SPAPR_DRC_DEV_ID_BASE   0x40000000
+#define SPAPR_DRC_PHB_TABLE_SIZE  32
+#define SPAPR_DRC_PHB_SLOT_MAX    32
+#define SPAPR_DRC_DEV_ID_BASE     0x40000000
 
 typedef struct sPAPRConfigureConnectorState {
     void *fdt;
@@ -72,7 +72,7 @@ typedef struct sPAPREnvironment {
     int htab_fd;
 
     /* state for Dynamic Reconfiguration Connectors */
-    sPAPRDrcEntry drc_table[SPAPR_DRC_TABLE_SIZE];
+    sPAPRDrcEntry drc_table[SPAPR_DRC_PHB_TABLE_SIZE];
 
     /* Platform state - sensors and indicators */
     uint32_t state;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 03/15] ppc: Rename sPAPRDrcEntry.phb_buid to sPAPRDrcEntry.id
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 01/15] ppc: Store dr entity state bits at the right bit offset Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 02/15] ppc: Rename SPAPR_DRC_TABLE_SIZE to SPAPR_DRC_PHB_TABLE_SIZE Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 04/15] ppc: Make creation of DRC entries in FDT endian safe Bharata B Rao
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

sPAPRDrcEntry.phb_buid field can be reused for CPU entries too, hence call it
by a generic name.

This patch doesn't change any functionality.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c         | 8 ++++----
 include/hw/ppc/spapr.h | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 071d65b..29b7de4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -301,7 +301,7 @@ sPAPRDrcEntry *spapr_phb_to_drc_entry(uint64_t buid)
     int i;
 
     for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
-        if (spapr->drc_table[i].phb_buid == buid) {
+        if (spapr->drc_table[i].id == buid) {
             return &spapr->drc_table[i];
         }
      }
@@ -351,11 +351,11 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
     int i, phb_index;
 
     for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
-        if (spapr->drc_table[i].phb_buid == 0) {
+        if (spapr->drc_table[i].id == 0) {
             empty_drc = &spapr->drc_table[i];
         }
 
-        if (spapr->drc_table[i].phb_buid == buid) {
+        if (spapr->drc_table[i].id == buid) {
             found_drc = &spapr->drc_table[i];
             break;
         }
@@ -366,8 +366,8 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
     }
 
     if (empty_drc) {
-        empty_drc->phb_buid = buid;
         empty_drc->state = state << INDICATOR_ENTITY_SENSE_SHIFT;
+        empty_drc->id = buid;
         empty_drc->cc_state.fdt = NULL;
         empty_drc->cc_state.offset = 0;
         empty_drc->cc_state.depth = 0;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 9631aeb..d7f9562 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -32,7 +32,7 @@ typedef struct sPAPRDrcEntry sPAPRDrcEntry;
 
 struct sPAPRDrcEntry {
     uint32_t drc_index;
-    uint64_t phb_buid;
+    uint64_t id;
     void *fdt;
     int fdt_offset;
     uint32_t state;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 04/15] ppc: Make creation of DRC entries in FDT endian safe
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (2 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 03/15] ppc: Rename sPAPRDrcEntry.phb_buid to sPAPRDrcEntry.id Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 05/15] ppc: Accommodate CPU DRC entries in DRC table Bharata B Rao
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 29b7de4..bdbda1f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -397,10 +397,10 @@ static void spapr_create_drc_dt_entries(void *fdt)
 
     /* ibm,drc-indexes */
     memset(int_buf, 0, sizeof(int_buf));
-    int_buf[0] = SPAPR_DRC_PHB_TABLE_SIZE;
+    int_buf[0] = cpu_to_be32(SPAPR_DRC_PHB_TABLE_SIZE);
 
     for (i = 1; i <= SPAPR_DRC_PHB_TABLE_SIZE; i++) {
-        int_buf[i] = spapr->drc_table[i-1].drc_index;
+        int_buf[i] = cpu_to_be32(spapr->drc_table[i-1].drc_index);
     }
 
     ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes", int_buf,
@@ -411,10 +411,10 @@ static void spapr_create_drc_dt_entries(void *fdt)
 
     /* ibm,drc-power-domains */
     memset(int_buf, 0, sizeof(int_buf));
-    int_buf[0] = SPAPR_DRC_PHB_TABLE_SIZE;
+    int_buf[0] = cpu_to_be32(SPAPR_DRC_PHB_TABLE_SIZE);
 
     for (i = 1; i <= SPAPR_DRC_PHB_TABLE_SIZE; i++) {
-        int_buf[i] = 0xffffffff;
+        int_buf[i] = cpu_to_be32(0xffffffff);
     }
 
     ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains", int_buf,
@@ -426,7 +426,7 @@ static void spapr_create_drc_dt_entries(void *fdt)
     /* ibm,drc-names */
     memset(char_buf, 0, sizeof(char_buf));
     entries = (uint32_t *)&char_buf[0];
-    *entries = SPAPR_DRC_PHB_TABLE_SIZE;
+    *entries = cpu_to_be32(SPAPR_DRC_PHB_TABLE_SIZE);
     offset = sizeof(*entries);
 
     for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
@@ -442,7 +442,7 @@ static void spapr_create_drc_dt_entries(void *fdt)
     /* ibm,drc-types */
     memset(char_buf, 0, sizeof(char_buf));
     entries = (uint32_t *)&char_buf[0];
-    *entries = SPAPR_DRC_PHB_TABLE_SIZE;
+    *entries = cpu_to_be32(SPAPR_DRC_PHB_TABLE_SIZE);
     offset = sizeof(*entries);
 
     for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 05/15] ppc: Accommodate CPU DRC entries in DRC table
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (3 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 04/15] ppc: Make creation of DRC entries in FDT endian safe Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 06/15] ppc: stop after getting first unused DR slot " Bharata B Rao
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Extend the DRC table to accommodate CPU DRC entries too. Generalize
spapr_add_phb_to_drc_table() to add CPU entries too.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c         | 73 +++++++++++++++++++++++++++++++++++++-------------
 include/hw/ppc/spapr.h |  8 +++++-
 2 files changed, 62 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index bdbda1f..441a4a7 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -105,6 +105,9 @@ struct sPAPRMachineState {
 
 sPAPREnvironment *spapr;
 
+#define SPAPR_DRC_ENTRY_TYPE_PHB 1
+#define SPAPR_DRC_ENTRY_TYPE_CPU 2
+
 static XICSState *try_create_xics(const char *type, int nr_servers,
                                   int nr_irqs)
 {
@@ -313,7 +316,7 @@ sPAPRDrcEntry *spapr_find_drc_entry(int drc_index)
 {
     int i, j;
 
-    for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
+    for (i = 0; i < SPAPR_DRC_TABLE_SIZE; i++) {
         sPAPRDrcEntry *phb_entry = &spapr->drc_table[i];
         if (phb_entry->drc_index == drc_index) {
             return phb_entry;
@@ -335,22 +338,38 @@ sPAPRDrcEntry *spapr_find_drc_entry(int drc_index)
 static void spapr_init_drc_table(void)
 {
     int i;
+    int smt = kvmppc_smt_threads();
 
     memset(spapr->drc_table, 0, sizeof(spapr->drc_table));
 
-    /* For now we only care about PHB entries */
+    /* PHB entries */
     for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
         spapr->drc_table[i].drc_index = 0x2000001 + i;
     }
+
+    /* CPU entries */
+    for (; i < SPAPR_DRC_TABLE_SIZE; i++) {
+        spapr->drc_table[i].drc_index = SPAPR_DRC_CPU_ID_BASE +
+            smt * (i - SPAPR_DRC_PHB_TABLE_SIZE);
+    }
 }
 
-sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
+static sPAPRDrcEntry *spapr_add_to_drc_table(int type, uint64_t buid,
+    uint32_t state)
 {
     sPAPRDrcEntry *empty_drc = NULL;
     sPAPRDrcEntry *found_drc = NULL;
-    int i, phb_index;
+    int i, phb_index, start, end;
 
-    for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
+    if (type == SPAPR_DRC_ENTRY_TYPE_PHB) {
+        start = 0;
+        end = SPAPR_DRC_PHB_TABLE_SIZE;
+    } else {
+        start = SPAPR_DRC_PHB_TABLE_SIZE;
+        end = SPAPR_DRC_TABLE_SIZE;
+    }
+
+    for (i = start; i < end; i++) {
         if (spapr->drc_table[i].id == 0) {
             empty_drc = &spapr->drc_table[i];
         }
@@ -372,12 +391,14 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
         empty_drc->cc_state.offset = 0;
         empty_drc->cc_state.depth = 0;
         empty_drc->cc_state.state = CC_STATE_IDLE;
-        empty_drc->child_entries =
-            g_malloc0(sizeof(sPAPRDrcEntry) * SPAPR_DRC_PHB_SLOT_MAX);
-        phb_index = buid - SPAPR_PCI_BASE_BUID;
-        for (i = 0; i < SPAPR_DRC_PHB_SLOT_MAX; i++) {
-            empty_drc->child_entries[i].drc_index =
-                SPAPR_DRC_DEV_ID_BASE + (phb_index << 8) + (i << 3);
+        if (type == SPAPR_DRC_ENTRY_TYPE_PHB) {
+            empty_drc->child_entries =
+                g_malloc0(sizeof(sPAPRDrcEntry) * SPAPR_DRC_PHB_SLOT_MAX);
+            phb_index = buid - SPAPR_PCI_BASE_BUID;
+            for (i = 0; i < SPAPR_DRC_PHB_SLOT_MAX; i++) {
+                empty_drc->child_entries[i].drc_index =
+                    SPAPR_DRC_DEV_ID_BASE + (phb_index << 8) + (i << 3);
+            }
         }
         return empty_drc;
     }
@@ -385,10 +406,15 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
     return NULL;
 }
 
+sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
+{
+    return spapr_add_to_drc_table(SPAPR_DRC_ENTRY_TYPE_PHB, buid, state);
+}
+
 static void spapr_create_drc_dt_entries(void *fdt)
 {
     char char_buf[1024];
-    uint32_t int_buf[SPAPR_DRC_PHB_TABLE_SIZE + 1];
+    uint32_t int_buf[SPAPR_DRC_TABLE_SIZE + 1];
     uint32_t *entries;
     int offset, fdt_offset;
     int i, ret;
@@ -397,9 +423,9 @@ static void spapr_create_drc_dt_entries(void *fdt)
 
     /* ibm,drc-indexes */
     memset(int_buf, 0, sizeof(int_buf));
-    int_buf[0] = cpu_to_be32(SPAPR_DRC_PHB_TABLE_SIZE);
+    int_buf[0] = cpu_to_be32(SPAPR_DRC_TABLE_SIZE);
 
-    for (i = 1; i <= SPAPR_DRC_PHB_TABLE_SIZE; i++) {
+    for (i = 1; i <= SPAPR_DRC_TABLE_SIZE; i++) {
         int_buf[i] = cpu_to_be32(spapr->drc_table[i-1].drc_index);
     }
 
@@ -411,9 +437,9 @@ static void spapr_create_drc_dt_entries(void *fdt)
 
     /* ibm,drc-power-domains */
     memset(int_buf, 0, sizeof(int_buf));
-    int_buf[0] = cpu_to_be32(SPAPR_DRC_PHB_TABLE_SIZE);
+    int_buf[0] = cpu_to_be32(SPAPR_DRC_TABLE_SIZE);
 
-    for (i = 1; i <= SPAPR_DRC_PHB_TABLE_SIZE; i++) {
+    for (i = 1; i <= SPAPR_DRC_TABLE_SIZE; i++) {
         int_buf[i] = cpu_to_be32(0xffffffff);
     }
 
@@ -426,7 +452,7 @@ static void spapr_create_drc_dt_entries(void *fdt)
     /* ibm,drc-names */
     memset(char_buf, 0, sizeof(char_buf));
     entries = (uint32_t *)&char_buf[0];
-    *entries = cpu_to_be32(SPAPR_DRC_PHB_TABLE_SIZE);
+    *entries = cpu_to_be32(SPAPR_DRC_TABLE_SIZE);
     offset = sizeof(*entries);
 
     for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
@@ -434,6 +460,12 @@ static void spapr_create_drc_dt_entries(void *fdt)
         char_buf[offset++] = '\0';
     }
 
+    for (; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
+        offset += sprintf(char_buf + offset, "CPU %d",
+            (i - SPAPR_DRC_PHB_TABLE_SIZE));
+        char_buf[offset++] = '\0';
+    }
+
     ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names", char_buf, offset);
     if (ret) {
         fprintf(stderr, "Couldn't finalize ibm,drc-names property\n");
@@ -442,7 +474,7 @@ static void spapr_create_drc_dt_entries(void *fdt)
     /* ibm,drc-types */
     memset(char_buf, 0, sizeof(char_buf));
     entries = (uint32_t *)&char_buf[0];
-    *entries = cpu_to_be32(SPAPR_DRC_PHB_TABLE_SIZE);
+    *entries = cpu_to_be32(SPAPR_DRC_TABLE_SIZE);
     offset = sizeof(*entries);
 
     for (i = 0; i < SPAPR_DRC_PHB_TABLE_SIZE; i++) {
@@ -450,6 +482,11 @@ static void spapr_create_drc_dt_entries(void *fdt)
         char_buf[offset++] = '\0';
     }
 
+    for (; i < SPAPR_DRC_TABLE_SIZE; i++) {
+        offset += sprintf(char_buf + offset, "CPU");
+        char_buf[offset++] = '\0';
+    }
+
     ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types", char_buf, offset);
     if (ret) {
         fprintf(stderr, "Couldn't finalize ibm,drc-types property\n");
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index d7f9562..cb45175 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -15,6 +15,12 @@ struct sPAPRNVRAM;
 #define SPAPR_DRC_PHB_SLOT_MAX    32
 #define SPAPR_DRC_DEV_ID_BASE     0x40000000
 
+#define SPAPR_DRC_CPU_TABLE_SIZE  64
+#define SPAPR_DRC_CPU_ID_BASE     0x10000000
+
+#define SPAPR_DRC_TABLE_SIZE      \
+        (SPAPR_DRC_PHB_TABLE_SIZE + SPAPR_DRC_CPU_TABLE_SIZE)
+
 typedef struct sPAPRConfigureConnectorState {
     void *fdt;
     int offset_start;
@@ -72,7 +78,7 @@ typedef struct sPAPREnvironment {
     int htab_fd;
 
     /* state for Dynamic Reconfiguration Connectors */
-    sPAPRDrcEntry drc_table[SPAPR_DRC_PHB_TABLE_SIZE];
+    sPAPRDrcEntry drc_table[SPAPR_DRC_TABLE_SIZE];
 
     /* Platform state - sensors and indicators */
     uint32_t state;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 06/15] ppc: stop after getting first unused DR slot in DRC table
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (4 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 05/15] ppc: Accommodate CPU DRC entries in DRC table Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 07/15] ppc: Initialize DRC table before initializing CPUs Bharata B Rao
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

When adding a new entry to the DRC table, stop looking at more entries
after finding the first free slot.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 441a4a7..6a0b9c5 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -372,6 +372,7 @@ static sPAPRDrcEntry *spapr_add_to_drc_table(int type, uint64_t buid,
     for (i = start; i < end; i++) {
         if (spapr->drc_table[i].id == 0) {
             empty_drc = &spapr->drc_table[i];
+            break;
         }
 
         if (spapr->drc_table[i].id == buid) {
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 07/15] ppc: Initialize DRC table before initializing CPUs
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (5 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 06/15] ppc: stop after getting first unused DR slot " Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 08/15] ppc: Add CPU dynamic reconfiguration (DR) support Bharata B Rao
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

CPU initialization code expects the DRC table to be setup already. Hence
do spapr_init_drc_table() early before the CPUs are initialized.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6a0b9c5..de65370 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1565,6 +1565,8 @@ static void ppc_spapr_init(MachineState *machine)
     spapr->icp = xics_system_init(smp_cpus * kvmppc_smt_threads() / smp_threads,
                                   XICS_IRQS);
 
+    spapr_init_drc_table();
+
     /* init CPUs */
     if (cpu_model == NULL) {
         cpu_model = kvm_enabled() ? "host" : "POWER7";
@@ -1648,7 +1650,6 @@ static void ppc_spapr_init(MachineState *machine)
     spapr_pci_msi_init(spapr, SPAPR_PCI_MSI_WINDOW);
     spapr_pci_rtas_init();
 
-    spapr_init_drc_table();
     phb = spapr_create_phb(spapr, 0);
 
     for (i = 0; i < nb_nics; i++) {
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 08/15] ppc: Add CPU dynamic reconfiguration (DR) support
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (6 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 07/15] ppc: Initialize DRC table before initializing CPUs Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 09/15] ppc: Consider max_cpus during xics initialization Bharata B Rao
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Add DR specific device tree entries for CPU.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c              | 122 ++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h      |   2 +
 target-ppc/translate_init.c |   5 ++
 3 files changed, 129 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index de65370..fc6b923 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -312,6 +312,19 @@ sPAPRDrcEntry *spapr_phb_to_drc_entry(uint64_t buid)
      return NULL;
 }
 
+sPAPRDrcEntry *spapr_cpu_to_drc_entry(uint64_t cpuid)
+{
+    int i;
+
+    for (i = SPAPR_DRC_PHB_TABLE_SIZE; i < SPAPR_DRC_TABLE_SIZE; i++) {
+        if (spapr->drc_table[i].id == cpuid) {
+            return &spapr->drc_table[i];
+        }
+     }
+
+     return NULL;
+}
+
 sPAPRDrcEntry *spapr_find_drc_entry(int drc_index)
 {
     int i, j;
@@ -412,6 +425,11 @@ sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state)
     return spapr_add_to_drc_table(SPAPR_DRC_ENTRY_TYPE_PHB, buid, state);
 }
 
+sPAPRDrcEntry *spapr_add_cpu_to_drc_table(uint64_t buid, uint32_t state)
+{
+    return spapr_add_to_drc_table(SPAPR_DRC_ENTRY_TYPE_CPU, buid, state);
+}
+
 static void spapr_create_drc_dt_entries(void *fdt)
 {
     char char_buf[1024];
@@ -494,6 +512,97 @@ static void spapr_create_drc_dt_entries(void *fdt)
     }
 }
 
+/* cpus DR configuration */
+static int spapr_create_drc_cpu_dt_entries(void *fdt)
+{
+    int i, ret, offset;
+    uint32_t int_buf[max_cpus + 1];
+    int smt = kvmppc_smt_threads();
+    int fdt_offset = fdt_path_offset(fdt, "/cpus");
+    char char_buf[1024];
+    uint32_t *entries;
+
+    /* ibm,drc-indexes */
+    memset(int_buf, 0, sizeof(int_buf));
+    int_buf[0] = cpu_to_be32(max_cpus/smp_threads);
+
+    for (i = 1; i <= max_cpus/smp_threads; i++) {
+        int_buf[i] = cpu_to_be32(SPAPR_DRC_CPU_ID_BASE + (i - 1) * smt);
+    }
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes", int_buf,
+                  sizeof(int_buf));
+    if (ret) {
+        g_warning("error adding 'ibm,drc-indexes' field for CPU FDT");
+    }
+
+    /* ibm,drc-names */
+    memset(char_buf, 0, sizeof(char_buf));
+    entries = (uint32_t *)&char_buf[0];
+    *entries = cpu_to_be32(max_cpus/smp_threads);
+    offset = sizeof(*entries);
+
+    for (i = 1; i <= max_cpus/smp_threads; i++) {
+        offset += sprintf(char_buf + offset, "CPU %d", (i - 1) * smt);
+        char_buf[offset++] = '\0';
+    }
+
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names", char_buf, offset);
+    if (ret) {
+        g_warning("error adding 'ibm,drc-names' field for CPU FDT");
+    }
+
+    /* ibm,drc-power-domains */
+    memset(int_buf, 0, sizeof(int_buf));
+    int_buf[0] = cpu_to_be32(max_cpus/smp_threads);
+
+    for (i = 1; i <= max_cpus/smp_threads; i++) {
+        int_buf[i] = cpu_to_be32(0xffffffff);
+    }
+
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains", int_buf,
+                      sizeof(int_buf));
+    if (ret) {
+        g_warning("error adding 'ibm,drc-power-domains' field for CPU FDT");
+    }
+
+    /* ibm,drc-types */
+    memset(char_buf, 0, sizeof(char_buf));
+    entries = (uint32_t *)&char_buf[0];
+    *entries = cpu_to_be32(max_cpus/smp_threads);
+    offset = sizeof(*entries);
+
+    for (i = 1; i < max_cpus/smp_threads; i++) {
+        offset += sprintf(char_buf + offset, "CPU");
+        char_buf[offset++] = '\0';
+    }
+
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types", char_buf, offset);
+    if (ret) {
+        g_warning("error adding 'ibm,drc-types' field for CPU FDT");
+    }
+
+    /* ibm,indicator-9003 */
+    memset(int_buf, 0, sizeof(int_buf));
+    int_buf[0] = cpu_to_be32(max_cpus/smp_threads);
+
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,indicator-9003", int_buf,
+                      sizeof(int_buf));
+    if (ret) {
+        g_warning("error adding 'ibm,indicator-9003' field for CPU FDT");
+    }
+
+    /* ibm,sensor-9003 */
+    memset(int_buf, 0, sizeof(int_buf));
+    int_buf[0] = cpu_to_be32(max_cpus/smp_threads);
+
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,sensor-9003", int_buf,
+                      sizeof(int_buf));
+    if (ret) {
+        g_warning("error adding 'ibm,sensor-9003' field for CPU FDT");
+    }
+    return ret;
+}
+
 #define _FDT(exp) \
     do { \
         int ret = (exp);                                           \
@@ -641,6 +750,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
         uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
         uint32_t page_sizes_prop[64];
         size_t page_sizes_prop_size;
+        sPAPRDrcEntry *drc_entry;
 
         if ((index % smt) != 0) {
             continue;
@@ -717,6 +827,12 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
 
         _FDT((fdt_property_cell(fdt, "ibm,chip-id",
                                 cs->cpu_index / cpus_per_socket)));
+        drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id +
+            SPAPR_DRC_CPU_ID_BASE);
+        g_assert(drc_entry);
+        _FDT((fdt_property_cell(fdt, "ibm,my-drc-index",
+            drc_entry->drc_index)));
+
 
         _FDT((fdt_end_node(fdt)));
     }
@@ -961,6 +1077,12 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
         exit(1);
     }
 
+    ret = spapr_create_drc_cpu_dt_entries(fdt);
+    if (ret < 0) {
+        fprintf(stderr, "couldn't setup CPU DR entries in fdt\n");
+        exit(1);
+    }
+
     /* RTAS */
     ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
     if (ret < 0) {
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index cb45175..07f3af2 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -527,7 +527,9 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname,
 int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
                       sPAPRTCETable *tcet);
 sPAPRDrcEntry *spapr_add_phb_to_drc_table(uint64_t buid, uint32_t state);
+sPAPRDrcEntry *spapr_add_cpu_to_drc_table(uint64_t buid, uint32_t state);
 sPAPRDrcEntry *spapr_phb_to_drc_entry(uint64_t buid);
+sPAPRDrcEntry *spapr_cpu_to_drc_entry(uint64_t cpuid);
 sPAPRDrcEntry *spapr_find_drc_entry(int drc_index);
 void spapr_pci_hotplug_add_event(DeviceState *qdev, int slot);
 void spapr_pci_hotplug_remove_event(DeviceState *qdev, int slot);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 48177ed..1398f1b 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -30,6 +30,7 @@
 #include "qemu/error-report.h"
 #include "qapi/visitor.h"
 #include "hw/qdev-properties.h"
+#include "hw/ppc/spapr.h"
 
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
@@ -8879,6 +8880,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
 
     cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
         + (cs->cpu_index % smp_threads);
+
+    if (!(cpu->cpu_dt_id % max_smt)) {
+        spapr_add_cpu_to_drc_table(cpu->cpu_dt_id + SPAPR_DRC_CPU_ID_BASE, 2);
+    }
 #endif
 
     if (tcg_enabled()) {
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 09/15] ppc: Consider max_cpus during xics initialization
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (7 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 08/15] ppc: Add CPU dynamic reconfiguration (DR) support Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 10/15] ppc: Factor out CPU initialization code to a new routine Bharata B Rao
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Use max_cpus instead of smp_cpus when intializating xics system. Also
report max_cpus in ibm,interrupt-server-ranges device tree property of
interrupt controller node.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index fc6b923..b2ca527 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -633,7 +633,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
     GString *hypertas = g_string_sized_new(256);
     GString *qemu_hypertas = g_string_sized_new(256);
     uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
-    uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
+    uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(max_cpus)};
     int smt = kvmppc_smt_threads();
     unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
     QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
@@ -1684,7 +1684,7 @@ static void ppc_spapr_init(MachineState *machine)
     }
 
     /* Set up Interrupt Controller before we create the VCPUs */
-    spapr->icp = xics_system_init(smp_cpus * kvmppc_smt_threads() / smp_threads,
+    spapr->icp = xics_system_init(max_cpus * kvmppc_smt_threads() / smp_threads,
                                   XICS_IRQS);
 
     spapr_init_drc_table();
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 10/15] ppc: Factor out CPU initialization code to a new routine
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (8 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 09/15] ppc: Consider max_cpus during xics initialization Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-26 15:29   ` Igor Mammedov
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 11/15] ppc: Move RTAS indicator defines to a header file Bharata B Rao
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Separate out CPU initialization code into a new routine ppc_new_cpu()
so that it can be used from CPU hotplug path too.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c | 73 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 42 insertions(+), 31 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b2ca527..41207ae 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1603,6 +1603,45 @@ static SaveVMHandlers savevm_htab_handlers = {
     .load_state = htab_load,
 };
 
+static const char *current_cpu_model;
+
+static PowerPCCPU *ppc_new_cpu(const char *cpu_model)
+{
+    PowerPCCPU *cpu;
+    CPUPPCState *env;
+
+    cpu = cpu_ppc_init(cpu_model);
+    if (cpu == NULL) {
+        fprintf(stderr, "Unable to find PowerPC CPU definition\n");
+        exit(1);
+    }
+    env = &cpu->env;
+
+    /* Set time-base frequency to 512 MHz */
+    cpu_ppc_tb_init(env, TIMEBASE_FREQ);
+
+    /* PAPR always has exception vectors in RAM not ROM. To ensure this,
+     * MSR[IP] should never be set.
+     */
+    env->msr_mask &= ~(1 << 6);
+
+    /* Tell KVM that we're in PAPR mode */
+    if (kvm_enabled()) {
+        kvmppc_set_papr(cpu);
+    }
+
+    if (cpu->max_compat) {
+        if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
+            exit(1);
+        }
+    }
+
+    xics_cpu_setup(spapr->icp, cpu);
+    qemu_register_reset(spapr_cpu_reset, cpu);
+
+    return cpu;
+}
+
 /* pSeries LPAR / sPAPR hardware init */
 static void ppc_spapr_init(MachineState *machine)
 {
@@ -1612,8 +1651,6 @@ static void ppc_spapr_init(MachineState *machine)
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
     const char *boot_device = machine->boot_order;
-    PowerPCCPU *cpu;
-    CPUPPCState *env;
     PCIHostState *phb;
     int i;
     MemoryRegion *sysmem = get_system_memory();
@@ -1693,36 +1730,10 @@ static void ppc_spapr_init(MachineState *machine)
     if (cpu_model == NULL) {
         cpu_model = kvm_enabled() ? "host" : "POWER7";
     }
-    for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(cpu_model);
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
-            exit(1);
-        }
-        env = &cpu->env;
-
-        /* Set time-base frequency to 512 MHz */
-        cpu_ppc_tb_init(env, TIMEBASE_FREQ);
-
-        /* PAPR always has exception vectors in RAM not ROM. To ensure this,
-         * MSR[IP] should never be set.
-         */
-        env->msr_mask &= ~(1 << 6);
+    current_cpu_model = cpu_model;
 
-        /* Tell KVM that we're in PAPR mode */
-        if (kvm_enabled()) {
-            kvmppc_set_papr(cpu);
-        }
-
-        if (cpu->max_compat) {
-            if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
-                exit(1);
-            }
-        }
-
-        xics_cpu_setup(spapr->icp, cpu);
-
-        qemu_register_reset(spapr_cpu_reset, cpu);
+    for (i = 0; i < smp_cpus; i++) {
+        ppc_new_cpu(current_cpu_model);
     }
 
     /* allocate RAM */
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 11/15] ppc: Move RTAS indicator defines to a header file
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (9 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 10/15] ppc: Factor out CPU initialization code to a new routine Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 12/15] ppc: Support ibm, lrdr-capacity device tree property Bharata B Rao
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Move RTAS indicator defines and helpers from spapr_pci.c to spapr.h
as these are needed by CPU hotplug code too.

This patch doesn't change any functionality.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr_pci.c     | 30 ------------------------------
 include/hw/ppc/spapr.h | 30 ++++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 995b633..76463b3 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -57,36 +57,6 @@
 #define RTAS_TYPE_MSI           1
 #define RTAS_TYPE_MSIX          2
 
-/* For set-indicator RTAS interface */
-#define INDICATOR_ISOLATION_MASK            0x0001   /* 9001 one bit */
-#define INDICATOR_GLOBAL_INTERRUPT_MASK     0x0002   /* 9005 one bit */
-#define INDICATOR_ERROR_LOG_MASK            0x0004   /* 9006 one bit */
-#define INDICATOR_IDENTIFY_MASK             0x0008   /* 9007 one bit */
-#define INDICATOR_RESET_MASK                0x0010   /* 9009 one bit */
-#define INDICATOR_DR_MASK                   0x00e0   /* 9002 three bits */
-#define INDICATOR_ALLOCATION_MASK           0x0300   /* 9003 two bits */
-#define INDICATOR_EPOW_MASK                 0x1c00   /* 9 three bits */
-#define INDICATOR_ENTITY_SENSE_MASK         0xe000   /* 9003 three bits */
-
-#define INDICATOR_ISOLATION_SHIFT           0x00     /* bit 0 */
-#define INDICATOR_GLOBAL_INTERRUPT_SHIFT    0x01     /* bit 1 */
-#define INDICATOR_ERROR_LOG_SHIFT           0x02     /* bit 2 */
-#define INDICATOR_IDENTIFY_SHIFT            0x03     /* bit 3 */
-#define INDICATOR_RESET_SHIFT               0x04     /* bit 4 */
-#define INDICATOR_DR_SHIFT                  0x05     /* bits 5-7 */
-#define INDICATOR_ALLOCATION_SHIFT          0x08     /* bits 8-9 */
-#define INDICATOR_EPOW_SHIFT                0x0a     /* bits 10-12 */
-#define INDICATOR_ENTITY_SENSE_SHIFT        0x0d     /* bits 13-15 */
-
-#define INDICATOR_ENTITY_SENSE_EMPTY    0
-#define INDICATOR_ENTITY_SENSE_PRESENT  1
-
-#define DECODE_DRC_STATE(state, m, s)                  \
-    ((((uint32_t)(state) & (uint32_t)(m))) >> (s))
-
-#define ENCODE_DRC_STATE(val, m, s) \
-    (((uint32_t)(val) << (s)) & (uint32_t)(m))
-
 #define FDT_MAX_SIZE            0x10000
 #define _FDT(exp) \
     do { \
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 07f3af2..650d63c 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -442,6 +442,36 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
 #define DIAGNOSTICS_RUN_MODE_IMMEDIATE 2
 #define DIAGNOSTICS_RUN_MODE_PERIODIC  3
 
+/* For set-indicator RTAS interface */
+#define INDICATOR_ISOLATION_MASK            0x0001   /* 9001 one bit */
+#define INDICATOR_GLOBAL_INTERRUPT_MASK     0x0002   /* 9005 one bit */
+#define INDICATOR_ERROR_LOG_MASK            0x0004   /* 9006 one bit */
+#define INDICATOR_IDENTIFY_MASK             0x0008   /* 9007 one bit */
+#define INDICATOR_RESET_MASK                0x0010   /* 9009 one bit */
+#define INDICATOR_DR_MASK                   0x00e0   /* 9002 three bits */
+#define INDICATOR_ALLOCATION_MASK           0x0300   /* 9003 two bits */
+#define INDICATOR_EPOW_MASK                 0x1c00   /* 9 three bits */
+#define INDICATOR_ENTITY_SENSE_MASK         0xe000   /* 9003 three bits */
+
+#define INDICATOR_ISOLATION_SHIFT           0x00     /* bit 0 */
+#define INDICATOR_GLOBAL_INTERRUPT_SHIFT    0x01     /* bit 1 */
+#define INDICATOR_ERROR_LOG_SHIFT           0x02     /* bit 2 */
+#define INDICATOR_IDENTIFY_SHIFT            0x03     /* bit 3 */
+#define INDICATOR_RESET_SHIFT               0x04     /* bit 4 */
+#define INDICATOR_DR_SHIFT                  0x05     /* bits 5-7 */
+#define INDICATOR_ALLOCATION_SHIFT          0x08     /* bits 8-9 */
+#define INDICATOR_EPOW_SHIFT                0x0a     /* bits 10-12 */
+#define INDICATOR_ENTITY_SENSE_SHIFT        0x0d     /* bits 13-15 */
+
+#define INDICATOR_ENTITY_SENSE_EMPTY    0
+#define INDICATOR_ENTITY_SENSE_PRESENT  1
+
+#define DECODE_DRC_STATE(state, m, s)                  \
+    ((((uint32_t)(state) & (uint32_t)(m))) >> (s))
+
+#define ENCODE_DRC_STATE(val, m, s) \
+    (((uint32_t)(val) << (s)) & (uint32_t)(m))
+
 static inline uint64_t ppc64_phys_to_real(uint64_t addr)
 {
     return addr & ~0xF000000000000000ULL;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 12/15] ppc: Support ibm, lrdr-capacity device tree property
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (10 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 11/15] ppc: Move RTAS indicator defines to a header file Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 13/15] ppc: Make ibm, configure-connector endian-safe Bharata B Rao
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Add support for ibm,lrdr-capacity since this is needed by the guest
kernel to know about the possible hot-pluggable CPUs. Also start
storing maximum possible memory for the guest in sPAPREnvironment.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c         |  3 ++-
 hw/ppc/spapr_rtas.c    | 28 ++++++++++++++++++++++++++--
 include/hw/ppc/spapr.h |  8 ++++++--
 3 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 41207ae..d128834 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1084,7 +1084,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
     }
 
     /* RTAS */
-    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
+    ret = spapr_rtas_device_tree_setup(spapr, fdt, rtas_addr, rtas_size);
     if (ret < 0) {
         fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
     }
@@ -1738,6 +1738,7 @@ static void ppc_spapr_init(MachineState *machine)
 
     /* allocate RAM */
     spapr->ram_limit = ram_size;
+    spapr->maxram_limit = machine->maxram_size;
     memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram",
                                          spapr->ram_limit);
     memory_region_add_subregion(sysmem, 0, ram);
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 2ec2a8e..00a96b9 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -29,6 +29,7 @@
 #include "sysemu/char.h"
 #include "hw/qdev.h"
 #include "sysemu/device_tree.h"
+#include "sysemu/cpus.h"
 
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
@@ -340,11 +341,12 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
     rtas_table[token].fn = fn;
 }
 
-int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
-                                 hwaddr rtas_size)
+int spapr_rtas_device_tree_setup(sPAPREnvironment *spapr, void *fdt,
+                                 hwaddr rtas_addr, hwaddr rtas_size)
 {
     int ret;
     int i;
+    uint32_t lrdr_capacity[5];
 
     ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
     if (ret < 0) {
@@ -393,6 +395,28 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
         }
 
     }
+
+    ret = qemu_fdt_setprop_cell(fdt, "/rtas", "#address-cells", 0x2);
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't add #address-cells rtas property\n");
+    }
+
+    ret = qemu_fdt_setprop_cell(fdt, "/rtas", "#size-cells", 0x2);
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't add #size-cells rtas property\n");
+    }
+
+    lrdr_capacity[0] = cpu_to_be32(spapr->maxram_limit >> 32);
+    lrdr_capacity[1] = cpu_to_be32(spapr->maxram_limit & 0xffffffff);
+    lrdr_capacity[2] = 0;
+    lrdr_capacity[3] = cpu_to_be32(SPAPR_LRDR_MEM_INCREMENT);
+    lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
+    ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
+                     sizeof(lrdr_capacity));
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't add ibm,lrdr-capacity rtas property\n");
+    }
+
     return 0;
 }
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 650d63c..d70e5ec 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -56,6 +56,7 @@ typedef struct sPAPREnvironment {
     XICSState *icp;
 
     hwaddr ram_limit;
+    hwaddr maxram_limit;
     void *htab;
     uint32_t htab_shift;
     hwaddr rma_size;
@@ -508,8 +509,8 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn);
 target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                              uint32_t token, uint32_t nargs, target_ulong args,
                              uint32_t nret, target_ulong rets);
-int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
-                                 hwaddr rtas_size);
+int spapr_rtas_device_tree_setup(sPAPREnvironment *spapr, void *fdt,
+                                 hwaddr rtas_addr, hwaddr rtas_size);
 
 #define SPAPR_TCE_PAGE_SHIFT   12
 #define SPAPR_TCE_PAGE_SIZE    (1ULL << SPAPR_TCE_PAGE_SHIFT)
@@ -522,6 +523,9 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
 
 #define RTAS_EVENT_SCAN_RATE    1
 
+/* Size of memory increments for ibm,lrdr-capacity */
+#define SPAPR_LRDR_MEM_INCREMENT 0x10000000
+
 typedef struct sPAPRTCETable sPAPRTCETable;
 
 #define TYPE_SPAPR_TCE_TABLE "spapr-tce-table"
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 13/15] ppc: Make ibm, configure-connector endian-safe
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (11 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 12/15] ppc: Support ibm, lrdr-capacity device tree property Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 14/15] ppc: Add CPU hotplug support for sPAPR guests Bharata B Rao
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 15/15] ppc: Allow hotplugging of CPU cores only Bharata B Rao
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Store RTAS data in ibm,configure-connector RTAS call in big endian
format as per sPAPR specifications.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr_pci.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 76463b3..4a384aa 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -641,7 +641,7 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
     }
     wa_buf_int = wa_buf;
 
-    drc_index = *(uint32_t *)wa_buf;
+    drc_index = be32_to_cpu(*(uint32_t *)wa_buf);
     drc_entry = spapr_find_drc_entry(drc_index);
     if (!drc_entry) {
         rc = -1;
@@ -671,7 +671,7 @@ retry:
     case FDT_BEGIN_NODE:
         ccs->depth++;
         node_name = fdt_get_name(ccs->fdt, ccs->offset, &node_name_len);
-        wa_buf_int[CC_IDX_NODE_NAME_OFFSET] = CC_VAL_DATA_OFFSET;
+        wa_buf_int[CC_IDX_NODE_NAME_OFFSET] = cpu_to_be32(CC_VAL_DATA_OFFSET);
         strcpy(wa_buf + wa_buf_int[CC_IDX_NODE_NAME_OFFSET], node_name);
         rc = CC_RET_NEXT_CHILD;
         break;
@@ -688,10 +688,10 @@ retry:
     case FDT_PROP:
         prop = fdt_get_property_by_offset(ccs->fdt, ccs->offset, &prop_len);
         prop_name = fdt_string(ccs->fdt, fdt32_to_cpu(prop->nameoff));
-        wa_buf_int[CC_IDX_PROP_NAME_OFFSET] = CC_VAL_DATA_OFFSET;
-        wa_buf_int[CC_IDX_PROP_LEN] = prop_len;
+        wa_buf_int[CC_IDX_PROP_NAME_OFFSET] = cpu_to_be32(CC_VAL_DATA_OFFSET);
+        wa_buf_int[CC_IDX_PROP_LEN] = cpu_to_be32(prop_len);
         wa_buf_int[CC_IDX_PROP_DATA_OFFSET] =
-            CC_VAL_DATA_OFFSET + strlen(prop_name) + 1;
+            cpu_to_be32(CC_VAL_DATA_OFFSET + strlen(prop_name) + 1);
         strcpy(wa_buf + wa_buf_int[CC_IDX_PROP_NAME_OFFSET], prop_name);
         memcpy(wa_buf + wa_buf_int[CC_IDX_PROP_DATA_OFFSET],
                prop->data, prop_len);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 14/15] ppc: Add CPU hotplug support for sPAPR guests
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (12 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 13/15] ppc: Make ibm, configure-connector endian-safe Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  2014-09-05 21:51   ` Tyrel Datwyler
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 15/15] ppc: Allow hotplugging of CPU cores only Bharata B Rao
  14 siblings, 1 reply; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

Add support for cpu-add monitor command. Use the exising EPOW event
infrastructure to send CPU hotplug notification to the guest.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c         | 240 ++++++++++++++++++++++++++++++++++++++++++++++++-
 hw/ppc/spapr_events.c  |  35 ++++++--
 include/hw/ppc/spapr.h |   1 +
 3 files changed, 269 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d128834..9a3d1ca 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -618,6 +618,8 @@ static void add_str(GString *s, const gchar *s1)
     g_string_append_len(s, s1, strlen(s1) + 1);
 }
 
+uint32_t cpus_per_socket;
+
 static void *spapr_create_fdt_skel(hwaddr initrd_base,
                                    hwaddr initrd_size,
                                    hwaddr kernel_size,
@@ -638,9 +640,10 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
     unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
     QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
     unsigned sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
-    uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
     char *buf;
 
+    cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
+
     add_str(hypertas, "hcall-pft");
     add_str(hypertas, "hcall-term");
     add_str(hypertas, "hcall-dabr");
@@ -1603,6 +1606,208 @@ static SaveVMHandlers savevm_htab_handlers = {
     .load_state = htab_load,
 };
 
+Notifier cpu_added_notifier;
+
+/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */
+static int spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+    int index = ppc_get_vcpu_dt_id(cpu);
+    uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
+                       0xffffffff, 0xffffffff};
+    uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
+    uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
+    uint32_t page_sizes_prop[64];
+    size_t page_sizes_prop_size;
+    sPAPRDrcEntry *drc_entry;
+    int smpt = ppc_get_compat_smt_threads(cpu);
+    uint32_t servers_prop[smpt];
+    uint32_t gservers_prop[smpt * 2];
+    int i;
+    uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
+
+    _FDT((fdt_setprop_cell(fdt, offset, "reg", index)));
+    _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
+
+    _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
+    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size",
+                        env->dcache_line_size)));
+    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size",
+                        env->dcache_line_size)));
+    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size",
+                        env->icache_line_size)));
+    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size",
+                            env->icache_line_size)));
+
+    if (pcc->l1_dcache_size) {
+        _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size",
+            pcc->l1_dcache_size)));
+    } else {
+        fprintf(stderr, "Warning: Unknown L1 dcache size for cpu\n");
+    }
+    if (pcc->l1_icache_size) {
+        _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size",
+            pcc->l1_icache_size)));
+    } else {
+        fprintf(stderr, "Warning: Unknown L1 icache size for cpu\n");
+    }
+
+    _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq)));
+    _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq)));
+    _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", env->slb_nr)));
+    _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));
+    _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));
+
+    if (env->spr_cb[SPR_PURR].oea_read) {
+        _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0)));
+    }
+
+    if (env->mmu_model & POWERPC_MMU_1TSEG) {
+        _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",
+                           segs, sizeof(segs))));
+    }
+
+    /* Advertise VMX/VSX (vector extensions) if available
+     *   0 / no property == no vector extensions
+     *   1               == VMX / Altivec available
+     *   2               == VSX available */
+    if (env->insns_flags & PPC_ALTIVEC) {
+        uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
+
+        _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
+    }
+
+    /* Advertise DFP (Decimal Floating Point) if available
+     *   0 / no property == no DFP
+     *   1               == DFP available */
+    if (env->insns_flags2 & PPC2_DFP) {
+        _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
+    }
+
+    page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop,
+                                                  sizeof(page_sizes_prop));
+    if (page_sizes_prop_size) {
+        _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
+                           page_sizes_prop, page_sizes_prop_size)));
+    }
+
+    _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
+                                cs->cpu_index / cpus_per_socket)));
+
+    drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id + SPAPR_DRC_CPU_ID_BASE);
+    g_assert(drc_entry);
+    _FDT((fdt_setprop_cell(fdt, offset, "ibm,my-drc-index",
+        drc_entry->drc_index)));
+
+    /* Build interrupt servers and gservers properties */
+    for (i = 0; i < smpt; i++) {
+        servers_prop[i] = cpu_to_be32(index + i);
+        /* Hack, direct the group queues back to cpu 0 */
+        gservers_prop[i*2] = cpu_to_be32(index + i);
+        gservers_prop[i*2 + 1] = 0;
+    }
+    _FDT(fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
+                       servers_prop, sizeof(servers_prop)));
+    _FDT(fdt_setprop(fdt, offset, "ibm,ppc-interrupt-gserver#s",
+                      gservers_prop, sizeof(gservers_prop)));
+    _FDT(fdt_setprop(fdt, offset, "ibm,pft-size",
+                          pft_size_prop, sizeof(pft_size_prop)));
+    return 0;
+}
+
+static void spapr_cpu_hotplug_add(CPUState *cs)
+{
+    int i, j;
+    sPAPRDrcEntry *drc_entry;
+    sPAPRConfigureConnectorState *ccs;
+    int offset, ret;
+    void *fdt_orig, *fdt;
+
+    /*
+     * TODO: Unlike PCI hotplug, we aren't marking the state as PRESENT
+     * here since CPU hotplug code in the guest kernel expects the
+     * state to be UNUSABLE.
+     */
+#if 0
+    uint32_t encoded = ENCODE_DRC_STATE(INDICATOR_ENTITY_SENSE_PRESENT,
+                                        INDICATOR_ENTITY_SENSE_MASK,
+                                        INDICATOR_ENTITY_SENSE_SHIFT);
+#endif
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    DeviceClass *dc = DEVICE_GET_CLASS(cs);
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+    char *nodename;
+    int index = ppc_get_vcpu_dt_id(cpu);
+
+    drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id + SPAPR_DRC_CPU_ID_BASE);
+    g_assert(drc_entry);
+
+#if 0
+    drc_entry->state &= ~(uint32_t)INDICATOR_ENTITY_SENSE_MASK;
+    drc_entry->state |= encoded; /* DR entity present */
+#endif
+
+    /* add OF node for CPU and required OF DT properties */
+    fdt_orig = g_malloc0(FDT_MAX_SIZE);
+    offset = fdt_create(fdt_orig, FDT_MAX_SIZE);
+    fdt_begin_node(fdt_orig, "");
+    fdt_end_node(fdt_orig);
+    fdt_finish(fdt_orig);
+
+    fdt = g_malloc0(FDT_MAX_SIZE);
+    fdt_open_into(fdt_orig, fdt, FDT_MAX_SIZE);
+
+    if (dc->fw_name == NULL) {
+        ObjectClass *oc = OBJECT_CLASS(pcc);
+        const char *typename;
+
+        typename = object_class_get_name(oc);
+        if (kvm_enabled() &&
+            strcmp(typename, "host-" TYPE_POWERPC_CPU) == 0) {
+            typename = object_class_get_name(object_class_get_parent(oc));
+        }
+        nodename = g_strndup(typename,
+                             strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
+        for (i = j = 0; j < strlen(nodename); i++, j++) {
+            if (nodename[j] == '_') {
+                j++;
+            }
+            if (j > i) {
+                nodename[i] = nodename[j];
+            }
+        }
+        if (j > i) {
+            nodename[i] = '\0';
+        }
+        dc->fw_name = g_strdup_printf("PowerPC,%s", nodename);
+        g_free(nodename);
+    }
+    nodename = g_strdup_printf("%s@%x", dc->fw_name, index);
+
+    offset = fdt_add_subnode(fdt, offset, nodename);
+    ret = spapr_populate_cpu_dt(cs, fdt, offset);
+    g_assert(!ret);
+    g_free(fdt_orig);
+    g_free(nodename);
+
+    /* hold on to node, configure_connector will pass it to the guest later */
+    ccs = &drc_entry->cc_state;
+    ccs->fdt = fdt;
+    ccs->offset_start = offset;
+    ccs->state = CC_STATE_PENDING;
+}
+
+static void spapr_cpu_added_req(Notifier *n, void *opaque)
+{
+    CPUState *cs = CPU(opaque);
+
+    spapr_cpu_hotplug_add(cs);
+    spapr_cpu_hotplug_add_event(cs);
+    return;
+}
+
 static const char *current_cpu_model;
 
 static PowerPCCPU *ppc_new_cpu(const char *cpu_model)
@@ -1736,6 +1941,10 @@ static void ppc_spapr_init(MachineState *machine)
         ppc_new_cpu(current_cpu_model);
     }
 
+    /* Register a handler for CPU hotplug */
+    cpu_added_notifier.notify = spapr_cpu_added_req;
+    qemu_register_cpu_added_notifier(&cpu_added_notifier);
+
     /* allocate RAM */
     spapr->ram_limit = ram_size;
     spapr->maxram_limit = machine->maxram_size;
@@ -1980,6 +2189,34 @@ static void spapr_machine_initfn(Object *obj)
                             spapr_get_kvm_type, spapr_set_kvm_type, NULL);
 }
 
+static void ppc_hot_add_cpu(const int64_t id, Error **errp)
+{
+    CPUState *cs;
+    PowerPCCPU *cpu;
+
+    if (id < 0) {
+        error_setg(errp, "Invalid CPU id: %" PRIi64, id);
+        return;
+    }
+
+    CPU_FOREACH(cs) {
+        if (cs->cpu_index == id) {
+            error_setg(errp, "Unable to add CPU: %" PRIi64
+                   ", it already exists", id);
+            return;
+        }
+    }
+
+    if (id >= max_cpus) {
+        error_setg(errp, "Unable to add CPU: %" PRIi64
+                   ", max allowed: %d", id, max_cpus - 1);
+        return;
+    }
+
+    cpu = ppc_new_cpu(current_cpu_model);
+    spapr_cpu_reset(cpu);
+}
+
 static void spapr_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -1995,6 +2232,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     mc->no_parallel = 1;
     mc->default_boot_order = NULL;
     mc->kvm_type = spapr_kvm_type;
+    mc->hot_add_cpu = ppc_hot_add_cpu;
 
     fwc->get_dev_path = spapr_get_fw_dev_path;
 }
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index bb80080..f772255 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -324,8 +324,10 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
 }
 
 static void spapr_hotplug_req_event(uint8_t hp_type, uint8_t hp_action,
-                                    sPAPRPHBState *phb, int slot)
+                                    void *dev, int slot)
 {
+    sPAPRPHBState *phb;
+    PowerPCCPU *cpu;
     struct rtas_error_log *hdr;
     struct rtas_event_log_v6 *v6hdr;
     struct rtas_event_log_v6_maina *maina;
@@ -372,21 +374,42 @@ static void spapr_hotplug_req_event(uint8_t hp_type, uint8_t hp_action,
 
     hp->hotplug_type = hp_type;
 
-    drc_entry = spapr_phb_to_drc_entry(phb->buid);
-    if (!drc_entry) {
-        drc_entry = spapr_add_phb_to_drc_table(phb->buid, 2 /* Unusable */);
-    }
-
     switch (hp_type) {
     case RTAS_LOG_V6_HP_TYPE_PCI:
+        phb = (sPAPRPHBState *)dev;
+        drc_entry = spapr_phb_to_drc_entry(phb->buid);
+        if (!drc_entry) {
+            drc_entry = spapr_add_phb_to_drc_table(phb->buid, 2 /* Unusable */);
+        }
+
         hp->drc.index = drc_entry->child_entries[slot].drc_index;
         hp->hotplug_identifier = RTAS_LOG_V6_HP_ID_DRC_INDEX;
         break;
+
+    case RTAS_LOG_V6_HP_TYPE_CPU:
+        cpu = (PowerPCCPU *)dev;
+        drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id +
+            SPAPR_DRC_CPU_ID_BASE);
+        if (!drc_entry) {
+            drc_entry = spapr_add_cpu_to_drc_table(cpu->cpu_dt_id +
+                SPAPR_DRC_CPU_ID_BASE, 2);
+        }
+
+        hp->drc.index = drc_entry->drc_index;
+        hp->hotplug_identifier = RTAS_LOG_V6_HP_ID_DRC_INDEX;
+        break;
     }
 
     qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
 }
 
+void spapr_cpu_hotplug_add_event(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    return spapr_hotplug_req_event(RTAS_LOG_V6_HP_TYPE_CPU,
+                                   RTAS_LOG_V6_HP_ACTION_ADD, cpu, 0);
+}
+
 void spapr_pci_hotplug_add_event(DeviceState *qdev, int slot)
 {
     sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(qdev);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index d70e5ec..e5fa696 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -567,5 +567,6 @@ sPAPRDrcEntry *spapr_cpu_to_drc_entry(uint64_t cpuid);
 sPAPRDrcEntry *spapr_find_drc_entry(int drc_index);
 void spapr_pci_hotplug_add_event(DeviceState *qdev, int slot);
 void spapr_pci_hotplug_remove_event(DeviceState *qdev, int slot);
+void spapr_cpu_hotplug_add_event(CPUState *cs);
 
 #endif /* !defined (__HW_SPAPR_H__) */
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [RFC PATCH v0 15/15] ppc: Allow hotplugging of CPU cores only
  2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
                   ` (13 preceding siblings ...)
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 14/15] ppc: Add CPU hotplug support for sPAPR guests Bharata B Rao
@ 2014-09-04  6:06 ` Bharata B Rao
  14 siblings, 0 replies; 20+ messages in thread
From: Bharata B Rao @ 2014-09-04  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, Bharata B Rao

pseries kernels support hot-plugging CPUs in core granularity. i,e., when
a core is hotplugged, guest kernel tries to bring up all the threads in
that core. This doesn't match 1-to-1 with QEMU hotplug semantics where
cpu-add monitor command hotplugs 1 CPU at a time.

While it is still an open question as to what kind of CPU hotplug semantics
we should support here, this patch restricts cpu-add monitor command
to allow only CPU cores to be added. All the threads of the hot-plugged
core at onlined at once.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 hw/ppc/spapr.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9a3d1ca..96fb11b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1717,7 +1717,7 @@ static int spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset)
     return 0;
 }
 
-static void spapr_cpu_hotplug_add(CPUState *cs)
+static int spapr_cpu_hotplug_add(CPUState *cs)
 {
     int i, j;
     sPAPRDrcEntry *drc_entry;
@@ -1740,6 +1740,11 @@ static void spapr_cpu_hotplug_add(CPUState *cs)
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
     char *nodename;
     int index = ppc_get_vcpu_dt_id(cpu);
+    int smt = kvmppc_smt_threads();
+
+    if ((index % smt) != 0) {
+        return -1;
+    }
 
     drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id + SPAPR_DRC_CPU_ID_BASE);
     g_assert(drc_entry);
@@ -1797,14 +1802,17 @@ static void spapr_cpu_hotplug_add(CPUState *cs)
     ccs->fdt = fdt;
     ccs->offset_start = offset;
     ccs->state = CC_STATE_PENDING;
+
+    return 0;
 }
 
 static void spapr_cpu_added_req(Notifier *n, void *opaque)
 {
     CPUState *cs = CPU(opaque);
 
-    spapr_cpu_hotplug_add(cs);
-    spapr_cpu_hotplug_add_event(cs);
+    if (!spapr_cpu_hotplug_add(cs)) {
+        spapr_cpu_hotplug_add_event(cs);
+    }
     return;
 }
 
@@ -2193,6 +2201,7 @@ static void ppc_hot_add_cpu(const int64_t id, Error **errp)
 {
     CPUState *cs;
     PowerPCCPU *cpu;
+    int i;
 
     if (id < 0) {
         error_setg(errp, "Invalid CPU id: %" PRIi64, id);
@@ -2213,8 +2222,16 @@ static void ppc_hot_add_cpu(const int64_t id, Error **errp)
         return;
     }
 
-    cpu = ppc_new_cpu(current_cpu_model);
-    spapr_cpu_reset(cpu);
+    if ((id % smp_threads) != 0) {
+        error_setg(errp, "Invalid CPU id: %" PRIi64
+                   ", only cores can be added", id);
+        return;
+    }
+
+    for (i = 0; i < smp_threads; i++) {
+        cpu = ppc_new_cpu(current_cpu_model);
+        spapr_cpu_reset(cpu);
+    }
 }
 
 static void spapr_machine_class_init(ObjectClass *oc, void *data)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v0 14/15] ppc: Add CPU hotplug support for sPAPR guests
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 14/15] ppc: Add CPU hotplug support for sPAPR guests Bharata B Rao
@ 2014-09-05 21:51   ` Tyrel Datwyler
  0 siblings, 0 replies; 20+ messages in thread
From: Tyrel Datwyler @ 2014-09-05 21:51 UTC (permalink / raw)
  To: Bharata B Rao, qemu-devel; +Cc: mdroth

On 09/03/2014 11:06 PM, Bharata B Rao wrote:
> Add support for cpu-add monitor command. Use the exising EPOW event
> infrastructure to send CPU hotplug notification to the guest.
> 
> Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> ---
>  hw/ppc/spapr.c         | 240 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  hw/ppc/spapr_events.c  |  35 ++++++--
>  include/hw/ppc/spapr.h |   1 +
>  3 files changed, 269 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index d128834..9a3d1ca 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -618,6 +618,8 @@ static void add_str(GString *s, const gchar *s1)
>      g_string_append_len(s, s1, strlen(s1) + 1);
>  }
>  
> +uint32_t cpus_per_socket;
> +
>  static void *spapr_create_fdt_skel(hwaddr initrd_base,
>                                     hwaddr initrd_size,
>                                     hwaddr kernel_size,
> @@ -638,9 +640,10 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
>      unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
>      QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
>      unsigned sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
> -    uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
>      char *buf;
>  
> +    cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
> +
>      add_str(hypertas, "hcall-pft");
>      add_str(hypertas, "hcall-term");
>      add_str(hypertas, "hcall-dabr");
> @@ -1603,6 +1606,208 @@ static SaveVMHandlers savevm_htab_handlers = {
>      .load_state = htab_load,
>  };
>  
> +Notifier cpu_added_notifier;
> +
> +/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */
> +static int spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
> +    int index = ppc_get_vcpu_dt_id(cpu);
> +    uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
> +                       0xffffffff, 0xffffffff};
> +    uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
> +    uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
> +    uint32_t page_sizes_prop[64];
> +    size_t page_sizes_prop_size;
> +    sPAPRDrcEntry *drc_entry;
> +    int smpt = ppc_get_compat_smt_threads(cpu);
> +    uint32_t servers_prop[smpt];
> +    uint32_t gservers_prop[smpt * 2];
> +    int i;
> +    uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
> +
> +    _FDT((fdt_setprop_cell(fdt, offset, "reg", index)));
> +    _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
> +
> +    _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
> +    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size",
> +                        env->dcache_line_size)));
> +    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size",
> +                        env->dcache_line_size)));
> +    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size",
> +                        env->icache_line_size)));
> +    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size",
> +                            env->icache_line_size)));
> +
> +    if (pcc->l1_dcache_size) {
> +        _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size",
> +            pcc->l1_dcache_size)));
> +    } else {
> +        fprintf(stderr, "Warning: Unknown L1 dcache size for cpu\n");
> +    }
> +    if (pcc->l1_icache_size) {
> +        _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size",
> +            pcc->l1_icache_size)));
> +    } else {
> +        fprintf(stderr, "Warning: Unknown L1 icache size for cpu\n");
> +    }
> +
> +    _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq)));
> +    _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq)));
> +    _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", env->slb_nr)));
> +    _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));
> +    _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));
> +
> +    if (env->spr_cb[SPR_PURR].oea_read) {
> +        _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0)));
> +    }
> +
> +    if (env->mmu_model & POWERPC_MMU_1TSEG) {
> +        _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",
> +                           segs, sizeof(segs))));
> +    }
> +
> +    /* Advertise VMX/VSX (vector extensions) if available
> +     *   0 / no property == no vector extensions
> +     *   1               == VMX / Altivec available
> +     *   2               == VSX available */
> +    if (env->insns_flags & PPC_ALTIVEC) {
> +        uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
> +
> +        _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
> +    }
> +
> +    /* Advertise DFP (Decimal Floating Point) if available
> +     *   0 / no property == no DFP
> +     *   1               == DFP available */
> +    if (env->insns_flags2 & PPC2_DFP) {
> +        _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
> +    }
> +
> +    page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop,
> +                                                  sizeof(page_sizes_prop));
> +    if (page_sizes_prop_size) {
> +        _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
> +                           page_sizes_prop, page_sizes_prop_size)));
> +    }
> +
> +    _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
> +                                cs->cpu_index / cpus_per_socket)));
> +
> +    drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id + SPAPR_DRC_CPU_ID_BASE);
> +    g_assert(drc_entry);
> +    _FDT((fdt_setprop_cell(fdt, offset, "ibm,my-drc-index",
> +        drc_entry->drc_index)));
> +
> +    /* Build interrupt servers and gservers properties */
> +    for (i = 0; i < smpt; i++) {
> +        servers_prop[i] = cpu_to_be32(index + i);
> +        /* Hack, direct the group queues back to cpu 0 */
> +        gservers_prop[i*2] = cpu_to_be32(index + i);
> +        gservers_prop[i*2 + 1] = 0;
> +    }
> +    _FDT(fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
> +                       servers_prop, sizeof(servers_prop)));
> +    _FDT(fdt_setprop(fdt, offset, "ibm,ppc-interrupt-gserver#s",
> +                      gservers_prop, sizeof(gservers_prop)));
> +    _FDT(fdt_setprop(fdt, offset, "ibm,pft-size",
> +                          pft_size_prop, sizeof(pft_size_prop)));
> +    return 0;
> +}
> +
> +static void spapr_cpu_hotplug_add(CPUState *cs)
> +{
> +    int i, j;
> +    sPAPRDrcEntry *drc_entry;
> +    sPAPRConfigureConnectorState *ccs;
> +    int offset, ret;
> +    void *fdt_orig, *fdt;
> +
> +    /*
> +     * TODO: Unlike PCI hotplug, we aren't marking the state as PRESENT
> +     * here since CPU hotplug code in the guest kernel expects the
> +     * state to be UNUSABLE.
> +     */

PCI hotplug is considered a physical entity and the state transitions
are slightly different from that of cpus which are considered a logical
entity. The state needs to start out as UNUSABLE as stated in your
comment. The guest will call get-sensor-state to check the
dr-entity-sensor to ensure that it is in UNUSABLE state (ie. not yet
owned by the OS). Once this is confirmed the guest calls set-indicator
to change the allocation state to USABLE. If that call is successful the
dr-entity-sensor state for the cpu should now be PRESENT indicating that
it is now owned by the OS. The guest then calls set-indicator to change
the isolation state to unisolate which is then followed by the
configure-connector call.

-Tyrel

> +#if 0
> +    uint32_t encoded = ENCODE_DRC_STATE(INDICATOR_ENTITY_SENSE_PRESENT,
> +                                        INDICATOR_ENTITY_SENSE_MASK,
> +                                        INDICATOR_ENTITY_SENSE_SHIFT);
> +#endif
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    DeviceClass *dc = DEVICE_GET_CLASS(cs);
> +    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
> +    char *nodename;
> +    int index = ppc_get_vcpu_dt_id(cpu);
> +
> +    drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id + SPAPR_DRC_CPU_ID_BASE);
> +    g_assert(drc_entry);
> +
> +#if 0
> +    drc_entry->state &= ~(uint32_t)INDICATOR_ENTITY_SENSE_MASK;
> +    drc_entry->state |= encoded; /* DR entity present */
> +#endif
> +
> +    /* add OF node for CPU and required OF DT properties */
> +    fdt_orig = g_malloc0(FDT_MAX_SIZE);
> +    offset = fdt_create(fdt_orig, FDT_MAX_SIZE);
> +    fdt_begin_node(fdt_orig, "");
> +    fdt_end_node(fdt_orig);
> +    fdt_finish(fdt_orig);
> +
> +    fdt = g_malloc0(FDT_MAX_SIZE);
> +    fdt_open_into(fdt_orig, fdt, FDT_MAX_SIZE);
> +
> +    if (dc->fw_name == NULL) {
> +        ObjectClass *oc = OBJECT_CLASS(pcc);
> +        const char *typename;
> +
> +        typename = object_class_get_name(oc);
> +        if (kvm_enabled() &&
> +            strcmp(typename, "host-" TYPE_POWERPC_CPU) == 0) {
> +            typename = object_class_get_name(object_class_get_parent(oc));
> +        }
> +        nodename = g_strndup(typename,
> +                             strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
> +        for (i = j = 0; j < strlen(nodename); i++, j++) {
> +            if (nodename[j] == '_') {
> +                j++;
> +            }
> +            if (j > i) {
> +                nodename[i] = nodename[j];
> +            }
> +        }
> +        if (j > i) {
> +            nodename[i] = '\0';
> +        }
> +        dc->fw_name = g_strdup_printf("PowerPC,%s", nodename);
> +        g_free(nodename);
> +    }
> +    nodename = g_strdup_printf("%s@%x", dc->fw_name, index);
> +
> +    offset = fdt_add_subnode(fdt, offset, nodename);
> +    ret = spapr_populate_cpu_dt(cs, fdt, offset);
> +    g_assert(!ret);
> +    g_free(fdt_orig);
> +    g_free(nodename);
> +
> +    /* hold on to node, configure_connector will pass it to the guest later */
> +    ccs = &drc_entry->cc_state;
> +    ccs->fdt = fdt;
> +    ccs->offset_start = offset;
> +    ccs->state = CC_STATE_PENDING;
> +}
> +
> +static void spapr_cpu_added_req(Notifier *n, void *opaque)
> +{
> +    CPUState *cs = CPU(opaque);
> +
> +    spapr_cpu_hotplug_add(cs);
> +    spapr_cpu_hotplug_add_event(cs);
> +    return;
> +}
> +
>  static const char *current_cpu_model;
>  
>  static PowerPCCPU *ppc_new_cpu(const char *cpu_model)
> @@ -1736,6 +1941,10 @@ static void ppc_spapr_init(MachineState *machine)
>          ppc_new_cpu(current_cpu_model);
>      }
>  
> +    /* Register a handler for CPU hotplug */
> +    cpu_added_notifier.notify = spapr_cpu_added_req;
> +    qemu_register_cpu_added_notifier(&cpu_added_notifier);
> +
>      /* allocate RAM */
>      spapr->ram_limit = ram_size;
>      spapr->maxram_limit = machine->maxram_size;
> @@ -1980,6 +2189,34 @@ static void spapr_machine_initfn(Object *obj)
>                              spapr_get_kvm_type, spapr_set_kvm_type, NULL);
>  }
>  
> +static void ppc_hot_add_cpu(const int64_t id, Error **errp)
> +{
> +    CPUState *cs;
> +    PowerPCCPU *cpu;
> +
> +    if (id < 0) {
> +        error_setg(errp, "Invalid CPU id: %" PRIi64, id);
> +        return;
> +    }
> +
> +    CPU_FOREACH(cs) {
> +        if (cs->cpu_index == id) {
> +            error_setg(errp, "Unable to add CPU: %" PRIi64
> +                   ", it already exists", id);
> +            return;
> +        }
> +    }
> +
> +    if (id >= max_cpus) {
> +        error_setg(errp, "Unable to add CPU: %" PRIi64
> +                   ", max allowed: %d", id, max_cpus - 1);
> +        return;
> +    }
> +
> +    cpu = ppc_new_cpu(current_cpu_model);
> +    spapr_cpu_reset(cpu);
> +}
> +
>  static void spapr_machine_class_init(ObjectClass *oc, void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
> @@ -1995,6 +2232,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>      mc->no_parallel = 1;
>      mc->default_boot_order = NULL;
>      mc->kvm_type = spapr_kvm_type;
> +    mc->hot_add_cpu = ppc_hot_add_cpu;
>  
>      fwc->get_dev_path = spapr_get_fw_dev_path;
>  }
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index bb80080..f772255 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -324,8 +324,10 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
>  }
>  
>  static void spapr_hotplug_req_event(uint8_t hp_type, uint8_t hp_action,
> -                                    sPAPRPHBState *phb, int slot)
> +                                    void *dev, int slot)
>  {
> +    sPAPRPHBState *phb;
> +    PowerPCCPU *cpu;
>      struct rtas_error_log *hdr;
>      struct rtas_event_log_v6 *v6hdr;
>      struct rtas_event_log_v6_maina *maina;
> @@ -372,21 +374,42 @@ static void spapr_hotplug_req_event(uint8_t hp_type, uint8_t hp_action,
>  
>      hp->hotplug_type = hp_type;
>  
> -    drc_entry = spapr_phb_to_drc_entry(phb->buid);
> -    if (!drc_entry) {
> -        drc_entry = spapr_add_phb_to_drc_table(phb->buid, 2 /* Unusable */);
> -    }
> -
>      switch (hp_type) {
>      case RTAS_LOG_V6_HP_TYPE_PCI:
> +        phb = (sPAPRPHBState *)dev;
> +        drc_entry = spapr_phb_to_drc_entry(phb->buid);
> +        if (!drc_entry) {
> +            drc_entry = spapr_add_phb_to_drc_table(phb->buid, 2 /* Unusable */);
> +        }
> +
>          hp->drc.index = drc_entry->child_entries[slot].drc_index;
>          hp->hotplug_identifier = RTAS_LOG_V6_HP_ID_DRC_INDEX;
>          break;
> +
> +    case RTAS_LOG_V6_HP_TYPE_CPU:
> +        cpu = (PowerPCCPU *)dev;
> +        drc_entry = spapr_cpu_to_drc_entry(cpu->cpu_dt_id +
> +            SPAPR_DRC_CPU_ID_BASE);
> +        if (!drc_entry) {
> +            drc_entry = spapr_add_cpu_to_drc_table(cpu->cpu_dt_id +
> +                SPAPR_DRC_CPU_ID_BASE, 2);
> +        }
> +
> +        hp->drc.index = drc_entry->drc_index;
> +        hp->hotplug_identifier = RTAS_LOG_V6_HP_ID_DRC_INDEX;
> +        break;
>      }
>  
>      qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
>  }
>  
> +void spapr_cpu_hotplug_add_event(CPUState *cs)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    return spapr_hotplug_req_event(RTAS_LOG_V6_HP_TYPE_CPU,
> +                                   RTAS_LOG_V6_HP_ACTION_ADD, cpu, 0);
> +}
> +
>  void spapr_pci_hotplug_add_event(DeviceState *qdev, int slot)
>  {
>      sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(qdev);
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index d70e5ec..e5fa696 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -567,5 +567,6 @@ sPAPRDrcEntry *spapr_cpu_to_drc_entry(uint64_t cpuid);
>  sPAPRDrcEntry *spapr_find_drc_entry(int drc_index);
>  void spapr_pci_hotplug_add_event(DeviceState *qdev, int slot);
>  void spapr_pci_hotplug_remove_event(DeviceState *qdev, int slot);
> +void spapr_cpu_hotplug_add_event(CPUState *cs);
>  
>  #endif /* !defined (__HW_SPAPR_H__) */
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v0 10/15] ppc: Factor out CPU initialization code to a new routine
  2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 10/15] ppc: Factor out CPU initialization code to a new routine Bharata B Rao
@ 2014-09-26 15:29   ` Igor Mammedov
  2014-09-29  3:00     ` Bharata B Rao
  0 siblings, 1 reply; 20+ messages in thread
From: Igor Mammedov @ 2014-09-26 15:29 UTC (permalink / raw)
  To: Bharata B Rao; +Cc: qemu-devel, mdroth

On Thu,  4 Sep 2014 11:36:20 +0530
Bharata B Rao <bharata@linux.vnet.ibm.com> wrote:

> Separate out CPU initialization code into a new routine ppc_new_cpu()
> so that it can be used from CPU hotplug path too.
> 
> Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> ---
>  hw/ppc/spapr.c | 73 +++++++++++++++++++++++++++++++++-------------------------
>  1 file changed, 42 insertions(+), 31 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index b2ca527..41207ae 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1603,6 +1603,45 @@ static SaveVMHandlers savevm_htab_handlers = {
>      .load_state = htab_load,
>  };
>  
looking at following code from POV of using CPU with device_add cmd.

> +static const char *current_cpu_model;
do PPC CPUs use full 'model-name,feature1,-feature2' format or only
model-name from cpu_model string?
 
> +static PowerPCCPU *ppc_new_cpu(const char *cpu_model)
> +{
> +    PowerPCCPU *cpu;
> +    CPUPPCState *env;
> +
> +    cpu = cpu_ppc_init(cpu_model);
> +    if (cpu == NULL) {
> +        fprintf(stderr, "Unable to find PowerPC CPU definition\n");
> +        exit(1);
> +    }

-- cut --
> +    env = &cpu->env;
> +
> +    /* Set time-base frequency to 512 MHz */
> +    cpu_ppc_tb_init(env, TIMEBASE_FREQ);
> +
> +    /* PAPR always has exception vectors in RAM not ROM. To ensure this,
> +     * MSR[IP] should never be set.
> +     */
> +    env->msr_mask &= ~(1 << 6);
> +
> +    /* Tell KVM that we're in PAPR mode */
> +    if (kvm_enabled()) {
> +        kvmppc_set_papr(cpu);
> +    }
> +
> +    if (cpu->max_compat) {
> +        if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
> +            exit(1);
> +        }
> +    }
-- cut --
selected block looks like setting CPU internals, which could be done
inside of CPU's realizefn.

> +
> +    xics_cpu_setup(spapr->icp, cpu);


> +    qemu_register_reset(spapr_cpu_reset, cpu);
also could be put inside of CPU's realizefn, like it's done in
for x86 CPU.

> +
> +    return cpu;
> +}
> +
>  /* pSeries LPAR / sPAPR hardware init */
>  static void ppc_spapr_init(MachineState *machine)
>  {
> @@ -1612,8 +1651,6 @@ static void ppc_spapr_init(MachineState *machine)
>      const char *kernel_cmdline = machine->kernel_cmdline;
>      const char *initrd_filename = machine->initrd_filename;
>      const char *boot_device = machine->boot_order;
> -    PowerPCCPU *cpu;
> -    CPUPPCState *env;
>      PCIHostState *phb;
>      int i;
>      MemoryRegion *sysmem = get_system_memory();
> @@ -1693,36 +1730,10 @@ static void ppc_spapr_init(MachineState *machine)
>      if (cpu_model == NULL) {
>          cpu_model = kvm_enabled() ? "host" : "POWER7";
>      }
> -    for (i = 0; i < smp_cpus; i++) {
> -        cpu = cpu_ppc_init(cpu_model);
> -        if (cpu == NULL) {
> -            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
> -            exit(1);
> -        }
> -        env = &cpu->env;
> -
> -        /* Set time-base frequency to 512 MHz */
> -        cpu_ppc_tb_init(env, TIMEBASE_FREQ);
> -
> -        /* PAPR always has exception vectors in RAM not ROM. To ensure this,
> -         * MSR[IP] should never be set.
> -         */
> -        env->msr_mask &= ~(1 << 6);
> +    current_cpu_model = cpu_model;
>  
> -        /* Tell KVM that we're in PAPR mode */
> -        if (kvm_enabled()) {
> -            kvmppc_set_papr(cpu);
> -        }
> -
> -        if (cpu->max_compat) {
> -            if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
> -                exit(1);
> -            }
> -        }
> -
> -        xics_cpu_setup(spapr->icp, cpu);
> -
> -        qemu_register_reset(spapr_cpu_reset, cpu);
> +    for (i = 0; i < smp_cpus; i++) {
> +        ppc_new_cpu(current_cpu_model);
>      }
>  
>      /* allocate RAM */

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v0 10/15] ppc: Factor out CPU initialization code to a new routine
  2014-09-26 15:29   ` Igor Mammedov
@ 2014-09-29  3:00     ` Bharata B Rao
  2014-09-29  8:49       ` Igor Mammedov
  0 siblings, 1 reply; 20+ messages in thread
From: Bharata B Rao @ 2014-09-29  3:00 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel, mdroth

On Fri, Sep 26, 2014 at 05:29:02PM +0200, Igor Mammedov wrote:
> On Thu,  4 Sep 2014 11:36:20 +0530
> Bharata B Rao <bharata@linux.vnet.ibm.com> wrote:
> 
> > Separate out CPU initialization code into a new routine ppc_new_cpu()
> > so that it can be used from CPU hotplug path too.
> > 
> > Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> > ---
> >  hw/ppc/spapr.c | 73 +++++++++++++++++++++++++++++++++-------------------------
> >  1 file changed, 42 insertions(+), 31 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index b2ca527..41207ae 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -1603,6 +1603,45 @@ static SaveVMHandlers savevm_htab_handlers = {
> >      .load_state = htab_load,
> >  };
> >  
> looking at following code from POV of using CPU with device_add cmd.
> 
> > +static const char *current_cpu_model;
> do PPC CPUs use full 'model-name,feature1,-feature2' format or only
> model-name from cpu_model string?

I think it is just the model-name.

> 
> > +static PowerPCCPU *ppc_new_cpu(const char *cpu_model)
> > +{
> > +    PowerPCCPU *cpu;
> > +    CPUPPCState *env;
> > +
> > +    cpu = cpu_ppc_init(cpu_model);
> > +    if (cpu == NULL) {
> > +        fprintf(stderr, "Unable to find PowerPC CPU definition\n");
> > +        exit(1);
> > +    }
> 
> -- cut --
> > +    env = &cpu->env;
> > +
> > +    /* Set time-base frequency to 512 MHz */
> > +    cpu_ppc_tb_init(env, TIMEBASE_FREQ);
> > +
> > +    /* PAPR always has exception vectors in RAM not ROM. To ensure this,
> > +     * MSR[IP] should never be set.
> > +     */
> > +    env->msr_mask &= ~(1 << 6);
> > +
> > +    /* Tell KVM that we're in PAPR mode */
> > +    if (kvm_enabled()) {
> > +        kvmppc_set_papr(cpu);
> > +    }
> > +
> > +    if (cpu->max_compat) {
> > +        if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
> > +            exit(1);
> > +        }
> > +    }
> -- cut --
> selected block looks like setting CPU internals, which could be done
> inside of CPU's realizefn.
> 
> > +
> > +    xics_cpu_setup(spapr->icp, cpu);
> 
> 
> > +    qemu_register_reset(spapr_cpu_reset, cpu);
> also could be put inside of CPU's realizefn, like it's done in
> for x86 CPU.

Right, I just converted my CPU hotplug patchset for PowerPC to use the
hotplug handler APIs and now working on to see if I can switch over to
device_add and support device_del for CPU hotplug on PowerPC.

Regards,
Bharata.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v0 10/15] ppc: Factor out CPU initialization code to a new routine
  2014-09-29  3:00     ` Bharata B Rao
@ 2014-09-29  8:49       ` Igor Mammedov
  0 siblings, 0 replies; 20+ messages in thread
From: Igor Mammedov @ 2014-09-29  8:49 UTC (permalink / raw)
  To: Bharata B Rao; +Cc: qemu-devel, mdroth

On Mon, 29 Sep 2014 08:30:15 +0530
Bharata B Rao <bharata@linux.vnet.ibm.com> wrote:

> On Fri, Sep 26, 2014 at 05:29:02PM +0200, Igor Mammedov wrote:
> > On Thu,  4 Sep 2014 11:36:20 +0530
> > Bharata B Rao <bharata@linux.vnet.ibm.com> wrote:
> > 
> > > Separate out CPU initialization code into a new routine
> > > ppc_new_cpu() so that it can be used from CPU hotplug path too.
> > > 
> > > Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> > > ---
> > >  hw/ppc/spapr.c | 73
> > > +++++++++++++++++++++++++++++++++------------------------- 1 file
> > > changed, 42 insertions(+), 31 deletions(-)
> > > 
> > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > index b2ca527..41207ae 100644
> > > --- a/hw/ppc/spapr.c
> > > +++ b/hw/ppc/spapr.c
> > > @@ -1603,6 +1603,45 @@ static SaveVMHandlers savevm_htab_handlers
> > > = { .load_state = htab_load,
> > >  };
> > >  
> > looking at following code from POV of using CPU with device_add cmd.
> > 
> > > +static const char *current_cpu_model;
> > do PPC CPUs use full 'model-name,feature1,-feature2' format or only
> > model-name from cpu_model string?
> 
> I think it is just the model-name.
Then without lagacy baggage that x86 has, it should be possible
to convert PPC to device_add/del supported object. You wont't need a
global to keep model name, it will come as type name device_add command.

> 
> > 
> > > +static PowerPCCPU *ppc_new_cpu(const char *cpu_model)
> > > +{
> > > +    PowerPCCPU *cpu;
> > > +    CPUPPCState *env;
> > > +
> > > +    cpu = cpu_ppc_init(cpu_model);
for fully QOMified CPU you don't need cpu_ppc_init()
object_new() should be sufficient.

> > > +    if (cpu == NULL) {
> > > +        fprintf(stderr, "Unable to find PowerPC CPU
> > > definition\n");
> > > +        exit(1);
> > > +    }
> > 
> > -- cut --
> > > +    env = &cpu->env;
> > > +
> > > +    /* Set time-base frequency to 512 MHz */
> > > +    cpu_ppc_tb_init(env, TIMEBASE_FREQ);
> > > +
> > > +    /* PAPR always has exception vectors in RAM not ROM. To
> > > ensure this,
> > > +     * MSR[IP] should never be set.
> > > +     */
> > > +    env->msr_mask &= ~(1 << 6);
> > > +
> > > +    /* Tell KVM that we're in PAPR mode */
> > > +    if (kvm_enabled()) {
> > > +        kvmppc_set_papr(cpu);
> > > +    }
> > > +
> > > +    if (cpu->max_compat) {
> > > +        if (ppc_set_compat(cpu, cpu->max_compat) < 0) {
> > > +            exit(1);
> > > +        }
> > > +    }
> > -- cut --
> > selected block looks like setting CPU internals, which could be done
> > inside of CPU's realizefn.
> > 
> > > +
> > > +    xics_cpu_setup(spapr->icp, cpu);
xics_cpu_setup() looks like a wiring of CPU with external component.
I'd move it into plug handler and handle it in PPCMAchine object.

It should be possible to split/move the rest of this function into
initfn()/realize() of CPU.

> > 
> > 
> > > +    qemu_register_reset(spapr_cpu_reset, cpu);
> > also could be put inside of CPU's realizefn, like it's done in
> > for x86 CPU.
> 
> Right, I just converted my CPU hotplug patchset for PowerPC to use the
> hotplug handler APIs and now working on to see if I can switch over to
> device_add and support device_del for CPU hotplug on PowerPC.
> 
> Regards,
> Bharata.
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2014-09-29  8:49 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-04  6:06 [Qemu-devel] [RFC PATCH v0 00/15] CPU hotplug support of PowerPC sPAPR guests Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 01/15] ppc: Store dr entity state bits at the right bit offset Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 02/15] ppc: Rename SPAPR_DRC_TABLE_SIZE to SPAPR_DRC_PHB_TABLE_SIZE Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 03/15] ppc: Rename sPAPRDrcEntry.phb_buid to sPAPRDrcEntry.id Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 04/15] ppc: Make creation of DRC entries in FDT endian safe Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 05/15] ppc: Accommodate CPU DRC entries in DRC table Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 06/15] ppc: stop after getting first unused DR slot " Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 07/15] ppc: Initialize DRC table before initializing CPUs Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 08/15] ppc: Add CPU dynamic reconfiguration (DR) support Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 09/15] ppc: Consider max_cpus during xics initialization Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 10/15] ppc: Factor out CPU initialization code to a new routine Bharata B Rao
2014-09-26 15:29   ` Igor Mammedov
2014-09-29  3:00     ` Bharata B Rao
2014-09-29  8:49       ` Igor Mammedov
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 11/15] ppc: Move RTAS indicator defines to a header file Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 12/15] ppc: Support ibm, lrdr-capacity device tree property Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 13/15] ppc: Make ibm, configure-connector endian-safe Bharata B Rao
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 14/15] ppc: Add CPU hotplug support for sPAPR guests Bharata B Rao
2014-09-05 21:51   ` Tyrel Datwyler
2014-09-04  6:06 ` [Qemu-devel] [RFC PATCH v0 15/15] ppc: Allow hotplugging of CPU cores only Bharata B Rao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.