*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "qemu/datadir.h"
+#include "qemu/memalign.h"
#include "qapi/error.h"
#include "qapi/qapi-events-machine.h"
#include "qapi/qapi-events-qdev.h"
if (reset) {
const char *boot_device = spapr->boot_device;
- char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
+ g_autofree char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
size_t cb = 0;
- char *bootlist = get_boot_devices_list(&cb);
+ g_autofree char *bootlist = get_boot_devices_list(&cb);
if (machine->kernel_cmdline && machine->kernel_cmdline[0]) {
_FDT(fdt_setprop_string(fdt, chosen, "bootargs",
}
spapr_dt_ov5_platform_support(spapr, fdt, chosen);
-
- g_free(stdout_path);
- g_free(bootlist);
}
_FDT(spapr_dt_ovec(fdt, chosen, spapr->ov5_cas, "ibm,architecture-vec-5"));
/* The TCG path should also be holding the BQL at this point */
g_assert(qemu_mutex_iothread_locked());
+ g_assert(!vhyp_cpu_in_nested(cpu));
+
if (msr_pr) {
hcall_dprintf("Hypercall made with MSR[PR]=1\n");
env->gpr[3] = H_PRIVILEGE;
}
}
-static void spapr_get_pate(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry)
+static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
+ target_ulong lpid, ppc_v3_pate_t *entry)
{
SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ if (!spapr_cpu->in_nested) {
+ assert(lpid == 0);
+
+ /* Copy PATE1:GR into PATE0:HR */
+ entry->dw0 = spapr->patb_entry & PATE0_HR;
+ entry->dw1 = spapr->patb_entry;
+
+ } else {
+ uint64_t patb, pats;
+
+ assert(lpid != 0);
+
+ patb = spapr->nested_ptcr & PTCR_PATB;
+ pats = spapr->nested_ptcr & PTCR_PATS;
+
+ /* Calculate number of entries */
+ pats = 1ull << (pats + 12 - 4);
+ if (pats <= lpid) {
+ return false;
+ }
+
+ /* Grab entry */
+ patb += 16 * lpid;
+ entry->dw0 = ldq_phys(CPU(cpu)->as, patb);
+ entry->dw1 = ldq_phys(CPU(cpu)->as, patb + 8);
+ }
- /* Copy PATE1:GR into PATE0:HR */
- entry->dw0 = spapr->patb_entry & PATE0_HR;
- entry->dw1 = spapr->patb_entry;
+ return true;
}
#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2))
spapr->ov5_cas = spapr_ovec_clone(spapr->ov5);
}
+ spapr_nvdimm_finish_flushes();
+
/* 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
MachineClass *mc = MACHINE_GET_CLASS(machine);
const char *bios_default = spapr->vof ? FW_FILE_NAME_VOF : FW_FILE_NAME;
const char *bios_name = machine->firmware ?: bios_default;
+ g_autofree char *filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
const char *kernel_filename = machine->kernel_filename;
const char *initrd_filename = machine->initrd_filename;
PCIHostState *phb;
int i;
MemoryRegion *sysmem = get_system_memory();
long load_limit, fw_size;
- char *filename;
Error *resize_hpt_err = NULL;
+ if (!filename) {
+ error_report("Could not find LPAR firmware '%s'", bios_name);
+ exit(1);
+ }
+ fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
+ if (fw_size <= 0) {
+ error_report("Could not load LPAR firmware '%s'", filename);
+ exit(1);
+ }
+
/*
* if Secure VM (PEF) support is configured, then initialize it
*/
}
}
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- if (!filename) {
- error_report("Could not find LPAR firmware '%s'", bios_name);
- exit(1);
- }
- fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
- if (fw_size <= 0) {
- error_report("Could not load LPAR firmware '%s'", filename);
- exit(1);
- }
- g_free(filename);
-
/* FIXME: Should register things through the MachineState's qdev
* interface, this is a legacy from the sPAPREnvironment structure
* which predated MachineState but had a similar function */
VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);
- if (d) {
+ if (d && bus) {
void *spapr = CAST(void, bus->parent, "spapr-vscsi");
VirtIOSCSI *virtio = CAST(VirtIOSCSI, bus->parent, TYPE_VIRTIO_SCSI);
USBDevice *usb = CAST(USBDevice, bus->parent, TYPE_USB_DEVICE);
*/
ds = spapr_pending_dimm_unplugs_find(spapr, dimm);
if (!ds) {
- ds = g_malloc0(sizeof(SpaprDimmState));
+ ds = g_new0(SpaprDimmState, 1);
ds->nr_lmbs = nr_lmbs;
ds->dimm = dimm;
QTAILQ_INSERT_HEAD(&spapr->pending_dimm_unplugs, ds, next);
return NULL;
}
+static bool spapr_cpu_in_nested(PowerPCCPU *cpu)
+{
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ return spapr_cpu->in_nested;
+}
+
static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
{
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
fwc->get_dev_path = spapr_get_fw_dev_path;
nc->nmi_monitor_handler = spapr_nmi;
smc->phb_placement = spapr_phb_placement;
+ vhc->cpu_in_nested = spapr_cpu_in_nested;
+ vhc->deliver_hv_excp = spapr_exit_nested;
vhc->hypercall = emulate_spapr_hypercall;
vhc->hpt_mask = spapr_hpt_mask;
vhc->map_hptes = spapr_map_hptes;