Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.6-201602…
Browse files Browse the repository at this point in the history
…29' into staging

ppc patch queue for 2016-02-29

Some more accumulated patches for target-ppc, pseries machine type and
related devices to fit in before the qemu-2.6 soft freeze.
    * Mostly bugfixes and small cleanups for spapr and Mac platforms

# gpg: Signature made Mon 29 Feb 2016 06:56:34 GMT using RSA key ID 20D9B392
# 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.6-20160229:
  xics: report errors with the QEMU Error API
  migration: allow machine to enforce configuration section migration
  spapr: skip configuration section during migration of older machines
  dbdma: warn when using unassigned channel
  spapr: disable vmdesc submission for old machines
  spapr_pci: fix irq leak in RTAS ibm,change-msi
  spapr_pci: kill useless variable in rtas_ibm_change_msi()
  spapr_rng: disable hotpluggability

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Feb 29, 2016
2 parents 6e378dd + a005b3e commit 35227e6
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 27 deletions.
21 changes: 21 additions & 0 deletions hw/core/machine.c
Expand Up @@ -312,6 +312,21 @@ static bool machine_get_suppress_vmdesc(Object *obj, Error **errp)
return ms->suppress_vmdesc;
}

static void machine_set_enforce_config_section(Object *obj, bool value,
Error **errp)
{
MachineState *ms = MACHINE(obj);

ms->enforce_config_section = value;
}

static bool machine_get_enforce_config_section(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);

return ms->enforce_config_section;
}

static int error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
{
error_report("Option '-device %s' cannot be handled by this machine",
Expand Down Expand Up @@ -467,6 +482,12 @@ static void machine_initfn(Object *obj)
object_property_set_description(obj, "suppress-vmdesc",
"Set on to disable self-describing migration",
NULL);
object_property_add_bool(obj, "enforce-config-section",
machine_get_enforce_config_section,
machine_set_enforce_config_section, NULL);
object_property_set_description(obj, "enforce-config-section",
"Set on to enforce configuration section migration",
NULL);

/* Register notifier when init is done for sysbus sanity checks */
ms->sysbus_notifier.notify = machine_init_notify;
Expand Down
13 changes: 9 additions & 4 deletions hw/intc/xics.c
Expand Up @@ -712,22 +712,22 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
return -1;
}

int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi)
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp)
{
ICSState *ics = &icp->ics[src];
int irq;

if (irq_hint) {
assert(src == xics_find_source(icp, irq_hint));
if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
trace_xics_alloc_failed_hint(src, irq_hint);
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) {
trace_xics_alloc_failed_no_left(src);
error_setg(errp, "can't allocate IRQ: no IRQ left");
return -1;
}
irq += ics->offset;
Expand All @@ -743,7 +743,8 @@ int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi)
* 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 xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align)
int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align,
Error **errp)
{
int i, first = -1;
ICSState *ics = &icp->ics[src];
Expand All @@ -763,6 +764,10 @@ int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align)
} 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;
}

if (first >= 0) {
for (i = first; i < first + num; ++i) {
Expand Down
25 changes: 23 additions & 2 deletions hw/misc/macio/mac_dbdma.c
Expand Up @@ -557,11 +557,13 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,

DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan);

assert(rw);
assert(flush);

ch->irq = irq;
ch->rw = rw;
ch->flush = flush;
ch->io.opaque = opaque;
ch->io.channel = ch;
}

static void
Expand Down Expand Up @@ -775,6 +777,20 @@ static void dbdma_reset(void *opaque)
memset(s->channels[i].regs, 0, DBDMA_SIZE);
}

static void dbdma_unassigned_rw(DBDMA_io *io)
{
DBDMA_channel *ch = io->channel;
qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
__func__, ch->channel);
}

static void dbdma_unassigned_flush(DBDMA_io *io)
{
DBDMA_channel *ch = io->channel;
qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
__func__, ch->channel);
}

