From 681431893e7c2414825aa3f5265368adbe005dae Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 4 May 2018 10:45:50 +0200 Subject: [PATCH 01/33] ppc440_pcix: Fix a typo in setting a register (Coverity CID1390577) Signed-off-by: BALATON Zoltan Signed-off-by: David Gibson --- hw/ppc/ppc440_pcix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index b1307e6477..d8af04b70f 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -257,7 +257,7 @@ static void ppc440_pcix_reg_write4(void *opaque, hwaddr addr, break; case PCIX0_PIM2SAL: s->pim[2].sa &= 0xffffffff00000000ULL; - s->pim[2].sa = val; + s->pim[2].sa |= val; ppc440_pcix_update_pim(s, 2); break; case PCIX0_PIM2LAL: From 56e7404bc19c8abfe02c08f733ad387b58817f94 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 6 May 2018 15:20:03 +0100 Subject: [PATCH 02/33] macio: add trace-events to timer device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/misc/macio/macio.c | 3 +++ hw/misc/macio/trace-events | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 79621eb879..f9a40eea81 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -32,6 +32,7 @@ #include "hw/char/escc.h" #include "hw/misc/macio/macio.h" #include "hw/intc/heathrow_pic.h" +#include "trace.h" /* Note: this code is strongly inspirated from the corresponding code * in PearPC */ @@ -246,6 +247,7 @@ static void macio_oldworld_init(Object *obj) static void timer_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { + trace_macio_timer_write(addr, size, value); } static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size) @@ -266,6 +268,7 @@ static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size) break; } + trace_macio_timer_read(addr, size, value); return value; } diff --git a/hw/misc/macio/trace-events b/hw/misc/macio/trace-events index 24c0a36824..d499d78c99 100644 --- a/hw/misc/macio/trace-events +++ b/hw/misc/macio/trace-events @@ -9,3 +9,7 @@ cuda_packet_receive(int len) "length %d" cuda_packet_receive_data(int i, const uint8_t data) "[%d] 0x%02x" cuda_packet_send(int len) "length %d" cuda_packet_send_data(int i, const uint8_t data) "[%d] 0x%02x" + +# hw/misc/macio/macio.c +macio_timer_write(uint64_t addr, unsigned len, uint64_t val) "write addr 0x%"PRIx64 " len %d val 0x%"PRIx64 +macio_timer_read(uint64_t addr, unsigned len, uint32_t val) "read addr 0x%"PRIx64 " len %d val 0x%"PRIx32 From 45fefe7c4d9bfc5a4a222d3d2c8244531e87130f Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 6 May 2018 15:20:05 +0100 Subject: [PATCH 03/33] uninorth: remove token register from uninorth device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit >From observation of various OS sources it can be seen that the token register introduced in 4e46dcdbd3 "PPC: Newworld: Add uninorth token register" is not required, since the only register currently implemented is the uninorth hardware version which is read-only. Remove the token register implementation and instead return the uninorth version corresponding to the hardware. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 11 +++++------ include/hw/pci-host/uninorth.h | 4 +++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index ba76b84dbc..a843aa7b36 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -524,19 +524,18 @@ static void unin_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { trace_unin_write(addr, value); - if (addr == 0x0) { - *(int *)opaque = value; - } } static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size) { uint32_t value; - value = 0; switch (addr) { case 0: - value = *(int *)opaque; + value = UNINORTH_VERSION_10A; + break; + default: + value = 0; } trace_unin_read(addr, value); @@ -555,7 +554,7 @@ static void unin_init(Object *obj) UNINState *s = UNI_NORTH(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - memory_region_init_io(&s->mem, obj, &unin_ops, &s->token, "unin", 0x1000); + memory_region_init_io(&s->mem, obj, &unin_ops, s, "unin", 0x1000); sysbus_init_mmio(sbd, &s->mem); } diff --git a/include/hw/pci-host/uninorth.h b/include/hw/pci-host/uninorth.h index f6654bad9b..2a1cf9f284 100644 --- a/include/hw/pci-host/uninorth.h +++ b/include/hw/pci-host/uninorth.h @@ -29,6 +29,9 @@ #include "hw/ppc/openpic.h" +/* UniNorth version */ +#define UNINORTH_VERSION_10A 0x7 + #define TYPE_UNI_NORTH_PCI_HOST_BRIDGE "uni-north-pci-pcihost" #define TYPE_UNI_NORTH_AGP_HOST_BRIDGE "uni-north-agp-pcihost" #define TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE "uni-north-internal-pci-pcihost" @@ -57,7 +60,6 @@ typedef struct UNINState { SysBusDevice parent_obj; MemoryRegion mem; - int token[1]; } UNINState; #define TYPE_UNI_NORTH "uni-north" From e20c63140a185c166e91d8c68a2aa6bb99e600c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 29 May 2018 14:48:19 -0300 Subject: [PATCH 04/33] hw/ppc/spapr_drc: Replace error_setg(&error_abort) by error_report() + abort() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use error_report() + abort() instead of error_setg(&error_abort), as suggested by the "qapi/error.h" documentation: Please don't error_setg(&error_fatal, ...), use error_report() and exit(), because that's more obvious. Likewise, don't error_setg(&error_abort, ...), use assert(). Use abort() instead of the suggested assert() because the error message already got displayed. Suggested-by: Eric Blake Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Eric Auger Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 8a045d6b93..2edb7d1e9c 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -366,7 +366,8 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name, break; } default: - error_setg(&error_abort, "device FDT in unexpected state: %d", tag); + error_report("device FDT in unexpected state: %d", tag); + abort(); } fdt_offset = fdt_offset_next; } while (fdt_depth != 0); From 31085338293a1203187c6ef6dba9dfce14021189 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Mon, 28 May 2018 20:11:19 +0200 Subject: [PATCH 05/33] target/ppc: Use proper logging function for possible guest errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fprintf() and qemu_log_separate() are frowned upon these days for printing logging information in QEMU. Accessing the wrong SPRs indicates wrong guest behaviour in most cases, and we've got a proper way to log such situations, which is the qemu_log_mask(LOG_GUEST_ERROR, ...) function. So use this function now for logging the bad SPR accesses instead. Signed-off-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Greg Kurz Reviewed-by: Alistair Francis Signed-off-by: David Gibson --- target/ppc/translate.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index b28e8b91d3..8ba8f67dc5 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -3933,13 +3933,9 @@ static inline void gen_op_mfspr(DisasContext *ctx) * allowing userland application to read the PVR */ if (sprn != SPR_PVR) { - fprintf(stderr, "Trying to read privileged spr %d (0x%03x) at " - TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); - if (qemu_log_separate()) { - qemu_log("Trying to read privileged spr %d (0x%03x) at " - TARGET_FMT_lx "\n", sprn, sprn, - ctx->base.pc_next - 4); - } + qemu_log_mask(LOG_GUEST_ERROR, "Trying to read privileged spr " + "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn, + ctx->base.pc_next - 4); } gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); } @@ -3951,12 +3947,9 @@ static inline void gen_op_mfspr(DisasContext *ctx) return; } /* Not defined */ - fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at " - TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); - if (qemu_log_separate()) { - qemu_log("Trying to read invalid spr %d (0x%03x) at " - TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); - } + qemu_log_mask(LOG_GUEST_ERROR, + "Trying to read invalid spr %d (0x%03x) at " + TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); /* The behaviour depends on MSR:PR and SPR# bit 0x10, * it can generate a priv, a hv emu or a no-op @@ -4097,12 +4090,9 @@ static void gen_mtspr(DisasContext *ctx) (*write_cb)(ctx, sprn, rS(ctx->opcode)); } else { /* Privilege exception */ - fprintf(stderr, "Trying to write privileged spr %d (0x%03x) at " - TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); - if (qemu_log_separate()) { - qemu_log("Trying to write privileged spr %d (0x%03x) at " - TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); - } + qemu_log_mask(LOG_GUEST_ERROR, "Trying to write privileged spr " + "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn, + ctx->base.pc_next - 4); gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); } } else { @@ -4114,12 +4104,9 @@ static void gen_mtspr(DisasContext *ctx) } /* Not defined */ - if (qemu_log_separate()) { - qemu_log("Trying to write invalid spr %d (0x%03x) at " - TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); - } - fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at " - TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); + qemu_log_mask(LOG_GUEST_ERROR, + "Trying to write invalid spr %d (0x%03x) at " + TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); /* The behaviour depends on MSR:PR and SPR# bit 0x10, From 875bad313580f99cc9642d2941d0dbeeadf4ef25 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 May 2018 22:15:23 +0100 Subject: [PATCH 06/33] 40p: remove pci_allow_0_address = true from 40p machine class The Linux sandalfoot zImage has an initialisation process which resets the VGA controller by setting all the BAR addresses to zero to access the VGA ioports at their legacy addresses. Unfortunately setting the framebuffer BAR to address 0 makes the framebuffer memory overlap the internal VGA memory causing accesses to fail, and so prevents the kernel from switching successfully to text mode. Since OpenHackWare configures the framebuffer BAR address outside of the legacy VGA internal memory space, remove pci_allow_0_address from the 40p machine class which causes the BAR reprogramming to zero to fail and so the VGA internal memory can be accessed correctly again. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/ppc/prep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index a1e7219db6..dbbe749bde 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -885,7 +885,6 @@ static void ibm_40p_machine_init(MachineClass *mc) mc->desc = "IBM RS/6000 7020 (40p)", mc->init = ibm_40p_init; mc->max_cpus = 1; - mc->pci_allow_0_address = true; mc->default_ram_size = 128 * M_BYTE; mc->block_default_type = IF_SCSI; mc->default_boot_order = "c"; From 7cb00357c155240bae3b17eaa00415087b004c52 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 24 May 2018 06:39:58 +0100 Subject: [PATCH 07/33] prep: fix keyboard for the 40p machine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 72d3d8f052 "hw/isa/superio: Add a keyboard/mouse controller (8042)" added an 8042 keyboard device to the PC87312 superio device to replace that being used by the prep machine. Unfortunately this commit didn't do the same for the 40p machine which broke the keyboard by registering two 8042 keyboard devices at the same address. Resolve this by similarly removing the 8042 keyboard from the 40p machine as done for the prep machine in commit 72d3d8f052. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Hervé Poussineau Signed-off-by: David Gibson --- hw/ppc/prep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index dbbe749bde..5ed0bcd862 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -770,7 +770,6 @@ static void ibm_40p_init(MachineState *machine) /* add some more devices */ if (defaults_enabled()) { - isa_create_simple(isa_bus, TYPE_I8042); m48t59 = NVRAM(isa_create_simple(isa_bus, "isa-m48t59")); dev = DEVICE(isa_create(isa_bus, "cs4231a")); From 8fea70440eb0d095442de7e80d586a285cf96be5 Mon Sep 17 00:00:00 2001 From: Suraj Jitindar Singh Date: Fri, 11 May 2018 16:25:07 +1000 Subject: [PATCH 08/33] target/ppc: Factor out the parsing in kvmppc_get_cpu_characteristics() Factor out the parsing of struct kvm_ppc_cpu_char in kvmppc_get_cpu_characteristics() into a separate function for each cap for simplicity. Signed-off-by: Suraj Jitindar Singh Signed-off-by: David Gibson --- target/ppc/kvm.c | 59 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index cbe13b18d1..2c0c34e125 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -2412,6 +2412,41 @@ bool kvmppc_has_cap_mmu_hash_v3(void) return cap_mmu_hash_v3; } +static int parse_cap_ppc_safe_cache(struct kvm_ppc_cpu_char c) +{ + if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_L1D_FLUSH_PR) { + return 2; + } else if ((c.character & c.character_mask & H_CPU_CHAR_L1D_THREAD_PRIV) && + (c.character & c.character_mask + & (H_CPU_CHAR_L1D_FLUSH_ORI30 | H_CPU_CHAR_L1D_FLUSH_TRIG2))) { + return 1; + } + + return 0; +} + +static int parse_cap_ppc_safe_bounds_check(struct kvm_ppc_cpu_char c) +{ + if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) { + return 2; + } else if (c.character & c.character_mask & H_CPU_CHAR_SPEC_BAR_ORI31) { + return 1; + } + + return 0; +} + +static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c) +{ + if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) { + return SPAPR_CAP_FIXED_CCD; + } else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) { + return SPAPR_CAP_FIXED_IBS; + } + + return 0; +} + static void kvmppc_get_cpu_characteristics(KVMState *s) { struct kvm_ppc_cpu_char c; @@ -2430,26 +2465,10 @@ static void kvmppc_get_cpu_characteristics(KVMState *s) if (ret < 0) { return; } - /* Parse and set cap_ppc_safe_cache */ - if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_L1D_FLUSH_PR) { - cap_ppc_safe_cache = 2; - } else if ((c.character & c.character_mask & H_CPU_CHAR_L1D_THREAD_PRIV) && - (c.character & c.character_mask - & (H_CPU_CHAR_L1D_FLUSH_ORI30 | H_CPU_CHAR_L1D_FLUSH_TRIG2))) { - cap_ppc_safe_cache = 1; - } - /* Parse and set cap_ppc_safe_bounds_check */ - if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) { - cap_ppc_safe_bounds_check = 2; - } else if (c.character & c.character_mask & H_CPU_CHAR_SPEC_BAR_ORI31) { - cap_ppc_safe_bounds_check = 1; - } - /* Parse and set cap_ppc_safe_indirect_branch */ - if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) { - cap_ppc_safe_indirect_branch = SPAPR_CAP_FIXED_CCD; - } else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) { - cap_ppc_safe_indirect_branch = SPAPR_CAP_FIXED_IBS; - } + + cap_ppc_safe_cache = parse_cap_ppc_safe_cache(c); + cap_ppc_safe_bounds_check = parse_cap_ppc_safe_bounds_check(c); + cap_ppc_safe_indirect_branch = parse_cap_ppc_safe_indirect_branch(c); } int kvmppc_get_cap_safe_cache(void) From 6b37554458a1e8cfe8f91ef0beac82e8de8f85bb Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Mon, 4 Jun 2018 18:15:13 +0930 Subject: [PATCH 09/33] target/ppc: Allow privileged access to SPR_PCR The powerpc Linux kernel[1] and skiboot firmware[2] recently gained changes that cause the Processor Compatibility Register (PCR) SPR to be cleared. These changes cause Linux to fail to boot on the Qemu powernv machine with an error: Trying to write privileged spr 338 (0x152) at 0000000030017f0c With this patch Qemu makes this register available as a hypervisor privileged register. Note that bits set in this register disable features of the processor. Currently the only register state that is supported is when the register is zeroed (enable all features). This is sufficient for guests to once again boot. [1] https://lkml.kernel.org/r/20180518013742.24095-1-mikey@neuling.org [2] https://patchwork.ozlabs.org/patch/915932/ Signed-off-by: Joel Stanley Signed-off-by: David Gibson --- target/ppc/helper.h | 1 + target/ppc/misc_helper.c | 9 +++++++++ target/ppc/translate_init.inc.c | 9 +++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 19453c6813..d751f0e219 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -17,6 +17,7 @@ DEF_HELPER_2(pminsn, void, env, i32) DEF_HELPER_1(rfid, void, env) DEF_HELPER_1(hrfid, void, env) DEF_HELPER_2(store_lpcr, void, env, tl) +DEF_HELPER_2(store_pcr, void, env, tl) #endif DEF_HELPER_1(check_tlb_flush_local, void, env) DEF_HELPER_1(check_tlb_flush_global, void, env) diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 8c8cba5cc6..b884930096 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -20,6 +20,7 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" +#include "qemu/error-report.h" #include "helper_regs.h" @@ -98,6 +99,14 @@ void helper_store_ptcr(CPUPPCState *env, target_ulong val) tlb_flush(CPU(cpu)); } } + +void helper_store_pcr(CPUPPCState *env, target_ulong value) +{ + PowerPCCPU *cpu = ppc_env_get_cpu(env); + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + + env->spr[SPR_PCR] = value & pcc->pcr_mask; +} #endif /* defined(TARGET_PPC64) */ void helper_store_pidr(CPUPPCState *env, target_ulong val) diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index ab782cb32a..1a89017dde 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -424,6 +424,10 @@ static void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn) gen_helper_store_ptcr(cpu_env, cpu_gpr[gprn]); } +static void spr_write_pcr(DisasContext *ctx, int sprn, int gprn) +{ + gen_helper_store_pcr(cpu_env, cpu_gpr[gprn]); +} #endif #endif @@ -7957,11 +7961,12 @@ static void gen_spr_power6_common(CPUPPCState *env) #endif /* * Register PCR to report POWERPC_EXCP_PRIV_REG instead of - * POWERPC_EXCP_INVAL_SPR. + * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access. */ - spr_register(env, SPR_PCR, "PCR", + spr_register_hv(env, SPR_PCR, "PCR", SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pcr, 0x00000000); } From efe2add7cb7f870ebd90ac4f9637161a4821200a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 5 Jun 2018 08:56:26 +0200 Subject: [PATCH 10/33] spapr/vio: deprecate the "irq" property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VIO devices have an "irq" property that can be used by the sPAPR IRQ allocator as an IRQ number hint. But it is not set in QEMU nor in libvirt. It brings unnecessary complexity to the underlying layers managing the IRQ number space and it is in full opposition with the new static IRQ allocator we want to introduce in sPAPR. Let's deprecate it to simplify the spapr_irq_alloc routine in the future. Signed-off-by: Cédric Le Goater Reviewed-by: Thomas Huth Reviewed-by: Greg Kurz [dwg: Check qtest_enabled() to suppress bogus warnings from make check] Signed-off-by: David Gibson --- hw/ppc/spapr_vio.c | 22 +++++++++++++++++++++- qemu-doc.texi | 12 ++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 472dd6f33a..4555c648a8 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -22,6 +22,7 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "qapi/error.h" +#include "qapi/visitor.h" #include "hw/hw.h" #include "qemu/log.h" #include "sysemu/sysemu.h" @@ -32,6 +33,7 @@ #include "sysemu/kvm.h" #include "sysemu/device_tree.h" #include "kvm_ppc.h" +#include "sysemu/qtest.h" #include "hw/ppc/spapr.h" #include "hw/ppc/spapr_vio.h" @@ -41,8 +43,26 @@ #include +static void spapr_vio_getset_irq(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + Property *prop = opaque; + uint32_t *ptr = qdev_get_prop_ptr(DEVICE(obj), prop); + + if (!qtest_enabled()) { + warn_report(TYPE_VIO_SPAPR_DEVICE " '%s' property is deprecated", name); + } + visit_type_uint32(v, name, ptr, errp); +} + +static const PropertyInfo spapr_vio_irq_propinfo = { + .name = "irq", + .get = spapr_vio_getset_irq, + .set = spapr_vio_getset_irq, +}; + static Property spapr_vio_props[] = { - DEFINE_PROP_UINT32("irq", VIOsPAPRDevice, irq, 0), \ + DEFINE_PROP("irq", VIOsPAPRDevice, irq, spapr_vio_irq_propinfo, uint32_t), DEFINE_PROP_END_OF_LIST(), }; diff --git a/qemu-doc.texi b/qemu-doc.texi index 9aff6b4ea9..cd05760cac 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2958,13 +2958,21 @@ support page sizes < 4096 any longer. @section System emulator machines -@section Block device options +@section Device options -@subsection "backing": "" (since 2.12.0) +@subsection Block device options + +@subsubsection "backing": "" (since 2.12.0) In order to prevent QEMU from automatically opening an image's backing chain, use ``"backing": null'' instead. +@subsection vio-spapr-device device options + +@subsubsection "irq": "" (since 3.0.0) + +The ``irq'' property is obsoleted. + @node Supported build platforms @appendix Supported build platforms From 0c1272cc7c72dfe0ef66be8f283cf67c74b58586 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sun, 6 May 2018 17:29:49 +1000 Subject: [PATCH 11/33] osdep: powerpc64 align memory to allow 2MB radix THP page tables This allows KVM with the Book3S radix MMU mode to take advantage of THP and install larger pages in the partition scope page tables (the host translation). Signed-off-by: Nicholas Piggin Signed-off-by: David Gibson --- include/qemu/osdep.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index afc28e5903..9ed62423c0 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -367,7 +367,8 @@ void qemu_anon_ram_free(void *ptr, size_t size); #endif #if defined(__linux__) && \ - (defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)) + (defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) \ + || defined(__powerpc64__)) /* Use 2 MiB alignment so transparent hugepages can be used by KVM. Valgrind does not support alignments larger than 1 MiB, therefore we need special code which handles running on Valgrind. */ From eba45926c2dfb64000da7f83b253f935d6d77941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 6 Jun 2018 11:59:19 -0300 Subject: [PATCH 12/33] MAINTAINERS: Add an entry for the MacIO device headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Missed while moved in 7092e84d42b. Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index a40f558694..5286a1519c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -766,8 +766,9 @@ F: hw/ppc/mac_newworld.c F: hw/pci-host/uninorth.c F: hw/pci-bridge/dec.[hc] F: hw/misc/macio/ -F: include/hw/ppc/mac_dbdma.h F: hw/nvram/mac_nvram.c +F: include/hw/misc/macio/ +F: include/hw/ppc/mac_dbdma.h Old World M: Alexander Graf From 6ba1647664efc0d7295c03ad4295df403853c70f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 6 Jun 2018 11:59:20 -0300 Subject: [PATCH 13/33] MAINTAINERS: Add entries for the MOS6522 VIA device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduced in 51f233ec92c. Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 5286a1519c..8a94517e9e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -766,8 +766,10 @@ F: hw/ppc/mac_newworld.c F: hw/pci-host/uninorth.c F: hw/pci-bridge/dec.[hc] F: hw/misc/macio/ +F: hw/misc/mos6522.c F: hw/nvram/mac_nvram.c F: include/hw/misc/macio/ +F: include/hw/misc/mos6522.h F: include/hw/ppc/mac_dbdma.h Old World From c9bca798447879ee1288a469604cf824bc2a4622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 6 Jun 2018 11:59:21 -0300 Subject: [PATCH 14/33] hw/misc/mos6522: Add trailing '\n' to qemu_log() calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/misc/mos6522.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c index 6163cea6ab..49166cb8ad 100644 --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -189,12 +189,12 @@ static uint64_t mos6522_get_load_time(MOS6522State *s, MOS6522Timer *ti) static void mos6522_portA_write(MOS6522State *s) { - qemu_log_mask(LOG_UNIMP, "portA_write unimplemented"); + qemu_log_mask(LOG_UNIMP, "portA_write unimplemented\n"); } static void mos6522_portB_write(MOS6522State *s) { - qemu_log_mask(LOG_UNIMP, "portB_write unimplemented"); + qemu_log_mask(LOG_UNIMP, "portB_write unimplemented\n"); } uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned size) From a72fed214a9a9503764fc6f62eea17dd09cb487a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 7 Jun 2018 17:59:53 +0100 Subject: [PATCH 15/33] ppc: remove obsolete pci_pmac_init() definitions from mac.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commits 7b19318bee and 8ce3f743c7 removed the pci_pmac_init() and pci_pmac_u3_init() functions but missed the header prototypes in mac.h. Remove them since they are no longer needed. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/mac.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 22a7efbed6..dac96317af 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -97,12 +97,6 @@ void macio_init(PCIDevice *dev, /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" -/* UniNorth PCI */ -UNINHostState *pci_pmac_init(qemu_irq *pic, - MemoryRegion *address_space_mem); -UNINHostState *pci_pmac_u3_init(qemu_irq *pic, - MemoryRegion *address_space_mem); - /* Mac NVRAM */ #define TYPE_MACIO_NVRAM "macio-nvram" #define MACIO_NVRAM(obj) \ From 4558fadaf550c0bf3c2284f353439a1cdbc407f1 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 7 Jun 2018 17:59:54 +0100 Subject: [PATCH 16/33] ppc: remove obsolete macio_init() definition from mac.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commits b6712ea391 removed the macio_init() function but missed the header prototype in mac.h. Remove it since it is no longer needed. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/mac.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index dac96317af..89fa8bbed7 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -91,9 +91,6 @@ typedef struct MACIOIDEState { void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); void macio_ide_register_dma(MACIOIDEState *ide); -void macio_init(PCIDevice *dev, - MemoryRegion *pic_mem); - /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" From 5b64db9754bde0b8e0329ce77d3647a0a2f6da56 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 7 Jun 2018 17:59:55 +0100 Subject: [PATCH 17/33] ppc: add missing FW_CFG_PPC_NVRAM_FLAT definition This is used in OpenBIOS to define the memory layout of the NVRAM device. Whilst currently left at its default value, add the missing definition to ensure it is reserved. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- include/hw/ppc/ppc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h index ff0ac306be..b18ef3eefb 100644 --- a/include/hw/ppc/ppc.h +++ b/include/hw/ppc/ppc.h @@ -100,6 +100,7 @@ enum { #define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07) #define FW_CFG_PPC_NVRAM_ADDR (FW_CFG_ARCH_LOCAL + 0x08) #define FW_CFG_PPC_BUSFREQ (FW_CFG_ARCH_LOCAL + 0x09) +#define FW_CFG_PPC_NVRAM_FLAT (FW_CFG_ARCH_LOCAL + 0x0a) #define PPC_SERIAL_MM_BAUDBASE 399193 From 72ee08cf4f2d4443d198b4e9f7a6fa2beb06dd6b Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 7 Jun 2018 18:17:48 +0100 Subject: [PATCH 18/33] mos6522: fix vmstate_mos6522_timer version in vmstate_mos6522 This was accidentally introduced when extracting the 6522 VIA functionality from the CUDA device, and prevents loadvm from completing successfully. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/mos6522.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c index 49166cb8ad..bcb306d357 100644 --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -405,7 +405,7 @@ static const VMStateDescription vmstate_mos6522 = { VMSTATE_UINT8(ifr, MOS6522State), VMSTATE_UINT8(ier, MOS6522State), VMSTATE_UINT8(anh, MOS6522State), - VMSTATE_STRUCT_ARRAY(timers, MOS6522State, 2, 1, + VMSTATE_STRUCT_ARRAY(timers, MOS6522State, 2, 0, vmstate_mos6522_timer, MOS6522Timer), VMSTATE_END_OF_LIST() } From 2e3e5c7e92452900e2bb5143c5fb6d47c0897a34 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 7 Jun 2018 18:17:49 +0100 Subject: [PATCH 19/33] cuda: embed mos6522_cuda device directly rather than using QOM object link Examining the migration stream it can be seen that the mos6522 device state is being stored separately rather than as part of the CUDA device which is incorrect (and likely to cause issues if another mos6522 device is added to the machine). Resolve this by embedding the mos6522_cuda device directly within the CUDA device rather than using a QOM object link to reference the device separately. Note that we also bump the version in vmstate_cuda to reflect this change: this isn't particularly important for the moment as the Mac machine migration isn't 100% reliable due to issues migrating the timebase under TCG. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 44 +++++++++++++++--------------------- hw/misc/mos6522.c | 2 +- include/hw/misc/macio/cuda.h | 27 ++++++++++------------ include/hw/misc/mos6522.h | 2 ++ 4 files changed, 33 insertions(+), 42 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index bd9b862034..8aba2e63ec 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -65,7 +65,7 @@ static void cuda_receive_packet_from_host(CUDAState *s, static uint64_t cuda_get_counter_value(MOS6522State *s, MOS6522Timer *ti) { MOS6522CUDAState *mcs = container_of(s, MOS6522CUDAState, parent_obj); - CUDAState *cs = mcs->cuda; + CUDAState *cs = container_of(mcs, CUDAState, mos6522_cuda); /* Reverse of the tb calculation algorithm that Mac OS X uses on bootup */ uint64_t tb_diff = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), @@ -78,7 +78,7 @@ static uint64_t cuda_get_counter_value(MOS6522State *s, MOS6522Timer *ti) static uint64_t cuda_get_load_time(MOS6522State *s, MOS6522Timer *ti) { MOS6522CUDAState *mcs = container_of(s, MOS6522CUDAState, parent_obj); - CUDAState *cs = mcs->cuda; + CUDAState *cs = container_of(mcs, CUDAState, mos6522_cuda); uint64_t load_time = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), cs->tb_frequency, NANOSECONDS_PER_SECOND); @@ -88,7 +88,7 @@ static uint64_t cuda_get_load_time(MOS6522State *s, MOS6522Timer *ti) static void cuda_set_sr_int(void *opaque) { CUDAState *s = opaque; - MOS6522CUDAState *mcs = s->mos6522_cuda; + MOS6522CUDAState *mcs = &s->mos6522_cuda; MOS6522State *ms = MOS6522(mcs); MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms); @@ -97,7 +97,7 @@ static void cuda_set_sr_int(void *opaque) static void cuda_delay_set_sr_int(CUDAState *s) { - MOS6522CUDAState *mcs = s->mos6522_cuda; + MOS6522CUDAState *mcs = &s->mos6522_cuda; MOS6522State *ms = MOS6522(mcs); MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms); int64_t expire; @@ -117,7 +117,7 @@ static void cuda_delay_set_sr_int(CUDAState *s) /* NOTE: TIP and TREQ are negated */ static void cuda_update(CUDAState *s) { - MOS6522CUDAState *mcs = s->mos6522_cuda; + MOS6522CUDAState *mcs = &s->mos6522_cuda; MOS6522State *ms = MOS6522(mcs); int packet_received, len; @@ -462,7 +462,7 @@ static void cuda_receive_packet_from_host(CUDAState *s, static uint64_t mos6522_cuda_read(void *opaque, hwaddr addr, unsigned size) { CUDAState *s = opaque; - MOS6522CUDAState *mcs = s->mos6522_cuda; + MOS6522CUDAState *mcs = &s->mos6522_cuda; MOS6522State *ms = MOS6522(mcs); addr = (addr >> 9) & 0xf; @@ -473,7 +473,7 @@ static void mos6522_cuda_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { CUDAState *s = opaque; - MOS6522CUDAState *mcs = s->mos6522_cuda; + MOS6522CUDAState *mcs = &s->mos6522_cuda; MOS6522State *ms = MOS6522(mcs); addr = (addr >> 9) & 0xf; @@ -492,9 +492,11 @@ static const MemoryRegionOps mos6522_cuda_ops = { static const VMStateDescription vmstate_cuda = { .name = "cuda", - .version_id = 4, - .minimum_version_id = 4, + .version_id = 5, + .minimum_version_id = 5, .fields = (VMStateField[]) { + VMSTATE_STRUCT(mos6522_cuda.parent_obj, CUDAState, 0, vmstate_mos6522, + MOS6522State), VMSTATE_UINT8(last_b, CUDAState), VMSTATE_UINT8(last_acr, CUDAState), VMSTATE_INT32(data_in_size, CUDAState), @@ -530,12 +532,8 @@ static void cuda_realize(DeviceState *dev, Error **errp) DeviceState *d; struct tm tm; - d = qdev_create(NULL, TYPE_MOS6522_CUDA); - object_property_set_link(OBJECT(d), OBJECT(s), "cuda", errp); - qdev_init_nofail(d); - s->mos6522_cuda = MOS6522_CUDA(d); - /* Pass IRQ from 6522 */ + d = DEVICE(&s->mos6522_cuda); ms = MOS6522(d); sbd = SYS_BUS_DEVICE(s); sysbus_pass_irq(sbd, SYS_BUS_DEVICE(ms)); @@ -556,6 +554,10 @@ static void cuda_init(Object *obj) CUDAState *s = CUDA(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + object_initialize(&s->mos6522_cuda, sizeof(s->mos6522_cuda), + TYPE_MOS6522_CUDA); + qdev_set_parent_bus(DEVICE(&s->mos6522_cuda), sysbus_get_default()); + memory_region_init_io(&s->mem, obj, &mos6522_cuda_ops, s, "cuda", 0x2000); sysbus_init_mmio(sbd, &s->mem); @@ -590,8 +592,9 @@ static const TypeInfo cuda_type_info = { static void mos6522_cuda_portB_write(MOS6522State *s) { MOS6522CUDAState *mcs = container_of(s, MOS6522CUDAState, parent_obj); + CUDAState *cs = container_of(mcs, CUDAState, mos6522_cuda); - cuda_update(mcs->cuda); + cuda_update(cs); } static void mos6522_cuda_realize(DeviceState *dev, Error **errp) @@ -605,16 +608,6 @@ static void mos6522_cuda_realize(DeviceState *dev, Error **errp) ms->timers[1].frequency = (SCALE_US * 6000) / 4700; } -static void mos6522_cuda_init(Object *obj) -{ - MOS6522CUDAState *s = MOS6522_CUDA(obj); - - object_property_add_link(obj, "cuda", TYPE_CUDA, - (Object **) &s->cuda, - qdev_prop_allow_set_link_before_realize, - 0, NULL); -} - static void mos6522_cuda_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -632,7 +625,6 @@ static const TypeInfo mos6522_cuda_type_info = { .name = TYPE_MOS6522_CUDA, .parent = TYPE_MOS6522, .instance_size = sizeof(MOS6522CUDAState), - .instance_init = mos6522_cuda_init, .class_init = mos6522_cuda_class_init, }; diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c index bcb306d357..524a250329 100644 --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -390,7 +390,7 @@ static const VMStateDescription vmstate_mos6522_timer = { } }; -static const VMStateDescription vmstate_mos6522 = { +const VMStateDescription vmstate_mos6522 = { .name = "mos6522", .version_id = 0, .minimum_version_id = 0, diff --git a/include/hw/misc/macio/cuda.h b/include/hw/misc/macio/cuda.h index 494b709579..7dad469142 100644 --- a/include/hw/misc/macio/cuda.h +++ b/include/hw/misc/macio/cuda.h @@ -54,12 +54,21 @@ #define CUDA_TIMER_TICKLE 0x24 #define CUDA_COMBINED_FORMAT_IIC 0x25 + +/* MOS6522 CUDA */ +typedef struct MOS6522CUDAState { + /*< private >*/ + MOS6522State parent_obj; +} MOS6522CUDAState; + +#define TYPE_MOS6522_CUDA "mos6522-cuda" +#define MOS6522_CUDA(obj) OBJECT_CHECK(MOS6522CUDAState, (obj), \ + TYPE_MOS6522_CUDA) + /* Cuda */ #define TYPE_CUDA "cuda" #define CUDA(obj) OBJECT_CHECK(CUDAState, (obj), TYPE_CUDA) -typedef struct MOS6522CUDAState MOS6522CUDAState; - typedef struct CUDAState { /*< private >*/ SysBusDevice parent_obj; @@ -67,7 +76,7 @@ typedef struct CUDAState { MemoryRegion mem; ADBBusState adb_bus; - MOS6522CUDAState *mos6522_cuda; + MOS6522CUDAState mos6522_cuda; uint32_t tick_offset; uint64_t tb_frequency; @@ -92,16 +101,4 @@ typedef struct CUDAState { QEMUTimer *adb_poll_timer; } CUDAState; -/* MOS6522 CUDA */ -struct MOS6522CUDAState { - /*< private >*/ - MOS6522State parent_obj; - - CUDAState *cuda; -}; - -#define TYPE_MOS6522_CUDA "mos6522-cuda" -#define MOS6522_CUDA(obj) OBJECT_CHECK(MOS6522CUDAState, (obj), \ - TYPE_MOS6522_CUDA) - #endif /* CUDA_H */ diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h index a53c161b00..cb0fd7db78 100644 --- a/include/hw/misc/mos6522.h +++ b/include/hw/misc/mos6522.h @@ -146,6 +146,8 @@ typedef struct MOS6522DeviceClass { #define MOS6522_DEVICE_GET_CLASS(obj) \ OBJECT_GET_CLASS(MOS6522DeviceClass, (obj), TYPE_MOS6522) +extern const VMStateDescription vmstate_mos6522; + uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned size); void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); From d638fd5c9681dbb8915147365520888c64f39dac Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 7 Jun 2018 18:17:50 +0100 Subject: [PATCH 20/33] mos6522: move timer frequency initialisation to mos6522_reset The 6522 VIA timer frequency cannot be set by altering registers within the device itself and hence it is a fixed property of the machine. Move the initialisation of the timer frequency to the mos6522 reset function and ensure that any subclasses always call the parent reset function so that it isn't required to store the timer frequency within vmstate_mos6522_timer itself. By moving the frequency initialisation to the device reset function then we find that the realize function for both mos6522 and mos6522_cuda becomes obsolete and can simply be removed. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 6 +++--- hw/misc/mos6522.c | 13 +++---------- include/hw/misc/mos6522.h | 2 +- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 8aba2e63ec..9651ed9744 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -597,12 +597,12 @@ static void mos6522_cuda_portB_write(MOS6522State *s) cuda_update(cs); } -static void mos6522_cuda_realize(DeviceState *dev, Error **errp) +static void mos6522_cuda_reset(DeviceState *dev) { MOS6522State *ms = MOS6522(dev); MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms); - mdc->parent_realize(dev, errp); + mdc->parent_reset(dev); ms->timers[0].frequency = CUDA_TIMER_FREQ; ms->timers[1].frequency = (SCALE_US * 6000) / 4700; @@ -613,7 +613,7 @@ static void mos6522_cuda_class_init(ObjectClass *oc, void *data) DeviceClass *dc = DEVICE_CLASS(oc); MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc); - dc->realize = mos6522_cuda_realize; + dc->reset = mos6522_cuda_reset; mdc->portB_write = mos6522_cuda_portB_write; mdc->get_timer1_counter_value = cuda_get_counter_value; mdc->get_timer2_counter_value = cuda_get_counter_value; diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c index 524a250329..2f58b9707f 100644 --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -427,18 +427,12 @@ static void mos6522_reset(DeviceState *dev) /* s->ier = T1_INT | SR_INT; */ s->anh = 0; + s->timers[0].frequency = s->frequency; s->timers[0].latch = 0xffff; set_counter(s, &s->timers[0], 0xffff); - s->timers[1].latch = 0xffff; -} - -static void mos6522_realize(DeviceState *dev, Error **errp) -{ - MOS6522State *s = MOS6522(dev); - - s->timers[0].frequency = s->frequency; s->timers[1].frequency = s->frequency; + s->timers[1].latch = 0xffff; } static void mos6522_init(Object *obj) @@ -469,11 +463,10 @@ static void mos6522_class_init(ObjectClass *oc, void *data) DeviceClass *dc = DEVICE_CLASS(oc); MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc); - dc->realize = mos6522_realize; dc->reset = mos6522_reset; dc->vmsd = &vmstate_mos6522; dc->props = mos6522_properties; - mdc->parent_realize = dc->realize; + mdc->parent_reset = dc->reset; mdc->set_sr_int = mos6522_set_sr_int; mdc->portB_write = mos6522_portB_write; mdc->portA_write = mos6522_portA_write; diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h index cb0fd7db78..f52b41920b 100644 --- a/include/hw/misc/mos6522.h +++ b/include/hw/misc/mos6522.h @@ -130,7 +130,7 @@ typedef struct MOS6522State { typedef struct MOS6522DeviceClass { DeviceClass parent_class; - DeviceRealize parent_realize; + DeviceReset parent_reset; void (*set_sr_int)(MOS6522State *dev); void (*portB_write)(MOS6522State *dev); void (*portA_write)(MOS6522State *dev); From 3431bdf5a3c3bd732f78b0433471c2b1cb373564 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 7 Jun 2018 18:17:51 +0100 Subject: [PATCH 21/33] mos6522: convert VMSTATE_TIMER_PTR_TEST to VMSTATE_TIMER_PTR The timers are configured in the mos6522 init function and therefore will always exist, so the function can never return false. Peter also pointed out that this is the only remaining user of VMSTATE_TIMER_PTR_TEST in the codebase, so we might as well just convert it over to VMSTATE_TIMER_PTR and remove mos6522_timer_exist() as it is no longer required. Signed-off-by: Mark Cave-Ayland Reviewed-by: Peter Maydell Signed-off-by: David Gibson --- hw/misc/mos6522.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c index 2f58b9707f..44eb306cf1 100644 --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -369,13 +369,6 @@ static const MemoryRegionOps mos6522_ops = { }, }; -static bool mos6522_timer_exist(void *opaque, int version_id) -{ - MOS6522Timer *s = opaque; - - return s->timer != NULL; -} - static const VMStateDescription vmstate_mos6522_timer = { .name = "mos6522_timer", .version_id = 0, @@ -385,7 +378,7 @@ static const VMStateDescription vmstate_mos6522_timer = { VMSTATE_UINT16(counter_value, MOS6522Timer), VMSTATE_INT64(load_time, MOS6522Timer), VMSTATE_INT64(next_irq_time, MOS6522Timer), - VMSTATE_TIMER_PTR_TEST(timer, MOS6522Timer, mos6522_timer_exist), + VMSTATE_TIMER_PTR(timer, MOS6522Timer), VMSTATE_END_OF_LIST() } }; From c8fd8373e42821984400382cd91b8bf4e7c14e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Wed, 6 Jun 2018 09:33:53 +0200 Subject: [PATCH 22/33] target/ppc: extend eieio for POWER9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POWER9 introduced a new variant of the eieio instruction using bit 6 as a hint to tell the CPU it is a store-forwarding barrier. The usage of this eieio extension was recently added in Linux 4.17 which activated the "support for a store forwarding barrier at kernel entry/exit". Unfortunately, it is not possible to insert this new eieio instruction without considerable change in ppc_tr_translate_insn(). So instead we loosen the QEMU eieio instruction mask and modify the gen_eieio() helper to test for bit6. On non-POWER9 CPUs, the bit6 is just ignored but a warning is emitted as this is not an instruction software should be using. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- target/ppc/translate.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 8ba8f67dc5..5fe1ba6555 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -2967,7 +2967,28 @@ static void gen_stswx(DisasContext *ctx) /* eieio */ static void gen_eieio(DisasContext *ctx) { - tcg_gen_mb(TCG_MO_LD_ST | TCG_BAR_SC); + TCGBar bar = TCG_MO_LD_ST; + + /* + * POWER9 has a eieio instruction variant using bit 6 as a hint to + * tell the CPU it is a store-forwarding barrier. + */ + if (ctx->opcode & 0x2000000) { + /* + * ISA says that "Reserved fields in instructions are ignored + * by the processor". So ignore the bit 6 on non-POWER9 CPU but + * as this is not an instruction software should be using, + * complain to the user. + */ + if (!(ctx->insns_flags2 & PPC2_ISA300)) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid eieio using bit 6 at @" + TARGET_FMT_lx "\n", ctx->base.pc_next - 4); + } else { + bar = TCG_MO_ST_LD; + } + } + + tcg_gen_mb(bar | TCG_BAR_SC); } #if !defined(CONFIG_USER_ONLY) @@ -6483,7 +6504,7 @@ GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING), GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING), GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING), GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING), -GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO), +GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x01FFF801, PPC_MEM_EIEIO), GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM), GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206), GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206), From 42a907e83921ff2c4f5e6ca9fa6aa6791b43a73f Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 6 Jun 2018 15:31:48 +0200 Subject: [PATCH 23/33] ppc4xx_i2c: Clean up and improve error logging Make it more readable by converting register indexes to decimal (avoids lot of superfluous 0x0) and distinguish errors caused by accessing non-existent vs. unimplemented registers. No functional change. Signed-off-by: BALATON Zoltan Signed-off-by: David Gibson --- hw/i2c/ppc4xx_i2c.c | 94 ++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c index ab64d196be..d1936dbdca 100644 --- a/hw/i2c/ppc4xx_i2c.c +++ b/hw/i2c/ppc4xx_i2c.c @@ -31,7 +31,7 @@ #include "hw/hw.h" #include "hw/i2c/ppc4xx_i2c.h" -#define PPC4xx_I2C_MEM_SIZE 0x12 +#define PPC4xx_I2C_MEM_SIZE 18 #define IIC_CNTL_PT (1 << 0) #define IIC_CNTL_READ (1 << 1) @@ -70,7 +70,7 @@ static void ppc4xx_i2c_reset(DeviceState *s) i2c->intrmsk = 0; i2c->xfrcnt = 0; i2c->xtcntlss = 0; - i2c->directcntl = 0x0f; + i2c->directcntl = 0xf; i2c->intr = 0; } @@ -85,7 +85,7 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size) uint64_t ret; switch (addr) { - case 0x00: + case 0: ret = i2c->mdata; if (ppc4xx_i2c_is_master(i2c)) { ret = 0xff; @@ -139,58 +139,62 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size) TYPE_PPC4xx_I2C, __func__); } break; - case 0x02: + case 2: ret = i2c->sdata; break; - case 0x04: + case 4: ret = i2c->lmadr; break; - case 0x05: + case 5: ret = i2c->hmadr; break; - case 0x06: + case 6: ret = i2c->cntl; break; - case 0x07: + case 7: ret = i2c->mdcntl; break; - case 0x08: + case 8: ret = i2c->sts; break; - case 0x09: + case 9: ret = i2c->extsts; break; - case 0x0A: + case 10: ret = i2c->lsadr; break; - case 0x0B: + case 11: ret = i2c->hsadr; break; - case 0x0C: + case 12: ret = i2c->clkdiv; break; - case 0x0D: + case 13: ret = i2c->intrmsk; break; - case 0x0E: + case 14: ret = i2c->xfrcnt; break; - case 0x0F: + case 15: ret = i2c->xtcntlss; break; - case 0x10: + case 16: ret = i2c->directcntl; break; - case 0x11: + case 17: ret = i2c->intr; break; default: - qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%" - HWADDR_PRIx "\n", TYPE_PPC4xx_I2C, __func__, addr); + if (addr < PPC4xx_I2C_MEM_SIZE) { + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register 0x%" + HWADDR_PRIx "\n", __func__, addr); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address 0x%" + HWADDR_PRIx "\n", __func__, addr); + } ret = 0; break; } - return ret; } @@ -200,7 +204,7 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, PPC4xxI2CState *i2c = opaque; switch (addr) { - case 0x00: + case 0: i2c->mdata = value; if (!i2c_bus_busy(i2c->bus)) { /* assume we start a write transfer */ @@ -225,19 +229,19 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, } } break; - case 0x02: + case 2: i2c->sdata = value; break; - case 0x04: + case 4: i2c->lmadr = value; if (i2c_bus_busy(i2c->bus)) { i2c_end_transfer(i2c->bus); } break; - case 0x05: + case 5: i2c->hmadr = value; break; - case 0x06: + case 6: i2c->cntl = value; if (i2c->cntl & IIC_CNTL_PT) { if (i2c->cntl & IIC_CNTL_READ) { @@ -263,32 +267,31 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, } } break; - case 0x07: - i2c->mdcntl = value & 0xDF; + case 7: + i2c->mdcntl = value & 0xdf; break; - case 0x08: - i2c->sts &= ~(value & 0x0A); + case 8: + i2c->sts &= ~(value & 0xa); break; - case 0x09: - i2c->extsts &= ~(value & 0x8F); + case 9: + i2c->extsts &= ~(value & 0x8f); break; - case 0x0A: + case 10: i2c->lsadr = value; - /*i2c_set_slave_address(i2c->bus, i2c->lsadr);*/ break; - case 0x0B: + case 11: i2c->hsadr = value; break; - case 0x0C: + case 12: i2c->clkdiv = value; break; - case 0x0D: + case 13: i2c->intrmsk = value; break; - case 0x0E: + case 14: i2c->xfrcnt = value & 0x77; break; - case 0x0F: + case 15: if (value & IIC_XTCNTLSS_SRST) { /* Is it actually a full reset? U-Boot sets some regs before */ ppc4xx_i2c_reset(DEVICE(i2c)); @@ -296,15 +299,20 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, } i2c->xtcntlss = value; break; - case 0x10: + case 16: i2c->directcntl = value & 0x7; break; - case 0x11: + case 17: i2c->intr = value; break; default: - qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%" - HWADDR_PRIx "\n", TYPE_PPC4xx_I2C, __func__, addr); + if (addr < PPC4xx_I2C_MEM_SIZE) { + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register 0x%" + HWADDR_PRIx "\n", __func__, addr); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address 0x%" + HWADDR_PRIx "\n", __func__, addr); + } break; } } From bfda32a87bc77b9fac83f6c2789d65585115970d Mon Sep 17 00:00:00 2001 From: luporl Date: Fri, 8 Jun 2018 11:46:55 +0200 Subject: [PATCH 24/33] target/ppc: Allow PIR read in privileged mode According to PowerISA, the PIR register should be readable in privileged mode also, not only in hypervisor privileged mode. PowerISA 3.0 - 4.3.3 Processor Identification Register "Read access to the PIR is privileged; write access is not provided." Figure 18 in section 4.4.4 explicitly confirms that mfspr PIR is privileged and doesn't require hypervisor state. Cc: David Gibson Cc: Alexander Graf Cc: qemu-ppc@nongnu.org Signed-off-by: Leandro Lupori Reviewed-by: Jose Ricardo Ziviani Reviewed-by: Greg Kurz Signed-off-by: Greg Kurz Signed-off-by: David Gibson --- target/ppc/translate_init.inc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 1a89017dde..bb9296f5a3 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -7819,7 +7819,7 @@ static void gen_spr_book3s_ids(CPUPPCState *env) /* Processor identification */ spr_register_hv(env, SPR_PIR, "PIR", SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, &spr_read_generic, NULL, 0x00000000); spr_register_hv(env, SPR_HID0, "HID0", From fcc8ef17e264ef6f4afb6fa4af71b88993f49363 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 8 Jun 2018 14:48:11 +0200 Subject: [PATCH 25/33] spapr: no need to verify the node The node property can always be queried and the value has already been verified in pc_dimm_realize(). Acked-by: David Gibson Reviewed-by: Greg Kurz Signed-off-by: David Hildenbrand Signed-off-by: David Gibson --- hw/ppc/spapr.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 2375cbee12..f16a0b2870 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3578,14 +3578,8 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, error_setg(errp, "Memory hotplug not supported for this machine"); return; } - node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP, errp); - if (*errp) { - return; - } - if (node < 0 || node >= MAX_NODES) { - error_setg(errp, "Invaild node %d", node); - return; - } + node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP, + &error_abort); spapr_memory_plug(hotplug_dev, dev, node, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) { From 81985f3be9679b8770f46f78d475ff53a2e8cdbb Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 8 Jun 2018 14:48:12 +0200 Subject: [PATCH 26/33] spapr: move lookup of the node into spapr_memory_plug() Let's clean the hotplug handler up by moving lookup of the node into the function where it is actually being used. Signed-off-by: David Hildenbrand Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f16a0b2870..1f577b274b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3136,7 +3136,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, } static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, - uint32_t node, Error **errp) + Error **errp) { Error *local_err = NULL; sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev); @@ -3144,6 +3144,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr; uint64_t align, size, addr; + uint32_t node; mr = ddc->get_memory_region(dimm, &local_err); if (local_err) { @@ -3163,6 +3164,8 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, goto out_unplug; } + node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP, + &error_abort); spapr_add_lmbs(dev, addr, size, node, spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT), &local_err); @@ -3572,16 +3575,11 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms); if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - int node; - if (!smc->dr_lmb_enabled) { error_setg(errp, "Memory hotplug not supported for this machine"); return; } - node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP, - &error_abort); - - spapr_memory_plug(hotplug_dev, dev, node, errp); + spapr_memory_plug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) { spapr_core_plug(hotplug_dev, dev, errp); } From 4e8a01bdb20557ee4f5bf6f86890d2b95fa2a7fb Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 8 Jun 2018 14:48:13 +0200 Subject: [PATCH 27/33] spapr: move memory hotplug support check into spapr_memory_pre_plug() Let's finish cleaning up the hotplug handler. This check can be performed in the pre_plug code as the very first thing. Signed-off-by: David Hildenbrand Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 1f577b274b..9b8b4068b1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3184,12 +3184,18 @@ out: static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { + const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr; uint64_t size; char *mem_dev; + if (!smc->dr_lmb_enabled) { + error_setg(errp, "Memory hotplug not supported for this machine"); + return; + } + mr = ddc->get_memory_region(dimm, errp); if (!mr) { return; @@ -3571,14 +3577,7 @@ out: static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - MachineState *ms = MACHINE(hotplug_dev); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms); - if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - if (!smc->dr_lmb_enabled) { - error_setg(errp, "Memory hotplug not supported for this machine"); - return; - } spapr_memory_plug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) { spapr_core_plug(hotplug_dev, dev, errp); From 88432f44aae752028103408f2f6df8c681143907 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 8 Jun 2018 14:48:14 +0200 Subject: [PATCH 28/33] spapr: introduce machine unplug handler We'll be handling unplug of e.g. CPUs and PCDIMMs via the general hotplug handler soon, so let's add that handler function. Acked-by: David Gibson Reviewed-by: Greg Kurz Signed-off-by: David Hildenbrand Signed-off-by: David Gibson --- hw/ppc/spapr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9b8b4068b1..c45f8bc75b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3584,6 +3584,11 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, } } +static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ +} + static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -3978,6 +3983,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->get_default_cpu_node_id = spapr_get_default_cpu_node_id; mc->possible_cpu_arch_ids = spapr_possible_cpu_arch_ids; hc->unplug_request = spapr_machine_device_unplug_request; + hc->unplug = spapr_machine_device_unplug; smc->dr_lmb_enabled = true; mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0"); From 3ec71474cad1066865b3c2059add208794a418da Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 8 Jun 2018 14:48:15 +0200 Subject: [PATCH 29/33] spapr: handle pc-dimm unplug via hotplug handler chain Factor out memory unplug into separate function from spapr_lmb_release(). Then use generic hotplug_handler_unplug() to trigger memory unplug, which will call spapr_machine_device_unplug() -> spapr_memory_unplug() in the end. This way unplug operation is not buried in lmb internals and located in the same place like in other targets, following similar logic/call chain across targets. Acked-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Igor Mammedov Signed-off-by: David Hildenbrand Signed-off-by: David Gibson --- hw/ppc/spapr.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c45f8bc75b..404d887f4e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3299,7 +3299,8 @@ static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms, /* Callback to be called during DRC release. */ void spapr_lmb_release(DeviceState *dev) { - sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_hotplug_handler(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)); /* This information will get lost if a migration occurs @@ -3317,9 +3318,17 @@ void spapr_lmb_release(DeviceState *dev) /* * Now that all the LMBs have been removed by the guest, call the - * pc-dimm unplug handler to cleanup up the pc-dimm device. + * unplug handler chain. This can never fail. */ - pc_dimm_memory_unplug(dev, MACHINE(spapr)); + hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort); +} + +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)); + + pc_dimm_memory_unplug(dev, MACHINE(hotplug_dev)); object_unparent(OBJECT(dev)); spapr_pending_dimm_unplugs_remove(spapr, ds); } @@ -3587,6 +3596,9 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + spapr_memory_unplug(hotplug_dev, dev); + } } static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev, From a4261be17213eea96673fac71bc89f5342422b76 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 8 Jun 2018 14:48:16 +0200 Subject: [PATCH 30/33] spapr: handle cpu core unplug via hotplug handler chain Factor out cpu core unplug into separate function from spapr_core_release(). Then use generic hotplug_handler_unplug() to trigger cpu core unplug, which would call spapr_machine_device_unplug() -> spapr_core_unplug() in the end. This way unplug operation is not buried in spapr internals and located in the same place like in other targets, following similar logic/call chain across targets. Acked-by: Igor Mammedov Acked-by: David Gibson Reviewed-by: Greg Kurz Signed-off-by: David Hildenbrand Signed-off-by: David Gibson --- hw/ppc/spapr.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 404d887f4e..f59999daac 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3416,7 +3416,15 @@ static void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset, /* Callback to be called during DRC release. */ void spapr_core_release(DeviceState *dev) { - MachineState *ms = MACHINE(qdev_get_hotplug_handler(dev)); + HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev); + + /* Call the unplug handler chain. This can never fail. */ + hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort); +} + +static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev) +{ + MachineState *ms = MACHINE(hotplug_dev); sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms); CPUCore *cc = CPU_CORE(dev); CPUArchId *core_slot = spapr_find_cpu_slot(ms, cc->core_id, NULL); @@ -3598,6 +3606,8 @@ static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, { if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { spapr_memory_unplug(hotplug_dev, dev); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) { + spapr_core_unplug(hotplug_dev, dev); } } From d61c2857037e6211667a52563742af798d4c0332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 11 Jun 2018 19:12:10 +0200 Subject: [PATCH 31/33] ppc/pnv: fix LPC HC firmware address space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A specific MemoryRegion is required for the LPC HC Firmware address space. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/pnv_lpc.c | 4 +++- include/hw/ppc/pnv_lpc.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index 2317d1e62c..402c4fefa8 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -79,6 +79,7 @@ enum { #define ISA_IO_SIZE 0x00010000 #define ISA_MEM_SIZE 0x10000000 +#define ISA_FW_SIZE 0x10000000 #define LPC_IO_OPB_ADDR 0xd0010000 #define LPC_IO_OPB_SIZE 0x00010000 #define LPC_MEM_OPB_ADDR 0xe0010000 @@ -429,6 +430,7 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp) */ memory_region_init(&lpc->isa_io, OBJECT(dev), "isa-io", ISA_IO_SIZE); memory_region_init(&lpc->isa_mem, OBJECT(dev), "isa-mem", ISA_MEM_SIZE); + memory_region_init(&lpc->isa_fw, OBJECT(dev), "isa-fw", ISA_FW_SIZE); /* Create windows from the OPB space to the ISA space */ memory_region_init_alias(&lpc->opb_isa_io, OBJECT(dev), "lpc-isa-io", @@ -440,7 +442,7 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&lpc->opb_mr, LPC_MEM_OPB_ADDR, &lpc->opb_isa_mem); memory_region_init_alias(&lpc->opb_isa_fw, OBJECT(dev), "lpc-isa-fw", - &lpc->isa_mem, 0, LPC_FW_OPB_SIZE); + &lpc->isa_fw, 0, LPC_FW_OPB_SIZE); memory_region_add_subregion(&lpc->opb_mr, LPC_FW_OPB_ADDR, &lpc->opb_isa_fw); diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h index 023b4f0fec..53fdd5bb64 100644 --- a/include/hw/ppc/pnv_lpc.h +++ b/include/hw/ppc/pnv_lpc.h @@ -38,6 +38,7 @@ typedef struct PnvLpcController { /* ISA IO and Memory space */ MemoryRegion isa_io; MemoryRegion isa_mem; + MemoryRegion isa_fw; /* Windows from OPB to ISA (aliases) */ MemoryRegion opb_isa_io; From bf358b541b803d8f415807a632c0d0cde1504bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 11 Jun 2018 18:23:10 +0200 Subject: [PATCH 32/33] xics_kvm: use KVM helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The KVM helpers hide the low level interface used to communicate to the XICS KVM device and provide a good cleanup to the XICS KVM models. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics_kvm.c | 52 +++++++++++++--------------------------------- 1 file changed, 14 insertions(+), 38 deletions(-) diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 89fb20e2c5..8bdf6afe82 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -56,10 +56,6 @@ static QLIST_HEAD(, KVMEnabledICP) static void icp_get_kvm_state(ICPState *icp) { uint64_t state; - struct kvm_one_reg reg = { - .id = KVM_REG_PPC_ICP_STATE, - .addr = (uintptr_t)&state, - }; int ret; /* ICP for this CPU thread is not in use, exiting */ @@ -67,7 +63,7 @@ static void icp_get_kvm_state(ICPState *icp) return; } - ret = kvm_vcpu_ioctl(icp->cs, KVM_GET_ONE_REG, ®); + ret = kvm_get_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state); if (ret != 0) { error_report("Unable to retrieve KVM interrupt controller state" " for CPU %ld: %s", kvm_arch_vcpu_id(icp->cs), strerror(errno)); @@ -96,10 +92,6 @@ static void icp_synchronize_state(ICPState *icp) static int icp_set_kvm_state(ICPState *icp, int version_id) { uint64_t state; - struct kvm_one_reg reg = { - .id = KVM_REG_PPC_ICP_STATE, - .addr = (uintptr_t)&state, - }; int ret; /* ICP for this CPU thread is not in use, exiting */ @@ -111,7 +103,7 @@ static int icp_set_kvm_state(ICPState *icp, int version_id) | ((uint64_t)icp->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT) | ((uint64_t)icp->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT); - ret = kvm_vcpu_ioctl(icp->cs, KVM_SET_ONE_REG, ®); + ret = kvm_set_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state); if (ret != 0) { error_report("Unable to restore KVM interrupt controller state (0x%" PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(icp->cs), @@ -185,21 +177,15 @@ static const TypeInfo icp_kvm_info = { static void ics_get_kvm_state(ICSState *ics) { uint64_t state; - struct kvm_device_attr attr = { - .flags = 0, - .group = KVM_DEV_XICS_GRP_SOURCES, - .addr = (uint64_t)(uintptr_t)&state, - }; int i; + Error *local_err = NULL; for (i = 0; i < ics->nr_irqs; i++) { ICSIRQState *irq = &ics->irqs[i]; - int ret; - attr.attr = i + ics->offset; - - ret = ioctl(kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr); - if (ret != 0) { + kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES, + i + ics->offset, &state, false, &local_err); + if (local_err) { error_report("Unable to retrieve KVM interrupt controller state" " for IRQ %d: %s", i + ics->offset, strerror(errno)); exit(1); @@ -255,19 +241,13 @@ static void ics_synchronize_state(ICSState *ics) static int ics_set_kvm_state(ICSState *ics, int version_id) { uint64_t state; - struct kvm_device_attr attr = { - .flags = 0, - .group = KVM_DEV_XICS_GRP_SOURCES, - .addr = (uint64_t)(uintptr_t)&state, - }; int i; + Error *local_err = NULL; for (i = 0; i < ics->nr_irqs; i++) { ICSIRQState *irq = &ics->irqs[i]; int ret; - attr.attr = i + ics->offset; - state = irq->server; state |= (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK) << KVM_XICS_PRIORITY_SHIFT; @@ -293,8 +273,9 @@ static int ics_set_kvm_state(ICSState *ics, int version_id) state |= KVM_XICS_QUEUED; } - ret = ioctl(kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr); - if (ret != 0) { + kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES, + i + ics->offset, &state, true, &local_err); + if (local_err) { error_report("Unable to restore KVM interrupt controller state" " for IRQs %d: %s", i + ics->offset, strerror(errno)); return ret; @@ -391,10 +372,6 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr, int xics_kvm_init(sPAPRMachineState *spapr, Error **errp) { int rc; - struct kvm_create_device xics_create_device = { - .type = KVM_DEV_TYPE_XICS, - .flags = 0, - }; if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) { error_setg(errp, @@ -431,20 +408,19 @@ int xics_kvm_init(sPAPRMachineState *spapr, Error **errp) goto fail; } - /* Create the kernel ICP */ - rc = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &xics_create_device); + /* Create the KVM XICS device */ + rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false); if (rc < 0) { error_setg_errno(errp, -rc, "Error on KVM_CREATE_DEVICE for XICS"); goto fail; } - kernel_xics_fd = xics_create_device.fd; - + kernel_xics_fd = rc; kvm_kernel_irqchip = true; kvm_msi_via_irqfd_allowed = true; kvm_gsi_direct_mapping = true; - return rc; + return 0; fail: kvmppc_define_rtas_kernel_token(0, "ibm,set-xive"); From 30f79dc13f116a79ff45d37ad0f5c035012064a7 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 19 Apr 2018 16:07:40 +1000 Subject: [PATCH 33/33] spapr_pci: Remove unhelpful pagesize warning By default, the IOMMU model built into the spapr virtual PCI host bridge supports 4kiB and 64kiB IOMMU page sizes. However this can be overridden which may be desirable to allow larger IOMMU page sizes when running a guest with hugepage backing and passthrough devices. For that reason a warning was printed when the device wasn't configured to allow the pagesize with which guest RAM is backed. Experience has proven, however, that this message is more confusing than useful. Worse it sometimes makes little sense when the host-available page sizes don't match those available on the guest, which can happen with a POWER8 guest running on a POWER9 KVM host. Long term we do want better handling to allow large IOMMU page sizes to be used, but for now this parameter and warning don't really accomplish it. So, remove the message, pending a better solution. Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 39a14980d3..f936ce63ef 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1717,13 +1717,6 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) } /* DMA setup */ - if (((sphb->page_size_mask & qemu_getrampagesize()) == 0) - && kvm_enabled()) { - warn_report("System page size 0x%lx is not enabled in page_size_mask " - "(0x%"PRIx64"). Performance may be slow", - qemu_getrampagesize(), sphb->page_size_mask); - } - for (i = 0; i < windows_supported; ++i) { tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn[i]); if (!tcet) {