* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
- *
*/
+
#include "qemu/osdep.h"
+#include "qemu-common.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "sysemu/sysemu.h"
#include "sysemu/numa.h"
-#include "hw/hw.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
#include "qemu/log.h"
#include "hw/fw-path-provider.h"
#include "elf.h"
#include "sysemu/hw_accel.h"
#include "kvm_ppc.h"
#include "migration/misc.h"
+#include "migration/qemu-file-types.h"
#include "migration/global_state.h"
#include "migration/register.h"
#include "mmu-hash64.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
+#include "hw/qdev-properties.h"
#include "hw/pci-host/spapr.h"
#include "hw/pci/msi.h"
* all and one to identify thread 0 of a VCORE. Any change to the first one
* is likely to have an impact on the second one, so let's keep them close.
*/
-static int spapr_vcpu_id(sPAPRMachineState *spapr, int cpu_index)
+static int spapr_vcpu_id(SpaprMachineState *spapr, int cpu_index)
{
+ MachineState *ms = MACHINE(spapr);
+ unsigned int smp_threads = ms->smp.threads;
+
assert(spapr->vsmt);
return
(cpu_index / smp_threads) * spapr->vsmt + cpu_index % smp_threads;
}
-static bool spapr_is_thread0_in_vcore(sPAPRMachineState *spapr,
+static bool spapr_is_thread0_in_vcore(SpaprMachineState *spapr,
PowerPCCPU *cpu)
{
assert(spapr->vsmt);
(void *)(uintptr_t) i);
}
-int spapr_max_server_number(sPAPRMachineState *spapr)
+int spapr_max_server_number(SpaprMachineState *spapr)
{
+ MachineState *ms = MACHINE(spapr);
+
assert(spapr->vsmt);
- return DIV_ROUND_UP(max_cpus * spapr->vsmt, smp_threads);
+ return DIV_ROUND_UP(ms->smp.max_cpus * spapr->vsmt, ms->smp.threads);
}
static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
}
/* Populate the "ibm,pa-features" property */
-static void spapr_populate_pa_features(sPAPRMachineState *spapr,
+static void spapr_populate_pa_features(SpaprMachineState *spapr,
PowerPCCPU *cpu,
void *fdt, int offset,
bool legacy_guest)
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
}
-static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
+static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr)
{
+ MachineState *ms = MACHINE(spapr);
int ret = 0, offset, cpus_offset;
CPUState *cs;
char cpu_model[32];
PowerPCCPU *cpu = POWERPC_CPU(cs);
DeviceClass *dc = DEVICE_GET_CLASS(cs);
int index = spapr_get_vcpu_id(cpu);
- int compat_smt = MIN(smp_threads, ppc_compat_max_vthreads(cpu));
+ int compat_smt = MIN(ms->smp.threads, ppc_compat_max_vthreads(cpu));
if (!spapr_is_thread0_in_vcore(spapr, cpu)) {
continue;
return off;
}
-static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
+static int spapr_populate_memory(SpaprMachineState *spapr, void *fdt)
{
MachineState *machine = MACHINE(spapr);
hwaddr mem_start, node_size;
}
static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
- sPAPRMachineState *spapr)
+ SpaprMachineState *spapr)
{
+ MachineState *ms = MACHINE(spapr);
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
uint32_t page_sizes_prop[64];
size_t page_sizes_prop_size;
- uint32_t vcpus_per_socket = smp_threads * smp_cores;
+ unsigned int smp_threads = ms->smp.threads;
+ uint32_t vcpus_per_socket = smp_threads * ms->smp.cores;
uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
int compat_smt = MIN(smp_threads, ppc_compat_max_vthreads(cpu));
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
int drc_index;
uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ];
int i;
_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)));
+ _FDT((fdt_setprop_cell(fdt, offset, "ibm,purr", 1)));
+ }
+ if (env->spr_cb[SPR_SPURR].oea_read) {
+ _FDT((fdt_setprop_cell(fdt, offset, "ibm,spurr", 1)));
}
if (ppc_hash64_has(cpu, PPC_HASH64_1TSEG)) {
pcc->radix_page_info->count *
sizeof(radix_AP_encodings[0]))));
}
+
+ /*
+ * We set this property to let the guest know that it can use the large
+ * decrementer and its width in bits.
+ */
+ if (spapr_get_cap(spapr, SPAPR_CAP_LARGE_DECREMENTER) != SPAPR_CAP_OFF)
+ _FDT((fdt_setprop_u32(fdt, offset, "ibm,dec-bits",
+ pcc->lrg_decr_bits)));
}
-static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr)
+static void spapr_populate_cpus_dt_node(void *fdt, SpaprMachineState *spapr)
{
CPUState **rev;
CPUState *cs;
}
/* ibm,dynamic-memory-v2 */
-static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt,
+static int spapr_populate_drmem_v2(SpaprMachineState *spapr, void *fdt,
int offset, MemoryDeviceInfoList *dimms)
{
MachineState *machine = MACHINE(spapr);
uint64_t mem_end = machine->device_memory->base +
memory_region_size(&machine->device_memory->mr);
uint32_t node, buf_len, nr_entries = 0;
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
DrconfCellQueue *elem, *next;
MemoryDeviceInfoList *info;
QSIMPLEQ_HEAD(, DrconfCellQueue) drconf_queue
}
/* ibm,dynamic-memory */
-static int spapr_populate_drmem_v1(sPAPRMachineState *spapr, void *fdt,
+static int spapr_populate_drmem_v1(SpaprMachineState *spapr, void *fdt,
int offset, MemoryDeviceInfoList *dimms)
{
MachineState *machine = MACHINE(spapr);
uint32_t *dynamic_memory = cur_index;
if (i >= device_lmb_start) {
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, i);
g_assert(drc);
* Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation
* of this device tree node.
*/
-static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
+static int spapr_populate_drconf_memory(SpaprMachineState *spapr, void *fdt)
{
MachineState *machine = MACHINE(spapr);
int ret, i, offset;
return ret;
}
-static int spapr_dt_cas_updates(sPAPRMachineState *spapr, void *fdt,
- sPAPROptionVector *ov5_updates)
+static int spapr_dt_cas_updates(SpaprMachineState *spapr, void *fdt,
+ SpaprOptionVector *ov5_updates)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
int ret = 0, offset;
/* Generate ibm,dynamic-reconfiguration-memory node if required */
return false;
}
-int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
+int spapr_h_cas_compose_response(SpaprMachineState *spapr,
target_ulong addr, target_ulong size,
- sPAPROptionVector *ov5_updates)
+ SpaprOptionVector *ov5_updates)
{
void *fdt, *fdt_skel;
- sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
+ SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
if (spapr_hotplugged_dev_before_cas()) {
return 1;
return 0;
}
-static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
+static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
{
+ MachineState *ms = MACHINE(spapr);
int rtas;
GString *hypertas = g_string_sized_new(256);
GString *qemu_hypertas = g_string_sized_new(256);
cpu_to_be32(max_device_addr >> 32),
cpu_to_be32(max_device_addr & 0xffffffff),
0, cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE),
- cpu_to_be32(max_cpus / smp_threads),
+ cpu_to_be32(ms->smp.max_cpus / ms->smp.threads),
};
+ uint32_t maxdomain = cpu_to_be32(spapr->gpu_numa_id > 1 ? 1 : 0);
uint32_t maxdomains[] = {
cpu_to_be32(4),
- cpu_to_be32(0),
- cpu_to_be32(0),
- cpu_to_be32(0),
- cpu_to_be32(nb_numa_nodes ? nb_numa_nodes : 1),
+ maxdomain,
+ maxdomain,
+ maxdomain,
+ cpu_to_be32(spapr->gpu_numa_id),
};
_FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
* and the XIVE features that the guest may request and thus the valid
* values for bytes 23..26 of option vector 5:
*/
-static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, void *fdt,
+static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
int chosen)
{
PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
val, sizeof(val)));
}
-static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt)
+static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt)
{
MachineState *machine = MACHINE(spapr);
int chosen;
g_free(bootlist);
}
-static void spapr_dt_hypervisor(sPAPRMachineState *spapr, void *fdt)
+static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt)
{
/* The /hypervisor node isn't in PAPR - this is a hack to allow PR
* KVM to work under pHyp with some guest co-operation */
}
}
-static void *spapr_build_fdt(sPAPRMachineState *spapr)
+static void *spapr_build_fdt(SpaprMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
int ret;
void *fdt;
- sPAPRPHBState *phb;
+ SpaprPhbState *phb;
char *buf;
fdt = g_malloc0(FDT_MAX_SIZE);
_FDT(fdt_setprop_string(fdt, 0, "model", "IBM pSeries (emulated by qemu)"));
_FDT(fdt_setprop_string(fdt, 0, "compatible", "qemu,pseries"));
- /*
- * Add info to guest to indentify which host is it being run on
- * and what is the uuid of the guest
- */
- if (spapr->host_model && !g_str_equal(spapr->host_model, "none")) {
- if (g_str_equal(spapr->host_model, "passthrough")) {
- /* -M host-model=passthrough */
- if (kvmppc_get_host_model(&buf)) {
- _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
- g_free(buf);
- }
- } else {
- /* -M host-model=<user-string> */
- _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
- }
- }
-
- if (spapr->host_serial && !g_str_equal(spapr->host_serial, "none")) {
- if (g_str_equal(spapr->host_serial, "passthrough")) {
- /* -M host-serial=passthrough */
- if (kvmppc_get_host_serial(&buf)) {
- _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
- g_free(buf);
- }
- } else {
- /* -M host-serial=<user-string> */
- _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
- }
- }
-
+ /* Guest UUID & Name*/
buf = qemu_uuid_unparse_strdup(&qemu_uuid);
-
_FDT(fdt_setprop_string(fdt, 0, "vm,uuid", buf));
if (qemu_uuid_set) {
_FDT(fdt_setprop_string(fdt, 0, "system-id", buf));
qemu_get_vm_name()));
}
+ /* Host Model & Serial Number */
+ if (spapr->host_model) {
+ _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
+ } else if (smc->broken_host_serial_model && kvmppc_get_host_model(&buf)) {
+ _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
+ g_free(buf);
+ }
+
+ if (spapr->host_serial) {
+ _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
+ } else if (smc->broken_host_serial_model && kvmppc_get_host_serial(&buf)) {
+ _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
+ g_free(buf);
+ }
+
_FDT(fdt_setprop_cell(fdt, 0, "#address-cells", 2));
_FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
}
QLIST_FOREACH(phb, &spapr->phbs, list) {
- ret = spapr_populate_pci_dt(phb, PHANDLE_INTC, fdt,
- spapr->irq->nr_msis, NULL);
+ ret = spapr_dt_phb(phb, PHANDLE_INTC, fdt, spapr->irq->nr_msis, NULL);
if (ret < 0) {
error_report("couldn't setup PCI devices in fdt");
exit(1);
spapr_populate_cpus_dt_node(fdt, spapr);
if (smc->dr_lmb_enabled) {
- _FDT(spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
+ _FDT(spapr_dt_drc(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
}
if (mc->has_hotpluggable_cpus) {
int offset = fdt_path_offset(fdt, "/cpus");
- ret = spapr_drc_populate_dt(fdt, offset, NULL,
- SPAPR_DR_CONNECTOR_TYPE_CPU);
+ ret = spapr_dt_drc(fdt, offset, NULL, SPAPR_DR_CONNECTOR_TYPE_CPU);
if (ret < 0) {
error_report("Couldn't set up CPU DR device tree properties");
exit(1);
}
if (smc->dr_phb_enabled) {
- ret = spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_PHB);
+ ret = spapr_dt_drc(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_PHB);
if (ret < 0) {
error_report("Couldn't set up PHB DR device tree properties");
exit(1);
static void spapr_get_pate(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
/* Copy PATE1:GR into PATE0:HR */
entry->dw0 = spapr->patb_entry & PATE0_HR;
/*
* Get the fd to access the kernel htab, re-opening it if necessary
*/
-static int get_htab_fd(sPAPRMachineState *spapr)
+static int get_htab_fd(SpaprMachineState *spapr)
{
Error *local_err = NULL;
return spapr->htab_fd;
}
-void close_htab_fd(sPAPRMachineState *spapr)
+void close_htab_fd(SpaprMachineState *spapr)
{
if (spapr->htab_fd >= 0) {
close(spapr->htab_fd);
static hwaddr spapr_hpt_mask(PPCVirtualHypervisor *vhyp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
return HTAB_SIZE(spapr) / HASH_PTEG_SIZE_64 - 1;
}
static target_ulong spapr_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
assert(kvm_enabled());
static const ppc_hash_pte64_t *spapr_map_hptes(PPCVirtualHypervisor *vhyp,
hwaddr ptex, int n)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
hwaddr pte_offset = ptex * HASH_PTE_SIZE_64;
if (!spapr->htab) {
const ppc_hash_pte64_t *hptes,
hwaddr ptex, int n)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
if (!spapr->htab) {
g_free((void *)hptes);
/* Nothing to do for qemu managed HPT */
}
-static void spapr_store_hpte(PPCVirtualHypervisor *vhyp, hwaddr ptex,
- uint64_t pte0, uint64_t pte1)
+void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
+ uint64_t pte0, uint64_t pte1)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprMachineState *spapr = SPAPR_MACHINE(cpu->vhyp);
hwaddr offset = ptex * HASH_PTE_SIZE_64;
if (!spapr->htab) {
}
}
+static void spapr_hpte_set_c(PPCVirtualHypervisor *vhyp, hwaddr ptex,
+ uint64_t pte1)
+{
+ hwaddr offset = ptex * HASH_PTE_SIZE_64 + 15;
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
+
+ if (!spapr->htab) {
+ /* There should always be a hash table when this is called */
+ error_report("spapr_hpte_set_c called with no hash table !");
+ return;
+ }
+
+ /* The HW performs a non-atomic byte update */
+ stb_p(spapr->htab + offset, (pte1 & 0xff) | 0x80);
+}
+
+static void spapr_hpte_set_r(PPCVirtualHypervisor *vhyp, hwaddr ptex,
+ uint64_t pte1)
+{
+ hwaddr offset = ptex * HASH_PTE_SIZE_64 + 14;
+ SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
+
+ if (!spapr->htab) {
+ /* There should always be a hash table when this is called */
+ error_report("spapr_hpte_set_r called with no hash table !");
+ return;
+ }
+
+ /* The HW performs a non-atomic byte update */
+ stb_p(spapr->htab + offset, ((pte1 >> 8) & 0xff) | 0x01);
+}
+
int spapr_hpt_shift_for_ramsize(uint64_t ramsize)
{
int shift;
return shift;
}
-void spapr_free_hpt(sPAPRMachineState *spapr)
+void spapr_free_hpt(SpaprMachineState *spapr)
{
g_free(spapr->htab);
spapr->htab = NULL;
close_htab_fd(spapr);
}
-void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
+void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift,
Error **errp)
{
long rc;
}
}
/* We're setting up a hash table, so that means we're not radix */
+ spapr->patb_entry = 0;
spapr_set_all_lpcrs(0, LPCR_HR | LPCR_UPRT);
}
-void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
+void spapr_setup_hpt_and_vrma(SpaprMachineState *spapr)
{
int hpt_shift;
static int spapr_reset_drcs(Object *child, void *opaque)
{
- sPAPRDRConnector *drc =
- (sPAPRDRConnector *) object_dynamic_cast(child,
+ SpaprDrc *drc =
+ (SpaprDrc *) object_dynamic_cast(child,
TYPE_SPAPR_DR_CONNECTOR);
if (drc) {
return 0;
}
-static void spapr_machine_reset(void)
+static void spapr_machine_reset(MachineState *machine)
{
- MachineState *machine = MACHINE(qdev_get_machine());
- sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
+ SpaprMachineState *spapr = SPAPR_MACHINE(machine);
PowerPCCPU *first_ppc_cpu;
uint32_t rtas_limit;
hwaddr rtas_addr, fdt_addr;
spapr_setup_hpt_and_vrma(spapr);
}
+ /*
+ * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
+ * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
+ * called from vPHB reset handler so we initialize the counter here.
+ * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
+ * must be equally distant from any other node.
+ * The final value of spapr->gpu_numa_id is going to be written to
+ * max-associativity-domains in spapr_build_fdt().
+ */
+ spapr->gpu_numa_id = MAX(1, nb_numa_nodes);
+ qemu_devices_reset();
+
/*
* If this reset wasn't generated by CAS, we should reset our
* negotiated options and start from scratch
spapr_irq_msi_reset(spapr);
}
- qemu_devices_reset();
-
/*
* This is fixing some of the default configuration of the XIVE
* devices. To be called after the reset of the machine devices.
*/
spapr_irq_reset(spapr, &error_fatal);
+ /*
+ * There is no CAS under qtest. Simulate one to please the code that
+ * depends on spapr->ov5_cas. This is especially needed to test device
+ * unplug, so we do that before resetting the DRCs.
+ */
+ if (qtest_enabled()) {
+ spapr_ovec_cleanup(spapr->ov5_cas);
+ spapr->ov5_cas = spapr_ovec_clone(spapr->ov5);
+ }
+
/* DRC reset may cause a device to be unplugged. This will cause troubles
* if this device is used by another device (eg, a running vhost backend
* will crash QEMU if the DIMM holding the vring goes away). To avoid such
spapr->cas_reboot = false;
}
-static void spapr_create_nvram(sPAPRMachineState *spapr)
+static void spapr_create_nvram(SpaprMachineState *spapr)
{
DeviceState *dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram");
DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
qdev_init_nofail(dev);
- spapr->nvram = (struct sPAPRNVRAM *)dev;
+ spapr->nvram = (struct SpaprNvram *)dev;
}
-static void spapr_rtc_create(sPAPRMachineState *spapr)
+static void spapr_rtc_create(SpaprMachineState *spapr)
{
object_initialize_child(OBJECT(spapr), "rtc",
&spapr->rtc, sizeof(spapr->rtc), TYPE_SPAPR_RTC,
static int spapr_post_load(void *opaque, int version_id)
{
- sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+ SpaprMachineState *spapr = (SpaprMachineState *)opaque;
int err = 0;
err = spapr_caps_post_migration(spapr);
static bool spapr_pending_events_needed(void *opaque)
{
- sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+ SpaprMachineState *spapr = (SpaprMachineState *)opaque;
return !QTAILQ_EMPTY(&spapr->pending_events);
}
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_UINT32(summary, sPAPREventLogEntry),
- VMSTATE_UINT32(extended_length, sPAPREventLogEntry),
- VMSTATE_VBUFFER_ALLOC_UINT32(extended_log, sPAPREventLogEntry, 0,
+ VMSTATE_UINT32(summary, SpaprEventLogEntry),
+ VMSTATE_UINT32(extended_length, SpaprEventLogEntry),
+ VMSTATE_VBUFFER_ALLOC_UINT32(extended_log, SpaprEventLogEntry, 0,
NULL, extended_length),
VMSTATE_END_OF_LIST()
},
.minimum_version_id = 1,
.needed = spapr_pending_events_needed,
.fields = (VMStateField[]) {
- VMSTATE_QTAILQ_V(pending_events, sPAPRMachineState, 1,
- vmstate_spapr_event_entry, sPAPREventLogEntry, next),
+ VMSTATE_QTAILQ_V(pending_events, SpaprMachineState, 1,
+ vmstate_spapr_event_entry, SpaprEventLogEntry, next),
VMSTATE_END_OF_LIST()
},
};
static bool spapr_ov5_cas_needed(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
- sPAPROptionVector *ov5_mask = spapr_ovec_new();
- sPAPROptionVector *ov5_legacy = spapr_ovec_new();
- sPAPROptionVector *ov5_removed = spapr_ovec_new();
+ SpaprMachineState *spapr = opaque;
+ SpaprOptionVector *ov5_mask = spapr_ovec_new();
+ SpaprOptionVector *ov5_legacy = spapr_ovec_new();
+ SpaprOptionVector *ov5_removed = spapr_ovec_new();
bool cas_needed;
- /* Prior to the introduction of sPAPROptionVector, we had two option
+ /* Prior to the introduction of SpaprOptionVector, we had two option
* vectors we dealt with: OV5_FORM1_AFFINITY, and OV5_DRCONF_MEMORY.
* Both of these options encode machine topology into the device-tree
* in such a way that the now-booted OS should still be able to interact
.minimum_version_id = 1,
.needed = spapr_ov5_cas_needed,
.fields = (VMStateField[]) {
- VMSTATE_STRUCT_POINTER_V(ov5_cas, sPAPRMachineState, 1,
- vmstate_spapr_ovec, sPAPROptionVector),
+ VMSTATE_STRUCT_POINTER_V(ov5_cas, SpaprMachineState, 1,
+ vmstate_spapr_ovec, SpaprOptionVector),
VMSTATE_END_OF_LIST()
},
};
static bool spapr_patb_entry_needed(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
return !!spapr->patb_entry;
}
.minimum_version_id = 1,
.needed = spapr_patb_entry_needed,
.fields = (VMStateField[]) {
- VMSTATE_UINT64(patb_entry, sPAPRMachineState),
+ VMSTATE_UINT64(patb_entry, SpaprMachineState),
VMSTATE_END_OF_LIST()
},
};
static bool spapr_irq_map_needed(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
return spapr->irq_map && !bitmap_empty(spapr->irq_map, spapr->irq_map_nr);
}
.minimum_version_id = 1,
.needed = spapr_irq_map_needed,
.fields = (VMStateField[]) {
- VMSTATE_BITMAP(irq_map, sPAPRMachineState, 0, irq_map_nr),
+ VMSTATE_BITMAP(irq_map, SpaprMachineState, 0, irq_map_nr),
VMSTATE_END_OF_LIST()
},
};
static bool spapr_dtb_needed(void *opaque)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(opaque);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(opaque);
return smc->update_dt_enabled;
}
static int spapr_dtb_pre_load(void *opaque)
{
- sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+ SpaprMachineState *spapr = (SpaprMachineState *)opaque;
g_free(spapr->fdt_blob);
spapr->fdt_blob = NULL;
.needed = spapr_dtb_needed,
.pre_load = spapr_dtb_pre_load,
.fields = (VMStateField[]) {
- VMSTATE_UINT32(fdt_initial_size, sPAPRMachineState),
- VMSTATE_UINT32(fdt_size, sPAPRMachineState),
- VMSTATE_VBUFFER_ALLOC_UINT32(fdt_blob, sPAPRMachineState, 0, NULL,
+ VMSTATE_UINT32(fdt_initial_size, SpaprMachineState),
+ VMSTATE_UINT32(fdt_size, SpaprMachineState),
+ VMSTATE_VBUFFER_ALLOC_UINT32(fdt_blob, SpaprMachineState, 0, NULL,
fdt_size),
VMSTATE_END_OF_LIST()
},
VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),
/* RTC offset */
- VMSTATE_UINT64_TEST(rtc_offset, sPAPRMachineState, version_before_3),
+ VMSTATE_UINT64_TEST(rtc_offset, SpaprMachineState, version_before_3),
- VMSTATE_PPC_TIMEBASE_V(tb, sPAPRMachineState, 2),
+ VMSTATE_PPC_TIMEBASE_V(tb, SpaprMachineState, 2),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
&vmstate_spapr_cap_cfpc,
&vmstate_spapr_cap_sbbc,
&vmstate_spapr_cap_ibs,
+ &vmstate_spapr_cap_hpt_maxpagesize,
&vmstate_spapr_irq_map,
&vmstate_spapr_cap_nested_kvm_hv,
&vmstate_spapr_dtb,
+ &vmstate_spapr_cap_large_decr,
+ &vmstate_spapr_cap_ccf_assist,
NULL
}
};
static int htab_save_setup(QEMUFile *f, void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
/* "Iteration" header */
if (!spapr->htab_shift) {
return 0;
}
-static void htab_save_chunk(QEMUFile *f, sPAPRMachineState *spapr,
+static void htab_save_chunk(QEMUFile *f, SpaprMachineState *spapr,
int chunkstart, int n_valid, int n_invalid)
{
qemu_put_be32(f, chunkstart);
qemu_put_be16(f, 0);
}
-static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr,
+static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr,
int64_t max_ns)
{
bool has_timeout = max_ns != -1;
spapr->htab_save_index = index;
}
-static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr,
+static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr,
int64_t max_ns)
{
bool final = max_ns < 0;
static int htab_save_iterate(QEMUFile *f, void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
int fd;
int rc = 0;
static int htab_save_complete(QEMUFile *f, void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
int fd;
/* Iteration header */
static int htab_load(QEMUFile *f, void *opaque, int version_id)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
uint32_t section_hdr;
int fd = -1;
Error *local_err = NULL;
static void htab_save_cleanup(void *opaque)
{
- sPAPRMachineState *spapr = opaque;
+ SpaprMachineState *spapr = opaque;
close_htab_fd(spapr);
}
machine->boot_order = g_strdup(boot_device);
}
-static void spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr)
+static void spapr_create_lmb_dr_connectors(SpaprMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
/* find cpu slot in machine->possible_cpus by core_id */
static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx)
{
- int index = id / smp_threads;
+ int index = id / ms->smp.threads;
if (index >= ms->possible_cpus->len) {
return NULL;
return &ms->possible_cpus->cpus[index];
}
-static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
+static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp)
{
+ MachineState *ms = MACHINE(spapr);
Error *local_err = NULL;
bool vsmt_user = !!spapr->vsmt;
int kvm_smt = kvmppc_smt_threads();
int ret;
+ unsigned int smp_threads = ms->smp.threads;
if (!kvm_enabled() && (smp_threads > 1)) {
error_setg(&local_err, "TCG cannot support more than 1 thread/core "
error_propagate(errp, local_err);
}
-static void spapr_init_cpus(sPAPRMachineState *spapr)
+static void spapr_init_cpus(SpaprMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
const char *type = spapr_get_cpu_core_type(machine->cpu_type);
const CPUArchIdList *possible_cpus;
+ unsigned int smp_cpus = machine->smp.cpus;
+ unsigned int smp_threads = machine->smp.threads;
+ unsigned int max_cpus = machine->smp.max_cpus;
int boot_cores_nr = smp_cpus / smp_threads;
int i;
/* pSeries LPAR / sPAPR hardware init */
static void spapr_machine_init(MachineState *machine)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+ SpaprMachineState *spapr = SPAPR_MACHINE(machine);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
const char *kernel_filename = machine->kernel_filename;
const char *initrd_filename = machine->initrd_filename;
PCIHostState *phb;
/* advertise XIVE on POWER9 machines */
if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
- if (ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00,
- 0, spapr->max_compat_pvr)) {
- spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
- } else if (spapr->irq->ov5 & SPAPR_OV5_XIVE_EXPLOIT) {
- error_report("XIVE-only machines require a POWER9 CPU");
- exit(1);
- }
+ spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
}
/* init CPUs */
/* H_CLEAR_MOD/_REF are mandatory in PAPR, but off by default */
kvmppc_enable_clear_ref_mod_hcalls();
+
+ /* Enable H_PAGE_INIT */
+ kvmppc_enable_h_page_init();
}
/* allocate RAM */
}
}
-static int spapr_kvm_type(const char *vm_type)
+static int spapr_kvm_type(MachineState *machine, const char *vm_type)
{
if (!vm_type) {
return 0;
#define CAST(type, obj, name) \
((type *)object_dynamic_cast(OBJECT(obj), (name)))
SCSIDevice *d = CAST(SCSIDevice, dev, TYPE_SCSI_DEVICE);
- sPAPRPHBState *phb = CAST(sPAPRPHBState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
+ SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
if (d) {
static char *spapr_get_kvm_type(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
return g_strdup(spapr->kvm_type);
}
static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
g_free(spapr->kvm_type);
spapr->kvm_type = g_strdup(value);
static bool spapr_get_modern_hotplug_events(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
return spapr->use_hotplug_event_source;
}
static void spapr_set_modern_hotplug_events(Object *obj, bool value,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
spapr->use_hotplug_event_source = value;
}
static char *spapr_get_resize_hpt(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
switch (spapr->resize_hpt) {
case SPAPR_RESIZE_HPT_DEFAULT:
static void spapr_set_resize_hpt(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
if (strcmp(value, "default") == 0) {
spapr->resize_hpt = SPAPR_RESIZE_HPT_DEFAULT;
static char *spapr_get_ic_mode(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
if (spapr->irq == &spapr_irq_xics_legacy) {
return g_strdup("legacy");
static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
error_setg(errp, "This machine only uses the legacy XICS backend, don't pass ic-mode");
static char *spapr_get_host_model(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
return g_strdup(spapr->host_model);
}
static void spapr_set_host_model(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
g_free(spapr->host_model);
spapr->host_model = g_strdup(value);
static char *spapr_get_host_serial(Object *obj, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
return g_strdup(spapr->host_serial);
}
static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
g_free(spapr->host_serial);
spapr->host_serial = g_strdup(value);
static void spapr_instance_init(Object *obj)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
spapr->htab_fd = -1;
spapr->use_hotplug_event_source = true;
spapr_get_host_model, spapr_set_host_model,
&error_abort);
object_property_set_description(obj, "host-model",
- "Set host's model-id to use - none|passthrough|string", &error_abort);
+ "Host model to advertise in guest device tree", &error_abort);
object_property_add_str(obj, "host-serial",
spapr_get_host_serial, spapr_set_host_serial,
&error_abort);
object_property_set_description(obj, "host-serial",
- "Set host's system-id to use - none|passthrough|string", &error_abort);
+ "Host serial number to advertise in guest device tree", &error_abort);
}
static void spapr_machine_finalizefn(Object *obj)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
g_free(spapr->kvm_type);
}
}
}
-int spapr_lmb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp)
{
uint64_t addr;
static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
bool dedicated_hp_event_source, Error **errp)
{
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE;
int i;
uint64_t addr = addr_start;
Error **errp)
{
Error *local_err = NULL;
- sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev);
+ SpaprMachineState *ms = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
uint64_t size, addr;
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);
+ const SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
Error *local_err = NULL;
uint64_t size;
pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp);
}
-struct sPAPRDIMMState {
+struct SpaprDimmState {
PCDIMMDevice *dimm;
uint32_t nr_lmbs;
- QTAILQ_ENTRY(sPAPRDIMMState) next;
+ QTAILQ_ENTRY(SpaprDimmState) next;
};
-static sPAPRDIMMState *spapr_pending_dimm_unplugs_find(sPAPRMachineState *s,
+static SpaprDimmState *spapr_pending_dimm_unplugs_find(SpaprMachineState *s,
PCDIMMDevice *dimm)
{
- sPAPRDIMMState *dimm_state = NULL;
+ SpaprDimmState *dimm_state = NULL;
QTAILQ_FOREACH(dimm_state, &s->pending_dimm_unplugs, next) {
if (dimm_state->dimm == dimm) {
return dimm_state;
}
-static sPAPRDIMMState *spapr_pending_dimm_unplugs_add(sPAPRMachineState *spapr,
+static SpaprDimmState *spapr_pending_dimm_unplugs_add(SpaprMachineState *spapr,
uint32_t nr_lmbs,
PCDIMMDevice *dimm)
{
- sPAPRDIMMState *ds = NULL;
+ SpaprDimmState *ds = NULL;
/*
* If this request is for a DIMM whose removal had failed earlier
*/
ds = spapr_pending_dimm_unplugs_find(spapr, dimm);
if (!ds) {
- ds = g_malloc0(sizeof(sPAPRDIMMState));
+ ds = g_malloc0(sizeof(SpaprDimmState));
ds->nr_lmbs = nr_lmbs;
ds->dimm = dimm;
QTAILQ_INSERT_HEAD(&spapr->pending_dimm_unplugs, ds, next);
return ds;
}
-static void spapr_pending_dimm_unplugs_remove(sPAPRMachineState *spapr,
- sPAPRDIMMState *dimm_state)
+static void spapr_pending_dimm_unplugs_remove(SpaprMachineState *spapr,
+ SpaprDimmState *dimm_state)
{
QTAILQ_REMOVE(&spapr->pending_dimm_unplugs, dimm_state, next);
g_free(dimm_state);
}
-static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms,
+static SpaprDimmState *spapr_recover_pending_dimm_state(SpaprMachineState *ms,
PCDIMMDevice *dimm)
{
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
uint64_t size = memory_device_get_region_size(MEMORY_DEVICE(dimm),
&error_abort);
uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
void spapr_lmb_release(DeviceState *dev)
{
HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);
- sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_ctrl);
- sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
+ SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_ctrl);
+ SpaprDimmState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
/* This information will get lost if a migration occurs
* during the unplug process. In this case recover it. */
* unplug handler chain. This can never fail.
*/
hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
+ object_unparent(OBJECT(dev));
}
static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
- sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
+ SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
+ SpaprDimmState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev));
- object_unparent(OBJECT(dev));
+ object_property_set_bool(OBJECT(dev), false, "realized", NULL);
spapr_pending_dimm_unplugs_remove(spapr, ds);
}
static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
Error *local_err = NULL;
PCDIMMDevice *dimm = PC_DIMM(dev);
uint32_t nr_lmbs;
uint64_t size, addr_start, addr;
int i;
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort);
nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
/* Call the unplug handler chain. This can never fail. */
hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
+ object_unparent(OBJECT(dev));
}
static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
MachineState *ms = MACHINE(hotplug_dev);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms);
CPUCore *cc = CPU_CORE(dev);
CPUArchId *core_slot = spapr_find_cpu_slot(ms, cc->core_id, NULL);
if (smc->pre_2_10_has_unused_icps) {
- sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
+ SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
int i;
for (i = 0; i < cc->nr_threads; i++) {
assert(core_slot);
core_slot->cpu = NULL;
- object_unparent(OBJECT(dev));
+ object_property_set_bool(OBJECT(dev), false, "realized", NULL);
}
static
void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
int index;
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
CPUCore *cc = CPU_CORE(dev);
if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index)) {
spapr_hotplug_req_remove_by_index(drc);
}
-int spapr_core_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp)
{
- sPAPRCPUCore *core = SPAPR_CPU_CORE(drc->dev);
+ SpaprCpuCore *core = SPAPR_CPU_CORE(drc->dev);
CPUState *cs = CPU(core->threads[0]);
PowerPCCPU *cpu = POWERPC_CPU(cs);
DeviceClass *dc = DEVICE_GET_CLASS(cs);
static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
MachineClass *mc = MACHINE_GET_CLASS(spapr);
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
- sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprCpuCore *core = SPAPR_CPU_CORE(OBJECT(dev));
CPUCore *cc = CPU_CORE(dev);
CPUState *cs;
- sPAPRDRConnector *drc;
+ SpaprDrc *drc;
Error *local_err = NULL;
CPUArchId *core_slot;
int index;
const char *type = object_get_typename(OBJECT(dev));
CPUArchId *core_slot;
int index;
+ unsigned int smp_threads = machine->smp.threads;
if (dev->hotplugged && !mc->has_hotpluggable_cpus) {
error_setg(&local_err, "CPU hotplug not supported for this machine");
error_propagate(errp, local_err);
}
-int spapr_phb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
+int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp)
{
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(drc->dev);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(drc->dev);
int intc_phandle;
intc_phandle = spapr_irq_get_phandle(spapr, spapr->fdt_blob, errp);
return -1;
}
- if (spapr_populate_pci_dt(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
- fdt_start_offset)) {
+ if (spapr_dt_phb(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
+ fdt_start_offset)) {
error_setg(errp, "unable to create FDT node for PHB %d", sphb->index);
return -1;
}
static void spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
const unsigned windows_supported = spapr_phb_windows_supported(sphb);
if (dev->hotplugged && !smc->dr_phb_enabled) {
smc->phb_placement(spapr, sphb->index,
&sphb->buid, &sphb->io_win_addr,
&sphb->mem_win_addr, &sphb->mem64_win_addr,
- windows_supported, sphb->dma_liobn, errp);
+ windows_supported, sphb->dma_liobn,
+ &sphb->nv2_gpa_win_addr, &sphb->nv2_atsd_win_addr,
+ errp);
}
static void spapr_phb_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
- sPAPRDRConnector *drc;
+ SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
+ SpaprDrc *drc;
bool hotplugged = spapr_drc_hotplugged(dev);
Error *local_err = NULL;
HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);
hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
+ object_unparent(OBJECT(dev));
}
static void spapr_phb_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
- object_unparent(OBJECT(dev));
+ object_property_set_bool(OBJECT(dev), false, "realized", NULL);
}
static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
- sPAPRDRConnector *drc;
+ SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
+ SpaprDrc *drc;
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, sphb->index);
assert(drc);
static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- sPAPRMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ SpaprMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev));
MachineClass *mc = MACHINE_GET_CLASS(sms);
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
if (spapr_ovec_test(sms->ov5_cas, OV5_HP_EVT)) {
object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
return HOTPLUG_HANDLER(machine);
}
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+ PCIDevice *pcidev = PCI_DEVICE(dev);
+ PCIBus *root = pci_device_root_bus(pcidev);
+ SpaprPhbState *phb =
+ (SpaprPhbState *)object_dynamic_cast(OBJECT(BUS(root)->parent),
+ TYPE_SPAPR_PCI_HOST_BRIDGE);
+
+ if (phb) {
+ return HOTPLUG_HANDLER(phb);
+ }
+ }
return NULL;
}
static int64_t spapr_get_default_cpu_node_id(const MachineState *ms, int idx)
{
- return idx / smp_cores % nb_numa_nodes;
+ return idx / ms->smp.cores % nb_numa_nodes;
}
static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
{
int i;
+ unsigned int smp_threads = machine->smp.threads;
+ unsigned int smp_cpus = machine->smp.cpus;
const char *core_type;
- int spapr_max_cores = max_cpus / smp_threads;
+ int spapr_max_cores = machine->smp.max_cpus / smp_threads;
MachineClass *mc = MACHINE_GET_CLASS(machine);
if (!mc->has_hotpluggable_cpus) {
return machine->possible_cpus;
}
-static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
+static void spapr_phb_placement(SpaprMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
- unsigned n_dma, uint32_t *liobns, Error **errp)
+ unsigned n_dma, uint32_t *liobns,
+ hwaddr *nv2gpa, hwaddr *nv2atsd, Error **errp)
{
/*
* New-style PHB window placement.
*pio = SPAPR_PCI_BASE + index * SPAPR_PCI_IO_WIN_SIZE;
*mmio32 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM32_WIN_SIZE;
*mmio64 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM64_WIN_SIZE;
+
+ *nv2gpa = SPAPR_PCI_NV2RAM64_WIN_BASE + index * SPAPR_PCI_NV2RAM64_WIN_SIZE;
+ *nv2atsd = SPAPR_PCI_NV2ATSD_WIN_BASE + index * SPAPR_PCI_NV2ATSD_WIN_SIZE;
}
static ICSState *spapr_ics_get(XICSFabric *dev, int irq)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(dev);
return ics_valid_irq(spapr->ics, irq) ? spapr->ics : NULL;
}
static void spapr_ics_resend(XICSFabric *dev)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(dev);
+ SpaprMachineState *spapr = SPAPR_MACHINE(dev);
ics_resend(spapr->ics);
}
static void spapr_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
spapr->irq->print_info(spapr, mon);
}
void spapr_set_vcpu_id(PowerPCCPU *cpu, int cpu_index, Error **errp)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ MachineState *ms = MACHINE(spapr);
int vcpu_id;
vcpu_id = spapr_vcpu_id(spapr, cpu_index);
error_setg(errp, "Can't create CPU with id %d in KVM", vcpu_id);
error_append_hint(errp, "Adjust the number of cpus to %d "
"or try to raise the number of threads per core\n",
- vcpu_id * smp_threads / spapr->vsmt);
+ vcpu_id * ms->smp.threads / spapr->vsmt);
return;
}
static void spapr_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
NMIClass *nc = NMI_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
vhc->hpt_mask = spapr_hpt_mask;
vhc->map_hptes = spapr_map_hptes;
vhc->unmap_hptes = spapr_unmap_hptes;
- vhc->store_hpte = spapr_store_hpte;
+ vhc->hpte_set_c = spapr_hpte_set_c;
+ vhc->hpte_set_r = spapr_hpte_set_r;
vhc->get_pate = spapr_get_pate;
vhc->encode_hpt_for_kvm_pr = spapr_encode_hpt_for_kvm_pr;
xic->ics_get = spapr_ics_get;
* in which LMBs are represented and hot-added
*/
mc->numa_mem_align_shift = 28;
+ mc->numa_mem_supported = true;
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
- 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_CFPC] = SPAPR_CAP_WORKAROUND;
+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND;
+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_WORKAROUND;
smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */
smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
+ smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
+ smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
spapr_caps_add_properties(smc, &error_abort);
- smc->irq = &spapr_irq_xics;
+ smc->irq = &spapr_irq_dual;
smc->dr_phb_enabled = true;
}
.name = TYPE_SPAPR_MACHINE,
.parent = TYPE_MACHINE,
.abstract = true,
- .instance_size = sizeof(sPAPRMachineState),
+ .instance_size = sizeof(SpaprMachineState),
.instance_init = spapr_instance_init,
.instance_finalize = spapr_machine_finalizefn,
- .class_size = sizeof(sPAPRMachineClass),
+ .class_size = sizeof(SpaprMachineClass),
.class_init = spapr_machine_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_FW_PATH_PROVIDER },
} \
type_init(spapr_machine_register_##suffix)
+/*
+ * pseries-4.1
+ */
+static void spapr_machine_4_1_class_options(MachineClass *mc)
+{
+ /* Defaults for the latest behaviour inherited from the base class */
+}
+
+DEFINE_SPAPR_MACHINE(4_1, "4.1", true);
+
/*
* pseries-4.0
*/
+static void phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
+ uint64_t *buid, hwaddr *pio,
+ hwaddr *mmio32, hwaddr *mmio64,
+ unsigned n_dma, uint32_t *liobns,
+ hwaddr *nv2gpa, hwaddr *nv2atsd, Error **errp)
+{
+ spapr_phb_placement(spapr, index, buid, pio, mmio32, mmio64, n_dma, liobns,
+ nv2gpa, nv2atsd, errp);
+ *nv2gpa = 0;
+ *nv2atsd = 0;
+}
+
static void spapr_machine_4_0_class_options(MachineClass *mc)
{
- /* Defaults for the latest behaviour inherited from the base class */
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ spapr_machine_4_1_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
+ smc->phb_placement = phb_placement_4_0;
+ smc->irq = &spapr_irq_xics;
+ smc->pre_4_1_migration = true;
}
-DEFINE_SPAPR_MACHINE(4_0, "4.0", true);
+DEFINE_SPAPR_MACHINE(4_0, "4.0", false);
/*
* pseries-3.1
*/
static void spapr_machine_3_1_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
- static GlobalProperty compat[] = {
- { TYPE_SPAPR_MACHINE, "host-model", "passthrough" },
- { TYPE_SPAPR_MACHINE, "host-serial", "passthrough" },
- };
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_4_0_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
- compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
smc->update_dt_enabled = false;
smc->dr_phb_enabled = false;
+ smc->broken_host_serial_model = true;
+ 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_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
}
DEFINE_SPAPR_MACHINE(3_1, "3.1", false);
static void spapr_machine_3_0_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_3_1_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
*/
static void spapr_machine_2_12_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ TYPE_POWERPC_CPU, "pre-3.0-migration", "on" },
{ TYPE_SPAPR_CPU_CORE, "pre-3.0-migration", "on" },
static void spapr_machine_2_12_sxxm_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_2_12_class_options(mc);
smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND;
static void spapr_machine_2_11_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_2_12_class_options(mc);
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
static void spapr_machine_2_9_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ TYPE_POWERPC_CPU, "pre-2.10-migration", "on" },
};
* pseries-2.7
*/
-static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
+static void phb_placement_2_7(SpaprMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
- unsigned n_dma, uint32_t *liobns, Error **errp)
+ unsigned n_dma, uint32_t *liobns,
+ hwaddr *nv2gpa, hwaddr *nv2atsd, Error **errp)
{
/* Legacy PHB placement for pseries-2.7 and earlier machine types */
const uint64_t base_buid = 0x800000020000000ULL;
* fallback behaviour of automatically splitting a large "32-bit"
* window into contiguous 32-bit and 64-bit windows
*/
+
+ *nv2gpa = 0;
+ *nv2atsd = 0;
}
static void spapr_machine_2_7_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem_win_size", "0xf80000000", },
{ TYPE_SPAPR_PCI_HOST_BRIDGE, "mem64_win_size", "0", },
static void spapr_machine_2_5_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
static GlobalProperty compat[] = {
{ "spapr-vlan", "use-rx-buffer-pools", "off" },
};
static void spapr_machine_2_4_class_options(MachineClass *mc)
{
- sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_2_5_class_options(mc);
smc->dr_lmb_enabled = false;