void* DBDMA_init (MemoryRegion **dbdma_mem)
{
DBDMAState *s;
Expand All @@ -784,8 +800,13 @@ void* DBDMA_init (MemoryRegion **dbdma_mem)

for (i = 0; i < DBDMA_CHANNELS; i++) {
DBDMA_io *io = &s->channels[i].io;
DBDMA_channel *ch = &s->channels[i];
qemu_iovec_init(&io->iov, 1);
s->channels[i].channel = i;

ch->rw = dbdma_unassigned_rw;
ch->flush = dbdma_unassigned_flush;
ch->channel = i;
ch->io.channel = ch;
}

memory_region_init_io(&s->mem, NULL, &dbdma_ops, s, "dbdma", 0x1000);
Expand Down
2 changes: 2 additions & 0 deletions hw/ppc/spapr.c
Expand Up @@ -2427,6 +2427,7 @@ static void spapr_machine_2_3_instance_options(MachineState *machine)
spapr_machine_2_4_instance_options(machine);
savevm_skip_section_footers();
global_state_set_optional();
savevm_skip_configuration();
}

static void spapr_machine_2_3_class_options(MachineClass *mc)
Expand All @@ -2452,6 +2453,7 @@ DEFINE_SPAPR_MACHINE(2_3, "2.3", false);
static void spapr_machine_2_2_instance_options(MachineState *machine)
{
spapr_machine_2_3_instance_options(machine);
machine->suppress_vmdesc = true;
}

static void spapr_machine_2_2_class_options(MachineClass *mc)
Expand Down
3 changes: 2 additions & 1 deletion hw/ppc/spapr_events.c
Expand Up @@ -588,7 +588,8 @@ static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
void spapr_events_init(sPAPRMachineState *spapr)
{
QTAILQ_INIT(&spapr->pending_events);
spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false);
spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false,
&error_fatal);
spapr->epow_notifier.notify = spapr_powerdown_req;
qemu_register_powerdown_notifier(&spapr->epow_notifier);
spapr_rtas_register(RTAS_CHECK_EXCEPTION, "check-exception",
Expand Down
31 changes: 21 additions & 10 deletions hw/ppc/spapr_pci.c
Expand Up @@ -275,11 +275,12 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
unsigned int req_num = rtas_ld(args, 4); /* 0 == remove all */
unsigned int seq_num = rtas_ld(args, 5);
unsigned int ret_intr_type;
unsigned int irq, max_irqs = 0, num = 0;
unsigned int irq, max_irqs = 0;
sPAPRPHBState *phb = NULL;
PCIDevice *pdev = NULL;
spapr_pci_msi *msi;
int *config_addr_key;
Error *err = NULL;

switch (func) {
case RTAS_CHANGE_MSI_FN:
Expand All @@ -305,9 +306,10 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return;
}

msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr);

