summaryrefslogtreecommitdiffstats
path: root/hw/ppc/spapr.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc/spapr.c')
-rw-r--r--hw/ppc/spapr.c122
1 files changed, 54 insertions, 68 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index db0fb385d4..0d032a1ad0 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -63,6 +63,7 @@
#include "hw/virtio/vhost-scsi-common.h"
#include "exec/address-spaces.h"
+#include "exec/ram_addr.h"
#include "hw/usb.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
@@ -1612,12 +1613,12 @@ static void spapr_machine_reset(void)
void *fdt;
int rc;
- spapr_caps_reset(spapr);
+ spapr_caps_apply(spapr);
first_ppc_cpu = POWERPC_CPU(first_cpu);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
- ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
- spapr->max_compat_pvr)) {
+ ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0,
+ spapr->max_compat_pvr)) {
/* If using KVM with radix mode available, VCPUs can be started
* without a HPT because KVM will start them in radix mode.
* Set the GR bit in PATB so that we know there is no HPT. */
@@ -2520,14 +2521,15 @@ static void spapr_machine_init(MachineState *machine)
long load_limit, fw_size;
char *filename;
Error *resize_hpt_err = NULL;
- PowerPCCPU *first_ppc_cpu;
msi_nonbroken = true;
QLIST_INIT(&spapr->phbs);
QTAILQ_INIT(&spapr->pending_dimm_unplugs);
- /* Check HPT resizing availability */
+ /* Determine capabilities to run with */
+ spapr_caps_init(spapr);
+
kvmppc_check_papr_resize_hpt(&resize_hpt_err);
if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DEFAULT) {
/*
@@ -2618,10 +2620,9 @@ static void spapr_machine_init(MachineState *machine)
/* init CPUs */
spapr_init_cpus(spapr);
- first_ppc_cpu = POWERPC_CPU(first_cpu);
if ((!kvm_enabled() || kvmppc_has_cap_mmu_radix()) &&
- ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
- spapr->max_compat_pvr)) {
+ ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0,
+ spapr->max_compat_pvr)) {
/* KVM and TCG always allow GTSE with radix... */
spapr_ovec_set(spapr->ov5, OV5_MMU_RADIX_GTSE);
}
@@ -3191,11 +3192,13 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev);
+ sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *mr;
uint64_t size;
- char *mem_dev;
+ Object *memdev;
+ hwaddr pagesize;
if (!smc->dr_lmb_enabled) {
error_setg(errp, "Memory hotplug not supported for this machine");
@@ -3214,15 +3217,10 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
- mem_dev = object_property_get_str(OBJECT(dimm), PC_DIMM_MEMDEV_PROP, NULL);
- if (mem_dev && !kvmppc_is_mem_backend_page_size_ok(mem_dev)) {
- error_setg(errp, "Memory backend has bad page size. "
- "Use 'memory-backend-file' with correct mem-path.");
- goto out;
- }
-
-out:
- g_free(mem_dev);
+ memdev = object_property_get_link(OBJECT(dimm), PC_DIMM_MEMDEV_PROP,
+ &error_abort);
+ pagesize = host_memory_backend_pagesize(MEMORY_BACKEND(memdev));
+ spapr_check_pagesize(spapr, pagesize, errp);
}
struct sPAPRDIMMState {
@@ -3816,52 +3814,10 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
return -1;
}
-/*
- * Allocate the IRQ number and set the IRQ type, LSI or MSI
- */
-static void spapr_irq_set_lsi(sPAPRMachineState *spapr, int irq, bool lsi)
-{
- ics_set_irq_type(spapr->ics, irq - spapr->ics->offset, lsi);
-}
-
-int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi,
- Error **errp)
-{
- ICSState *ics = spapr->ics;
- int irq;
-
- assert(ics);
-
- if (irq_hint) {
- if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
- error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
- return -1;
- }
- irq = irq_hint;
- } else {
- irq = ics_find_free_block(ics, 1, 1);
- if (irq < 0) {
- error_setg(errp, "can't allocate IRQ: no IRQ left");
- return -1;
- }
- irq += ics->offset;
- }
-
- spapr_irq_set_lsi(spapr, irq, lsi);
- trace_spapr_irq_alloc(irq);
-
- return irq;
-}
-
-/*
- * Allocate block of consecutive IRQs, and return the number of the first IRQ in
- * the block. If align==true, aligns the first IRQ number to num.
- */
-int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi,
- bool align, Error **errp)
+int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp)
{
ICSState *ics = spapr->ics;
- int i, first = -1;
+ int first = -1;
assert(ics);
@@ -3879,19 +3835,33 @@ int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi,
} else {
first = ics_find_free_block(ics, num, 1);
}
+
if (first < 0) {
error_setg(errp, "can't find a free %d-IRQ block", num);
return -1;
}
- first += ics->offset;
- for (i = first; i < first + num; ++i) {
- spapr_irq_set_lsi(spapr, i, lsi);
+ return first + ics->offset;
+}
+
+int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp)
+{
+ ICSState *ics = spapr->ics;
+
+ assert(ics);
+
+ if (!ics_valid_irq(ics, irq)) {
+ error_setg(errp, "IRQ %d is invalid", irq);
+ return -1;
}
- trace_spapr_irq_alloc_block(first, num, lsi, align);
+ if (!ICS_IRQ_FREE(ics, irq - ics->offset)) {
+ error_setg(errp, "IRQ %d is not free", irq);
+ return -1;
+ }
- return first;
+ ics_set_irq_type(ics, irq - ics->offset, lsi);
+ return 0;
}
void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num)
@@ -4043,6 +4013,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
+ smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */
spapr_caps_add_properties(smc, &error_abort);
}
@@ -4115,7 +4086,12 @@ DEFINE_SPAPR_MACHINE(3_0, "3.0", true);
HW_COMPAT_2_12 \
{ \
.driver = TYPE_POWERPC_CPU, \
- .property = "pre-3.0-migration", \
+ .property = "pre-3.0-migration", \
+ .value = "on", \
+ }, \
+ { \
+ .driver = TYPE_SPAPR_CPU_CORE, \
+ .property = "pre-3.0-migration", \
.value = "on", \
},
@@ -4126,8 +4102,18 @@ static void spapr_machine_2_12_instance_options(MachineState *machine)
static void spapr_machine_2_12_class_options(MachineClass *mc)
{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ uint8_t mps;
+
spapr_machine_3_0_class_options(mc);
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_12);
+
+ if (kvmppc_hpt_needs_host_contiguous_pages()) {
+ mps = ctz64(qemu_getrampagesize());
+ } else {
+ mps = 34; /* allow everything up to 16GiB, i.e. everything */
+ }
+ smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = mps;
}
DEFINE_SPAPR_MACHINE(2_12, "2.12", false);