From f92be77fea88b6347f22ca96ba54bef0c382e3b7 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 12 Aug 2019 17:10:44 +1000 Subject: [PATCH 01/42] spapr: quantify error messages regarding capability settings Its not immediately obvious how cap-X=Y setting need to be applied to the command line so, for spapr capability error messages, this has been clarified to: appending -machine cap-X=Y The wrong value messages have been left as is, as the user has found the right location. Reviewed-by: Greg Kurz Signed-off-by: Daniel Black Message-Id: <20190812071044.30806-1-daniel@linux.ibm.com> Signed-off-by: David Gibson --- hw/ppc/spapr_caps.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 7830d66d77..a61bf329bf 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -195,10 +195,12 @@ static void cap_htm_apply(SpaprMachineState *spapr, uint8_t val, Error **errp) } if (tcg_enabled()) { error_setg(errp, - "No Transactional Memory support in TCG, try cap-htm=off"); + "No Transactional Memory support in TCG," + " try appending -machine cap-htm=off"); } else if (kvm_enabled() && !kvmppc_has_cap_htm()) { error_setg(errp, -"KVM implementation does not support Transactional Memory, try cap-htm=off" +"KVM implementation does not support Transactional Memory," + " try appending -machine cap-htm=off" ); } } @@ -216,7 +218,8 @@ static void cap_vsx_apply(SpaprMachineState *spapr, uint8_t val, Error **errp) * rid of anything that doesn't do VMX */ g_assert(env->insns_flags & PPC_ALTIVEC); if (!(env->insns_flags2 & PPC2_VSX)) { - error_setg(errp, "VSX support not available, try cap-vsx=off"); + error_setg(errp, "VSX support not available," + " try appending -machine cap-vsx=off"); } } @@ -230,7 +233,8 @@ static void cap_dfp_apply(SpaprMachineState *spapr, uint8_t val, Error **errp) return; } if (!(env->insns_flags2 & PPC2_DFP)) { - error_setg(errp, "DFP support not available, try cap-dfp=off"); + error_setg(errp, "DFP support not available," + " try appending -machine cap-dfp=off"); } } @@ -254,7 +258,8 @@ static void cap_safe_cache_apply(SpaprMachineState *spapr, uint8_t val, cap_cfpc_possible.vals[val]); } else if (kvm_enabled() && (val > kvm_val)) { error_setg(errp, -"Requested safe cache capability level not supported by kvm, try cap-cfpc=%s", + "Requested safe cache capability level not supported by kvm," + " try appending -machine cap-cfpc=%s", cap_cfpc_possible.vals[kvm_val]); } @@ -282,7 +287,8 @@ static void cap_safe_bounds_check_apply(SpaprMachineState *spapr, uint8_t val, cap_sbbc_possible.vals[val]); } else if (kvm_enabled() && (val > kvm_val)) { error_setg(errp, -"Requested safe bounds check capability level not supported by kvm, try cap-sbbc=%s", +"Requested safe bounds check capability level not supported by kvm," + " try appending -machine cap-sbbc=%s", cap_sbbc_possible.vals[kvm_val]); } @@ -313,7 +319,8 @@ static void cap_safe_indirect_branch_apply(SpaprMachineState *spapr, cap_ibs_possible.vals[val]); } else if (kvm_enabled() && (val > kvm_val)) { error_setg(errp, -"Requested safe indirect branch capability level not supported by kvm, try cap-ibs=%s", +"Requested safe indirect branch capability level not supported by kvm," + " try appending -machine cap-ibs=%s", cap_ibs_possible.vals[kvm_val]); } @@ -402,11 +409,13 @@ static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr, if (tcg_enabled()) { error_setg(errp, - "No Nested KVM-HV support in tcg, try cap-nested-hv=off"); + "No Nested KVM-HV support in tcg," + " try appending -machine cap-nested-hv=off"); } else if (kvm_enabled()) { if (!kvmppc_has_cap_nested_kvm_hv()) { error_setg(errp, -"KVM implementation does not support Nested KVM-HV, try cap-nested-hv=off"); +"KVM implementation does not support Nested KVM-HV," + " try appending -machine cap-nested-hv=off"); } else if (kvmppc_set_cap_nested_kvm_hv(val) < 0) { error_setg(errp, "Error enabling cap-nested-hv with KVM, try cap-nested-hv=off"); @@ -436,10 +445,12 @@ static void cap_large_decr_apply(SpaprMachineState *spapr, if (!kvm_nr_bits) { error_setg(errp, - "No large decrementer support, try cap-large-decr=off"); + "No large decrementer support," + " try appending -machine cap-large-decr=off"); } else if (pcc->lrg_decr_bits != kvm_nr_bits) { error_setg(errp, -"KVM large decrementer size (%d) differs to model (%d), try -cap-large-decr=off", +"KVM large decrementer size (%d) differs to model (%d)," + " try appending -machine cap-large-decr=off", kvm_nr_bits, pcc->lrg_decr_bits); } } @@ -455,7 +466,8 @@ static void cap_large_decr_cpu_apply(SpaprMachineState *spapr, if (kvm_enabled()) { if (kvmppc_enable_cap_large_decr(cpu, val)) { error_setg(errp, - "No large decrementer support, try cap-large-decr=off"); + "No large decrementer support," + " try appending -machine cap-large-decr=off"); } } @@ -475,10 +487,12 @@ static void cap_ccf_assist_apply(SpaprMachineState *spapr, uint8_t val, if (tcg_enabled() && val) { /* TODO - for now only allow broken for TCG */ error_setg(errp, -"Requested count cache flush assist capability level not supported by tcg, try cap-ccf-assist=off"); +"Requested count cache flush assist capability level not supported by tcg," + " try appending -machine cap-ccf-assist=off"); } else if (kvm_enabled() && (val > kvm_val)) { error_setg(errp, -"Requested count cache flush assist capability level not supported by kvm, try cap-ccf-assist=off"); +"Requested count cache flush assist capability level not supported by kvm," + " try appending -machine cap-ccf-assist=off"); } } From a14f04ebbab80fb7342c277705e6076c309a5e50 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Mon, 12 Aug 2019 15:42:02 +1000 Subject: [PATCH 02/42] spapr_iommu: Fix xlate trace to print translated address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we basically print IO address twice, fix this. Fixes: 7e472264e9e2 ("PPC: spapr: iommu: rework traces") Signed-off-by: Alexey Kardashevskiy Message-Id: <20190812054202.125492-1-aik@ozlabs.ru> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/spapr_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index ce85f8ac63..e87b3d50f7 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -136,7 +136,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu, ret.addr_mask = ~page_mask; ret.perm = spapr_tce_iommu_access_flags(tce); } - trace_spapr_iommu_xlate(tcet->liobn, addr, ret.iova, ret.perm, + trace_spapr_iommu_xlate(tcet->liobn, addr, ret.translated_addr, ret.perm, ret.addr_mask); return ret; From 9aec2e52ce9d9632a86be2d1d0dd493722d2e7be Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 24 Jul 2019 12:35:24 +0200 Subject: [PATCH 03/42] hw: add compat machines for 4.2 Add 4.2 machine types for arm/i440fx/q35/s390x/spapr. For i440fx and q35, unversioned cpu models are still translated to -v1, as 0788a56bd1ae ("i386: Make unversioned CPU models be aliases") states this should only transition to the latest cpu model version in 4.3 (or later). Signed-off-by: Cornelia Huck Message-Id: <20190724103524.20916-1-cohuck@redhat.com> Reviewed-by: Eduardo Habkost Signed-off-by: David Gibson --- hw/arm/virt.c | 11 +++++++++-- hw/core/machine.c | 3 +++ hw/i386/pc.c | 3 +++ hw/i386/pc_piix.c | 14 +++++++++++++- hw/i386/pc_q35.c | 13 ++++++++++++- hw/ppc/spapr.c | 17 ++++++++++++++--- hw/s390x/s390-virtio-ccw.c | 14 +++++++++++++- include/hw/boards.h | 3 +++ include/hw/i386/pc.h | 3 +++ 9 files changed, 73 insertions(+), 8 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 02510acb81..0d1629ccb3 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2050,10 +2050,17 @@ static void machvirt_machine_init(void) } type_init(machvirt_machine_init); -static void virt_machine_4_1_options(MachineClass *mc) +static void virt_machine_4_2_options(MachineClass *mc) { } -DEFINE_VIRT_MACHINE_AS_LATEST(4, 1) +DEFINE_VIRT_MACHINE_AS_LATEST(4, 2) + +static void virt_machine_4_1_options(MachineClass *mc) +{ + virt_machine_4_2_options(mc); + compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); +} +DEFINE_VIRT_MACHINE(4, 1) static void virt_machine_4_0_options(MachineClass *mc) { diff --git a/hw/core/machine.c b/hw/core/machine.c index 32d1ca9abc..83cd1bfeec 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -27,6 +27,9 @@ #include "hw/pci/pci.h" #include "hw/mem/nvdimm.h" +GlobalProperty hw_compat_4_1[] = {}; +const size_t hw_compat_4_1_len = G_N_ELEMENTS(hw_compat_4_1); + GlobalProperty hw_compat_4_0[] = { { "VGA", "edid", "false" }, { "secondary-vga", "edid", "false" }, diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3ab4bcb3ca..95edbbfe9e 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -119,6 +119,9 @@ struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; /* Physical Address of PVH entry point read from kernel ELF NOTE */ static size_t pvh_start_addr; +GlobalProperty pc_compat_4_1[] = {}; +const size_t pc_compat_4_1_len = G_N_ELEMENTS(pc_compat_4_1); + GlobalProperty pc_compat_4_0[] = {}; const size_t pc_compat_4_0_len = G_N_ELEMENTS(pc_compat_4_0); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 9e187f856a..a70cf0aafc 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -432,7 +432,7 @@ static void pc_i440fx_machine_options(MachineClass *m) machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); } -static void pc_i440fx_4_1_machine_options(MachineClass *m) +static void pc_i440fx_4_2_machine_options(MachineClass *m) { PCMachineClass *pcmc = PC_MACHINE_CLASS(m); pc_i440fx_machine_options(m); @@ -441,6 +441,18 @@ static void pc_i440fx_4_1_machine_options(MachineClass *m) pcmc->default_cpu_version = 1; } +DEFINE_I440FX_MACHINE(v4_2, "pc-i440fx-4.2", NULL, + pc_i440fx_4_2_machine_options); + +static void pc_i440fx_4_1_machine_options(MachineClass *m) +{ + pc_i440fx_4_2_machine_options(m); + m->alias = NULL; + m->is_default = 0; + compat_props_add(m->compat_props, hw_compat_4_1, hw_compat_4_1_len); + compat_props_add(m->compat_props, pc_compat_4_1, pc_compat_4_1_len); +} + DEFINE_I440FX_MACHINE(v4_1, "pc-i440fx-4.1", NULL, pc_i440fx_4_1_machine_options); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index be3464f485..d4e8a1cb9f 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -364,7 +364,7 @@ static void pc_q35_machine_options(MachineClass *m) m->max_cpus = 288; } -static void pc_q35_4_1_machine_options(MachineClass *m) +static void pc_q35_4_2_machine_options(MachineClass *m) { PCMachineClass *pcmc = PC_MACHINE_CLASS(m); pc_q35_machine_options(m); @@ -372,6 +372,17 @@ static void pc_q35_4_1_machine_options(MachineClass *m) pcmc->default_cpu_version = 1; } +DEFINE_Q35_MACHINE(v4_2, "pc-q35-4.2", NULL, + pc_q35_4_2_machine_options); + +static void pc_q35_4_1_machine_options(MachineClass *m) +{ + pc_q35_4_2_machine_options(m); + m->alias = NULL; + compat_props_add(m->compat_props, hw_compat_4_1, hw_compat_4_1_len); + compat_props_add(m->compat_props, pc_compat_4_1, pc_compat_4_1_len); +} + DEFINE_Q35_MACHINE(v4_1, "pc-q35-4.1", NULL, pc_q35_4_1_machine_options); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index e09c67eb75..6587d9b559 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4431,14 +4431,25 @@ static const TypeInfo spapr_machine_info = { type_init(spapr_machine_register_##suffix) /* - * pseries-4.1 + * pseries-4.2 */ -static void spapr_machine_4_1_class_options(MachineClass *mc) +static void spapr_machine_4_2_class_options(MachineClass *mc) { /* Defaults for the latest behaviour inherited from the base class */ } -DEFINE_SPAPR_MACHINE(4_1, "4.1", true); +DEFINE_SPAPR_MACHINE(4_2, "4.2", true); + +/* + * pseries-4.1 + */ +static void spapr_machine_4_1_class_options(MachineClass *mc) +{ + spapr_machine_4_2_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); +} + +DEFINE_SPAPR_MACHINE(4_1, "4.1", false); /* * pseries-4.0 diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 434d933ec9..8bfb6684cb 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -663,14 +663,26 @@ bool css_migration_enabled(void) } \ type_init(ccw_machine_register_##suffix) +static void ccw_machine_4_2_instance_options(MachineState *machine) +{ +} + +static void ccw_machine_4_2_class_options(MachineClass *mc) +{ +} +DEFINE_CCW_MACHINE(4_2, "4.2", true); + static void ccw_machine_4_1_instance_options(MachineState *machine) { + ccw_machine_4_2_instance_options(machine); } static void ccw_machine_4_1_class_options(MachineClass *mc) { + ccw_machine_4_2_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); } -DEFINE_CCW_MACHINE(4_1, "4.1", true); +DEFINE_CCW_MACHINE(4_1, "4.1", false); static void ccw_machine_4_0_instance_options(MachineState *machine) { diff --git a/include/hw/boards.h b/include/hw/boards.h index 739d109fe1..aa35955f7f 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -317,6 +317,9 @@ struct MachineState { } \ type_init(machine_initfn##_register_types) +extern GlobalProperty hw_compat_4_1[]; +extern const size_t hw_compat_4_1_len; + extern GlobalProperty hw_compat_4_0[]; extern const size_t hw_compat_4_0_len; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 4bb9e29114..ec538df9b7 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -301,6 +301,9 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); int e820_get_num_entries(void); bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); +extern GlobalProperty pc_compat_4_1[]; +extern const size_t pc_compat_4_1_len; + extern GlobalProperty pc_compat_4_0[]; extern const size_t pc_compat_4_0_len; From d15d4ad64f12cf88df8eac0cc910fa0637ab15e0 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 5 Jul 2019 15:03:05 +1000 Subject: [PATCH 04/42] spapr_pci: Allow 2MiB and 16MiB IOMMU pagesizes by default We've had the qemu and kernel KVM infrastructure to handle larger TCE page sizes for a while, but forgot to update the defaults to actually allow them. This turns that change on. Signed-off-by: David Gibson --- hw/ppc/spapr.c | 6 ++++++ hw/ppc/spapr_pci.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 6587d9b559..22a45c3737 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4445,8 +4445,14 @@ DEFINE_SPAPR_MACHINE(4_2, "4.2", true); */ static void spapr_machine_4_1_class_options(MachineClass *mc) { + static GlobalProperty compat[] = { + /* Only allow 4kiB and 64kiB IOMMU pagesizes */ + { TYPE_SPAPR_PCI_HOST_BRIDGE, "pgsz", "0x11000" }, + }; + spapr_machine_4_2_class_options(mc); compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); + compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); } DEFINE_SPAPR_MACHINE(4_1, "4.1", false); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index bf31fd854c..4c5420c465 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2093,7 +2093,8 @@ static Property spapr_phb_properties[] = { 0x800000000000000ULL), DEFINE_PROP_BOOL("ddw", SpaprPhbState, ddw_enabled, true), DEFINE_PROP_UINT64("pgsz", SpaprPhbState, page_size_mask, - (1ULL << 12) | (1ULL << 16)), + (1ULL << 12) | (1ULL << 16) + | (1ULL << 21) | (1ULL << 24)), DEFINE_PROP_UINT32("numa_node", SpaprPhbState, numa_node, -1), DEFINE_PROP_BOOL("pre-2.8-migration", SpaprPhbState, pre_2_8_migration, false), From d14f33976282a8744ca1bf1d64e73996c145aa3f Mon Sep 17 00:00:00 2001 From: "Maxiwell S. Garcia" Date: Thu, 11 Jul 2019 16:47:02 -0300 Subject: [PATCH 05/42] migration: Do not re-read the clock on pre_save in case of paused guest Re-read the timebase before migrate was ported from x86 commit: 6053a86fe7bd: kvmclock: reduce kvmclock difference on migration The clock move makes the guest knows about the paused time between the stop and migrate commands. This is an issue in an already-paused VM because some side effects, like process stalls, could happen after migration. So, this patch checks the runstate of guest in the pre_save handler and do not re-reads the timebase in case of paused state (cold migration). Signed-off-by: Maxiwell S. Garcia Message-Id: <20190711194702.26598-1-maxiwell@linux.ibm.com> Signed-off-by: David Gibson --- hw/ppc/ppc.c | 13 +++++++++---- target/ppc/cpu-qom.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 7963feeab4..52a18eb7d7 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -1011,6 +1011,8 @@ static void timebase_save(PPCTimebase *tb) * there is no need to update it from KVM here */ tb->guest_timebase = ticks + first_ppc_cpu->env.tb_env->tb_offset; + + tb->runstate_paused = runstate_check(RUN_STATE_PAUSED); } static void timebase_load(PPCTimebase *tb) @@ -1054,9 +1056,9 @@ void cpu_ppc_clock_vm_state_change(void *opaque, int running, } /* - * When migrating, read the clock just before migration, - * so that the guest clock counts during the events - * between: + * When migrating a running guest, read the clock just + * before migration, so that the guest clock counts + * during the events between: * * * vm_stop() * * @@ -1071,7 +1073,10 @@ static int timebase_pre_save(void *opaque) { PPCTimebase *tb = opaque; - timebase_save(tb); + /* guest_timebase won't be overridden in case of paused guest */ + if (!tb->runstate_paused) { + timebase_save(tb); + } return 0; } diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index a2f202f021..5769fb78a9 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -201,6 +201,7 @@ typedef struct PowerPCCPUClass { typedef struct PPCTimebase { uint64_t guest_timebase; int64_t time_of_the_day_ns; + bool runstate_paused; } PPCTimebase; extern const VMStateDescription vmstate_ppc_timebase; From 1cc792698e568626b5bf833e15e641ad0a81c6bb Mon Sep 17 00:00:00 2001 From: Stefan Brankovic Date: Mon, 15 Jul 2019 16:22:47 +0200 Subject: [PATCH 06/42] target/ppc: Optimize emulation of lvsl and lvsr instructions Adding simple macro that is calling tcg implementation of appropriate instruction if altivec support is active. Optimization of altivec instruction lvsl (Load Vector for Shift Left). Place bytes sh:sh+15 of value 0x00 || 0x01 || 0x02 || ... || 0x1E || 0x1F in destination register. Sh is calculated by adding 2 source registers and getting bits 60-63 of result. First, the bits [28-31] are placed from EA to variable sh. After that, the bytes are created in the following way: sh:(sh+7) of X(from description) by multiplying sh with 0x0101010101010101 followed by addition of the result with 0x0001020304050607. Value obtained is placed in higher doubleword element of vD. (sh+8):(sh+15) by adding the result of previous multiplication with 0x08090a0b0c0d0e0f. Value obtained is placed in lower doubleword element of vD. Optimization of altivec instruction lvsr (Load Vector for Shift Right). Place bytes 16-sh:31-sh of value 0x00 || 0x01 || 0x02 || ... || 0x1E || 0x1F in destination register. Sh is calculated by adding 2 source registers and getting bits 60-63 of result. First, the bits [28-31] are placed from EA to variable sh. After that, the bytes are created in the following way: sh:(sh+7) of X(from description) by multiplying sh with 0x0101010101010101 followed by substraction of the result from 0x1011121314151617. Value obtained is placed in higher doubleword element of vD. (sh+8):(sh+15) by substracting the result of previous multiplication from 0x18191a1b1c1d1e1f. Value obtained is placed in lower doubleword element of vD. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-2-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 2 - target/ppc/int_helper.c | 18 ----- target/ppc/translate/vmx-impl.inc.c | 121 ++++++++++++++++++++-------- 3 files changed, 89 insertions(+), 52 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 380c9b1e2a..121d7868d0 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -193,8 +193,6 @@ DEF_HELPER_2(vprtybw, void, avr, avr) DEF_HELPER_2(vprtybd, void, avr, avr) DEF_HELPER_2(vprtybq, void, avr, avr) DEF_HELPER_3(vsubcuw, void, avr, avr, avr) -DEF_HELPER_2(lvsl, void, avr, tl) -DEF_HELPER_2(lvsr, void, avr, tl) DEF_HELPER_FLAGS_5(vaddsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 8f037af956..5dcca5362b 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -459,24 +459,6 @@ SATCVT(sd, uw, int64_t, uint32_t, 0, UINT32_MAX) #undef SATCVT #undef SATCVTU -void helper_lvsl(ppc_avr_t *r, target_ulong sh) -{ - int i, j = (sh & 0xf); - - for (i = 0; i < ARRAY_SIZE(r->u8); i++) { - r->VsrB(i) = j++; - } -} - -void helper_lvsr(ppc_avr_t *r, target_ulong sh) -{ - int i, j = 0x10 - (sh & 0xf); - - for (i = 0; i < ARRAY_SIZE(r->u8); i++) { - r->VsrB(i) = j++; - } -} - void helper_mtvscr(CPUPPCState *env, uint32_t vscr) { env->vscr = vscr & ~(1u << VSCR_SAT); diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 663275b729..a9fe3c7834 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -142,38 +142,6 @@ GEN_VR_STVE(bx, 0x07, 0x04, 1); GEN_VR_STVE(hx, 0x07, 0x05, 2); GEN_VR_STVE(wx, 0x07, 0x06, 4); -static void gen_lvsl(DisasContext *ctx) -{ - TCGv_ptr rd; - TCGv EA; - if (unlikely(!ctx->altivec_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VPU); - return; - } - EA = tcg_temp_new(); - gen_addr_reg_index(ctx, EA); - rd = gen_avr_ptr(rD(ctx->opcode)); - gen_helper_lvsl(rd, EA); - tcg_temp_free(EA); - tcg_temp_free_ptr(rd); -} - -static void gen_lvsr(DisasContext *ctx) -{ - TCGv_ptr rd; - TCGv EA; - if (unlikely(!ctx->altivec_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VPU); - return; - } - EA = tcg_temp_new(); - gen_addr_reg_index(ctx, EA); - rd = gen_avr_ptr(rD(ctx->opcode)); - gen_helper_lvsr(rd, EA); - tcg_temp_free(EA); - tcg_temp_free_ptr(rd); -} - static void gen_mfvscr(DisasContext *ctx) { TCGv_i32 t; @@ -316,6 +284,16 @@ static void glue(gen_, name)(DisasContext *ctx) \ tcg_temp_free_ptr(rd); \ } +#define GEN_VXFORM_TRANS(name, opc2, opc3) \ +static void glue(gen_, name)(DisasContext *ctx) \ +{ \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + trans_##name(ctx); \ +} + #define GEN_VXFORM_ENV(name, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ { \ @@ -515,6 +493,83 @@ static void gen_vmrgow(DisasContext *ctx) tcg_temp_free_i64(avr); } +/* + * lvsl VRT,RA,RB - Load Vector for Shift Left + * + * Let the EA be the sum (rA|0)+(rB). Let sh=EA[28–31]. + * Let X be the 32-byte value 0x00 || 0x01 || 0x02 || ... || 0x1E || 0x1F. + * Bytes sh:sh+15 of X are placed into vD. + */ +static void trans_lvsl(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + TCGv_i64 result = tcg_temp_new_i64(); + TCGv_i64 sh = tcg_temp_new_i64(); + TCGv EA = tcg_temp_new(); + + /* Get sh(from description) by anding EA with 0xf. */ + gen_addr_reg_index(ctx, EA); + tcg_gen_extu_tl_i64(sh, EA); + tcg_gen_andi_i64(sh, sh, 0xfULL); + + /* + * Create bytes sh:sh+7 of X(from description) and place them in + * higher doubleword of vD. + */ + tcg_gen_muli_i64(sh, sh, 0x0101010101010101ULL); + tcg_gen_addi_i64(result, sh, 0x0001020304050607ull); + set_avr64(VT, result, true); + /* + * Create bytes sh+8:sh+15 of X(from description) and place them in + * lower doubleword of vD. + */ + tcg_gen_addi_i64(result, sh, 0x08090a0b0c0d0e0fULL); + set_avr64(VT, result, false); + + tcg_temp_free_i64(result); + tcg_temp_free_i64(sh); + tcg_temp_free(EA); +} + +/* + * lvsr VRT,RA,RB - Load Vector for Shift Right + * + * Let the EA be the sum (rA|0)+(rB). Let sh=EA[28–31]. + * Let X be the 32-byte value 0x00 || 0x01 || 0x02 || ... || 0x1E || 0x1F. + * Bytes (16-sh):(31-sh) of X are placed into vD. + */ +static void trans_lvsr(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + TCGv_i64 result = tcg_temp_new_i64(); + TCGv_i64 sh = tcg_temp_new_i64(); + TCGv EA = tcg_temp_new(); + + + /* Get sh(from description) by anding EA with 0xf. */ + gen_addr_reg_index(ctx, EA); + tcg_gen_extu_tl_i64(sh, EA); + tcg_gen_andi_i64(sh, sh, 0xfULL); + + /* + * Create bytes (16-sh):(23-sh) of X(from description) and place them in + * higher doubleword of vD. + */ + tcg_gen_muli_i64(sh, sh, 0x0101010101010101ULL); + tcg_gen_subfi_i64(result, 0x1011121314151617ULL, sh); + set_avr64(VT, result, true); + /* + * Create bytes (24-sh):(32-sh) of X(from description) and place them in + * lower doubleword of vD. + */ + tcg_gen_subfi_i64(result, 0x18191a1b1c1d1e1fULL, sh); + set_avr64(VT, result, false); + + tcg_temp_free_i64(result); + tcg_temp_free_i64(sh); + tcg_temp_free(EA); +} + GEN_VXFORM(vmuloub, 4, 0); GEN_VXFORM(vmulouh, 4, 1); GEN_VXFORM(vmulouw, 4, 2); @@ -662,6 +717,8 @@ GEN_VXFORM_DUAL(vmrgow, PPC_NONE, PPC2_ALTIVEC_207, GEN_VXFORM_HETRO(vextubrx, 6, 28) GEN_VXFORM_HETRO(vextuhrx, 6, 29) GEN_VXFORM_HETRO(vextuwrx, 6, 30) +GEN_VXFORM_TRANS(lvsl, 6, 31) +GEN_VXFORM_TRANS(lvsr, 6, 32) GEN_VXFORM_DUAL(vmrgew, PPC_NONE, PPC2_ALTIVEC_207, \ vextuwrx, PPC_NONE, PPC2_ISA300) From 4e6d0920e7547e6af4bbac5ffe9adfe6ea621822 Mon Sep 17 00:00:00 2001 From: Stefan Brankovic Date: Mon, 15 Jul 2019 16:22:48 +0200 Subject: [PATCH 07/42] target/ppc: Optimize emulation of vsl and vsr instructions Optimization of altivec instructions vsl and vsr(Vector Shift Left/Rigt). Perform shift operation (left and right respectively) on 128 bit value of register vA by value specified in bits 125-127 of register vB. Lowest 3 bits in each byte element of register vB must be identical or result is undefined. For vsl instruction, the first step is bits 125-127 of register vB have to be saved in variable sh. Then, the highest sh bits of the lower doubleword element of register vA are saved in variable shifted, in order not to lose those bits when shift operation is performed on the lower doubleword element of register vA, which is the next step. After shifting the lower doubleword element shift operation is performed on higher doubleword element of vA, with replacement of the lowest sh bits(that are now 0) with bits saved in shifted. For vsr instruction, firstly, the bits 125-127 of register vB have to be saved in variable sh. Then, the lowest sh bits of the higher doubleword element of register vA are saved in variable shifted, in odred not to lose those bits when the shift operation is performed on the higher doubleword element of register vA, which is the next step. After shifting higher doubleword element, shift operation is performed on lower doubleword element of vA, with replacement of highest sh bits(that are now 0) with bits saved in shifted. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-3-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 2 - target/ppc/int_helper.c | 35 ---------- target/ppc/translate/vmx-impl.inc.c | 101 +++++++++++++++++++++++++++- 3 files changed, 99 insertions(+), 39 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 121d7868d0..6fb823c7b4 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -217,8 +217,6 @@ DEF_HELPER_3(vrlb, void, avr, avr, avr) DEF_HELPER_3(vrlh, void, avr, avr, avr) DEF_HELPER_3(vrlw, void, avr, avr, avr) DEF_HELPER_3(vrld, void, avr, avr, avr) -DEF_HELPER_3(vsl, void, avr, avr, avr) -DEF_HELPER_3(vsr, void, avr, avr, avr) DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) DEF_HELPER_3(vextractub, void, avr, avr, i32) DEF_HELPER_3(vextractuh, void, avr, avr, i32) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 5dcca5362b..d2cad787ad 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1740,41 +1740,6 @@ VEXTU_X_DO(vextuhrx, 16, 0) VEXTU_X_DO(vextuwrx, 32, 0) #undef VEXTU_X_DO -/* - * The specification says that the results are undefined if all of the - * shift counts are not identical. We check to make sure that they - * are to conform to what real hardware appears to do. - */ -#define VSHIFT(suffix, leftp) \ - void helper_vs##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ - { \ - int shift = b->VsrB(15) & 0x7; \ - int doit = 1; \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(r->u8); i++) { \ - doit = doit && ((b->u8[i] & 0x7) == shift); \ - } \ - if (doit) { \ - if (shift == 0) { \ - *r = *a; \ - } else if (leftp) { \ - uint64_t carry = a->VsrD(1) >> (64 - shift); \ - \ - r->VsrD(0) = (a->VsrD(0) << shift) | carry; \ - r->VsrD(1) = a->VsrD(1) << shift; \ - } else { \ - uint64_t carry = a->VsrD(0) << (64 - shift); \ - \ - r->VsrD(1) = (a->VsrD(1) >> shift) | carry; \ - r->VsrD(0) = a->VsrD(0) >> shift; \ - } \ - } \ - } -VSHIFT(l, 1) -VSHIFT(r, 0) -#undef VSHIFT - void helper_vslv(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int i; diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index a9fe3c7834..e06e65adb2 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -570,6 +570,103 @@ static void trans_lvsr(DisasContext *ctx) tcg_temp_free(EA); } +/* + * vsl VRT,VRA,VRB - Vector Shift Left + * + * Shifting left 128 bit value of vA by value specified in bits 125-127 of vB. + * Lowest 3 bits in each byte element of register vB must be identical or + * result is undefined. + */ +static void trans_vsl(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + int VA = rA(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i64 avrA = tcg_temp_new_i64(); + TCGv_i64 avrB = tcg_temp_new_i64(); + TCGv_i64 sh = tcg_temp_new_i64(); + TCGv_i64 shifted = tcg_temp_new_i64(); + TCGv_i64 tmp = tcg_temp_new_i64(); + + /* Place bits 125-127 of vB in sh. */ + get_avr64(avrB, VB, false); + tcg_gen_andi_i64(sh, avrB, 0x07ULL); + + /* + * Save highest sh bits of lower doubleword element of vA in variable + * shifted and perform shift on lower doubleword. + */ + get_avr64(avrA, VA, false); + tcg_gen_subfi_i64(tmp, 64, sh); + tcg_gen_shr_i64(shifted, avrA, tmp); + tcg_gen_andi_i64(shifted, shifted, 0x7fULL); + tcg_gen_shl_i64(avrA, avrA, sh); + set_avr64(VT, avrA, false); + + /* + * Perform shift on higher doubleword element of vA and replace lowest + * sh bits with shifted. + */ + get_avr64(avrA, VA, true); + tcg_gen_shl_i64(avrA, avrA, sh); + tcg_gen_or_i64(avrA, avrA, shifted); + set_avr64(VT, avrA, true); + + tcg_temp_free_i64(avrA); + tcg_temp_free_i64(avrB); + tcg_temp_free_i64(sh); + tcg_temp_free_i64(shifted); + tcg_temp_free_i64(tmp); +} + +/* + * vsr VRT,VRA,VRB - Vector Shift Right + * + * Shifting right 128 bit value of vA by value specified in bits 125-127 of vB. + * Lowest 3 bits in each byte element of register vB must be identical or + * result is undefined. + */ +static void trans_vsr(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + int VA = rA(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i64 avrA = tcg_temp_new_i64(); + TCGv_i64 avrB = tcg_temp_new_i64(); + TCGv_i64 sh = tcg_temp_new_i64(); + TCGv_i64 shifted = tcg_temp_new_i64(); + TCGv_i64 tmp = tcg_temp_new_i64(); + + /* Place bits 125-127 of vB in sh. */ + get_avr64(avrB, VB, false); + tcg_gen_andi_i64(sh, avrB, 0x07ULL); + + /* + * Save lowest sh bits of higher doubleword element of vA in variable + * shifted and perform shift on higher doubleword. + */ + get_avr64(avrA, VA, true); + tcg_gen_subfi_i64(tmp, 64, sh); + tcg_gen_shl_i64(shifted, avrA, tmp); + tcg_gen_andi_i64(shifted, shifted, 0xfe00000000000000ULL); + tcg_gen_shr_i64(avrA, avrA, sh); + set_avr64(VT, avrA, true); + /* + * Perform shift on lower doubleword element of vA and replace highest + * sh bits with shifted. + */ + get_avr64(avrA, VA, false); + tcg_gen_shr_i64(avrA, avrA, sh); + tcg_gen_or_i64(avrA, avrA, shifted); + set_avr64(VT, avrA, false); + + tcg_temp_free_i64(avrA); + tcg_temp_free_i64(avrB); + tcg_temp_free_i64(sh); + tcg_temp_free_i64(shifted); + tcg_temp_free_i64(tmp); +} + GEN_VXFORM(vmuloub, 4, 0); GEN_VXFORM(vmulouh, 4, 1); GEN_VXFORM(vmulouw, 4, 2); @@ -682,11 +779,11 @@ GEN_VXFORM(vrld, 2, 3); GEN_VXFORM(vrldmi, 2, 3); GEN_VXFORM_DUAL(vrld, PPC_NONE, PPC2_ALTIVEC_207, \ vrldmi, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vsl, 2, 7); +GEN_VXFORM_TRANS(vsl, 2, 7); GEN_VXFORM(vrldnm, 2, 7); GEN_VXFORM_DUAL(vsl, PPC_ALTIVEC, PPC_NONE, \ vrldnm, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vsr, 2, 11); +GEN_VXFORM_TRANS(vsr, 2, 11); GEN_VXFORM_ENV(vpkuhum, 7, 0); GEN_VXFORM_ENV(vpkuwum, 7, 1); GEN_VXFORM_ENV(vpkudum, 7, 17); From 28876bf27d2792e6b16cfb5283b9fb959fc0ad12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 16 Jul 2019 13:13:52 +0100 Subject: [PATCH 08/42] target/ppc: move opcode decode tables to PowerPCCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The opcode decode tables aren't really part of the CPUPPCState but an internal implementation detail for the translator. This can cause problems with memcpy in cpu_copy as any table created during ppc_cpu_realize get written over causing a memory leak. To avoid this move the tables into PowerPCCPU which is better suited to hold internal implementation details. Attempts to fix: https://bugs.launchpad.net/qemu/+bug/1836558 Cc: 1836558@bugs.launchpad.net Signed-off-by: Alex Bennée Message-Id: <20190716121352.302-1-alex.bennee@linaro.org> Reviewed-by: Richard Henderson Signed-off-by: David Gibson --- target/ppc/cpu.h | 8 ++++---- target/ppc/translate.c | 3 ++- target/ppc/translate_init.inc.c | 16 +++++++--------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 4ea33cf696..630a25c246 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1104,10 +1104,6 @@ struct CPUPPCState { bool resume_as_sreset; #endif - /* Those resources are used only during code translation */ - /* opcode handlers */ - opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN]; - /* Those resources are used only in QEMU core */ target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */ target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */ @@ -1191,6 +1187,10 @@ struct PowerPCCPU { int32_t node_id; /* NUMA node this CPU belongs to */ PPCHash64Options *hash64_opts; + /* Those resources are used only during code translation */ + /* opcode handlers */ + opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN]; + /* Fields related to migration compatibility hacks */ bool pre_2_8_migration; target_ulong mig_msr_mask; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 9f9553afb4..1afb31e855 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7858,6 +7858,7 @@ static bool ppc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { DisasContext *ctx = container_of(dcbase, DisasContext, base); + PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = cs->env_ptr; opc_handler_t **table, *handler; @@ -7875,7 +7876,7 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) opc3(ctx->opcode), opc4(ctx->opcode), ctx->le_mode ? "little" : "big"); ctx->base.pc_next += 4; - table = env->opcodes; + table = cpu->opcodes; handler = table[opc1(ctx->opcode)]; if (is_indirect_opcode(handler)) { table = ind_table(handler); diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 86fc8f2e31..9cd2033bb9 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9440,14 +9440,13 @@ static void fix_opcode_tables(opc_handler_t **ppc_opcodes) static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) { PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - CPUPPCState *env = &cpu->env; opcode_t *opc; - fill_new_table(env->opcodes, PPC_CPU_OPCODES_LEN); + fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN); for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { if (((opc->handler.type & pcc->insns_flags) != 0) || ((opc->handler.type2 & pcc->insns_flags2) != 0)) { - if (register_insn(env->opcodes, opc) < 0) { + if (register_insn(cpu->opcodes, opc) < 0) { error_setg(errp, "ERROR initializing PowerPC instruction " "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2, opc->opc3); @@ -9455,7 +9454,7 @@ static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) } } } - fix_opcode_tables(env->opcodes); + fix_opcode_tables(cpu->opcodes); fflush(stdout); fflush(stderr); } @@ -10023,7 +10022,6 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) { PowerPCCPU *cpu = POWERPC_CPU(dev); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - CPUPPCState *env = &cpu->env; Error *local_err = NULL; opc_handler_t **table, **table_2; int i, j, k; @@ -10035,11 +10033,11 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) } for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { - if (env->opcodes[i] == &invalid_handler) { + if (cpu->opcodes[i] == &invalid_handler) { continue; } - if (is_indirect_opcode(env->opcodes[i])) { - table = ind_table(env->opcodes[i]); + if (is_indirect_opcode(cpu->opcodes[i])) { + table = ind_table(cpu->opcodes[i]); for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { if (table[j] == &invalid_handler) { continue; @@ -10057,7 +10055,7 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) ~PPC_INDIRECT)); } } - g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] & + g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] & ~PPC_INDIRECT)); } } From 083b3f012fc27536afc74d005d706b20eae200f8 Mon Sep 17 00:00:00 2001 From: Stefan Brankovic Date: Mon, 15 Jul 2019 16:22:50 +0200 Subject: [PATCH 09/42] target/ppc: Optimize emulation of vgbbd instruction Optimize altivec instruction vgbbd (Vector Gather Bits by Bytes by Doubleword) All ith bits (i in range 1 to 8) of each byte of doubleword element in source register are concatenated and placed into ith byte of appropriate doubleword element in destination register. Following solution is done for both doubleword elements of source register in parallel, in order to reduce the number of instructions needed(that's why arrays are used): First, both doubleword elements of source register vB are placed in appropriate element of array avr. Bits are gathered in 2x8 iterations(2 for loops). In first iteration bit 1 of byte 1, bit 2 of byte 2,... bit 8 of byte 8 are in their final spots so avr[i], i={0,1} can be and-ed with tcg_mask. For every following iteration, both avr[i] and tcg_mask variables have to be shifted right for 7 and 8 places, respectively, in order to get bit 1 of byte 2, bit 2 of byte 3.. bit 7 of byte 8 in their final spots so shifted avr values(saved in tmp) can be and-ed with new value of tcg_mask... After first 8 iteration(first loop), all the first bits are in their final places, all second bits but second bit from eight byte are in their places... only 1 eight bit from eight byte is in it's place). In second loop we do all operations symmetrically, in order to get other half of bits in their final spots. Results for first and second doubleword elements are saved in result[0] and result[1] respectively. In the end those results are saved in appropriate doubleword element of destination register vD. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-5-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 1 - target/ppc/int_helper.c | 276 ---------------------------- target/ppc/translate/vmx-impl.inc.c | 77 +++++++- 3 files changed, 76 insertions(+), 278 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 6fb823c7b4..9b486a0c37 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -324,7 +324,6 @@ DEF_HELPER_1(vclzlsbb, tl, avr) DEF_HELPER_1(vctzlsbb, tl, avr) DEF_HELPER_3(vbpermd, void, avr, avr, avr) DEF_HELPER_3(vbpermq, void, avr, avr, avr) -DEF_HELPER_2(vgbbd, void, avr, avr) DEF_HELPER_3(vpmsumb, void, avr, avr, avr) DEF_HELPER_3(vpmsumh, void, avr, avr, avr) DEF_HELPER_3(vpmsumw, void, avr, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index d2cad787ad..a265cb07c5 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1187,282 +1187,6 @@ void helper_vbpermq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #undef VBPERMQ_INDEX #undef VBPERMQ_DW -static const uint64_t VGBBD_MASKS[256] = { - 0x0000000000000000ull, /* 00 */ - 0x0000000000000080ull, /* 01 */ - 0x0000000000008000ull, /* 02 */ - 0x0000000000008080ull, /* 03 */ - 0x0000000000800000ull, /* 04 */ - 0x0000000000800080ull, /* 05 */ - 0x0000000000808000ull, /* 06 */ - 0x0000000000808080ull, /* 07 */ - 0x0000000080000000ull, /* 08 */ - 0x0000000080000080ull, /* 09 */ - 0x0000000080008000ull, /* 0A */ - 0x0000000080008080ull, /* 0B */ - 0x0000000080800000ull, /* 0C */ - 0x0000000080800080ull, /* 0D */ - 0x0000000080808000ull, /* 0E */ - 0x0000000080808080ull, /* 0F */ - 0x0000008000000000ull, /* 10 */ - 0x0000008000000080ull, /* 11 */ - 0x0000008000008000ull, /* 12 */ - 0x0000008000008080ull, /* 13 */ - 0x0000008000800000ull, /* 14 */ - 0x0000008000800080ull, /* 15 */ - 0x0000008000808000ull, /* 16 */ - 0x0000008000808080ull, /* 17 */ - 0x0000008080000000ull, /* 18 */ - 0x0000008080000080ull, /* 19 */ - 0x0000008080008000ull, /* 1A */ - 0x0000008080008080ull, /* 1B */ - 0x0000008080800000ull, /* 1C */ - 0x0000008080800080ull, /* 1D */ - 0x0000008080808000ull, /* 1E */ - 0x0000008080808080ull, /* 1F */ - 0x0000800000000000ull, /* 20 */ - 0x0000800000000080ull, /* 21 */ - 0x0000800000008000ull, /* 22 */ - 0x0000800000008080ull, /* 23 */ - 0x0000800000800000ull, /* 24 */ - 0x0000800000800080ull, /* 25 */ - 0x0000800000808000ull, /* 26 */ - 0x0000800000808080ull, /* 27 */ - 0x0000800080000000ull, /* 28 */ - 0x0000800080000080ull, /* 29 */ - 0x0000800080008000ull, /* 2A */ - 0x0000800080008080ull, /* 2B */ - 0x0000800080800000ull, /* 2C */ - 0x0000800080800080ull, /* 2D */ - 0x0000800080808000ull, /* 2E */ - 0x0000800080808080ull, /* 2F */ - 0x0000808000000000ull, /* 30 */ - 0x0000808000000080ull, /* 31 */ - 0x0000808000008000ull, /* 32 */ - 0x0000808000008080ull, /* 33 */ - 0x0000808000800000ull, /* 34 */ - 0x0000808000800080ull, /* 35 */ - 0x0000808000808000ull, /* 36 */ - 0x0000808000808080ull, /* 37 */ - 0x0000808080000000ull, /* 38 */ - 0x0000808080000080ull, /* 39 */ - 0x0000808080008000ull, /* 3A */ - 0x0000808080008080ull, /* 3B */ - 0x0000808080800000ull, /* 3C */ - 0x0000808080800080ull, /* 3D */ - 0x0000808080808000ull, /* 3E */ - 0x0000808080808080ull, /* 3F */ - 0x0080000000000000ull, /* 40 */ - 0x0080000000000080ull, /* 41 */ - 0x0080000000008000ull, /* 42 */ - 0x0080000000008080ull, /* 43 */ - 0x0080000000800000ull, /* 44 */ - 0x0080000000800080ull, /* 45 */ - 0x0080000000808000ull, /* 46 */ - 0x0080000000808080ull, /* 47 */ - 0x0080000080000000ull, /* 48 */ - 0x0080000080000080ull, /* 49 */ - 0x0080000080008000ull, /* 4A */ - 0x0080000080008080ull, /* 4B */ - 0x0080000080800000ull, /* 4C */ - 0x0080000080800080ull, /* 4D */ - 0x0080000080808000ull, /* 4E */ - 0x0080000080808080ull, /* 4F */ - 0x0080008000000000ull, /* 50 */ - 0x0080008000000080ull, /* 51 */ - 0x0080008000008000ull, /* 52 */ - 0x0080008000008080ull, /* 53 */ - 0x0080008000800000ull, /* 54 */ - 0x0080008000800080ull, /* 55 */ - 0x0080008000808000ull, /* 56 */ - 0x0080008000808080ull, /* 57 */ - 0x0080008080000000ull, /* 58 */ - 0x0080008080000080ull, /* 59 */ - 0x0080008080008000ull, /* 5A */ - 0x0080008080008080ull, /* 5B */ - 0x0080008080800000ull, /* 5C */ - 0x0080008080800080ull, /* 5D */ - 0x0080008080808000ull, /* 5E */ - 0x0080008080808080ull, /* 5F */ - 0x0080800000000000ull, /* 60 */ - 0x0080800000000080ull, /* 61 */ - 0x0080800000008000ull, /* 62 */ - 0x0080800000008080ull, /* 63 */ - 0x0080800000800000ull, /* 64 */ - 0x0080800000800080ull, /* 65 */ - 0x0080800000808000ull, /* 66 */ - 0x0080800000808080ull, /* 67 */ - 0x0080800080000000ull, /* 68 */ - 0x0080800080000080ull, /* 69 */ - 0x0080800080008000ull, /* 6A */ - 0x0080800080008080ull, /* 6B */ - 0x0080800080800000ull, /* 6C */ - 0x0080800080800080ull, /* 6D */ - 0x0080800080808000ull, /* 6E */ - 0x0080800080808080ull, /* 6F */ - 0x0080808000000000ull, /* 70 */ - 0x0080808000000080ull, /* 71 */ - 0x0080808000008000ull, /* 72 */ - 0x0080808000008080ull, /* 73 */ - 0x0080808000800000ull, /* 74 */ - 0x0080808000800080ull, /* 75 */ - 0x0080808000808000ull, /* 76 */ - 0x0080808000808080ull, /* 77 */ - 0x0080808080000000ull, /* 78 */ - 0x0080808080000080ull, /* 79 */ - 0x0080808080008000ull, /* 7A */ - 0x0080808080008080ull, /* 7B */ - 0x0080808080800000ull, /* 7C */ - 0x0080808080800080ull, /* 7D */ - 0x0080808080808000ull, /* 7E */ - 0x0080808080808080ull, /* 7F */ - 0x8000000000000000ull, /* 80 */ - 0x8000000000000080ull, /* 81 */ - 0x8000000000008000ull, /* 82 */ - 0x8000000000008080ull, /* 83 */ - 0x8000000000800000ull, /* 84 */ - 0x8000000000800080ull, /* 85 */ - 0x8000000000808000ull, /* 86 */ - 0x8000000000808080ull, /* 87 */ - 0x8000000080000000ull, /* 88 */ - 0x8000000080000080ull, /* 89 */ - 0x8000000080008000ull, /* 8A */ - 0x8000000080008080ull, /* 8B */ - 0x8000000080800000ull, /* 8C */ - 0x8000000080800080ull, /* 8D */ - 0x8000000080808000ull, /* 8E */ - 0x8000000080808080ull, /* 8F */ - 0x8000008000000000ull, /* 90 */ - 0x8000008000000080ull, /* 91 */ - 0x8000008000008000ull, /* 92 */ - 0x8000008000008080ull, /* 93 */ - 0x8000008000800000ull, /* 94 */ - 0x8000008000800080ull, /* 95 */ - 0x8000008000808000ull, /* 96 */ - 0x8000008000808080ull, /* 97 */ - 0x8000008080000000ull, /* 98 */ - 0x8000008080000080ull, /* 99 */ - 0x8000008080008000ull, /* 9A */ - 0x8000008080008080ull, /* 9B */ - 0x8000008080800000ull, /* 9C */ - 0x8000008080800080ull, /* 9D */ - 0x8000008080808000ull, /* 9E */ - 0x8000008080808080ull, /* 9F */ - 0x8000800000000000ull, /* A0 */ - 0x8000800000000080ull, /* A1 */ - 0x8000800000008000ull, /* A2 */ - 0x8000800000008080ull, /* A3 */ - 0x8000800000800000ull, /* A4 */ - 0x8000800000800080ull, /* A5 */ - 0x8000800000808000ull, /* A6 */ - 0x8000800000808080ull, /* A7 */ - 0x8000800080000000ull, /* A8 */ - 0x8000800080000080ull, /* A9 */ - 0x8000800080008000ull, /* AA */ - 0x8000800080008080ull, /* AB */ - 0x8000800080800000ull, /* AC */ - 0x8000800080800080ull, /* AD */ - 0x8000800080808000ull, /* AE */ - 0x8000800080808080ull, /* AF */ - 0x8000808000000000ull, /* B0 */ - 0x8000808000000080ull, /* B1 */ - 0x8000808000008000ull, /* B2 */ - 0x8000808000008080ull, /* B3 */ - 0x8000808000800000ull, /* B4 */ - 0x8000808000800080ull, /* B5 */ - 0x8000808000808000ull, /* B6 */ - 0x8000808000808080ull, /* B7 */ - 0x8000808080000000ull, /* B8 */ - 0x8000808080000080ull, /* B9 */ - 0x8000808080008000ull, /* BA */ - 0x8000808080008080ull, /* BB */ - 0x8000808080800000ull, /* BC */ - 0x8000808080800080ull, /* BD */ - 0x8000808080808000ull, /* BE */ - 0x8000808080808080ull, /* BF */ - 0x8080000000000000ull, /* C0 */ - 0x8080000000000080ull, /* C1 */ - 0x8080000000008000ull, /* C2 */ - 0x8080000000008080ull, /* C3 */ - 0x8080000000800000ull, /* C4 */ - 0x8080000000800080ull, /* C5 */ - 0x8080000000808000ull, /* C6 */ - 0x8080000000808080ull, /* C7 */ - 0x8080000080000000ull, /* C8 */ - 0x8080000080000080ull, /* C9 */ - 0x8080000080008000ull, /* CA */ - 0x8080000080008080ull, /* CB */ - 0x8080000080800000ull, /* CC */ - 0x8080000080800080ull, /* CD */ - 0x8080000080808000ull, /* CE */ - 0x8080000080808080ull, /* CF */ - 0x8080008000000000ull, /* D0 */ - 0x8080008000000080ull, /* D1 */ - 0x8080008000008000ull, /* D2 */ - 0x8080008000008080ull, /* D3 */ - 0x8080008000800000ull, /* D4 */ - 0x8080008000800080ull, /* D5 */ - 0x8080008000808000ull, /* D6 */ - 0x8080008000808080ull, /* D7 */ - 0x8080008080000000ull, /* D8 */ - 0x8080008080000080ull, /* D9 */ - 0x8080008080008000ull, /* DA */ - 0x8080008080008080ull, /* DB */ - 0x8080008080800000ull, /* DC */ - 0x8080008080800080ull, /* DD */ - 0x8080008080808000ull, /* DE */ - 0x8080008080808080ull, /* DF */ - 0x8080800000000000ull, /* E0 */ - 0x8080800000000080ull, /* E1 */ - 0x8080800000008000ull, /* E2 */ - 0x8080800000008080ull, /* E3 */ - 0x8080800000800000ull, /* E4 */ - 0x8080800000800080ull, /* E5 */ - 0x8080800000808000ull, /* E6 */ - 0x8080800000808080ull, /* E7 */ - 0x8080800080000000ull, /* E8 */ - 0x8080800080000080ull, /* E9 */ - 0x8080800080008000ull, /* EA */ - 0x8080800080008080ull, /* EB */ - 0x8080800080800000ull, /* EC */ - 0x8080800080800080ull, /* ED */ - 0x8080800080808000ull, /* EE */ - 0x8080800080808080ull, /* EF */ - 0x8080808000000000ull, /* F0 */ - 0x8080808000000080ull, /* F1 */ - 0x8080808000008000ull, /* F2 */ - 0x8080808000008080ull, /* F3 */ - 0x8080808000800000ull, /* F4 */ - 0x8080808000800080ull, /* F5 */ - 0x8080808000808000ull, /* F6 */ - 0x8080808000808080ull, /* F7 */ - 0x8080808080000000ull, /* F8 */ - 0x8080808080000080ull, /* F9 */ - 0x8080808080008000ull, /* FA */ - 0x8080808080008080ull, /* FB */ - 0x8080808080800000ull, /* FC */ - 0x8080808080800080ull, /* FD */ - 0x8080808080808000ull, /* FE */ - 0x8080808080808080ull, /* FF */ -}; - -void helper_vgbbd(ppc_avr_t *r, ppc_avr_t *b) -{ - int i; - uint64_t t[2] = { 0, 0 }; - - VECTOR_FOR_INORDER_I(i, u8) { -#if defined(HOST_WORDS_BIGENDIAN) - t[i >> 3] |= VGBBD_MASKS[b->u8[i]] >> (i & 7); -#else - t[i >> 3] |= VGBBD_MASKS[b->u8[i]] >> (7 - (i & 7)); -#endif - } - - r->u64[0] = t[0]; - r->u64[1] = t[1]; -} - #define PMSUM(name, srcfld, trgfld, trgtyp) \ void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index e06e65adb2..13153352e4 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -667,6 +667,81 @@ static void trans_vsr(DisasContext *ctx) tcg_temp_free_i64(tmp); } +/* + * vgbbd VRT,VRB - Vector Gather Bits by Bytes by Doubleword + * + * All ith bits (i in range 1 to 8) of each byte of doubleword element in source + * register are concatenated and placed into ith byte of appropriate doubleword + * element in destination register. + * + * Following solution is done for both doubleword elements of source register + * in parallel, in order to reduce the number of instructions needed(that's why + * arrays are used): + * First, both doubleword elements of source register vB are placed in + * appropriate element of array avr. Bits are gathered in 2x8 iterations(2 for + * loops). In first iteration bit 1 of byte 1, bit 2 of byte 2,... bit 8 of + * byte 8 are in their final spots so avr[i], i={0,1} can be and-ed with + * tcg_mask. For every following iteration, both avr[i] and tcg_mask variables + * have to be shifted right for 7 and 8 places, respectively, in order to get + * bit 1 of byte 2, bit 2 of byte 3.. bit 7 of byte 8 in their final spots so + * shifted avr values(saved in tmp) can be and-ed with new value of tcg_mask... + * After first 8 iteration(first loop), all the first bits are in their final + * places, all second bits but second bit from eight byte are in their places... + * only 1 eight bit from eight byte is in it's place). In second loop we do all + * operations symmetrically, in order to get other half of bits in their final + * spots. Results for first and second doubleword elements are saved in + * result[0] and result[1] respectively. In the end those results are saved in + * appropriate doubleword element of destination register vD. + */ +static void trans_vgbbd(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i64 tmp = tcg_temp_new_i64(); + uint64_t mask = 0x8040201008040201ULL; + int i, j; + + TCGv_i64 result[2]; + result[0] = tcg_temp_new_i64(); + result[1] = tcg_temp_new_i64(); + TCGv_i64 avr[2]; + avr[0] = tcg_temp_new_i64(); + avr[1] = tcg_temp_new_i64(); + TCGv_i64 tcg_mask = tcg_temp_new_i64(); + + tcg_gen_movi_i64(tcg_mask, mask); + for (j = 0; j < 2; j++) { + get_avr64(avr[j], VB, j); + tcg_gen_and_i64(result[j], avr[j], tcg_mask); + } + for (i = 1; i < 8; i++) { + tcg_gen_movi_i64(tcg_mask, mask >> (i * 8)); + for (j = 0; j < 2; j++) { + tcg_gen_shri_i64(tmp, avr[j], i * 7); + tcg_gen_and_i64(tmp, tmp, tcg_mask); + tcg_gen_or_i64(result[j], result[j], tmp); + } + } + for (i = 1; i < 8; i++) { + tcg_gen_movi_i64(tcg_mask, mask << (i * 8)); + for (j = 0; j < 2; j++) { + tcg_gen_shli_i64(tmp, avr[j], i * 7); + tcg_gen_and_i64(tmp, tmp, tcg_mask); + tcg_gen_or_i64(result[j], result[j], tmp); + } + } + for (j = 0; j < 2; j++) { + set_avr64(VT, result[j], j); + } + + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tcg_mask); + tcg_temp_free_i64(result[0]); + tcg_temp_free_i64(result[1]); + tcg_temp_free_i64(avr[0]); + tcg_temp_free_i64(avr[1]); +} + GEN_VXFORM(vmuloub, 4, 0); GEN_VXFORM(vmulouh, 4, 1); GEN_VXFORM(vmulouw, 4, 2); @@ -1211,7 +1286,7 @@ GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \ vpopcntd, PPC_NONE, PPC2_ALTIVEC_207) GEN_VXFORM(vbpermd, 6, 23); GEN_VXFORM(vbpermq, 6, 21); -GEN_VXFORM_NOA(vgbbd, 6, 20); +GEN_VXFORM_TRANS(vgbbd, 6, 20); GEN_VXFORM(vpmsumb, 4, 16) GEN_VXFORM(vpmsumh, 4, 17) GEN_VXFORM(vpmsumw, 4, 18) From b8313f0d91b192c9415b3c678b387acb77ad112b Mon Sep 17 00:00:00 2001 From: Stefan Brankovic Date: Mon, 15 Jul 2019 16:22:51 +0200 Subject: [PATCH 10/42] target/ppc: Optimize emulation of vclzd instruction Optimize Altivec instruction vclzd (Vector Count Leading Zeros Doubleword). This instruction counts the number of leading zeros of each doubleword element in source register and places result in the appropriate doubleword element of destination register. Using tcg-s count leading zeros instruction two times(once for each doubleword element of source register vB) and placing result in appropriate doubleword element of destination register vD. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-6-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 1 - target/ppc/int_helper.c | 3 --- target/ppc/translate/vmx-impl.inc.c | 28 +++++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 9b486a0c37..e203f76bf1 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -311,7 +311,6 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32) DEF_HELPER_2(vclzb, void, avr, avr) DEF_HELPER_2(vclzh, void, avr, avr) DEF_HELPER_2(vclzw, void, avr, avr) -DEF_HELPER_2(vclzd, void, avr, avr) DEF_HELPER_2(vctzb, void, avr, avr) DEF_HELPER_2(vctzh, void, avr, avr) DEF_HELPER_2(vctzw, void, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index a265cb07c5..b82765db33 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1820,17 +1820,14 @@ VUPK(lsw, s64, s32, UPKLO) #define clzb(v) ((v) ? clz32((uint32_t)(v) << 24) : 8) #define clzh(v) ((v) ? clz32((uint32_t)(v) << 16) : 16) #define clzw(v) clz32((v)) -#define clzd(v) clz64((v)) VGENERIC_DO(clzb, u8) VGENERIC_DO(clzh, u16) VGENERIC_DO(clzw, u32) -VGENERIC_DO(clzd, u64) #undef clzb #undef clzh #undef clzw -#undef clzd #define ctzb(v) ((v) ? ctz32(v) : 8) #define ctzh(v) ((v) ? ctz32(v) : 16) diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 13153352e4..3372c2c3d3 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -742,6 +742,32 @@ static void trans_vgbbd(DisasContext *ctx) tcg_temp_free_i64(avr[1]); } +/* + * vclzd VRT,VRB - Vector Count Leading Zeros Doubleword + * + * Counting the number of leading zero bits of each doubleword element in source + * register and placing result in appropriate doubleword element of destination + * register. + */ +static void trans_vclzd(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i64 avr = tcg_temp_new_i64(); + + /* high doubleword */ + get_avr64(avr, VB, true); + tcg_gen_clzi_i64(avr, avr, 64); + set_avr64(VT, avr, true); + + /* low doubleword */ + get_avr64(avr, VB, false); + tcg_gen_clzi_i64(avr, avr, 64); + set_avr64(VT, avr, false); + + tcg_temp_free_i64(avr); +} + GEN_VXFORM(vmuloub, 4, 0); GEN_VXFORM(vmulouh, 4, 1); GEN_VXFORM(vmulouw, 4, 2); @@ -1258,7 +1284,7 @@ GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) GEN_VXFORM_NOA(vclzb, 1, 28) GEN_VXFORM_NOA(vclzh, 1, 29) GEN_VXFORM_NOA(vclzw, 1, 30) -GEN_VXFORM_NOA(vclzd, 1, 31) +GEN_VXFORM_TRANS(vclzd, 1, 31) GEN_VXFORM_NOA_2(vnegw, 1, 24, 6) GEN_VXFORM_NOA_2(vnegd, 1, 24, 7) GEN_VXFORM_NOA_2(vextsb2w, 1, 24, 16) From 1872588ede5770751ebc0e1df9909c8a785cb549 Mon Sep 17 00:00:00 2001 From: Stefan Brankovic Date: Mon, 15 Jul 2019 16:22:52 +0200 Subject: [PATCH 11/42] target/ppc: Optimize emulation of vclzw instruction Optimize Altivec instruction vclzw (Vector Count Leading Zeros Word). This instruction counts the number of leading zeros of each word element in source register and places result in the appropriate word element of destination register. Counting is to be performed in four iterations of for loop(one for each word elemnt of source register vB). Every iteration consists of loading appropriate word element from source register, counting leading zeros with tcg_gen_clzi_i32, and saving the result in appropriate word element of destination register. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-7-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 1 - target/ppc/int_helper.c | 3 --- target/ppc/translate/vmx-impl.inc.c | 28 +++++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index e203f76bf1..54ea9b9500 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -310,7 +310,6 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32) DEF_HELPER_2(vclzb, void, avr, avr) DEF_HELPER_2(vclzh, void, avr, avr) -DEF_HELPER_2(vclzw, void, avr, avr) DEF_HELPER_2(vctzb, void, avr, avr) DEF_HELPER_2(vctzh, void, avr, avr) DEF_HELPER_2(vctzw, void, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index b82765db33..46deb57a34 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1819,15 +1819,12 @@ VUPK(lsw, s64, s32, UPKLO) #define clzb(v) ((v) ? clz32((uint32_t)(v) << 24) : 8) #define clzh(v) ((v) ? clz32((uint32_t)(v) << 16) : 16) -#define clzw(v) clz32((v)) VGENERIC_DO(clzb, u8) VGENERIC_DO(clzh, u16) -VGENERIC_DO(clzw, u32) #undef clzb #undef clzh -#undef clzw #define ctzb(v) ((v) ? ctz32(v) : 8) #define ctzh(v) ((v) ? ctz32(v) : 16) diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 3372c2c3d3..0d71c10428 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -742,6 +742,32 @@ static void trans_vgbbd(DisasContext *ctx) tcg_temp_free_i64(avr[1]); } +/* + * vclzw VRT,VRB - Vector Count Leading Zeros Word + * + * Counting the number of leading zero bits of each word element in source + * register and placing result in appropriate word element of destination + * register. + */ +static void trans_vclzw(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i32 tmp = tcg_temp_new_i32(); + int i; + + /* Perform count for every word element using tcg_gen_clzi_i32. */ + for (i = 0; i < 4; i++) { + tcg_gen_ld_i32(tmp, cpu_env, + offsetof(CPUPPCState, vsr[32 + VB].u64[0]) + i * 4); + tcg_gen_clzi_i32(tmp, tmp, 32); + tcg_gen_st_i32(tmp, cpu_env, + offsetof(CPUPPCState, vsr[32 + VT].u64[0]) + i * 4); + } + + tcg_temp_free_i32(tmp); +} + /* * vclzd VRT,VRB - Vector Count Leading Zeros Doubleword * @@ -1283,7 +1309,7 @@ GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) GEN_VXFORM_NOA(vclzb, 1, 28) GEN_VXFORM_NOA(vclzh, 1, 29) -GEN_VXFORM_NOA(vclzw, 1, 30) +GEN_VXFORM_TRANS(vclzw, 1, 30) GEN_VXFORM_TRANS(vclzd, 1, 31) GEN_VXFORM_NOA_2(vnegw, 1, 24, 6) GEN_VXFORM_NOA_2(vnegd, 1, 24, 7) From d758880586323da46e3e737eaefb950a7279dfba Mon Sep 17 00:00:00 2001 From: Shivaprasad G Bhat Date: Wed, 17 Jul 2019 03:19:43 -0500 Subject: [PATCH 12/42] ppc: fix memory leak in spapr_caps_add_properties Free the capability name string after setting the capability. Signed-off-by: Shivaprasad G Bhat Message-Id: <156335156198.82682.8756968724044750843.stgit@lep8c.aus.stglabs.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_caps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index a61bf329bf..481dfd2a27 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -793,7 +793,7 @@ void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp) for (i = 0; i < ARRAY_SIZE(capability_table); i++) { SpaprCapabilityInfo *cap = &capability_table[i]; - const char *name = g_strdup_printf("cap-%s", cap->name); + char *name = g_strdup_printf("cap-%s", cap->name); char *desc; object_class_property_add(klass, name, cap->type, @@ -801,11 +801,13 @@ void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp) NULL, cap, &local_err); if (local_err) { error_propagate(errp, local_err); + g_free(name); return; } desc = g_strdup_printf("%s", cap->description); object_class_property_set_description(klass, name, desc, &local_err); + g_free(name); g_free(desc); if (local_err) { error_propagate(errp, local_err); From dbd26f2f7f589994aa2a2ec9740527a5bf201994 Mon Sep 17 00:00:00 2001 From: Shivaprasad G Bhat Date: Wed, 17 Jul 2019 03:20:01 -0500 Subject: [PATCH 13/42] ppc: fix memory leak in spapr_dt_drc() Leaking the drc_name while preparing the DT properties. Fixing that. Also, remove the const qualifier from spapr_drc_name(). Signed-off-by: Shivaprasad G Bhat Message-Id: <156335159028.82682.5404622104535818162.stgit@lep8c.aus.stglabs.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 09255f4951..62f1a42592 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -227,7 +227,7 @@ static uint32_t drc_set_unusable(SpaprDrc *drc) return RTAS_OUT_SUCCESS; } -static const char *spapr_drc_name(SpaprDrc *drc) +static char *spapr_drc_name(SpaprDrc *drc) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); @@ -828,6 +828,7 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask) Object *obj; SpaprDrc *drc; SpaprDrcClass *drck; + char *drc_name = NULL; uint32_t drc_index, drc_power_domain; if (!strstart(prop->type, "link<", NULL)) { @@ -857,8 +858,10 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask) g_array_append_val(drc_power_domains, drc_power_domain); /* ibm,drc-names */ - drc_names = g_string_append(drc_names, spapr_drc_name(drc)); + drc_name = spapr_drc_name(drc); + drc_names = g_string_append(drc_names, drc_name); drc_names = g_string_insert_len(drc_names, -1, "\0", 1); + g_free(drc_name); /* ibm,drc-types */ drc_types = g_string_append(drc_types, drck->typename); From 00005f222973d318a8a4d7bc7a15e251fb8cf604 Mon Sep 17 00:00:00 2001 From: Shivaprasad G Bhat Date: Wed, 17 Jul 2019 03:20:31 -0500 Subject: [PATCH 14/42] ppc: fix leak in h_client_architecture_support Free all SpaprOptionVector local pointers after use. Signed-off-by: Shivaprasad G Bhat Message-Id: <156335160761.82682.11912058325777251614.stgit@lep8c.aus.stglabs.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 225c60a9fc..47b566882b 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1613,6 +1613,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu, ov5_updates = spapr_ovec_new(); spapr->cas_reboot = spapr_ovec_diff(ov5_updates, ov5_cas_old, spapr->ov5_cas); + spapr_ovec_cleanup(ov5_cas_old); /* Now that processing is finished, set the radix/hash bit for the * guest if it requested a valid mode; otherwise terminate the boot. */ if (guest_radix) { @@ -1630,6 +1631,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu, } spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest, OV1_PPC_3_00); + spapr_ovec_cleanup(ov1_guest); if (!spapr->cas_reboot) { /* If spapr_machine_reset() did not set up a HPT but one is necessary * (because the guest isn't going to use radix) then set it up here. */ From 03ef074c04a219188bbd0094ee599bd50a0a374e Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 18 Jul 2019 13:42:11 +1000 Subject: [PATCH 15/42] spapr: Implement dispatch tracking for tcg Implement cpu_exec_enter/exit on ppc which calls into new methods of the same name in PPCVirtualHypervisorClass. These are used by spapr to implement the splpar VPA dispatch counter initially. Signed-off-by: Nicholas Piggin Message-Id: <20190718034214.14948-2-npiggin@gmail.com> [dwg: Removed unnecessary CONFIG_USER_ONLY checks as suggested by gkurz] Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 48 +++++++++++++++++++++++++++++++++ hw/ppc/spapr_hcall.c | 5 ---- include/hw/ppc/spapr.h | 7 +++++ target/ppc/cpu.h | 4 +++ target/ppc/translate_init.inc.c | 27 +++++++++++++++++++ 5 files changed, 86 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 22a45c3737..08cc7c2bd6 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4306,6 +4306,52 @@ PowerPCCPU *spapr_find_cpu(int vcpu_id) return NULL; } +static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) +{ + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + /* These are only called by TCG, KVM maintains dispatch state */ + + if (spapr_cpu->vpa_addr) { + CPUState *cs = CPU(cpu); + uint32_t dispatch; + + dispatch = ldl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER); + dispatch++; + if ((dispatch & 1) != 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "VPA: incorrect dispatch counter value for " + "dispatched partition %u, correcting.\n", dispatch); + dispatch++; + } + stl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER, dispatch); + } +} + +static void spapr_cpu_exec_exit(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) +{ + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + if (spapr_cpu->vpa_addr) { + CPUState *cs = CPU(cpu); + uint32_t dispatch; + + dispatch = ldl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER); + dispatch++; + if ((dispatch & 1) != 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "VPA: incorrect dispatch counter value for " + "preempted partition %u, correcting.\n", dispatch); + dispatch++; + } + stl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER, dispatch); + } +} + static void spapr_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -4362,6 +4408,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) 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; + vhc->cpu_exec_enter = spapr_cpu_exec_enter; + vhc->cpu_exec_exit = spapr_cpu_exec_exit; xic->ics_get = spapr_ics_get; xic->ics_resend = spapr_ics_resend; xic->icp_get = spapr_icp_get; diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 47b566882b..4c5ea17250 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -875,11 +875,6 @@ unmap_out: #define FLAGS_DEREGISTER_DTL 0x0000c00000000000ULL #define FLAGS_DEREGISTER_SLBSHADOW 0x0000e00000000000ULL -#define VPA_MIN_SIZE 640 -#define VPA_SIZE_OFFSET 0x4 -#define VPA_SHARED_PROC_OFFSET 0x9 -#define VPA_SHARED_PROC_VAL 0x2 - static target_ulong register_vpa(PowerPCCPU *cpu, target_ulong vpa) { CPUState *cs = CPU(cpu); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 60553d32c4..5d36eec9d0 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -525,6 +525,13 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, target_ulong *args); +/* Virtual Processor Area structure constants */ +#define VPA_MIN_SIZE 640 +#define VPA_SIZE_OFFSET 0x4 +#define VPA_SHARED_PROC_OFFSET 0x9 +#define VPA_SHARED_PROC_VAL 0x2 +#define VPA_DISPATCH_COUNTER 0x100 + /* ibm,set-eeh-option */ #define RTAS_EEH_DISABLE 0 #define RTAS_EEH_ENABLE 1 diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 630a25c246..50245a8c4d 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1224,6 +1224,10 @@ struct PPCVirtualHypervisorClass { void (*hpte_set_r)(PPCVirtualHypervisor *vhyp, hwaddr ptex, uint64_t pte1); void (*get_pate)(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry); target_ulong (*encode_hpt_for_kvm_pr)(PPCVirtualHypervisor *vhyp); +#ifndef CONFIG_USER_ONLY + void (*cpu_exec_enter)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu); + void (*cpu_exec_exit)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu); +#endif }; #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor" diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 9cd2033bb9..c9fcd87095 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -10469,6 +10469,28 @@ static bool ppc_cpu_is_big_endian(CPUState *cs) return !msr_le; } + +static void ppc_cpu_exec_enter(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->cpu_exec_enter(cpu->vhyp, cpu); + } +} + +static void ppc_cpu_exec_exit(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->cpu_exec_exit(cpu->vhyp, cpu); + } +} #endif static void ppc_cpu_instance_init(Object *obj) @@ -10622,6 +10644,11 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->tcg_initialize = ppc_translate_init; cc->tlb_fill = ppc_cpu_tlb_fill; #endif +#ifndef CONFIG_USER_ONLY + cc->cpu_exec_enter = ppc_cpu_exec_enter; + cc->cpu_exec_exit = ppc_cpu_exec_exit; +#endif + cc->disas_set_info = ppc_disas_set_info; dc->fw_name = "PowerPC,UNKNOWN"; From 3a6e6224a9d8f9637890e9beab14fa63eaf67937 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 18 Jul 2019 13:42:12 +1000 Subject: [PATCH 16/42] spapr: Implement H_PROD H_PROD is added, and H_CEDE is modified to test the prod bit according to PAPR. Signed-off-by: Nicholas Piggin Message-Id: <20190718034214.14948-3-npiggin@gmail.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 1 + hw/ppc/spapr_hcall.c | 32 ++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_cpu_core.h | 1 + 3 files changed, 34 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 08cc7c2bd6..0890c2840f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4312,6 +4312,7 @@ static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) /* These are only called by TCG, KVM maintains dispatch state */ + spapr_cpu->prod = false; if (spapr_cpu->vpa_addr) { CPUState *cs = CPU(cpu); uint32_t dispatch; diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 4c5ea17250..dd584da1ce 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1051,14 +1051,44 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, { CPUPPCState *env = &cpu->env; CPUState *cs = CPU(cpu); + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); env->msr |= (1ULL << MSR_EE); hreg_compute_hflags(env); + + if (spapr_cpu->prod) { + spapr_cpu->prod = false; + return H_SUCCESS; + } + if (!cpu_has_work(cs)) { cs->halted = 1; cs->exception_index = EXCP_HLT; cs->exit_request = 1; } + + return H_SUCCESS; +} + +static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + target_long target = args[0]; + PowerPCCPU *tcpu; + CPUState *cs; + SpaprCpuState *spapr_cpu; + + tcpu = spapr_find_cpu(target); + cs = CPU(tcpu); + if (!cs) { + return H_PARAMETER; + } + + spapr_cpu = spapr_cpu_state(tcpu); + spapr_cpu->prod = true; + cs->halted = 0; + qemu_cpu_kick(cs); + return H_SUCCESS; } @@ -1885,6 +1915,8 @@ static void hypercall_register_types(void) /* hcall-splpar */ spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); spapr_register_hypercall(H_CEDE, h_cede); + spapr_register_hypercall(H_PROD, h_prod); + spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); /* processor register resource access h-calls */ diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index 35e0a7eead..1c4cc6559c 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -46,6 +46,7 @@ typedef struct SpaprCpuState { uint64_t vpa_addr; uint64_t slb_shadow_addr, slb_shadow_size; uint64_t dtl_addr, dtl_size; + bool prod; /* not migrated, only used to improve dispatch latencies */ struct ICPState *icp; struct XiveTCTX *tctx; } SpaprCpuState; From e8ce0e40ee9494b789cb36260a6cf07bbef83cd0 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 18 Jul 2019 13:42:13 +1000 Subject: [PATCH 17/42] spapr: Implement H_CONFER This does not do directed yielding and is not quite as strict as PAPR specifies in terms of precise dispatch behaviour. This generally will mean suboptimal performance, rather than guest misbehaviour. Linux does not rely on exact dispatch behaviour. Signed-off-by: Nicholas Piggin Message-Id: <20190718034214.14948-4-npiggin@gmail.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index dd584da1ce..eb54b96097 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1070,6 +1070,72 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, return H_SUCCESS; } +static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + target_long target = args[0]; + uint32_t dispatch = args[1]; + CPUState *cs = CPU(cpu); + SpaprCpuState *spapr_cpu; + + /* + * -1 means confer to all other CPUs without dispatch counter check, + * otherwise it's a targeted confer. + */ + if (target != -1) { + PowerPCCPU *target_cpu = spapr_find_cpu(target); + uint32_t target_dispatch; + + if (!target_cpu) { + return H_PARAMETER; + } + + spapr_cpu = spapr_cpu_state(target_cpu); + + /* + * target == self is a special case, we wait until prodded, without + * dispatch counter check. + */ + if (cpu == target_cpu) { + if (spapr_cpu->prod) { + spapr_cpu->prod = false; + + return H_SUCCESS; + } + + cs->halted = 1; + cs->exception_index = EXCP_HALTED; + cs->exit_request = 1; + + return H_SUCCESS; + } + + if (!spapr_cpu->vpa_addr || ((dispatch & 1) == 0)) { + return H_SUCCESS; + } + + target_dispatch = ldl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER); + if (target_dispatch != dispatch) { + return H_SUCCESS; + } + + /* + * The targeted confer does not do anything special beyond yielding + * the current vCPU, but even this should be better than nothing. + * At least for single-threaded tcg, it gives the target a chance to + * run before we run again. Multi-threaded tcg does not really do + * anything with EXCP_YIELD yet. + */ + } + + cs->exception_index = EXCP_YIELD; + cs->exit_request = 1; + cpu_loop_exit(cs); + + return H_SUCCESS; +} + static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -1915,6 +1981,7 @@ static void hypercall_register_types(void) /* hcall-splpar */ spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); spapr_register_hypercall(H_CEDE, h_cede); + spapr_register_hypercall(H_CONFER, h_confer); spapr_register_hypercall(H_PROD, h_prod); spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); From 107413142bf34aecdea2398a3e976739f1256c64 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 18 Jul 2019 13:42:14 +1000 Subject: [PATCH 18/42] spapr: Implement H_JOIN This has been useful to modify and test the Linux pseries suspend code but it requires modification to the guest to call it (due to being gated by other unimplemented features). It is not otherwise used by Linux yet, but work is slowly progressing there. Signed-off-by: Nicholas Piggin Message-Id: <20190718034214.14948-5-npiggin@gmail.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 1 + hw/ppc/spapr_hcall.c | 74 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0890c2840f..15e27d9a10 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1070,6 +1070,7 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt) add_str(hypertas, "hcall-tce"); add_str(hypertas, "hcall-vio"); add_str(hypertas, "hcall-splpar"); + add_str(hypertas, "hcall-join"); add_str(hypertas, "hcall-bulk"); add_str(hypertas, "hcall-set-mode"); add_str(hypertas, "hcall-sprg0"); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index eb54b96097..10c0b53339 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1070,6 +1070,62 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, return H_SUCCESS; } +/* + * Confer to self, aka join. Cede could use the same pattern as well, if + * EXCP_HLT can be changed to ECXP_HALTED. + */ +static target_ulong h_confer_self(PowerPCCPU *cpu) +{ + CPUState *cs = CPU(cpu); + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + if (spapr_cpu->prod) { + spapr_cpu->prod = false; + return H_SUCCESS; + } + cs->halted = 1; + cs->exception_index = EXCP_HALTED; + cs->exit_request = 1; + + return H_SUCCESS; +} + +static target_ulong h_join(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + CPUPPCState *env = &cpu->env; + CPUState *cs; + bool last_unjoined = true; + + if (env->msr & (1ULL << MSR_EE)) { + return H_BAD_MODE; + } + + /* + * Must not join the last CPU running. Interestingly, no such restriction + * for H_CONFER-to-self, but that is probably not intended to be used + * when H_JOIN is available. + */ + CPU_FOREACH(cs) { + PowerPCCPU *c = POWERPC_CPU(cs); + CPUPPCState *e = &c->env; + if (c == cpu) { + continue; + } + + /* Don't have a way to indicate joined, so use halted && MSR[EE]=0 */ + if (!cs->halted || (e->msr & (1ULL << MSR_EE))) { + last_unjoined = false; + break; + } + } + if (last_unjoined) { + return H_CONTINUE; + } + + return h_confer_self(cpu); +} + static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -1090,26 +1146,15 @@ static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr, return H_PARAMETER; } - spapr_cpu = spapr_cpu_state(target_cpu); - /* * target == self is a special case, we wait until prodded, without * dispatch counter check. */ if (cpu == target_cpu) { - if (spapr_cpu->prod) { - spapr_cpu->prod = false; - - return H_SUCCESS; - } - - cs->halted = 1; - cs->exception_index = EXCP_HALTED; - cs->exit_request = 1; - - return H_SUCCESS; + return h_confer_self(cpu); } + spapr_cpu = spapr_cpu_state(target_cpu); if (!spapr_cpu->vpa_addr || ((dispatch & 1) == 0)) { return H_SUCCESS; } @@ -1984,6 +2029,9 @@ static void hypercall_register_types(void) spapr_register_hypercall(H_CONFER, h_confer); spapr_register_hypercall(H_PROD, h_prod); + /* hcall-join */ + spapr_register_hypercall(H_JOIN, h_join); + spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); /* processor register resource access h-calls */ From 1daba4d1b296d23907b73735615b12588da670fb Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Wed, 17 Jul 2019 15:58:41 -0500 Subject: [PATCH 19/42] docs/specs: initial spec summary for Ultravisor-related hcalls For now this only covers hcalls relating to TPM communication since it's the only one particularly important from a QEMU perspective atm, but others can be added here where it makes sense. The full specification for all hcalls/ucalls will eventually be made available in the public/OpenPower version of the PAPR specification. Signed-off-by: Michael Roth Message-Id: <20190717205842.17827-2-mdroth@linux.vnet.ibm.com> Signed-off-by: David Gibson --- docs/specs/ppc-spapr-uv-hcalls.txt | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 docs/specs/ppc-spapr-uv-hcalls.txt diff --git a/docs/specs/ppc-spapr-uv-hcalls.txt b/docs/specs/ppc-spapr-uv-hcalls.txt new file mode 100644 index 0000000000..389c2740d7 --- /dev/null +++ b/docs/specs/ppc-spapr-uv-hcalls.txt @@ -0,0 +1,76 @@ +On PPC64 systems supporting Protected Execution Facility (PEF), system +memory can be placed in a secured region where only an "ultravisor" +running in firmware can provide to access it. pseries guests on such +systems can communicate with the ultravisor (via ultracalls) to switch to a +secure VM mode (SVM) where the guest's memory is relocated to this secured +region, making its memory inaccessible to normal processes/guests running on +the host. + +The various ultracalls/hypercalls relating to SVM mode are currently +only documented internally, but are planned for direct inclusion into the +public OpenPOWER version of the PAPR specification (LoPAPR/LoPAR). An internal +ACR has been filed to reserve a hypercall number range specific to this +use-case to avoid any future conflicts with the internally-maintained PAPR +specification. This document summarizes some of these details as they relate +to QEMU. + +== hypercalls needed by the ultravisor == + +Switching to SVM mode involves a number of hcalls issued by the ultravisor +to the hypervisor to orchestrate the movement of guest memory to secure +memory and various other aspects SVM mode. Numbers are assigned for these +hcalls within the reserved range 0xEF00-0xEF80. The below documents the +hcalls relevant to QEMU. + +- H_TPM_COMM (0xef10) + + For TPM_COMM_OP_EXECUTE operation: + Send a request to a TPM and receive a response, opening a new TPM session + if one has not already been opened. + + For TPM_COMM_OP_CLOSE_SESSION operation: + Close the existing TPM session, if any. + + Arguments: + + r3 : H_TPM_COMM (0xef10) + r4 : TPM operation, one of: + TPM_COMM_OP_EXECUTE (0x1) + TPM_COMM_OP_CLOSE_SESSION (0x2) + r5 : in_buffer, guest physical address of buffer containing the request + - Caller may use the same address for both request and response + r6 : in_size, size of the in buffer + - Must be less than or equal to 4KB + r7 : out_buffer, guest physical address of buffer to store the response + - Caller may use the same address for both request and response + r8 : out_size, size of the out buffer + - Must be at least 4KB, as this is the maximum request/response size + supported by most TPM implementations, including the TPM Resource + Manager in the linux kernel. + + Return values: + + r3 : H_Success request processed successfully + H_PARAMETER invalid TPM operation + H_P2 in_buffer is invalid + H_P3 in_size is invalid + H_P4 out_buffer is invalid + H_P5 out_size is invalid + H_RESOURCE problem communicating with TPM + H_FUNCTION TPM access is not currently allowed/configured + r4 : For TPM_COMM_OP_EXECUTE, the size of the response will be stored here + upon success. + + Use-case/notes: + + SVM filesystems are encrypted using a symmetric key. This key is then + wrapped/encrypted using the public key of a trusted system which has the + private key stored in the system's TPM. An Ultravisor will use this + hcall to unwrap/unseal the symmetric key using the system's TPM device + or a TPM Resource Manager associated with the device. + + The Ultravisor sets up a separate session key with the TPM in advance + during host system boot. All sensitive in and out values will be + encrypted using the session key. Though the hypervisor will see the 'in' + and 'out' buffers in raw form, any sensitive contents will generally be + encrypted using this session key. From 0fb6bd07323019dc8d3f2c124323f71e2ddfc9f4 Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Wed, 17 Jul 2019 15:58:42 -0500 Subject: [PATCH 20/42] spapr: initial implementation for H_TPM_COMM/spapr-tpm-proxy This implements the H_TPM_COMM hypercall, which is used by an Ultravisor to pass TPM commands directly to the host's TPM device, or a TPM Resource Manager associated with the device. This also introduces a new virtual device, spapr-tpm-proxy, which is used to configure the host TPM path to be used to service requests sent by H_TPM_COMM hcalls, for example: -device spapr-tpm-proxy,id=tpmp0,host-path=/dev/tpmrm0 By default, no spapr-tpm-proxy will be created, and hcalls will return H_FUNCTION. The full specification for this hypercall can be found in docs/specs/ppc-spapr-uv-hcalls.txt Since SVM-related hcalls like H_TPM_COMM use a reserved range of 0xEF00-0xEF80, we introduce a separate hcall table here to handle them. Signed-off-by: Michael Roth [dwg: Corrected #include for upstream change] Signed-off-by: David Gibson --- hw/ppc/Makefile.objs | 1 + hw/ppc/spapr.c | 33 +++++- hw/ppc/spapr_hcall.c | 13 +++ hw/ppc/spapr_tpm_proxy.c | 178 +++++++++++++++++++++++++++++++ hw/ppc/trace-events | 4 + include/hw/ppc/spapr.h | 11 ++ include/hw/ppc/spapr_tpm_proxy.h | 31 ++++++ 7 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 hw/ppc/spapr_tpm_proxy.c create mode 100644 include/hw/ppc/spapr_tpm_proxy.h diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index 9da93af905..2c4e1c8de0 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -5,6 +5,7 @@ obj-$(CONFIG_PSERIES) += spapr.o spapr_caps.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o spapr_irq.o +obj-$(CONFIG_PSERIES) += spapr_tpm_proxy.o obj-$(CONFIG_SPAPR_RNG) += spapr_rng.o # IBM PowerNV obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o pnv_occ.o pnv_bmc.o diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 15e27d9a10..56b33571c5 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -79,6 +79,7 @@ #include "qemu/cutils.h" #include "hw/ppc/spapr_cpu_core.h" #include "hw/mem/memory-device.h" +#include "hw/ppc/spapr_tpm_proxy.h" #include @@ -4036,6 +4037,29 @@ static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev, } } +static void spapr_tpm_proxy_plug(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) +{ + SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); + SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(dev); + + if (spapr->tpm_proxy != NULL) { + error_setg(errp, "Only one TPM proxy can be specified for this machine"); + return; + } + + spapr->tpm_proxy = tpm_proxy; +} + +static void spapr_tpm_proxy_unplug(HotplugHandler *hotplug_dev, DeviceState *dev) +{ + SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); + + object_property_set_bool(OBJECT(dev), false, "realized", NULL); + object_unparent(OBJECT(dev)); + spapr->tpm_proxy = NULL; +} + static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -4045,6 +4069,8 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, spapr_core_plug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) { spapr_phb_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) { + spapr_tpm_proxy_plug(hotplug_dev, dev, errp); } } @@ -4057,6 +4083,8 @@ static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, spapr_core_unplug(hotplug_dev, dev); } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) { spapr_phb_unplug(hotplug_dev, dev); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) { + spapr_tpm_proxy_unplug(hotplug_dev, dev); } } @@ -4091,6 +4119,8 @@ static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev, return; } spapr_phb_unplug_request(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) { + spapr_tpm_proxy_unplug(hotplug_dev, dev); } } @@ -4111,7 +4141,8 @@ static HotplugHandler *spapr_get_hotplug_handler(MachineState *machine, { if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE) || - object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) { + object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE) || + object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) { return HOTPLUG_HANDLER(machine); } if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 10c0b53339..e20a946b99 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1963,6 +1963,7 @@ static target_ulong h_update_dt(PowerPCCPU *cpu, SpaprMachineState *spapr, static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1]; static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1]; +static spapr_hcall_fn svm_hypercall_table[(SVM_HCALL_MAX - SVM_HCALL_BASE) / 4 + 1]; void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) { @@ -1972,6 +1973,11 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) assert((opcode & 0x3) == 0); slot = &papr_hypercall_table[opcode / 4]; + } else if (opcode >= SVM_HCALL_BASE && opcode <= SVM_HCALL_MAX) { + /* we only have SVM-related hcall numbers assigned in multiples of 4 */ + assert((opcode & 0x3) == 0); + + slot = &svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4]; } else { assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX)); @@ -1991,6 +1997,13 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, && ((opcode & 0x3) == 0)) { spapr_hcall_fn fn = papr_hypercall_table[opcode / 4]; + if (fn) { + return fn(cpu, spapr, opcode, args); + } + } else if ((opcode >= SVM_HCALL_BASE) && + (opcode <= SVM_HCALL_MAX)) { + spapr_hcall_fn fn = svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4]; + if (fn) { return fn(cpu, spapr, opcode, args); } diff --git a/hw/ppc/spapr_tpm_proxy.c b/hw/ppc/spapr_tpm_proxy.c new file mode 100644 index 0000000000..b835d25be6 --- /dev/null +++ b/hw/ppc/spapr_tpm_proxy.c @@ -0,0 +1,178 @@ +/* + * SPAPR TPM Proxy/Hypercall + * + * Copyright IBM Corp. 2019 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "sysemu/reset.h" +#include "cpu.h" +#include "hw/ppc/spapr.h" +#include "hw/qdev-properties.h" +#include "trace.h" + +#define TPM_SPAPR_BUFSIZE 4096 + +enum { + TPM_COMM_OP_EXECUTE = 1, + TPM_COMM_OP_CLOSE_SESSION = 2, +}; + +static void spapr_tpm_proxy_reset(void *opaque) +{ + SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(opaque); + + if (tpm_proxy->host_fd != -1) { + close(tpm_proxy->host_fd); + tpm_proxy->host_fd = -1; + } +} + +static ssize_t tpm_execute(SpaprTpmProxy *tpm_proxy, target_ulong *args) +{ + uint64_t data_in = ppc64_phys_to_real(args[1]); + target_ulong data_in_size = args[2]; + uint64_t data_out = ppc64_phys_to_real(args[3]); + target_ulong data_out_size = args[4]; + uint8_t buf_in[TPM_SPAPR_BUFSIZE]; + uint8_t buf_out[TPM_SPAPR_BUFSIZE]; + ssize_t ret; + + trace_spapr_tpm_execute(data_in, data_in_size, data_out, data_out_size); + + if (data_in_size > TPM_SPAPR_BUFSIZE) { + error_report("invalid TPM input buffer size: " TARGET_FMT_lu, + data_in_size); + return H_P3; + } + + if (data_out_size < TPM_SPAPR_BUFSIZE) { + error_report("invalid TPM output buffer size: " TARGET_FMT_lu, + data_out_size); + return H_P5; + } + + if (tpm_proxy->host_fd == -1) { + tpm_proxy->host_fd = open(tpm_proxy->host_path, O_RDWR); + if (tpm_proxy->host_fd == -1) { + error_report("failed to open TPM device %s: %d", + tpm_proxy->host_path, errno); + return H_RESOURCE; + } + } + + cpu_physical_memory_read(data_in, buf_in, data_in_size); + + do { + ret = write(tpm_proxy->host_fd, buf_in, data_in_size); + if (ret > 0) { + data_in_size -= ret; + } + } while ((ret >= 0 && data_in_size > 0) || (ret == -1 && errno == EINTR)); + + if (ret == -1) { + error_report("failed to write to TPM device %s: %d", + tpm_proxy->host_path, errno); + return H_RESOURCE; + } + + do { + ret = read(tpm_proxy->host_fd, buf_out, data_out_size); + } while (ret == 0 || (ret == -1 && errno == EINTR)); + + if (ret == -1) { + error_report("failed to read from TPM device %s: %d", + tpm_proxy->host_path, errno); + return H_RESOURCE; + } + + cpu_physical_memory_write(data_out, buf_out, ret); + args[0] = ret; + + return H_SUCCESS; +} + +static target_ulong h_tpm_comm(PowerPCCPU *cpu, + SpaprMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong op = args[0]; + SpaprTpmProxy *tpm_proxy = spapr->tpm_proxy; + + if (!tpm_proxy) { + error_report("TPM proxy not available"); + return H_FUNCTION; + } + + trace_spapr_h_tpm_comm(tpm_proxy->host_path ?: "null", op); + + switch (op) { + case TPM_COMM_OP_EXECUTE: + return tpm_execute(tpm_proxy, args); + case TPM_COMM_OP_CLOSE_SESSION: + spapr_tpm_proxy_reset(tpm_proxy); + return H_SUCCESS; + default: + return H_PARAMETER; + } +} + +static void spapr_tpm_proxy_realize(DeviceState *d, Error **errp) +{ + SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(d); + + if (tpm_proxy->host_path == NULL) { + error_setg(errp, "must specify 'host-path' option for device"); + return; + } + + tpm_proxy->host_fd = -1; + qemu_register_reset(spapr_tpm_proxy_reset, tpm_proxy); +} + +static void spapr_tpm_proxy_unrealize(DeviceState *d, Error **errp) +{ + SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(d); + + qemu_unregister_reset(spapr_tpm_proxy_reset, tpm_proxy); +} + +static Property spapr_tpm_proxy_properties[] = { + DEFINE_PROP_STRING("host-path", SpaprTpmProxy, host_path), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_tpm_proxy_class_init(ObjectClass *k, void *data) +{ + DeviceClass *dk = DEVICE_CLASS(k); + + dk->realize = spapr_tpm_proxy_realize; + dk->unrealize = spapr_tpm_proxy_unrealize; + dk->user_creatable = true; + dk->props = spapr_tpm_proxy_properties; +} + +static const TypeInfo spapr_tpm_proxy_info = { + .name = TYPE_SPAPR_TPM_PROXY, + .parent = TYPE_DEVICE, + .instance_size = sizeof(SpaprTpmProxy), + .class_init = spapr_tpm_proxy_class_init, +}; + +static void spapr_tpm_proxy_register_types(void) +{ + type_register_static(&spapr_tpm_proxy_info); + spapr_register_hypercall(SVM_H_TPM_COMM, h_tpm_comm); +} + +type_init(spapr_tpm_proxy_register_types) diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index f76448f532..96dad767a1 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -25,6 +25,10 @@ spapr_update_dt(unsigned cb) "New blob %u bytes" spapr_update_dt_failed_size(unsigned cbold, unsigned cbnew, unsigned magic) "Old blob %u bytes, new blob %u bytes, magic 0x%x" spapr_update_dt_failed_check(unsigned cbold, unsigned cbnew, unsigned magic) "Old blob %u bytes, new blob %u bytes, magic 0x%x" +# spapr_hcall_tpm.c +spapr_h_tpm_comm(const char *device_path, uint64_t operation) "tpm_device_path=%s operation=0x%"PRIu64 +spapr_tpm_execute(uint64_t data_in, uint64_t data_in_sz, uint64_t data_out, uint64_t data_out_sz) "data_in=0x%"PRIx64", data_in_sz=%"PRIu64", data_out=0x%"PRIx64", data_out_sz=%"PRIu64 + # spapr_iommu.c spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=0x%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64 spapr_iommu_get(uint64_t liobn, uint64_t ioba, uint64_t ret, uint64_t tce) "liobn=0x%"PRIx64" ioba=0x%"PRIx64" ret=%"PRId64" tce=0x%"PRIx64 diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 5d36eec9d0..c79bc6a123 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -10,6 +10,7 @@ #include "hw/ppc/spapr_irq.h" #include "hw/ppc/spapr_xive.h" /* For SpaprXive */ #include "hw/ppc/xics.h" /* For ICSState */ +#include "hw/ppc/spapr_tpm_proxy.h" struct SpaprVioBus; struct SpaprPhbState; @@ -203,6 +204,7 @@ struct SpaprMachineState { SpaprCapabilities def, eff, mig; unsigned gpu_numa_id; + SpaprTpmProxy *tpm_proxy; }; #define H_SUCCESS 0 @@ -508,6 +510,15 @@ struct SpaprMachineState { #define KVMPPC_H_UPDATE_DT (KVMPPC_HCALL_BASE + 0x3) #define KVMPPC_HCALL_MAX KVMPPC_H_UPDATE_DT +/* + * The hcall range 0xEF00 to 0xEF80 is reserved for use in facilitating + * Secure VM mode via an Ultravisor / Protected Execution Facility + */ +#define SVM_HCALL_BASE 0xEF00 +#define SVM_H_TPM_COMM 0xEF10 +#define SVM_HCALL_MAX SVM_H_TPM_COMM + + typedef struct SpaprDeviceTreeUpdateHeader { uint32_t version_id; } SpaprDeviceTreeUpdateHeader; diff --git a/include/hw/ppc/spapr_tpm_proxy.h b/include/hw/ppc/spapr_tpm_proxy.h new file mode 100644 index 0000000000..c574e22ba4 --- /dev/null +++ b/include/hw/ppc/spapr_tpm_proxy.h @@ -0,0 +1,31 @@ +/* + * SPAPR TPM Proxy/Hypercall + * + * Copyright IBM Corp. 2019 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_SPAPR_TPM_PROXY_H +#define HW_SPAPR_TPM_PROXY_H + +#include "qom/object.h" +#include "hw/qdev-core.h" + +#define TYPE_SPAPR_TPM_PROXY "spapr-tpm-proxy" +#define SPAPR_TPM_PROXY(obj) OBJECT_CHECK(SpaprTpmProxy, (obj), \ + TYPE_SPAPR_TPM_PROXY) + +typedef struct SpaprTpmProxy { + /*< private >*/ + DeviceState parent; + + char *host_path; + int host_fd; +} SpaprTpmProxy; + +#endif /* HW_SPAPR_TPM_PROXY_H */ From 316f239c294101d63a2b336c86c7970d8ae15213 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 19 Jul 2019 11:47:59 +1000 Subject: [PATCH 21/42] pseries: Update SLOF firmware image The only change that SLOF does not rely on QEMU providing an RTAS blob and provides one itself: https://git.qemu.org/?p=SLOF.git;a=commitdiff;h=5e4ed1fd0f39e Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- pc-bios/README | 2 +- pc-bios/slof.bin | Bin 926432 -> 926784 bytes roms/SLOF | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index 68b4a81103..d59cd25461 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20190703. + built from git tag qemu-slof-20190719. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index 2def51471772b6091bc5dc19b3bb136dddd201b2..fb0837508be2e398054fe9837682f5eff18875ad 100644 GIT binary patch delta 215196 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

sjo1Ct%nAQY^w*oNkS6ABE>c6N^7t&k`# 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Ïqu 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 Date: Thu, 18 Jul 2019 13:54:04 +0200 Subject: [PATCH 22/42] ppc/xive: use an abstract type for XiveNotifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-2-clg@kaod.org> Signed-off-by: David Gibson --- include/hw/ppc/xive.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 9399c77d2d..ea6ae34375 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -148,13 +148,11 @@ * XIVE Notifier (Interface between Source and Router) */ -typedef struct XiveNotifier { - Object parent; -} XiveNotifier; +typedef struct XiveNotifier XiveNotifier; #define TYPE_XIVE_NOTIFIER "xive-notifier" #define XIVE_NOTIFIER(obj) \ - OBJECT_CHECK(XiveNotifier, (obj), TYPE_XIVE_NOTIFIER) + INTERFACE_CHECK(XiveNotifier, (obj), TYPE_XIVE_NOTIFIER) #define XIVE_NOTIFIER_CLASS(klass) \ OBJECT_CLASS_CHECK(XiveNotifierClass, (klass), TYPE_XIVE_NOTIFIER) #define XIVE_NOTIFIER_GET_CLASS(obj) \ From d98ec603c6587075a17820f07cada988a9a675bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Thu, 18 Jul 2019 13:54:06 +0200 Subject: [PATCH 23/42] ppc/xive: Implement TM_PULL_OS_CTX special command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a vCPU is not dispatched anymore on a HW thread, the Hypervisor (KVM on Linux) invalidates the OS interrupt context of a vCPU with this special command. It returns the OS CAM line value and resets the VO bit. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-4-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 7a6e4b763a..ab7ce64a83 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -337,6 +337,17 @@ static void xive_tm_set_os_pending(XiveTCTX *tctx, hwaddr offset, xive_tctx_notify(tctx, TM_QW1_OS); } +static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr offset, + unsigned size) +{ + uint32_t qw1w2_prev = xive_tctx_word2(&tctx->regs[TM_QW1_OS]); + uint32_t qw1w2; + + qw1w2 = xive_set_field32(TM_QW1W2_VO, qw1w2_prev, 0); + memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4); + return qw1w2; +} + /* * Define a mapping of "special" operations depending on the TIMA page * offset and the size of the operation. @@ -363,6 +374,8 @@ static const XiveTmOp xive_tm_operations[] = { /* MMIOs above 2K : special operations with side effects */ { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, NULL, xive_tm_ack_os_reg }, { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL }, + { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX, 4, NULL, xive_tm_pull_os_ctx }, + { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX, 8, NULL, xive_tm_pull_os_ctx }, { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG, 2, NULL, xive_tm_ack_hv_reg }, { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 4, NULL, xive_tm_pull_pool_ctx }, { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 8, NULL, xive_tm_pull_pool_ctx }, @@ -406,7 +419,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value, if (offset & 0x800) { xto = xive_tm_find_op(offset, size, true); if (!xto) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA" + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA " "@%"HWADDR_PRIx"\n", offset); } else { xto->write_handler(tctx, offset, value, size); From 52c5acf04ee0f111657c03916db13ff325c58866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Thu, 18 Jul 2019 13:54:07 +0200 Subject: [PATCH 24/42] ppc/xive: Provide backlog support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If backlog is activated ('b' bit) on the END, the pending priority of a missed event is recorded in the IPB field of the NVT for a later resend. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-5-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 77 +++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index ab7ce64a83..f27b4e3328 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1411,46 +1411,22 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format, * * The parameters represent what is sent on the PowerBus */ -static void xive_presenter_notify(XiveRouter *xrtr, uint8_t format, +static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, bool cam_ignore, uint8_t priority, uint32_t logic_serv) { - XiveNVT nvt; XiveTCTXMatch match = { .tctx = NULL, .ring = 0 }; bool found; - /* NVT cache lookup */ - if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, &nvt)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVT %x/%x\n", - nvt_blk, nvt_idx); - return; - } - - if (!xive_nvt_is_valid(&nvt)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is invalid\n", - nvt_blk, nvt_idx); - return; - } - found = xive_presenter_match(xrtr, format, nvt_blk, nvt_idx, cam_ignore, priority, logic_serv, &match); if (found) { ipb_update(&match.tctx->regs[match.ring], priority); xive_tctx_notify(match.tctx, match.ring); - return; } - /* Record the IPB in the associated NVT structure */ - ipb_update((uint8_t *) &nvt.w4, priority); - xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4); - - /* - * If no matching NVT is dispatched on a HW thread : - * - update the NVT structure if backlog is activated - * - escalate (ESe PQ bits and EAS in w4-5) if escalation is - * activated - */ + return found; } /* @@ -1464,6 +1440,10 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, XiveEND end; uint8_t priority; uint8_t format; + uint8_t nvt_blk; + uint32_t nvt_idx; + XiveNVT nvt; + bool found; /* END cache lookup */ if (xive_router_get_end(xrtr, end_blk, end_idx, &end)) { @@ -1522,14 +1502,53 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, /* * Follows IVPE notification */ - xive_presenter_notify(xrtr, format, - xive_get_field32(END_W6_NVT_BLOCK, end.w6), - xive_get_field32(END_W6_NVT_INDEX, end.w6), + nvt_blk = xive_get_field32(END_W6_NVT_BLOCK, end.w6); + nvt_idx = xive_get_field32(END_W6_NVT_INDEX, end.w6); + + /* NVT cache lookup */ + if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, &nvt)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVT %x/%x\n", + nvt_blk, nvt_idx); + return; + } + + if (!xive_nvt_is_valid(&nvt)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is invalid\n", + nvt_blk, nvt_idx); + return; + } + + found = xive_presenter_notify(xrtr, format, nvt_blk, nvt_idx, xive_get_field32(END_W7_F0_IGNORE, end.w7), priority, xive_get_field32(END_W7_F1_LOG_SERVER_ID, end.w7)); /* TODO: Auto EOI. */ + + if (found) { + return; + } + + /* + * If no matching NVT is dispatched on a HW thread : + * - specific VP: update the NVT structure if backlog is activated + * - logical server : forward request to IVPE (not supported) + */ + if (xive_end_is_backlog(&end)) { + if (format == 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "XIVE: END %x/%x invalid config: F1 & backlog\n", + end_blk, end_idx); + return; + } + /* Record the IPB in the associated NVT structure */ + ipb_update((uint8_t *) &nvt.w4, priority); + xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4); + + /* + * On HW, follows a "Broadcast Backlog" to IVPEs + */ + } } void xive_router_notify(XiveNotifier *xn, uint32_t lisn) From b4e3066684ea9379e09c8c6b0902eceb939fa97c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Thu, 18 Jul 2019 13:54:08 +0200 Subject: [PATCH 25/42] ppc/xive: Provide escalation support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the XIVE presenter can not find the NVT dispatched on any of the HW threads, it can not deliver the interrupt. XIVE offers an escalation mechanism to handle such scenarios and inform the hypervisor that an action should be taken. Escalation is configured by setting the 'e' bit and the EAS in word 4 & 5 to let the HW look for the escalation END on which to trigger a new event. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-6-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index f27b4e3328..12f0d09df6 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1549,6 +1549,22 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, * On HW, follows a "Broadcast Backlog" to IVPEs */ } + + /* + * If activated, escalate notification using the ESe PQ bits and + * the EAS in w4-5 + */ + if (!xive_end_is_escalate(&end)) { + return; + } + + /* + * The END trigger becomes an Escalation trigger + */ + xive_router_end_notify(xrtr, + xive_get_field32(END_W4_ESC_END_BLOCK, end.w4), + xive_get_field32(END_W4_ESC_END_INDEX, end.w4), + xive_get_field32(END_W5_ESC_END_DATA, end.w5)); } void xive_router_notify(XiveNotifier *xn, uint32_t lisn) From 53e934921d660be951167fccad4b6302c4633486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Thu, 18 Jul 2019 13:54:09 +0200 Subject: [PATCH 26/42] ppc/xive: Provide unconditional escalation support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the 'u' bit is set the escalation is said to be 'unconditional' which means that the ESe PQ bits are not used. Introduce a xive_router_end_es_notify() routine to share code with the ESn notification. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-7-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 44 ++++++++++++++++++++++++++++++-------- include/hw/ppc/xive_regs.h | 2 ++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 12f0d09df6..3fe84f3e76 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1429,6 +1429,27 @@ static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format, return found; } +/* + * Notification using the END ESe/ESn bit (Event State Buffer for + * escalation and notification). Profide futher coalescing in the + * Router. + */ +static bool xive_router_end_es_notify(XiveRouter *xrtr, uint8_t end_blk, + uint32_t end_idx, XiveEND *end, + uint32_t end_esmask) +{ + uint8_t pq = xive_get_field32(end_esmask, end->w1); + bool notify = xive_esb_trigger(&pq); + + if (pq != xive_get_field32(end_esmask, end->w1)) { + end->w1 = xive_set_field32(end_esmask, end->w1, pq); + xive_router_write_end(xrtr, end_blk, end_idx, end, 1); + } + + /* ESe/n[Q]=1 : end of notification */ + return notify; +} + /* * An END trigger can come from an event trigger (IPI or HW) or from * another chip. We don't model the PowerBus but the END trigger @@ -1485,16 +1506,9 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, * even futher coalescing in the Router */ if (!xive_end_is_notify(&end)) { - uint8_t pq = xive_get_field32(END_W1_ESn, end.w1); - bool notify = xive_esb_trigger(&pq); - - if (pq != xive_get_field32(END_W1_ESn, end.w1)) { - end.w1 = xive_set_field32(END_W1_ESn, end.w1, pq); - xive_router_write_end(xrtr, end_blk, end_idx, &end, 1); - } - /* ESn[Q]=1 : end of notification */ - if (!notify) { + if (!xive_router_end_es_notify(xrtr, end_blk, end_idx, + &end, END_W1_ESn)) { return; } } @@ -1558,6 +1572,18 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, return; } + /* + * Check the END ESe (Event State Buffer for escalation) for even + * futher coalescing in the Router + */ + if (!xive_end_is_uncond_escalation(&end)) { + /* ESe[Q]=1 : end of notification */ + if (!xive_router_end_es_notify(xrtr, end_blk, end_idx, + &end, END_W1_ESe)) { + return; + } + } + /* * The END trigger becomes an Escalation trigger */ diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index b0c68ab5f7..4378d7259c 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -210,6 +210,8 @@ typedef struct XiveEND { #define xive_end_is_notify(end) (be32_to_cpu((end)->w0) & END_W0_UCOND_NOTIFY) #define xive_end_is_backlog(end) (be32_to_cpu((end)->w0) & END_W0_BACKLOG) #define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) & END_W0_ESCALATE_CTL) +#define xive_end_is_uncond_escalation(end) \ + (be32_to_cpu((end)->w0) & END_W0_UNCOND_ESCALATE) static inline uint64_t xive_end_qaddr(XiveEND *end) { From ad31e2d242399bdaa300b940bbef253331c92ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Thu, 18 Jul 2019 13:54:10 +0200 Subject: [PATCH 27/42] ppc/xive: Provide silent escalation support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the 's' bit is set the escalation is said to be 'silent' or 'silent/gather'. In such configuration, the notification sequence is skipped and only the escalation sequence is performed. This is used to configure all the EQs of a vCPU to escalate on a single EQ which will then target the hypervisor. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-8-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 8 ++++++++ include/hw/ppc/xive_regs.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 3fe84f3e76..dd7d02dfdf 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1485,6 +1485,13 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, xive_router_write_end(xrtr, end_blk, end_idx, &end, 1); } + /* + * When the END is silent, we skip the notification part. + */ + if (xive_end_is_silent_escalation(&end)) { + goto do_escalation; + } + /* * The W7 format depends on the F bit in W6. It defines the type * of the notification : @@ -1564,6 +1571,7 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, */ } +do_escalation: /* * If activated, escalate notification using the ESe PQ bits and * the EAS in w4-5 diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index 4378d7259c..fed019516f 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -212,6 +212,8 @@ typedef struct XiveEND { #define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) & END_W0_ESCALATE_CTL) #define xive_end_is_uncond_escalation(end) \ (be32_to_cpu((end)->w0) & END_W0_UNCOND_ESCALATE) +#define xive_end_is_silent_escalation(end) \ + (be32_to_cpu((end)->w0) & END_W0_SILENT_ESCALATE) static inline uint64_t xive_end_qaddr(XiveEND *end) { From c5e760e0f2de9e6ba682c001c8cdd0b40c8b5731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Thu, 18 Jul 2019 13:54:11 +0200 Subject: [PATCH 28/42] ppc/xive: Improve 'info pic' support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide a better output of the XIVE END structures including the escalation information and extend the PowerNV machine 'info pic' command with a dump of the END EAS table used for escalations. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-9-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/pnv_xive.c | 9 +++++++ hw/intc/spapr_xive.c | 1 - hw/intc/xive.c | 48 +++++++++++++++++++++++++++++++++----- include/hw/ppc/xive.h | 5 ---- include/hw/ppc/xive_regs.h | 6 +++++ 5 files changed, 57 insertions(+), 12 deletions(-) diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c index a8caf258fd..ed6e9d71bb 100644 --- a/hw/intc/pnv_xive.c +++ b/hw/intc/pnv_xive.c @@ -1595,6 +1595,15 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon) } xive_end_pic_print_info(&end, i, mon); } + + monitor_printf(mon, "XIVE[%x] END Escalation %08x .. %08x\n", blk, 0, + nr_ends - 1); + for (i = 0; i < nr_ends; i++) { + if (xive_router_get_end(xrtr, blk, i, &end)) { + break; + } + xive_end_eas_pic_print_info(&end, i, mon); + } } static void pnv_xive_reset(void *dev) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index aad981cb78..a29b48edf7 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -146,7 +146,6 @@ static void spapr_xive_end_pic_print_info(SpaprXive *xive, XiveEND *end, priority, qindex, qentries, qaddr_base, qgen); xive_end_queue_pic_print_info(end, 6, mon); - monitor_printf(mon, "]"); } void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index dd7d02dfdf..b7417210d8 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1158,6 +1158,7 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon) be32_to_cpu(qdata)); qindex = (qindex + 1) & (qentries - 1); } + monitor_printf(mon, "]"); } void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon) @@ -1168,24 +1169,36 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon) uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0); uint32_t qentries = 1 << (qsize + 10); - uint32_t nvt = xive_get_field32(END_W6_NVT_INDEX, end->w6); + uint32_t nvt_blk = xive_get_field32(END_W6_NVT_BLOCK, end->w6); + uint32_t nvt_idx = xive_get_field32(END_W6_NVT_INDEX, end->w6); uint8_t priority = xive_get_field32(END_W7_F0_PRIORITY, end->w7); + uint8_t pq; if (!xive_end_is_valid(end)) { return; } - monitor_printf(mon, " %08x %c%c%c%c%c prio:%d nvt:%04x eq:@%08"PRIx64 - "% 6d/%5d ^%d", end_idx, + pq = xive_get_field32(END_W1_ESn, end->w1); + + monitor_printf(mon, " %08x %c%c %c%c%c%c%c%c%c prio:%d nvt:%02x/%04x", + end_idx, + pq & XIVE_ESB_VAL_P ? 'P' : '-', + pq & XIVE_ESB_VAL_Q ? 'Q' : '-', xive_end_is_valid(end) ? 'v' : '-', xive_end_is_enqueue(end) ? 'q' : '-', xive_end_is_notify(end) ? 'n' : '-', xive_end_is_backlog(end) ? 'b' : '-', xive_end_is_escalate(end) ? 'e' : '-', - priority, nvt, qaddr_base, qindex, qentries, qgen); + xive_end_is_uncond_escalation(end) ? 'u' : '-', + xive_end_is_silent_escalation(end) ? 's' : '-', + priority, nvt_blk, nvt_idx); - xive_end_queue_pic_print_info(end, 6, mon); - monitor_printf(mon, "]\n"); + if (qaddr_base) { + monitor_printf(mon, " eq:@%08"PRIx64"% 6d/%5d ^%d", + qaddr_base, qindex, qentries, qgen); + xive_end_queue_pic_print_info(end, 6, mon); + } + monitor_printf(mon, "\n"); } static void xive_end_enqueue(XiveEND *end, uint32_t data) @@ -1213,6 +1226,29 @@ static void xive_end_enqueue(XiveEND *end, uint32_t data) end->w1 = xive_set_field32(END_W1_PAGE_OFF, end->w1, qindex); } +void xive_end_eas_pic_print_info(XiveEND *end, uint32_t end_idx, + Monitor *mon) +{ + XiveEAS *eas = (XiveEAS *) &end->w4; + uint8_t pq; + + if (!xive_end_is_escalate(end)) { + return; + } + + pq = xive_get_field32(END_W1_ESe, end->w1); + + monitor_printf(mon, " %08x %c%c %c%c end:%02x/%04x data:%08x\n", + end_idx, + pq & XIVE_ESB_VAL_P ? 'P' : '-', + pq & XIVE_ESB_VAL_Q ? 'Q' : '-', + xive_eas_is_valid(eas) ? 'V' : ' ', + xive_eas_is_masked(eas) ? 'M' : ' ', + (uint8_t) xive_get_field64(EAS_END_BLOCK, eas->w), + (uint32_t) xive_get_field64(EAS_END_INDEX, eas->w), + (uint32_t) xive_get_field64(EAS_END_DATA, eas->w)); +} + /* * XIVE Router (aka. Virtualization Controller or IVRE) */ diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index ea6ae34375..6d38755f84 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -354,8 +354,6 @@ typedef struct XiveRouterClass { XiveTCTX *(*get_tctx)(XiveRouter *xrtr, CPUState *cs); } XiveRouterClass; -void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon); - int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx, XiveEAS *eas); int xive_router_get_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx, @@ -397,9 +395,6 @@ typedef struct XiveENDSource { */ #define XIVE_PRIORITY_MAX 7 -void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon); -void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon); - /* * XIVE Thread Interrupt Management Aera (TIMA) * diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index fed019516f..08c8bf7172 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -131,6 +131,8 @@ typedef struct XiveEAS { #define xive_eas_is_valid(eas) (be64_to_cpu((eas)->w) & EAS_VALID) #define xive_eas_is_masked(eas) (be64_to_cpu((eas)->w) & EAS_MASKED) +void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon); + static inline uint64_t xive_get_field64(uint64_t mask, uint64_t word) { return (be64_to_cpu(word) & mask) >> ctz64(mask); @@ -221,6 +223,10 @@ static inline uint64_t xive_end_qaddr(XiveEND *end) be32_to_cpu(end->w3); } +void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon); +void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon); +void xive_end_eas_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon); + /* Notification Virtual Target (NVT) */ typedef struct XiveNVT { uint32_t w0; From 4b5e06c9465ece90b48cb0b978c0b898ea46e133 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 22 Jul 2019 15:32:13 +1000 Subject: [PATCH 29/42] machine: Add wakeup method to MachineClass Waking from suspend is not logically a machine reset on all machines, particularly in the paravirtualized case rather than hardware emulated. The ppc spapr machine for example just invokes hypervisor to suspend, and expects that call to return with the machine in the same state (modulo some possible migration and reconfiguration details). Implement a machine ->wakeup method and use that if it exists. Signed-off-by: Nicholas Piggin Message-Id: <20190722053215.20808-2-npiggin@gmail.com> Acked-by: Paolo Bonzini Signed-off-by: David Gibson --- include/hw/boards.h | 1 + vl.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/hw/boards.h b/include/hw/boards.h index aa35955f7f..60d69217b4 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -180,6 +180,7 @@ struct MachineClass { void (*init)(MachineState *state); void (*reset)(MachineState *state); + void (*wakeup)(MachineState *state); void (*hot_add_cpu)(MachineState *state, const int64_t id, Error **errp); int (*kvm_type)(MachineState *machine, const char *arg); void (*smp_parse)(MachineState *ms, QemuOpts *opts); diff --git a/vl.c b/vl.c index edd5390110..09aa18cb35 100644 --- a/vl.c +++ b/vl.c @@ -1557,6 +1557,22 @@ void qemu_system_reset(ShutdownCause reason) cpu_synchronize_all_post_reset(); } +/* + * Wake the VM after suspend. + */ +static void qemu_system_wakeup(void) +{ + MachineClass *mc; + + mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; + + if (mc && mc->wakeup) { + mc->wakeup(current_machine); + } else { + qemu_system_reset(SHUTDOWN_CAUSE_NONE); + } +} + void qemu_system_guest_panicked(GuestPanicInformation *info) { qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed"); @@ -1765,7 +1781,7 @@ static bool main_loop_should_exit(void) } if (qemu_wakeup_requested()) { pause_all_vcpus(); - qemu_system_reset(SHUTDOWN_CAUSE_NONE); + qemu_system_wakeup(); notifier_list_notify(&wakeup_notifiers, &wakeup_reason); wakeup_reason = QEMU_WAKEUP_REASON_NONE; resume_all_vcpus(); From c508bd12f65e14f82eb62e462bcb64898d8806a6 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 22 Jul 2019 16:17:51 +1000 Subject: [PATCH 30/42] i386: use machine class ->wakeup method Move the i386 suspend_wakeup logic out of the fallback path, and into the new ->wakeup method. Signed-off-by: Nicholas Piggin Message-Id: <20190722061752.22114-1-npiggin@gmail.com> Acked-by: Paolo Bonzini Signed-off-by: David Gibson --- hw/i386/pc.c | 8 ++++++++ vl.c | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 95edbbfe9e..98581fe0c2 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2834,6 +2834,13 @@ static void pc_machine_reset(MachineState *machine) } } +static void pc_machine_wakeup(MachineState *machine) +{ + cpu_synchronize_all_states(); + pc_machine_reset(machine); + cpu_synchronize_all_post_reset(); +} + static CpuInstanceProperties pc_cpu_index_to_props(MachineState *ms, unsigned cpu_index) { @@ -2946,6 +2953,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_IDE; mc->max_cpus = 255; mc->reset = pc_machine_reset; + mc->wakeup = pc_machine_wakeup; hc->pre_plug = pc_machine_device_pre_plug_cb; hc->plug = pc_machine_device_plug_cb; hc->unplug_request = pc_machine_device_unplug_request_cb; diff --git a/vl.c b/vl.c index 09aa18cb35..8e5af7501f 100644 --- a/vl.c +++ b/vl.c @@ -1568,8 +1568,6 @@ static void qemu_system_wakeup(void) if (mc && mc->wakeup) { mc->wakeup(current_machine); - } else { - qemu_system_reset(SHUTDOWN_CAUSE_NONE); } } From 93eac7b8f44738f7d2f4ba4460d67b04af5b0b99 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 22 Jul 2019 16:17:52 +1000 Subject: [PATCH 31/42] spapr: Implement ibm,suspend-me This has been useful to modify and test the Linux pseries suspend code but it requires modification to the guest to call it (due to being gated by other unimplemented features). It is not otherwise used by Linux yet, but work is slowly progressing there. This allows a (lightly modified) guest kernel to suspend with `echo mem > /sys/power/state` and be resumed with system_wakeup monitor command. Signed-off-by: Nicholas Piggin Message-Id: <20190722061752.22114-2-npiggin@gmail.com> Acked-by: Paolo Bonzini Signed-off-by: David Gibson --- hw/ppc/spapr.c | 7 +++++++ hw/ppc/spapr_rtas.c | 32 ++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 3 ++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 56b33571c5..51e1cb0d46 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3083,6 +3083,13 @@ static void spapr_machine_init(MachineState *machine) qemu_register_boot_set(spapr_boot_set, spapr); + /* + * Nothing needs to be done to resume a suspended guest because + * suspending does not change the machine state, so no need for + * a ->wakeup method. + */ + qemu_register_wakeup_support(); + if (kvm_enabled()) { /* to stop and start vmclock */ qemu_add_vm_change_state_handler(cpu_ppc_clock_vm_state_change, diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index d3f9a69a51..526b489297 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -217,6 +217,36 @@ static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr, qemu_cpu_kick(cs); } +static void rtas_ibm_suspend_me(PowerPCCPU *cpu, SpaprMachineState *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ + CPUState *cs; + + if (nargs != 0 || nret != 1) { + rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); + return; + } + + CPU_FOREACH(cs) { + PowerPCCPU *c = POWERPC_CPU(cs); + CPUPPCState *e = &c->env; + if (c == cpu) { + continue; + } + + /* See h_join */ + if (!cs->halted || (e->msr & (1ULL << MSR_EE))) { + rtas_st(rets, 0, H_MULTI_THREADS_ACTIVE); + return; + } + } + + qemu_system_suspend_request(); + rtas_st(rets, 0, RTAS_OUT_SUCCESS); +} + static inline int sysparm_st(target_ulong addr, target_ulong len, const void *val, uint16_t vallen) { @@ -484,6 +514,8 @@ static void core_rtas_register_types(void) rtas_query_cpu_stopped_state); spapr_rtas_register(RTAS_START_CPU, "start-cpu", rtas_start_cpu); spapr_rtas_register(RTAS_STOP_SELF, "stop-self", rtas_stop_self); + spapr_rtas_register(RTAS_IBM_SUSPEND_ME, "ibm,suspend-me", + rtas_ibm_suspend_me); spapr_rtas_register(RTAS_IBM_GET_SYSTEM_PARAMETER, "ibm,get-system-parameter", rtas_ibm_get_system_parameter); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index c79bc6a123..fa7c380edb 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -642,8 +642,9 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, #define RTAS_IBM_CREATE_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x27) #define RTAS_IBM_REMOVE_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x28) #define RTAS_IBM_RESET_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x29) +#define RTAS_IBM_SUSPEND_ME (RTAS_TOKEN_BASE + 0x2A) -#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2A) +#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2B) /* RTAS ibm,get-system-parameter token values */ #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20 From 1e8f51e856621d3615a21cfea6f0baf055cbcce8 Mon Sep 17 00:00:00 2001 From: Shivaprasad G Bhat Date: Thu, 25 Jul 2019 09:15:08 -0500 Subject: [PATCH 32/42] ppc: remove idle_timer logic The logic is broken for multiple vcpu guests, also causing memory leak. The logic is in place to handle kvm not having KVM_CAP_PPC_IRQ_LEVEL, which is part of the kernel now since 2.6.37. Instead of fixing the leak, drop the redundant logic which is not excercised on new kernels anymore. Exit with error on older kernels. Signed-off-by: Shivaprasad G Bhat Message-Id: <156406409479.19996.7606556689856621111.stgit@lep8c.aus.stglabs.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- target/ppc/kvm.c | 75 ++++-------------------------------------------- 1 file changed, 5 insertions(+), 70 deletions(-) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 6162a903fa..8c5b1f25cc 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -58,7 +58,6 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { }; static int cap_interrupt_unset; -static int cap_interrupt_level; static int cap_segstate; static int cap_booke_sregs; static int cap_ppc_smt; @@ -89,25 +88,6 @@ static int cap_large_decr; static uint32_t debug_inst_opcode; -/* - * XXX We have a race condition where we actually have a level triggered - * interrupt, but the infrastructure can't expose that yet, so the guest - * takes but ignores it, goes to sleep and never gets notified that there's - * still an interrupt pending. - * - * As a quick workaround, let's just wake up again 20 ms after we injected - * an interrupt. That way we can assure that we're always reinjecting - * interrupts in case the guest swallowed them. - */ -static QEMUTimer *idle_timer; - -static void kvm_kick_cpu(void *opaque) -{ - PowerPCCPU *cpu = opaque; - - qemu_cpu_kick(CPU(cpu)); -} - /* * Check whether we are running with KVM-PR (instead of KVM-HV). This * should only be used for fallback tests - generally we should use @@ -127,7 +107,6 @@ static int kvmppc_get_dec_bits(void); int kvm_arch_init(MachineState *ms, KVMState *s) { cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ); - cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL); cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE); cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS); cap_ppc_smt_possible = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE); @@ -163,9 +142,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s) */ cap_ppc_pvr_compat = false; - if (!cap_interrupt_level) { - fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the " - "VM to stall at times!\n"); + if (!kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL)) { + error_report("KVM: Host kernel doesn't have level irq capability"); + exit(1); } kvm_ppc_register_host_cpu_type(ms); @@ -493,8 +472,6 @@ int kvm_arch_init_vcpu(CPUState *cs) return ret; } - idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, kvm_kick_cpu, cpu); - switch (cenv->mmu_model) { case POWERPC_MMU_BOOKE206: /* This target supports access to KVM's guest TLB */ @@ -1334,7 +1311,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) return 0; } - if (!kvm_enabled() || !cap_interrupt_unset || !cap_interrupt_level) { + if (!kvm_enabled() || !cap_interrupt_unset) { return 0; } @@ -1351,49 +1328,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - int r; - unsigned irq; - - qemu_mutex_lock_iothread(); - - /* - * PowerPC QEMU tracks the various core input pins (interrupt, - * critical interrupt, reset, etc) in PPC-specific - * env->irq_input_state. - */ - if (!cap_interrupt_level && - run->ready_for_interrupt_injection && - (cs->interrupt_request & CPU_INTERRUPT_HARD) && - (env->irq_input_state & (1 << PPC_INPUT_INT))) - { - /* - * For now KVM disregards the 'irq' argument. However, in the - * future KVM could cache it in-kernel to avoid a heavyweight - * exit when reading the UIC. - */ - irq = KVM_INTERRUPT_SET; - - trace_kvm_injected_interrupt(irq); - r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &irq); - if (r < 0) { - printf("cpu %d fail inject %x\n", cs->cpu_index, irq); - } - - /* Always wake up soon in case the interrupt was level based */ - timer_mod(idle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (NANOSECONDS_PER_SECOND / 50)); - } - - /* - * We don't know if there are more interrupts pending after - * this. However, the guest will return to userspace in the course - * of handling this one anyways, so we will get a chance to - * deliver the rest. - */ - - qemu_mutex_unlock_iothread(); + return; } MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) From 078eb6b05b7f962e43d8bc376e0b96cdd550c17a Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 26 Jul 2019 16:44:38 +0200 Subject: [PATCH 33/42] spapr/pci: Consolidate de-allocation of MSIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When freeing MSIs, we need to: - remove them from the machine's MSI bitmap - remove them from the IC backend - remove them from the PHB's MSI cache This is currently open coded in two places in rtas_ibm_change_msi(), and we're about to need this in spapr_phb_reset() as well. Instead of duplicating this code again, make it a destroy function for the PHB's MSI cache. Removing an MSI device from the cache will call the destroy function internally. Signed-off-by: Greg Kurz Message-Id: <156415227855.1064338.5657793835271464648.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 4c5420c465..6e6b4d0f60 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -338,10 +338,6 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr, return; } - if (!smc->legacy_irq_allocation) { - spapr_irq_msi_free(spapr, msi->first_irq, msi->num); - } - spapr_irq_free(spapr, msi->first_irq, msi->num); if (msi_present(pdev)) { spapr_msi_setmsg(pdev, 0, false, 0, 0); } @@ -411,10 +407,6 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr, /* Release previous MSIs */ if (msi) { - if (!smc->legacy_irq_allocation) { - spapr_irq_msi_free(spapr, msi->first_irq, msi->num); - } - spapr_irq_free(spapr, msi->first_irq, msi->num); g_hash_table_remove(phb->msi, &config_addr); } @@ -1808,6 +1800,19 @@ static void spapr_phb_unrealize(DeviceState *dev, Error **errp) memory_region_del_subregion(get_system_memory(), &sphb->mem32window); } +static void spapr_phb_destroy_msi(gpointer opaque) +{ + SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + spapr_pci_msi *msi = opaque; + + if (!smc->legacy_irq_allocation) { + spapr_irq_msi_free(spapr, msi->first_irq, msi->num); + } + spapr_irq_free(spapr, msi->first_irq, msi->num); + g_free(msi); +} + static void spapr_phb_realize(DeviceState *dev, Error **errp) { /* We don't use SPAPR_MACHINE() in order to exit gracefully if the user @@ -2019,7 +2024,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) spapr_tce_get_iommu(tcet)); } - sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); + sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, + spapr_phb_destroy_msi); return; unrealize: From ea52074d3a1c5fbe70f3014dc1b1f2e7d5ced5de Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 26 Jul 2019 16:44:44 +0200 Subject: [PATCH 34/42] spapr/pci: Free MSIs during reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the machine is reset, the MSI bitmap is cleared but the allocated MSIs are not freed. Some operating systems, such as AIX, can detect the previous configuration and assert. Empty the MSI cache, this performs the needed cleanup. Signed-off-by: Greg Kurz Message-Id: <156415228410.1064338.4486161194061636096.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 6e6b4d0f60..deb0b0c80c 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2080,6 +2080,8 @@ static void spapr_phb_reset(DeviceState *qdev) if (spapr_phb_eeh_available(SPAPR_PCI_HOST_BRIDGE(qdev))) { spapr_phb_vfio_reset(qdev); } + + g_hash_table_remove_all(sphb->msi); } static Property spapr_phb_properties[] = { From e1588bcdd2ceca232021a626aa3b8e835ea49c52 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 26 Jul 2019 16:44:49 +0200 Subject: [PATCH 35/42] spapr/irq: Drop spapr_irq_msi_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHBs already take care of clearing the MSIs from the bitmap during reset or unplug. No need to do this globally from the machine code. Rather add an assert to ensure that PHBs have acted as expected. Signed-off-by: Greg Kurz Message-Id: <156415228966.1064338.190189424190233355.stgit@bahia.lan> Reviewed-by: Cédric Le Goater [dwg: Fix crash in qtest case where spapr->irq_map can be NULL at the new assert()] Signed-off-by: David Gibson --- hw/ppc/spapr.c | 4 ---- hw/ppc/spapr_irq.c | 7 ++----- include/hw/ppc/spapr_irq.h | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 51e1cb0d46..64fc2255cc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1755,10 +1755,6 @@ static void spapr_machine_reset(MachineState *machine) ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal); } - if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { - spapr_irq_msi_reset(spapr); - } - /* * This is fixing some of the default configuration of the XIVE * devices. To be called after the reset of the machine devices. diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 2f87fe08f3..06fe2432ba 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -59,11 +59,6 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num) bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num); } -void spapr_irq_msi_reset(SpaprMachineState *spapr) -{ - bitmap_clear(spapr->irq_map, 0, spapr->irq_map_nr); -} - static void spapr_irq_init_kvm(SpaprMachineState *spapr, SpaprIrq *irq, Error **errp) { @@ -731,6 +726,8 @@ int spapr_irq_post_load(SpaprMachineState *spapr, int version_id) void spapr_irq_reset(SpaprMachineState *spapr, Error **errp) { + assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr)); + if (spapr->irq->reset) { spapr->irq->reset(spapr, errp); } diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 8132e00366..5db305165c 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -30,7 +30,6 @@ void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis); int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align, Error **errp); void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num); -void spapr_irq_msi_reset(SpaprMachineState *spapr); typedef struct SpaprIrq { uint32_t nr_irqs; From fd38b1629cdb73da17e6fa294168e0c1bb1ccb07 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 31 Jul 2019 14:36:54 +1000 Subject: [PATCH 36/42] spapr: Implement better workaround in spapr-vty device Linux guest kernels have code which scans the string of characters returned from the H_GET_TERM_CHAR hypercall and removes any \0 character which comes immediately after a \r character. This is to work around a bug which was present in some ancient versions of PowerVM. In order to avoid the corruption of the console byte stream that this introduced, commit 6c3bc244d3cb ("spapr: Implement bug in spapr-vty device to be compatible with PowerVM") added a workaround which adds a \0 character after every \r character. Unfortunately, this corrupts the console byte stream for those operating systems, such as AIX, which don't remove the null bytes. We can avoid triggering the Linux kernel workaround if we avoid returning a buffer which contains a \0 after a \r. We can do that by breaking out of the loop in vty_getchars() if we are about to insert a \0 and the previous character in the buffer is a \r. That means we return the characters up to the \r for the current H_GET_TERM_CHAR, and the characters starting with the \0 for the next one. With this workaround, we don't insert any spurious characters and we avoid triggering the Linux kernel workaround, so the guest will receive an uncorrupted stream whether or not they have the workaround. Fixes: 6c3bc244d3cb ("spapr: Implement bug in spapr-vty device to be compatible with PowerVM") Signed-off-by: Paul Mackerras Message-Id: <20190731043653.shdi5sizjp4t65op@oak.ozlabs.ibm.com> Signed-off-by: David Gibson --- hw/char/spapr_vty.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 7f860fcce7..087c93e4fa 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -59,25 +59,19 @@ static int vty_getchars(SpaprVioDevice *sdev, uint8_t *buf, int max) int n = 0; while ((n < max) && (dev->out != dev->in)) { - buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE]; - - /* PowerVM's vty implementation has a bug where it inserts a - * \0 after every \r going to the guest. Existing guests have - * a workaround for this which removes every \0 immediately - * following a \r, so here we make ourselves bug-for-bug - * compatible, so that the guest won't drop a real \0-after-\r - * that happens to occur in a binary stream. */ - if (buf[n - 1] == '\r') { - if (n < max) { - buf[n++] = '\0'; - } else { - /* No room for the extra \0, roll back and try again - * next time */ - dev->out--; - n--; - break; - } + /* + * Long ago, PowerVM's vty implementation had a bug where it + * inserted a \0 after every \r going to the guest. Existing + * guests have a workaround for this which removes every \0 + * immediately following a \r. To avoid triggering this + * workaround, we stop before inserting a \0 if the preceding + * character in the output buffer is a \r. + */ + if (n > 0 && (buf[n - 1] == '\r') && + (dev->buf[dev->out % VTERM_BUFSIZE] == '\0')) { + break; } + buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE]; } qemu_chr_fe_accept_input(&dev->chardev); From f55750e4e4fb35b6a12c81c485f16494e2c61ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 13 Aug 2019 18:44:20 +0200 Subject: [PATCH 37/42] spapr/xive: Mask the EAS when allocating an IRQ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If an IRQ is allocated and not configured, such as a MSI requested by a PCI driver, it can be saved in its default state and possibly later on restored using the same state. If not initially MASKED, KVM will try to find a matching priority/target tuple for the interrupt and fail to restore the VM because 0/0 is not a valid target. When allocating a IRQ number, the EAS should be set to a sane default : VALID and MASKED. Reported-by: Satheesh Rajendran Signed-off-by: Cédric Le Goater Message-Id: <20190813164420.9829-1-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/spapr_xive.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index a29b48edf7..c1c97192a7 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -536,7 +536,10 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi) return false; } - xive->eat[lisn].w |= cpu_to_be64(EAS_VALID); + /* + * Set default values when allocating an IRQ number + */ + xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED); if (lsi) { xive_source_irq_set_lsi(xsrc, lisn); } From cfc61ba62f30753849fe2b78da8b6d0a0a639db2 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 16 Aug 2019 16:17:33 +1000 Subject: [PATCH 38/42] target/ppc: Add Directed Privileged Door-bell Exception State (DPDES) SPR DPDES stores a status of a doorbell message and if it is lost in migration, the destination CPU won't receive it. This does not hit us much as IPIs complete too quick to catch a pending one and even if we missed one, broadcasts happen often enough to wake that CPU. This defines DPDES and registers with KVM for migration. Signed-off-by: Alexey Kardashevskiy Message-Id: <20190816061733.53572-1-aik@ozlabs.ru> Signed-off-by: David Gibson --- target/ppc/cpu.h | 1 + target/ppc/translate_init.inc.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 50245a8c4d..4b35c8e4f4 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1466,6 +1466,7 @@ typedef PowerPCCPU ArchCPU; #define SPR_MPC_ICTRL (0x09E) #define SPR_MPC_BAR (0x09F) #define SPR_PSPB (0x09F) +#define SPR_DPDES (0x0B0) #define SPR_DAWR (0x0B4) #define SPR_RPR (0x0BA) #define SPR_CIABR (0x0BB) diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index c9fcd87095..7e41ae1456 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -8198,6 +8198,18 @@ static void gen_spr_power8_pspb(CPUPPCState *env) KVM_REG_PPC_PSPB, 0); } +static void gen_spr_power8_dpdes(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* Directed Privileged Door-bell Exception State, used for IPI */ + spr_register_kvm_hv(env, SPR_DPDES, "DPDES", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DPDES, 0x00000000); +#endif +} + static void gen_spr_power8_ic(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) @@ -8629,6 +8641,7 @@ static void init_proc_POWER8(CPUPPCState *env) gen_spr_power8_pmu_user(env); gen_spr_power8_tm(env); gen_spr_power8_pspb(env); + gen_spr_power8_dpdes(env); gen_spr_vtb(env); gen_spr_power8_ic(env); gen_spr_power8_book4(env); @@ -8817,6 +8830,7 @@ static void init_proc_POWER9(CPUPPCState *env) gen_spr_power8_pmu_user(env); gen_spr_power8_tm(env); gen_spr_power8_pspb(env); + gen_spr_power8_dpdes(env); gen_spr_vtb(env); gen_spr_power8_ic(env); gen_spr_power8_book4(env); From 31eb7dddacc242af244798854444c3497b515e9f Mon Sep 17 00:00:00 2001 From: "Paul A. Clarke" Date: Fri, 16 Aug 2019 14:03:23 -0500 Subject: [PATCH 39/42] ppc: Add support for 'mffsl' instruction ISA 3.0B added a set of Floating-Point Status and Control Register (FPSCR) instructions: mffsce, mffscdrn, mffscdrni, mffscrn, mffscrni, mffsl. This patch adds support for 'mffsl'. 'mffsl' is identical to 'mffs', except it only returns mode, status, and enable bits from the FPSCR. On CPUs without support for 'mffsl' (below ISA 3.0), the 'mffsl' instruction will execute identically to 'mffs'. Note: I renamed FPSCR_RN to FPSCR_RN0 so I could create an FPSCR_RN mask which is both bits of the FPSCR rounding mode, as defined in the ISA. I also fixed a typo in the definition of FPSCR_FR. Signed-off-by: Paul A. Clarke v4: - nit: added some braces to resolve a checkpatch complaint. v3: - Changed tcg_gen_and_i64 to tcg_gen_andi_i64, eliminating the need for a temporary, per review from Richard Henderson. v2: - I found that I copied too much of the 'mffs' implementation. The 'Rc' condition code bits are not needed for 'mffsl'. Removed. - I now free the (renamed) 'tmask' temporary. - I now bail early for older ISA to the original 'mffs' implementation. Message-Id: <1565982203-11048-1-git-send-email-pc@us.ibm.com> Signed-off-by: David Gibson --- disas/ppc.c | 5 +++++ target/ppc/cpu.h | 15 ++++++++++----- target/ppc/fpu_helper.c | 4 ++-- target/ppc/translate/fp-impl.inc.c | 22 ++++++++++++++++++++++ target/ppc/translate/fp-ops.inc.c | 4 +++- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/disas/ppc.c b/disas/ppc.c index a545437de9..63e97cfe1d 100644 --- a/disas/ppc.c +++ b/disas/ppc.c @@ -1765,6 +1765,9 @@ extract_tbr (unsigned long insn, /* An X_MASK with the RA and RB fields fixed. */ #define XRARB_MASK (X_MASK | RA_MASK | RB_MASK) +/* An X form instruction with the RA field fixed. */ +#define XRA(op, xop, ra) (X((op), (xop)) | (((ra) << 16) & XRA_MASK)) + /* An XRARB_MASK, but with the L bit clear. */ #define XRLARB_MASK (XRARB_MASK & ~((unsigned long) 1 << 16)) @@ -4998,6 +5001,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "ddivq", XRC(63,546,0), X_MASK, POWER6, { FRT, FRA, FRB } }, { "ddivq.", XRC(63,546,1), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "mffsl", XRA(63,583,12), XRARB_MASK, POWER9, { FRT } }, + { "mffs", XRC(63,583,0), XRARB_MASK, COM, { FRT } }, { "mffs.", XRC(63,583,1), XRARB_MASK, COM, { FRT } }, diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 4b35c8e4f4..eaee1a5575 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -591,7 +591,7 @@ enum { #define FPSCR_XE 3 /* Floating-point inexact exception enable */ #define FPSCR_NI 2 /* Floating-point non-IEEE mode */ #define FPSCR_RN1 1 -#define FPSCR_RN 0 /* Floating-point rounding control */ +#define FPSCR_RN0 0 /* Floating-point rounding control */ #define fpscr_fex (((env->fpscr) >> FPSCR_FEX) & 0x1) #define fpscr_vx (((env->fpscr) >> FPSCR_VX) & 0x1) #define fpscr_ox (((env->fpscr) >> FPSCR_OX) & 0x1) @@ -614,7 +614,7 @@ enum { #define fpscr_ze (((env->fpscr) >> FPSCR_ZE) & 0x1) #define fpscr_xe (((env->fpscr) >> FPSCR_XE) & 0x1) #define fpscr_ni (((env->fpscr) >> FPSCR_NI) & 0x1) -#define fpscr_rn (((env->fpscr) >> FPSCR_RN) & 0x3) +#define fpscr_rn (((env->fpscr) >> FPSCR_RN0) & 0x3) /* Invalid operation exception summary */ #define fpscr_ix ((env->fpscr) & ((1 << FPSCR_VXSNAN) | (1 << FPSCR_VXISI) | \ (1 << FPSCR_VXIDI) | (1 << FPSCR_VXZDZ) | \ @@ -640,7 +640,7 @@ enum { #define FP_VXZDZ (1ull << FPSCR_VXZDZ) #define FP_VXIMZ (1ull << FPSCR_VXIMZ) #define FP_VXVC (1ull << FPSCR_VXVC) -#define FP_FR (1ull << FSPCR_FR) +#define FP_FR (1ull << FPSCR_FR) #define FP_FI (1ull << FPSCR_FI) #define FP_C (1ull << FPSCR_C) #define FP_FL (1ull << FPSCR_FL) @@ -648,7 +648,7 @@ enum { #define FP_FE (1ull << FPSCR_FE) #define FP_FU (1ull << FPSCR_FU) #define FP_FPCC (FP_FL | FP_FG | FP_FE | FP_FU) -#define FP_FPRF (FP_C | FP_FL | FP_FG | FP_FE | FP_FU) +#define FP_FPRF (FP_C | FP_FPCC) #define FP_VXSOFT (1ull << FPSCR_VXSOFT) #define FP_VXSQRT (1ull << FPSCR_VXSQRT) #define FP_VXCVI (1ull << FPSCR_VXCVI) @@ -659,7 +659,12 @@ enum { #define FP_XE (1ull << FPSCR_XE) #define FP_NI (1ull << FPSCR_NI) #define FP_RN1 (1ull << FPSCR_RN1) -#define FP_RN (1ull << FPSCR_RN) +#define FP_RN0 (1ull << FPSCR_RN0) +#define FP_RN (FP_RN1 | FP_RN0) + +#define FP_MODE FP_RN +#define FP_ENABLES (FP_VE | FP_OE | FP_UE | FP_ZE | FP_XE) +#define FP_STATUS (FP_FR | FP_FI | FP_FPRF) /* the exception bits which can be cleared by mcrfs - includes FX */ #define FP_EX_CLEAR_BITS (FP_FX | FP_OX | FP_UX | FP_ZX | \ diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index f437c88aad..5611cf0156 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -403,7 +403,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit) if (prev == 1) { switch (bit) { case FPSCR_RN1: - case FPSCR_RN: + case FPSCR_RN0: fpscr_set_rounding_mode(env); break; case FPSCR_VXSNAN: @@ -557,7 +557,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit) } break; case FPSCR_RN1: - case FPSCR_RN: + case FPSCR_RN0: fpscr_set_rounding_mode(env); break; default: diff --git a/target/ppc/translate/fp-impl.inc.c b/target/ppc/translate/fp-impl.inc.c index 9dcff947c0..7cd9d8db05 100644 --- a/target/ppc/translate/fp-impl.inc.c +++ b/target/ppc/translate/fp-impl.inc.c @@ -617,6 +617,28 @@ static void gen_mffs(DisasContext *ctx) tcg_temp_free_i64(t0); } +/* mffsl */ +static void gen_mffsl(DisasContext *ctx) +{ + TCGv_i64 t0; + + if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { + return gen_mffs(ctx); + } + + if (unlikely(!ctx->fpu_enabled)) { + gen_exception(ctx, POWERPC_EXCP_FPU); + return; + } + t0 = tcg_temp_new_i64(); + gen_reset_fpstatus(); + tcg_gen_extu_tl_i64(t0, cpu_fpscr); + /* Mask everything except mode, status, and enables. */ + tcg_gen_andi_i64(t0, t0, FP_MODE | FP_STATUS | FP_ENABLES); + set_fpr(rD(ctx->opcode), t0); + tcg_temp_free_i64(t0); +} + /* mtfsb0 */ static void gen_mtfsb0(DisasContext *ctx) { diff --git a/target/ppc/translate/fp-ops.inc.c b/target/ppc/translate/fp-ops.inc.c index 621f6bfe0c..88ebc2526c 100644 --- a/target/ppc/translate/fp-ops.inc.c +++ b/target/ppc/translate/fp-ops.inc.c @@ -104,7 +104,9 @@ GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205), GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT), -GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT), +GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE), +GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT, + PPC2_ISA300), GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT), From e6f1bfb21121b5aaf6f5ff339157c0d55e8b9fe2 Mon Sep 17 00:00:00 2001 From: "Paul A. Clarke" Date: Mon, 19 Aug 2019 12:43:21 -0500 Subject: [PATCH 40/42] ppc: conform to processor User's Manual for xscvdpspn The POWER8 and POWER9 User's Manuals specify the implementation behavior for what the ISA leaves "undefined" behavior for the xscvdpspn and xscvdpsp instructions. This patch corrects the QEMU implementation to match the hardware implementation for that case. ISA 3.0B has xscvdpspn leaving its result in word 0 of the target register, with the other words of the target register left "undefined". The User's Manuals specify: VSX scalar convert from double-precision to single-precision (xscvdpsp, xscvdpspn). VSR[32:63] is set to VSR[0:31]. So, words 0 and 1 both contain the result. Note: this is important because GCC as of version 8 or so, assumes and takes advantage of this behavior to optimize the following sequence: xscvdpspn vs0,vs1 mffprwz r8,f0 ISA 3.0B has xscvdpspn leaving its result in word 0 of the target register, and mffprwz expecting its input to come from word 1 of the source register. This sequence fails with QEMU, as a shift is required between those two instructions. However, since the hardware splats the result to both words 0 and 1 of its output register, the shift is not necessary. Expect a future revision of the ISA to specify this behavior. Signed-off-by: Paul A. Clarke v2 - Splitting patch "ppc: Three floating point fixes"; this is just one part. - Updated commit message to clarify behavior is documented in User's Manuals. - Updated commit message to correct which words are in output and source of xscvdpspn and mffprz. - No source changes to this part of the original patch. Message-Id: <1566236601-22954-1-git-send-email-pc@us.ibm.com> Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 5611cf0156..23b9c97439 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2871,10 +2871,14 @@ void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode, uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb) { + uint64_t result; + float_status tstat = env->fp_status; set_float_exception_flags(0, &tstat); - return (uint64_t)float64_to_float32(xb, &tstat) << 32; + result = (uint64_t)float64_to_float32(xb, &tstat); + /* hardware replicates result to both words of the doubleword result. */ + return (result << 32) | result; } uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb) From a7b7b98318f7d483e016f0f412df2b8a7dc1d636 Mon Sep 17 00:00:00 2001 From: "Paul A. Clarke" Date: Mon, 19 Aug 2019 14:19:48 -0500 Subject: [PATCH 41/42] ppc: Fix emulated INFINITY and NAN conversions helper_todouble() was not properly converting INFINITY from 32 bit float to 64 bit double. (Normalized operand conversion is unchanged, other than indentation.) Signed-off-by: Paul A. Clarke Message-Id: <1566242388-9244-1-git-send-email-pc@us.ibm.com> Reviewed-by: Richard Henderson Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 23b9c97439..52bcda27a6 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -58,10 +58,17 @@ uint64_t helper_todouble(uint32_t arg) uint64_t ret; if (likely(abs_arg >= 0x00800000)) { - /* Normalized operand, or Inf, or NaN. */ - ret = (uint64_t)extract32(arg, 30, 2) << 62; - ret |= ((extract32(arg, 30, 1) ^ 1) * (uint64_t)7) << 59; - ret |= (uint64_t)extract32(arg, 0, 30) << 29; + if (unlikely(extract32(arg, 23, 8) == 0xff)) { + /* Inf or NAN. */ + ret = (uint64_t)extract32(arg, 31, 1) << 63; + ret |= (uint64_t)0x7ff << 52; + ret |= (uint64_t)extract32(arg, 0, 23) << 29; + } else { + /* Normalized operand. */ + ret = (uint64_t)extract32(arg, 30, 2) << 62; + ret |= ((extract32(arg, 30, 1) ^ 1) * (uint64_t)7) << 59; + ret |= (uint64_t)extract32(arg, 0, 30) << 29; + } } else { /* Zero or Denormalized operand. */ ret = (uint64_t)extract32(arg, 31, 1) << 63; From c0e6616b6685ffdb4c5e091bc152e46e14703dd1 Mon Sep 17 00:00:00 2001 From: "Paul A. Clarke" Date: Mon, 19 Aug 2019 16:42:16 -0500 Subject: [PATCH 42/42] ppc: Fix emulated single to double denormalized conversions helper_todouble() was not properly converting any denormalized 32 bit float to 64 bit double. Fix-suggested-by: Richard Henderson Signed-off-by: Paul A. Clarke v2: - Splitting patch "ppc: Three floating point fixes"; this is just one part. - Original suggested "fix" was likely flawed. v2 is rewritten by Richard Henderson (Thanks, Richard!); I reformatted the comments in a couple of places, compiled, and tested. Message-Id: <1566250936-14538-1-git-send-email-pc@us.ibm.com> Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 52bcda27a6..07bc9051b0 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -73,11 +73,20 @@ uint64_t helper_todouble(uint32_t arg) /* Zero or Denormalized operand. */ ret = (uint64_t)extract32(arg, 31, 1) << 63; if (unlikely(abs_arg != 0)) { - /* Denormalized operand. */ - int shift = clz32(abs_arg) - 9; - int exp = -126 - shift + 1023; + /* + * Denormalized operand. + * Shift fraction so that the msb is in the implicit bit position. + * Thus, shift is in the range [1:23]. + */ + int shift = clz32(abs_arg) - 8; + /* + * The first 3 terms compute the float64 exponent. We then bias + * this result by -1 so that we can swallow the implicit bit below. + */ + int exp = -126 - shift + 1023 - 1; + ret |= (uint64_t)exp << 52; - ret |= abs_arg << (shift + 29); + ret += (uint64_t)abs_arg << (52 - 23 + shift); } } return ret;