/* Releasing MSIs */
if (!req_num) {
msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr);
if (!msi) {
trace_spapr_pci_msi("Releasing wrong config", config_addr);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
Expand All @@ -316,10 +318,10 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,

xics_free(spapr->icp, msi->first_irq, msi->num);
if (msi_present(pdev)) {
spapr_msi_setmsg(pdev, 0, false, 0, num);
spapr_msi_setmsg(pdev, 0, false, 0, 0);
}
if (msix_present(pdev)) {
spapr_msi_setmsg(pdev, 0, true, 0, num);
spapr_msi_setmsg(pdev, 0, true, 0, 0);
}
g_hash_table_remove(phb->msi, &config_addr);

Expand Down Expand Up @@ -353,13 +355,20 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,

/* Allocate MSIs */
irq = xics_alloc_block(spapr->icp, 0, req_num, false,
ret_intr_type == RTAS_TYPE_MSI);
if (!irq) {
error_report("Cannot allocate MSIs for device %x", config_addr);
ret_intr_type == RTAS_TYPE_MSI, &err);
if (err) {
error_reportf_err(err, "Can't allocate MSIs for device %x: ",
config_addr);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}

/* Release previous MSIs */
if (msi) {
xics_free(spapr->icp, msi->first_irq, msi->num);
g_hash_table_remove(phb->msi, &config_addr);
}

/* Setup MSI/MSIX vectors in the device (via cfgspace or MSIX BAR) */
spapr_msi_setmsg(pdev, SPAPR_PCI_MSI_WINDOW, ret_intr_type == RTAS_TYPE_MSIX,
irq, req_num);
Expand Down Expand Up @@ -1360,10 +1369,12 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
/* Initialize the LSI table */
for (i = 0; i < PCI_NUM_PINS; i++) {
uint32_t irq;
Error *local_err = NULL;

irq = xics_alloc_block(spapr->icp, 0, 1, true, false);
if (!irq) {
error_setg(errp, "spapr_allocate_lsi failed");
irq = xics_alloc_block(spapr->icp, 0, 1, true, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
error_prepend(errp, "can't allocate LSIs: ");
return;
}

Expand Down
1 change: 1 addition & 0 deletions hw/ppc/spapr_rng.c
Expand Up @@ -170,6 +170,7 @@ static void spapr_rng_class_init(ObjectClass *oc, void *data)
dc->realize = spapr_rng_realize;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->props = spapr_rng_properties;
dc->hotpluggable = false;
}

static const TypeInfo spapr_rng_info = {
Expand Down
7 changes: 4 additions & 3 deletions hw/ppc/spapr_vio.c
Expand Up @@ -431,6 +431,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
char *id;
Error *local_err = NULL;

if (dev->reg != -1) {
/*
Expand Down Expand Up @@ -463,9 +464,9 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
dev->qdev.id = id;
}

dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false);
if (!dev->irq) {
error_setg(errp, "can't allocate IRQ");
dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}

Expand Down
1 change: 1 addition & 0 deletions include/hw/boards.h
Expand Up @@ -127,6 +127,7 @@ struct MachineState {
char *firmware;
bool iommu;
bool suppress_vmdesc;
bool enforce_config_section;

ram_addr_t ram_size;
ram_addr_t maxram_size;
Expand Down
5 changes: 3 additions & 2 deletions include/hw/ppc/xics.h
Expand Up @@ -161,8 +161,9 @@ struct ICSIRQState {

qemu_irq xics_get_qirq(XICSState *icp, int irq);
void xics_set_irq_type(XICSState *icp, int irq, bool lsi);
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi);
int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align);
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp);
int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align,
Error **errp);
void xics_free(XICSState *icp, int irq, int num);

void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
Expand Down
10 changes: 8 additions & 2 deletions migration/savevm.c
Expand Up @@ -878,13 +878,19 @@ bool qemu_savevm_state_blocked(Error **errp)
return false;
}

static bool enforce_config_section(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
return machine->enforce_config_section;
}

void qemu_savevm_state_header(QEMUFile *f)
{
trace_savevm_state_header();
qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
qemu_put_be32(f, QEMU_VM_FILE_VERSION);

if (!savevm_state.skip_configuration) {
if (!savevm_state.skip_configuration || enforce_config_section()) {
qemu_put_byte(f, QEMU_VM_CONFIGURATION);
vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);
}
Expand Down Expand Up @@ -1883,7 +1889,7 @@ int qemu_loadvm_state(QEMUFile *f)
return -ENOTSUP;
}

if (!savevm_state.skip_configuration) {
if (!savevm_state.skip_configuration || enforce_config_section()) {
if (qemu_get_byte(f) != QEMU_VM_CONFIGURATION) {
error_report("Configuration section missing");
return -EINVAL;
Expand Down
3 changes: 2 additions & 1 deletion qemu-options.hx
Expand Up @@ -43,7 +43,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" aes-key-wrap=on|off controls support for AES key wrapping (default=on)\n"
" dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n"
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
" nvdimm=on|off controls NVDIMM support (default=off)\n",
" nvdimm=on|off controls NVDIMM support (default=off)\n"
" enforce-config-section=on|off enforce configuration section migration (default=off)\n",
QEMU_ARCH_ALL)
STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
Expand Down
2 changes: 0 additions & 2 deletions trace-events
Expand Up @@ -1409,8 +1409,6 @@ xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_
xics_ics_reject(int nr, int srcno) "reject irq %#x [src %d]"
xics_ics_eoi(int nr) "ics_eoi: irq %#x"
xics_alloc(int src, int irq) "source#%d, irq %d"
xics_alloc_failed_hint(int src, int irq) "source#%d, irq %d is already in use"
xics_alloc_failed_no_left(int src) "source#%d, no irq left"
xics_alloc_block(int src, int first, int num, bool lsi, int align) "source#%d, first irq %d, %d irqs, lsi=%d, alignnum %d"
xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free"
Expand Down

0 comments on commit 35227e6

Please sign in to comment.