提交 f49ee630 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.7-20160726' into staging

ppc patch queue 2016-07-26

Here's the current batch of ppc and spapr related patches intended for
qemu-2.7.  Given the late stage in 2.7 development, these are all
bugfixes with one exception:

The "spapr: disintricate core-id from DT semantics" changes the way
ids are assigned in the new core-based hotplug infrastructure.  This
isn't strictly a bugfix, but we've determined that the current way of
assigning core-ids will cause considerable grief with future plans for
cpu hotplug.  Therefore it's better to fix this now, late in 2.7,
before we have a released version with the problematic numbering.

# gpg: Signature made Tue 26 Jul 2016 04:04:57 BST
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.7-20160726:
  spapr: disintricate core-id from DT semantics
  target-ppc: add PPC_MFTB flag to e500mc and e5500
  spapr: fix spapr-nvram migration
  hw/ppc/spapr: Make sure to close the htab_fd when migration is canceled
  ppc: Huge page detection mechanism fixes - Episode III
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
...@@ -39,6 +39,7 @@ typedef struct sPAPRNVRAM { ...@@ -39,6 +39,7 @@ typedef struct sPAPRNVRAM {
uint32_t size; uint32_t size;
uint8_t *buf; uint8_t *buf;
BlockBackend *blk; BlockBackend *blk;
VMChangeStateEntry *vmstate;
} sPAPRNVRAM; } sPAPRNVRAM;
#define TYPE_VIO_SPAPR_NVRAM "spapr-nvram" #define TYPE_VIO_SPAPR_NVRAM "spapr-nvram"
...@@ -185,19 +186,25 @@ static int spapr_nvram_pre_load(void *opaque) ...@@ -185,19 +186,25 @@ static int spapr_nvram_pre_load(void *opaque)
return 0; return 0;
} }
static void postload_update_cb(void *opaque, int running, RunState state)
{
sPAPRNVRAM *nvram = opaque;
/* This is called after bdrv_invalidate_cache_all. */
qemu_del_vm_change_state_handler(nvram->vmstate);
nvram->vmstate = NULL;
blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size, 0);
}
static int spapr_nvram_post_load(void *opaque, int version_id) static int spapr_nvram_post_load(void *opaque, int version_id)
{ {
sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque); sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque);
if (nvram->blk) { if (nvram->blk) {
int alen = blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size, 0); nvram->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
nvram);
if (alen < 0) {
return alen;
}
if (alen != nvram->size) {
return -1;
}
} }
return 0; return 0;
......
...@@ -1512,7 +1512,6 @@ static int htab_save_complete(QEMUFile *f, void *opaque) ...@@ -1512,7 +1512,6 @@ static int htab_save_complete(QEMUFile *f, void *opaque)
if (rc < 0) { if (rc < 0) {
return rc; return rc;
} }
close_htab_fd(spapr);
} else { } else {
if (spapr->htab_first_pass) { if (spapr->htab_first_pass) {
htab_save_first_pass(f, spapr, -1); htab_save_first_pass(f, spapr, -1);
...@@ -1614,10 +1613,18 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) ...@@ -1614,10 +1613,18 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
static void htab_cleanup(void *opaque)
{
sPAPRMachineState *spapr = opaque;
close_htab_fd(spapr);
}
static SaveVMHandlers savevm_htab_handlers = { static SaveVMHandlers savevm_htab_handlers = {
.save_live_setup = htab_save_setup, .save_live_setup = htab_save_setup,
.save_live_iterate = htab_save_iterate, .save_live_iterate = htab_save_iterate,
.save_live_complete_precopy = htab_save_complete, .save_live_complete_precopy = htab_save_complete,
.cleanup = htab_cleanup,
.load_state = htab_load, .load_state = htab_load,
}; };
...@@ -1808,10 +1815,11 @@ static void ppc_spapr_init(MachineState *machine) ...@@ -1808,10 +1815,11 @@ static void ppc_spapr_init(MachineState *machine)
spapr->cores = g_new0(Object *, spapr_max_cores); spapr->cores = g_new0(Object *, spapr_max_cores);
for (i = 0; i < spapr_max_cores; i++) { for (i = 0; i < spapr_max_cores; i++) {
int core_dt_id = i * smt; int core_id = i * smp_threads;
sPAPRDRConnector *drc = sPAPRDRConnector *drc =
spapr_dr_connector_new(OBJECT(spapr), spapr_dr_connector_new(OBJECT(spapr),
SPAPR_DR_CONNECTOR_TYPE_CPU, core_dt_id); SPAPR_DR_CONNECTOR_TYPE_CPU,
(core_id / smp_threads) * smt);
qemu_register_reset(spapr_drc_reset, drc); qemu_register_reset(spapr_drc_reset, drc);
...@@ -1827,7 +1835,7 @@ static void ppc_spapr_init(MachineState *machine) ...@@ -1827,7 +1835,7 @@ static void ppc_spapr_init(MachineState *machine)
core = object_new(type); core = object_new(type);
object_property_set_int(core, smp_threads, "nr-threads", object_property_set_int(core, smp_threads, "nr-threads",
&error_fatal); &error_fatal);
object_property_set_int(core, core_dt_id, CPU_CORE_PROP_CORE_ID, object_property_set_int(core, core_id, CPU_CORE_PROP_CORE_ID,
&error_fatal); &error_fatal);
object_property_set_bool(core, true, "realized", &error_fatal); object_property_set_bool(core, true, "realized", &error_fatal);
} }
...@@ -2369,7 +2377,6 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine) ...@@ -2369,7 +2377,6 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine)
HotpluggableCPUList *head = NULL; HotpluggableCPUList *head = NULL;
sPAPRMachineState *spapr = SPAPR_MACHINE(machine); sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
int spapr_max_cores = max_cpus / smp_threads; int spapr_max_cores = max_cpus / smp_threads;
int smt = kvmppc_smt_threads();
for (i = 0; i < spapr_max_cores; i++) { for (i = 0; i < spapr_max_cores; i++) {
HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1); HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
...@@ -2379,7 +2386,7 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine) ...@@ -2379,7 +2386,7 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine)
cpu_item->type = spapr_get_cpu_core_type(machine->cpu_model); cpu_item->type = spapr_get_cpu_core_type(machine->cpu_model);
cpu_item->vcpus_count = smp_threads; cpu_item->vcpus_count = smp_threads;
cpu_props->has_core_id = true; cpu_props->has_core_id = true;
cpu_props->core_id = i * smt; cpu_props->core_id = i * smp_threads;
/* TODO: add 'has_node/node' here to describe /* TODO: add 'has_node/node' here to describe
to which node core belongs */ to which node core belongs */
......
...@@ -103,7 +103,6 @@ static void spapr_core_release(DeviceState *dev, void *opaque) ...@@ -103,7 +103,6 @@ static void spapr_core_release(DeviceState *dev, void *opaque)
size_t size = object_type_get_instance_size(typename); size_t size = object_type_get_instance_size(typename);
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
CPUCore *cc = CPU_CORE(dev); CPUCore *cc = CPU_CORE(dev);
int smt = kvmppc_smt_threads();
int i; int i;
for (i = 0; i < cc->nr_threads; i++) { for (i = 0; i < cc->nr_threads; i++) {
...@@ -117,7 +116,7 @@ static void spapr_core_release(DeviceState *dev, void *opaque) ...@@ -117,7 +116,7 @@ static void spapr_core_release(DeviceState *dev, void *opaque)
object_unparent(obj); object_unparent(obj);
} }
spapr->cores[cc->core_id / smt] = NULL; spapr->cores[cc->core_id / smp_threads] = NULL;
g_free(sc->threads); g_free(sc->threads);
object_unparent(OBJECT(dev)); object_unparent(OBJECT(dev));
...@@ -128,18 +127,19 @@ void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, ...@@ -128,18 +127,19 @@ void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
{ {
sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
CPUCore *cc = CPU_CORE(dev); CPUCore *cc = CPU_CORE(dev);
int smt = kvmppc_smt_threads();
int index = cc->core_id / smp_threads;
sPAPRDRConnector *drc = sPAPRDRConnector *drc =
spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, cc->core_id); spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);
sPAPRDRConnectorClass *drck; sPAPRDRConnectorClass *drck;
Error *local_err = NULL; Error *local_err = NULL;
int smt = kvmppc_smt_threads();
int index = cc->core_id / smt;
int spapr_max_cores = max_cpus / smp_threads; int spapr_max_cores = max_cpus / smp_threads;
int i; int i;
for (i = spapr_max_cores - 1; i > index; i--) { for (i = spapr_max_cores - 1; i > index; i--) {
if (spapr->cores[i]) { if (spapr->cores[i]) {
error_setg(errp, "core-id %d should be removed first", i * smt); error_setg(errp, "core-id %d should be removed first",
i * smp_threads);
return; return;
} }
} }
...@@ -168,11 +168,10 @@ void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, ...@@ -168,11 +168,10 @@ void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error *local_err = NULL; Error *local_err = NULL;
void *fdt = NULL; void *fdt = NULL;
int fdt_offset = 0; int fdt_offset = 0;
int index; int index = cc->core_id / smp_threads;
int smt = kvmppc_smt_threads(); int smt = kvmppc_smt_threads();
drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, cc->core_id); drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);
index = cc->core_id / smt;
spapr->cores[index] = OBJECT(dev); spapr->cores[index] = OBJECT(dev);
if (!smc->dr_cpu_enabled) { if (!smc->dr_cpu_enabled) {
...@@ -226,7 +225,6 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, ...@@ -226,7 +225,6 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
int spapr_max_cores = max_cpus / smp_threads; int spapr_max_cores = max_cpus / smp_threads;
int index, i; int index, i;
int smt = kvmppc_smt_threads();
Error *local_err = NULL; Error *local_err = NULL;
CPUCore *cc = CPU_CORE(dev); CPUCore *cc = CPU_CORE(dev);
char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model); char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model);
...@@ -247,12 +245,12 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, ...@@ -247,12 +245,12 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
goto out; goto out;
} }
if (cc->core_id % smt) { if (cc->core_id % smp_threads) {
error_setg(&local_err, "invalid core id %d\n", cc->core_id); error_setg(&local_err, "invalid core id %d\n", cc->core_id);
goto out; goto out;
} }
index = cc->core_id / smt; index = cc->core_id / smp_threads;
if (index < 0 || index >= spapr_max_cores) { if (index < 0 || index >= spapr_max_cores) {
error_setg(&local_err, "core id %d out of range", cc->core_id); error_setg(&local_err, "core id %d out of range", cc->core_id);
goto out; goto out;
...@@ -266,7 +264,7 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, ...@@ -266,7 +264,7 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
for (i = 0; i < index; i++) { for (i = 0; i < index; i++) {
if (!spapr->cores[i]) { if (!spapr->cores[i]) {
error_setg(&local_err, "core-id %d should be added first", error_setg(&local_err, "core-id %d should be added first",
i * smt); i * smp_threads);
goto out; goto out;
} }
} }
......
...@@ -366,10 +366,13 @@ static int find_max_supported_pagesize(Object *obj, void *opaque) ...@@ -366,10 +366,13 @@ static int find_max_supported_pagesize(Object *obj, void *opaque)
static long getrampagesize(void) static long getrampagesize(void)
{ {
long hpsize = LONG_MAX; long hpsize = LONG_MAX;
long mainrampagesize;
Object *memdev_root; Object *memdev_root;
if (mem_path) { if (mem_path) {
return gethugepagesize(mem_path); mainrampagesize = gethugepagesize(mem_path);
} else {
mainrampagesize = getpagesize();
} }
/* it's possible we have memory-backend objects with /* it's possible we have memory-backend objects with
...@@ -383,28 +386,26 @@ static long getrampagesize(void) ...@@ -383,28 +386,26 @@ static long getrampagesize(void)
* backend isn't backed by hugepages. * backend isn't backed by hugepages.
*/ */
memdev_root = object_resolve_path("/objects", NULL); memdev_root = object_resolve_path("/objects", NULL);
if (!memdev_root) { if (memdev_root) {
return getpagesize(); object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize);
} }
if (hpsize == LONG_MAX) {
object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize); /* No additional memory regions found ==> Report main RAM page size */
return mainrampagesize;
if (hpsize == LONG_MAX || hpsize == getpagesize()) {
return getpagesize();
} }
/* If NUMA is disabled or the NUMA nodes are not backed with a /* If NUMA is disabled or the NUMA nodes are not backed with a
* memory-backend, then there is at least one node using "normal" * memory-backend, then there is at least one node using "normal" RAM,
* RAM. And since normal RAM has not been configured with "-mem-path" * so if its page size is smaller we have got to report that size instead.
* (what we've checked earlier here already), we can not use huge pages!
*/ */
if (nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL) { if (hpsize > mainrampagesize &&
(nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) {
static bool warned; static bool warned;
if (!warned) { if (!warned) {
error_report("Huge page support disabled (n/a for main memory)."); error_report("Huge page support disabled (n/a for main memory).");
warned = true; warned = true;
} }
return getpagesize(); return mainrampagesize;
} }
return hpsize; return hpsize;
......
...@@ -5133,7 +5133,7 @@ POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data) ...@@ -5133,7 +5133,7 @@ POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
dc->desc = "e500mc core"; dc->desc = "e500mc core";
pcc->init_proc = init_proc_e500mc; pcc->init_proc = init_proc_e500mc;
pcc->check_pow = check_pow_none; pcc->check_pow = check_pow_none;
pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
PPC_WRTEE | PPC_RFDI | PPC_RFMCI | PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
PPC_CACHE_DCBZ | PPC_CACHE_DCBA | PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
...@@ -5179,7 +5179,7 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data) ...@@ -5179,7 +5179,7 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
dc->desc = "e5500 core"; dc->desc = "e5500 core";
pcc->init_proc = init_proc_e5500; pcc->init_proc = init_proc_e5500;
pcc->check_pow = check_pow_none; pcc->check_pow = check_pow_none;
pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
PPC_WRTEE | PPC_RFDI | PPC_RFMCI | PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
PPC_CACHE_DCBZ | PPC_CACHE_DCBA | PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册