[PULL 36/46] hw/arm/raspi: Extract the RAM size from the board revision
From: Philippe Mathieu-Daudé The board revision encode the amount of RAM. Add a helper to extract the RAM size, and use it. Since the amount of RAM is fixed (it is impossible to physically modify to have more or less RAM), do not allow sizes different than the one anounced by the manufacturer. Acked-by: Igor Mammedov Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-5-f4...@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index f285e2988fc..dcd8d2d6d38 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" +#include "qemu/cutils.h" #include "qapi/error.h" #include "cpu.h" #include "hw/arm/bcm2836.h" @@ -49,6 +50,12 @@ FIELD(REV_CODE, MANUFACTURER, 16, 4); FIELD(REV_CODE, MEMORY_SIZE, 20, 3); FIELD(REV_CODE, STYLE, 23, 1); +static uint64_t board_ram_size(uint32_t board_rev) +{ +assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ +return 256 * MiB << FIELD_EX32(board_rev, REV_CODE, MEMORY_SIZE); +} + static int board_processor_id(uint32_t board_rev) { assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ @@ -191,15 +198,17 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) { RasPiState *s = g_new0(RasPiState, 1); int version = board_version(board_rev); +uint64_t ram_size = board_ram_size(board_rev); uint32_t vcram_size; DriveInfo *di; BlockBackend *blk; BusState *bus; DeviceState *carddev; -if (machine->ram_size > 1 * GiB) { -error_report("Requested ram size is too large for this machine: " - "maximum is 1GB"); +if (machine->ram_size != ram_size) { +char *size_str = size_to_str(ram_size); +error_report("Invalid RAM size, should be %s", size_str); +g_free(size_str); exit(1); } -- 2.20.1
[PULL 30/46] hw/arm: ast2400/ast2500: Wire up EHCI controllers
From: Guenter Roeck Initialize EHCI controllers on AST2400 and AST2500 using the existing TYPE_PLATFORM_EHCI. After this change, booting ast2500-evb into Linux successfully instantiates a USB interface. ehci-platform 1e6a3000.usb: EHCI Host Controller ehci-platform 1e6a3000.usb: new USB bus registered, assigned bus number 1 ehci-platform 1e6a3000.usb: irq 21, io mem 0x1e6a3000 ehci-platform 1e6a3000.usb: USB 2.0 started, EHCI 1.00 usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.05 usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 usb usb1: Product: EHCI Host Controller Signed-off-by: Guenter Roeck Reviewed-by: Cédric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daudé Message-id: 20200206183437.3979-1-li...@roeck-us.net Signed-off-by: Peter Maydell --- include/hw/arm/aspeed_soc.h | 6 ++ hw/arm/aspeed_soc.c | 25 + 2 files changed, 31 insertions(+) diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 90ac7f7ffa3..78b9f6ae532 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -26,8 +26,10 @@ #include "target/arm/cpu.h" #include "hw/gpio/aspeed_gpio.h" #include "hw/sd/aspeed_sdhci.h" +#include "hw/usb/hcd-ehci.h" #define ASPEED_SPIS_NUM 2 +#define ASPEED_EHCIS_NUM 2 #define ASPEED_WDTS_NUM 4 #define ASPEED_CPUS_NUM 2 #define ASPEED_MACS_NUM 4 @@ -50,6 +52,7 @@ typedef struct AspeedSoCState { AspeedXDMAState xdma; AspeedSMCState fmc; AspeedSMCState spi[ASPEED_SPIS_NUM]; +EHCISysBusState ehci[ASPEED_EHCIS_NUM]; AspeedSDMCState sdmc; AspeedWDTState wdt[ASPEED_WDTS_NUM]; FTGMAC100State ftgmac100[ASPEED_MACS_NUM]; @@ -71,6 +74,7 @@ typedef struct AspeedSoCClass { uint32_t silicon_rev; uint64_t sram_size; int spis_num; +int ehcis_num; int wdts_num; int macs_num; const int *irqmap; @@ -94,6 +98,8 @@ enum { ASPEED_FMC, ASPEED_SPI1, ASPEED_SPI2, +ASPEED_EHCI1, +ASPEED_EHCI2, ASPEED_VIC, ASPEED_SDMC, ASPEED_SCU, diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index b5e809a1d3f..696c7fda14b 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -30,6 +30,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = { [ASPEED_IOMEM] = 0x1E60, [ASPEED_FMC]= 0x1E62, [ASPEED_SPI1] = 0x1E63, +[ASPEED_EHCI1] = 0x1E6A1000, [ASPEED_VIC]= 0x1E6C, [ASPEED_SDMC] = 0x1E6E, [ASPEED_SCU]= 0x1E6E2000, @@ -59,6 +60,8 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = { [ASPEED_FMC]= 0x1E62, [ASPEED_SPI1] = 0x1E63, [ASPEED_SPI2] = 0x1E631000, +[ASPEED_EHCI1] = 0x1E6A1000, +[ASPEED_EHCI2] = 0x1E6A3000, [ASPEED_VIC]= 0x1E6C, [ASPEED_SDMC] = 0x1E6E, [ASPEED_SCU]= 0x1E6E2000, @@ -91,6 +94,8 @@ static const int aspeed_soc_ast2400_irqmap[] = { [ASPEED_UART5] = 10, [ASPEED_VUART] = 8, [ASPEED_FMC]= 19, +[ASPEED_EHCI1] = 5, +[ASPEED_EHCI2] = 13, [ASPEED_SDMC] = 0, [ASPEED_SCU]= 21, [ASPEED_ADC]= 31, @@ -180,6 +185,11 @@ static void aspeed_soc_init(Object *obj) sizeof(s->spi[i]), typename); } +for (i = 0; i < sc->ehcis_num; i++) { +sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]), + sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI); +} + snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), typename); @@ -364,6 +374,19 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) s->spi[i].ctrl->flash_window_base); } +/* EHCI */ +for (i = 0; i < sc->ehcis_num; i++) { +object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized", &err); +if (err) { +error_propagate(errp, err); +return; +} +sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, +sc->memmap[ASPEED_EHCI1 + i]); +sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, + aspeed_soc_get_irq(s, ASPEED_EHCI1 + i)); +} + /* SDMC - SDRAM Memory Controller */ object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); if (err) { @@ -472,6 +495,7 @@ static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) sc->silicon_rev = AST2400_A1_SILICON_REV; sc->sram_size= 0x8000; sc->spis_num = 1; +sc->ehcis_num= 1; sc->wdts_num = 2; sc->macs_num = 2; sc->irqmap = aspeed_soc_ast2400_irqmap; @@ -496,6 +520,7 @@ static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) sc->silicon_rev = AST2500_A1_SILICON_REV; sc->sram_size= 0x9000; sc->spis_
[PULL 35/46] hw/arm/raspi: Extract the version from the board revision
From: Philippe Mathieu-Daudé The board revision encode the board version. Add a helper to extract the version, and use it. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-4-f4...@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 31 +++ 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 818146fdbb2..f285e2988fc 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -16,6 +16,7 @@ #include "qapi/error.h" #include "cpu.h" #include "hw/arm/bcm2836.h" +#include "hw/registerfields.h" #include "qemu/error-report.h" #include "hw/boards.h" #include "hw/loader.h" @@ -37,6 +38,28 @@ typedef struct RasPiState { MemoryRegion ram; } RasPiState; +/* + * Board revision codes: + * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/ + */ +FIELD(REV_CODE, REVISION, 0, 4); +FIELD(REV_CODE, TYPE, 4, 8); +FIELD(REV_CODE, PROCESSOR, 12, 4); +FIELD(REV_CODE, MANUFACTURER, 16, 4); +FIELD(REV_CODE, MEMORY_SIZE, 20, 3); +FIELD(REV_CODE, STYLE, 23, 1); + +static int board_processor_id(uint32_t board_rev) +{ +assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ +return FIELD_EX32(board_rev, REV_CODE, PROCESSOR); +} + +static int board_version(uint32_t board_rev) +{ +return board_processor_id(board_rev) + 1; +} + static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info) { static const uint32_t smpboot[] = { @@ -164,9 +187,10 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); } -static void raspi_init(MachineState *machine, int version) +static void raspi_init(MachineState *machine, uint32_t board_rev) { RasPiState *s = g_new0(RasPiState, 1); +int version = board_version(board_rev); uint32_t vcram_size; DriveInfo *di; BlockBackend *blk; @@ -192,7 +216,6 @@ static void raspi_init(MachineState *machine, int version) /* Setup the SOC */ object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram), &error_abort); -int board_rev = version == 3 ? 0xa02082 : 0xa21041; object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev", &error_abort); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort); @@ -216,7 +239,7 @@ static void raspi_init(MachineState *machine, int version) static void raspi2_init(MachineState *machine) { -raspi_init(machine, 2); +raspi_init(machine, 0xa21041); } static void raspi2_machine_init(MachineClass *mc) @@ -238,7 +261,7 @@ DEFINE_MACHINE("raspi2", raspi2_machine_init) #ifdef TARGET_AARCH64 static void raspi3_init(MachineState *machine) { -raspi_init(machine, 3); +raspi_init(machine, 0xa02082); } static void raspi3_machine_init(MachineClass *mc) -- 2.20.1
Re: [PULL 0/9] Mini misc patches queue for 2020-02-12
On Wed, 12 Feb 2020 at 16:42, Paolo Bonzini wrote: > > The following changes since commit 7bd9d0a9e26c7a3c67c0f174f0009ba19969b158: > > Merge remote-tracking branch > 'remotes/huth-gitlab/tags/pull-request-2020-02-04' into staging (2020-02-04 > 16:12:31 +) > > are available in the Git repository at: > > git://github.com/bonzini/qemu.git tags/for-upstream > > for you to fetch changes up to be02cda3afde60d219786e23c3f8edb53aec8e17: > > target/i386: enable monitor and ucode revision with -cpu max (2020-02-12 > 16:29:51 +0100) > > > * various small fixes and cleanups > * fixes for the ucode revision patch from the previous pull request > Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/5.0 for any user-visible changes. -- PMM
[PULL 27/46] target/arm: Update MSR access to UAO
From: Richard Henderson Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-19-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 6 ++ target/arm/internals.h | 3 +++ target/arm/helper.c| 21 + target/arm/translate-a64.c | 14 ++ 4 files changed, 44 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 71879393c22..e943ffe8a9a 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1253,6 +1253,7 @@ void pmu_init(ARMCPU *cpu); #define PSTATE_IL (1U << 20) #define PSTATE_SS (1U << 21) #define PSTATE_PAN (1U << 22) +#define PSTATE_UAO (1U << 23) #define PSTATE_V (1U << 28) #define PSTATE_C (1U << 29) #define PSTATE_Z (1U << 30) @@ -3642,6 +3643,11 @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2; } +static inline bool isar_feature_aa64_uao(const ARMISARegisters *id) +{ +return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0; +} + static inline bool isar_feature_aa64_bti(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0; diff --git a/target/arm/internals.h b/target/arm/internals.h index 4a139644b54..58c4d707c5d 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1112,6 +1112,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) if (isar_feature_aa64_pan(id)) { valid |= PSTATE_PAN; } +if (isar_feature_aa64_uao(id)) { +valid |= PSTATE_UAO; +} return valid; } diff --git a/target/arm/helper.c b/target/arm/helper.c index d29722d8acb..11a5f0be52f 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -4191,6 +4191,24 @@ static const ARMCPRegInfo pan_reginfo = { .readfn = aa64_pan_read, .writefn = aa64_pan_write }; +static uint64_t aa64_uao_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ +return env->pstate & PSTATE_UAO; +} + +static void aa64_uao_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +env->pstate = (env->pstate & ~PSTATE_UAO) | (value & PSTATE_UAO); +} + +static const ARMCPRegInfo uao_reginfo = { +.name = "UAO", .state = ARM_CP_STATE_AA64, +.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4, +.type = ARM_CP_NO_RAW, .access = PL1_RW, +.readfn = aa64_uao_read, .writefn = aa64_uao_write +}; + static CPAccessResult aa64_cacheop_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -7664,6 +7682,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) define_arm_cp_regs(cpu, ats1cp_reginfo); } #endif +if (cpu_isar_feature(aa64_uao, cpu)) { +define_one_arm_cp_reg(cpu, &uao_reginfo); +} if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) { define_arm_cp_regs(cpu, vhe_reginfo); diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index d8ba240a155..7c26c3bfebb 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1602,6 +1602,20 @@ static void handle_msr_i(DisasContext *s, uint32_t insn, s->base.is_jmp = DISAS_NEXT; break; +case 0x03: /* UAO */ +if (!dc_isar_feature(aa64_uao, s) || s->current_el == 0) { +goto do_unallocated; +} +if (crm & 1) { +set_pstate_bits(PSTATE_UAO); +} else { +clear_pstate_bits(PSTATE_UAO); +} +t1 = tcg_const_i32(s->current_el); +gen_helper_rebuild_hflags_a64(cpu_env, t1); +tcg_temp_free_i32(t1); +break; + case 0x04: /* PAN */ if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) { goto do_unallocated; -- 2.20.1
[PULL 37/46] hw/arm/raspi: Extract the processor type from the board revision
From: Philippe Mathieu-Daudé The board revision encode the processor type. Add a helper to extract the type, and use it. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-6-f4...@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index dcd8d2d6d38..7a2ca97347e 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -67,6 +67,21 @@ static int board_version(uint32_t board_rev) return board_processor_id(board_rev) + 1; } +static const char *board_soc_type(uint32_t board_rev) +{ +static const char *soc_types[] = { +NULL, TYPE_BCM2836, TYPE_BCM2837, +}; +int proc_id = board_processor_id(board_rev); + +if (proc_id >= ARRAY_SIZE(soc_types) || !soc_types[proc_id]) { +error_report("Unsupported processor id '%d' (board revision: 0x%x)", + proc_id, board_rev); +exit(1); +} +return soc_types[proc_id]; +} + static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info) { static const uint32_t smpboot[] = { @@ -213,8 +228,7 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) } object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), -version == 3 ? TYPE_BCM2837 : TYPE_BCM2836, -&error_abort, NULL); +board_soc_type(board_rev), &error_abort, NULL); /* Allocate and map RAM */ memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram", -- 2.20.1
[PULL 46/46] target/arm: Implement ARMv8.1-VMID16 extension
The ARMv8.1-VMID16 extension extends the VMID from 8 bits to 16 bits: * the ID_AA64MMFR1_EL1.VMIDBits field specifies whether the VMID is 8 or 16 bits * the VMID field in VTTBR_EL2 is extended to 16 bits * VTCR_EL2.VS lets the guest specify whether to use the full 16 bits, or use the backwards-compatible 8 bits For QEMU implementing this is trivial: * we do not track VMIDs in TLB entries, so we never use the VMID field * we treat any write to VTTBR_EL2, not just a change to the VMID field bits, as a "possible VMID change" that causes us to throw away TLB entries, so that code doesn't need changing * we allow the guest to read/write the VTCR_EL2.VS bit already So all that's missing is the ID register part: report that we support VMID16 in our 'max' CPU. Signed-off-by: Peter Maydell Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-id: 20200210120146.17631-1-peter.mayd...@linaro.org --- target/arm/cpu64.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 1359564c554..f0d98bc79d1 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -674,6 +674,7 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ +t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */ cpu->isar.id_aa64mmfr1 = t; t = cpu->isar.id_aa64mmfr2; -- 2.20.1
[PULL 18/46] target/arm: Remove CPSR_RESERVED
From: Richard Henderson The only remaining use was in op_helper.c. Use PSTATE_SS directly, and move the commentary so that it is more obvious what is going on. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20200208125816.14954-10-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 6 -- target/arm/op_helper.c | 9 - 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 694b0742983..c6dff1d55b6 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1186,12 +1186,6 @@ void pmu_init(ARMCPU *cpu); #define CPSR_IT_2_7 (0xfc00U) #define CPSR_GE (0xfU << 16) #define CPSR_IL (1U << 20) -/* Note that the RESERVED bits include bit 21, which is PSTATE_SS in - * an AArch64 SPSR but RES0 in AArch32 SPSR and CPSR. In QEMU we use - * env->uncached_cpsr bit 21 to store PSTATE.SS when executing in AArch32, - * where it is live state but not accessible to the AArch32 code. - */ -#define CPSR_RESERVED (0x7U << 21) #define CPSR_J (1U << 24) #define CPSR_IT_0_1 (3U << 25) #define CPSR_Q (1U << 27) diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index acf1815ea3e..af3020b78f8 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -387,7 +387,14 @@ void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome) uint32_t HELPER(cpsr_read)(CPUARMState *env) { -return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED); +/* + * We store the ARMv8 PSTATE.SS bit in env->uncached_cpsr. + * This is convenient for populating SPSR_ELx, but must be + * hidden from aarch32 mode, where it is not visible. + * + * TODO: ARMv8.4-DIT -- need to move SS somewhere else. + */ +return cpsr_read(env) & ~(CPSR_EXEC | PSTATE_SS); } void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) -- 2.20.1
[PULL 39/46] hw/arm/raspi: Make machines children of abstract RaspiMachineClass
From: Philippe Mathieu-Daudé QOM'ify RaspiMachineState. Now machines inherit of RaspiMachineClass. Cc: Igor Mammedov Signed-off-by: Philippe Mathieu-Daudé Acked-by: Igor Mammedov Message-id: 20200208165645.15657-8-f4...@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 56 +++--- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index b3e6f72b55a..62b8df3c2e7 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -34,10 +34,28 @@ /* Registered machine type (matches RPi Foundation bootloader and U-Boot) */ #define MACH_TYPE_BCM2708 3138 -typedef struct RasPiState { +typedef struct RaspiMachineState { +/*< private >*/ +MachineState parent_obj; +/*< public >*/ BCM283XState soc; MemoryRegion ram; -} RasPiState; +} RaspiMachineState; + +typedef struct RaspiMachineClass { +/*< private >*/ +MachineClass parent_obj; +/*< public >*/ +} RaspiMachineClass; + +#define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common") +#define RASPI_MACHINE(obj) \ +OBJECT_CHECK(RaspiMachineState, (obj), TYPE_RASPI_MACHINE) + +#define RASPI_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(RaspiMachineClass, (klass), TYPE_RASPI_MACHINE) +#define RASPI_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(RaspiMachineClass, (obj), TYPE_RASPI_MACHINE) /* * Board revision codes: @@ -211,7 +229,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) static void raspi_init(MachineState *machine, uint32_t board_rev) { -RasPiState *s = g_new0(RasPiState, 1); +RaspiMachineState *s = RASPI_MACHINE(machine); int version = board_version(board_rev); uint64_t ram_size = board_ram_size(board_rev); uint32_t vcram_size; @@ -264,8 +282,10 @@ static void raspi2_init(MachineState *machine) raspi_init(machine, 0xa21041); } -static void raspi2_machine_init(MachineClass *mc) +static void raspi2_machine_class_init(ObjectClass *oc, void *data) { +MachineClass *mc = MACHINE_CLASS(oc); + mc->desc = "Raspberry Pi 2B"; mc->init = raspi2_init; mc->block_default_type = IF_SD; @@ -278,7 +298,6 @@ static void raspi2_machine_init(MachineClass *mc) mc->default_ram_size = 1 * GiB; mc->ignore_memory_transaction_failures = true; }; -DEFINE_MACHINE("raspi2", raspi2_machine_init) #ifdef TARGET_AARCH64 static void raspi3_init(MachineState *machine) @@ -286,8 +305,10 @@ static void raspi3_init(MachineState *machine) raspi_init(machine, 0xa02082); } -static void raspi3_machine_init(MachineClass *mc) +static void raspi3_machine_class_init(ObjectClass *oc, void *data) { +MachineClass *mc = MACHINE_CLASS(oc); + mc->desc = "Raspberry Pi 3B"; mc->init = raspi3_init; mc->block_default_type = IF_SD; @@ -299,5 +320,26 @@ static void raspi3_machine_init(MachineClass *mc) mc->default_cpus = BCM283X_NCPUS; mc->default_ram_size = 1 * GiB; } -DEFINE_MACHINE("raspi3", raspi3_machine_init) #endif + +static const TypeInfo raspi_machine_types[] = { +{ +.name = MACHINE_TYPE_NAME("raspi2"), +.parent = TYPE_RASPI_MACHINE, +.class_init = raspi2_machine_class_init, +#ifdef TARGET_AARCH64 +}, { +.name = MACHINE_TYPE_NAME("raspi3"), +.parent = TYPE_RASPI_MACHINE, +.class_init = raspi3_machine_class_init, +#endif +}, { +.name = TYPE_RASPI_MACHINE, +.parent = TYPE_MACHINE, +.instance_size = sizeof(RaspiMachineState), +.class_size = sizeof(RaspiMachineClass), +.abstract = true, +} +}; + +DEFINE_TYPES(raspi_machine_types) -- 2.20.1
[PULL 34/46] hw/arm/raspi: Correct the board descriptions
From: Philippe Mathieu-Daudé We hardcode the board revision as 0xa21041 for the raspi2, and 0xa02082 for the raspi3: 166 static void raspi_init(MachineState *machine, int version) 167 { ... 194 int board_rev = version == 3 ? 0xa02082 : 0xa21041; These revision codes are for the 2B and 3B models, see: https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md Correct the board description. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-3-f4...@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index f2ccabc6628..818146fdbb2 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -221,7 +221,7 @@ static void raspi2_init(MachineState *machine) static void raspi2_machine_init(MachineClass *mc) { -mc->desc = "Raspberry Pi 2"; +mc->desc = "Raspberry Pi 2B"; mc->init = raspi2_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; @@ -243,7 +243,7 @@ static void raspi3_init(MachineState *machine) static void raspi3_machine_init(MachineClass *mc) { -mc->desc = "Raspberry Pi 3"; +mc->desc = "Raspberry Pi 3B"; mc->init = raspi3_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; -- 2.20.1
[PULL 11/46] target/arm: Add mmu_idx for EL1 and EL2 w/ PAN enabled
From: Richard Henderson To implement PAN, we will want to swap, for short periods of time, to a different privileged mmu_idx. In addition, we cannot do this with flushing alone, because the AT* instructions have both PAN and PAN-less versions. Add the ARMMMUIdx*_PAN constants where necessary next to the corresponding ARMMMUIdx* constant. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-3-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu-param.h | 2 +- target/arm/cpu.h | 33 ++--- target/arm/internals.h | 9 ++ target/arm/helper.c| 60 +++--- target/arm/translate-a64.c | 3 ++ target/arm/translate.c | 2 ++ 6 files changed, 87 insertions(+), 22 deletions(-) diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index 18ac5623462..d593b60b28d 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -29,6 +29,6 @@ # define TARGET_PAGE_BITS_MIN 10 #endif -#define NB_MMU_MODES 9 +#define NB_MMU_MODES 12 #endif diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 0b3036c484f..c63bceaaa5f 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2751,20 +2751,24 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync); * 5. we want to be able to use the TLB for accesses done as part of a * stage1 page table walk, rather than having to walk the stage2 page * table over and over. + * 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access + * Never (PAN) bit within PSTATE. * * This gives us the following list of cases: * * NS EL0 EL1&0 stage 1+2 (aka NS PL0) * NS EL1 EL1&0 stage 1+2 (aka NS PL1) + * NS EL1 EL1&0 stage 1+2 +PAN * NS EL0 EL2&0 - * NS EL2 EL2&0 + * NS EL2 EL2&0 +PAN * NS EL2 (aka NS PL2) * S EL0 EL1&0 (aka S PL0) * S EL1 EL1&0 (not used if EL3 is 32 bit) + * S EL1 EL1&0 +PAN * S EL3 (aka S PL1) * NS EL1&0 stage 2 * - * for a total of 9 different mmu_idx. + * for a total of 12 different mmu_idx. * * R profile CPUs have an MPU, but can use the same set of MMU indexes * as A profile. They only need to distinguish NS EL0 and NS EL1 (and @@ -2819,19 +2823,22 @@ typedef enum ARMMMUIdx { /* * A-profile. */ -ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A, -ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A, +ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A, +ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A, -ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A, +ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A, +ARMMMUIdx_E10_1_PAN = 3 | ARM_MMU_IDX_A, -ARMMMUIdx_E2 = 3 | ARM_MMU_IDX_A, -ARMMMUIdx_E20_2 = 4 | ARM_MMU_IDX_A, +ARMMMUIdx_E2 = 4 | ARM_MMU_IDX_A, +ARMMMUIdx_E20_2 = 5 | ARM_MMU_IDX_A, +ARMMMUIdx_E20_2_PAN = 6 | ARM_MMU_IDX_A, -ARMMMUIdx_SE10_0 = 5 | ARM_MMU_IDX_A, -ARMMMUIdx_SE10_1 = 6 | ARM_MMU_IDX_A, -ARMMMUIdx_SE3 =7 | ARM_MMU_IDX_A, +ARMMMUIdx_SE10_0 = 7 | ARM_MMU_IDX_A, +ARMMMUIdx_SE10_1 = 8 | ARM_MMU_IDX_A, +ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A, +ARMMMUIdx_SE3= 10 | ARM_MMU_IDX_A, -ARMMMUIdx_Stage2 = 8 | ARM_MMU_IDX_A, +ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A, /* * These are not allocated TLBs and are used only for AT system @@ -2839,6 +2846,7 @@ typedef enum ARMMMUIdx { */ ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB, ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB, +ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB, /* * M-profile. @@ -2864,10 +2872,13 @@ typedef enum ARMMMUIdxBit { TO_CORE_BIT(E10_0), TO_CORE_BIT(E20_0), TO_CORE_BIT(E10_1), +TO_CORE_BIT(E10_1_PAN), TO_CORE_BIT(E2), TO_CORE_BIT(E20_2), +TO_CORE_BIT(E20_2_PAN), TO_CORE_BIT(SE10_0), TO_CORE_BIT(SE10_1), +TO_CORE_BIT(SE10_1_PAN), TO_CORE_BIT(SE3), TO_CORE_BIT(Stage2), diff --git a/target/arm/internals.h b/target/arm/internals.h index 1f8ee5f573e..6be8b2d1a9b 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -843,12 +843,16 @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx) switch (mmu_idx) { case ARMMMUIdx_Stage1_E0: case ARMMMUIdx_Stage1_E1: +case ARMMMUIdx_Stage1_E1_PAN: case ARMMMUIdx_E10_0: case ARMMMUIdx_E10_1: +case ARMMMUIdx_E10_1_PAN: case ARMMMUIdx_E20_0: case ARMMMUIdx_E20_2: +case ARMMMUIdx_E20_2_PAN: case ARMMMUIdx_SE10_0: case ARMMMUIdx_SE10_1: +case ARMMMUIdx_SE10_1_PAN: return true; default: return false; @@ -861,10 +865,13 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) switch (mmu_idx) { case ARMMMUIdx_E10_0: case ARMMMUIdx_E10_1: +case ARMMMUIdx_E10_1_PAN: case ARMMMUIdx_E20_0: case ARMMMUIdx_E20_2: +case ARMMMUIdx_E20_2_PAN: case ARMMMUIdx_Stage1_E0: cas
[PULL 33/46] hw/arm/raspi: Use BCM2708 machine type with pre Device Tree kernels
From: Philippe Mathieu-Daudé When booting without device tree, the Linux kernels uses the $R1 register to determine the machine type. The list of values is registered at [1]. There are two entries for the Raspberry Pi: - https://www.arm.linux.org.uk/developer/machines/list.php?mid=3138 name: MACH_TYPE_BCM2708 value: 0xc42 (3138) status: Active, not mainlined date: 15 Oct 2010 - https://www.arm.linux.org.uk/developer/machines/list.php?mid=4828 name: MACH_TYPE_BCM2835 value: 4828 status: Active, mainlined date: 6 Dec 2013 QEMU always used the non-mainlined type MACH_TYPE_BCM2708. The value 0xc43 is registered to 'MX51_GGC' (processor i.MX51), and 0xc44 to 'Western Digital Sharespace NAS' (processor Marvell 88F5182). The Raspberry Pi foundation bootloader only sets the BCM2708 machine type, see [2] or [3]: 133 9: 134 mov r0, #0 135 ldr r1, =3138 @ BCM2708 machine id 136 ldr r2, atags @ ATAGS 137 bx r4 U-Boot only uses MACH_TYPE_BCM2708 (see [4]): 25 /* 26 * 2835 is a SKU in a series for which the 2708 is the first or primary SoC, 27 * so 2708 has historically been used rather than a dedicated 2835 ID. 28 * 29 * We don't define a machine type for bcm2709/bcm2836 since the RPi Foundation 30 * chose to use someone else's previously registered machine ID (3139, MX51_GGC) 31 * rather than obtaining a valid ID:-/ 32 * 33 * For the bcm2837, hopefully a machine type is not needed, since everything 34 * is DT. 35 */ While the definition MACH_BCM2709 with value 0xc43 was introduced in a commit described "Add 2709 platform for Raspberry Pi 2" out of the mainline Linux kernel, it does not seem used, and the platform is introduced with Device Tree support anyway (see [5] and [6]). Remove the unused values (0xc43 introduced in commit 1df7d1f9303aef "raspi: add raspberry pi 2 machine" and 0xc44 in commit bade58166f4 "raspi: Raspberry Pi 3 support"), keeping only MACH_TYPE_BCM2708. [1] https://www.arm.linux.org.uk/developer/machines/ [2] https://github.com/raspberrypi/tools/blob/920c7ed2e/armstubs/armstub7.S#L135 [3] https://github.com/raspberrypi/tools/blob/49719d554/armstubs/armstub7.S#L64 [4] https://gitlab.denx.de/u-boot/u-boot/blob/v2015.04/include/configs/rpi-common.h#L18 [5] https://github.com/raspberrypi/linux/commit/d9fac63adac#diff-6722037d79570df5b392a49e0e006573R526 [6] http://lists.infradead.org/pipermail/linux-rpi-kernel/2015-February/001268.html Cc: Zoltán Baldaszti Cc: Pekka Enberg Cc: Stephen Warren Cc: Kshitij Soni Cc: Michael Chan Cc: Andrew Baumann Reviewed-by: Alistair Francis Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Niek Linnenbank Message-id: 20200208165645.15657-2-f4...@amsat.org Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 3996f6c63a4..f2ccabc6628 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -29,8 +29,8 @@ #define FIRMWARE_ADDR_3 0x8 /* Pi 3 loads kernel.img here by default */ #define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */ -/* Table of Linux board IDs for different Pi versions */ -static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44}; +/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */ +#define MACH_TYPE_BCM2708 3138 typedef struct RasPiState { BCM283XState soc; @@ -116,7 +116,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) static struct arm_boot_info binfo; int r; -binfo.board_id = raspi_boardid[version]; +binfo.board_id = MACH_TYPE_BCM2708; binfo.ram_size = ram_size; binfo.nb_cpus = machine->smp.cpus; -- 2.20.1
[PULL 45/46] hw/arm/raspi: Extract the cores count from the board revision
From: Philippe Mathieu-Daudé The count of ARM cores is encoded in the board revision. Add a helper to extract the number of cores, and use it. This will be helpful when we add the Raspi0/1 that have a single core. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-14-f4...@amsat.org Reviewed-by: Peter Maydell [PMM: tweaked commit message as suggested by Igor] Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index bee6ca0a086..90ad9b81158 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -101,6 +101,21 @@ static const char *board_soc_type(uint32_t board_rev) return soc_types[proc_id]; } +static int cores_count(uint32_t board_rev) +{ +static const int soc_cores_count[] = { +0, BCM283X_NCPUS, BCM283X_NCPUS, +}; +int proc_id = board_processor_id(board_rev); + +if (proc_id >= ARRAY_SIZE(soc_cores_count) || !soc_cores_count[proc_id]) { +error_report("Unsupported processor id '%d' (board revision: 0x%x)", + proc_id, board_rev); +exit(1); +} +return soc_cores_count[proc_id]; +} + static const char *board_type(uint32_t board_rev) { static const char *types[] = { @@ -307,9 +322,7 @@ static void raspi_machine_class_init(ObjectClass *oc, void *data) mc->no_parallel = 1; mc->no_floppy = 1; mc->no_cdrom = 1; -mc->max_cpus = BCM283X_NCPUS; -mc->min_cpus = BCM283X_NCPUS; -mc->default_cpus = BCM283X_NCPUS; +mc->default_cpus = mc->min_cpus = mc->max_cpus = cores_count(board_rev); mc->default_ram_size = board_ram_size(board_rev); if (board_version(board_rev) == 2) { mc->ignore_memory_transaction_failures = true; -- 2.20.1
[PULL 40/46] hw/arm/raspi: Make board_rev a field of RaspiMachineClass
From: Philippe Mathieu-Daudé We want to have a common class_init(). The only value that matters (and changes) is the board revision. Pass the board_rev as class_data to class_init(). Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-9-f4...@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 17 ++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 62b8df3c2e7..fbfcd297326 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -46,6 +46,7 @@ typedef struct RaspiMachineClass { /*< private >*/ MachineClass parent_obj; /*< public >*/ +uint32_t board_rev; } RaspiMachineClass; #define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common") @@ -227,9 +228,11 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); } -static void raspi_init(MachineState *machine, uint32_t board_rev) +static void raspi_init(MachineState *machine) { +RaspiMachineClass *mc = RASPI_MACHINE_GET_CLASS(machine); RaspiMachineState *s = RASPI_MACHINE(machine); +uint32_t board_rev = mc->board_rev; int version = board_version(board_rev); uint64_t ram_size = board_ram_size(board_rev); uint32_t vcram_size; @@ -279,13 +282,16 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) static void raspi2_init(MachineState *machine) { -raspi_init(machine, 0xa21041); +raspi_init(machine); } static void raspi2_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); +RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); +uint32_t board_rev = (uint32_t)(uintptr_t)data; +rmc->board_rev = board_rev; mc->desc = "Raspberry Pi 2B"; mc->init = raspi2_init; mc->block_default_type = IF_SD; @@ -302,13 +308,16 @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data) #ifdef TARGET_AARCH64 static void raspi3_init(MachineState *machine) { -raspi_init(machine, 0xa02082); +raspi_init(machine); } static void raspi3_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); +RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); +uint32_t board_rev = (uint32_t)(uintptr_t)data; +rmc->board_rev = board_rev; mc->desc = "Raspberry Pi 3B"; mc->init = raspi3_init; mc->block_default_type = IF_SD; @@ -327,11 +336,13 @@ static const TypeInfo raspi_machine_types[] = { .name = MACHINE_TYPE_NAME("raspi2"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi2_machine_class_init, +.class_data = (void *)0xa21041, #ifdef TARGET_AARCH64 }, { .name = MACHINE_TYPE_NAME("raspi3"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi3_machine_class_init, +.class_data = (void *)0xa02082, #endif }, { .name = TYPE_RASPI_MACHINE, -- 2.20.1
[PULL 29/46] target/arm: Enable ARMv8.2-UAO in -cpu max
From: Richard Henderson Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-21-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu64.c | 4 1 file changed, 4 insertions(+) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 57fbc5eade7..1359564c554 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -676,6 +676,10 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ cpu->isar.id_aa64mmfr1 = t; +t = cpu->isar.id_aa64mmfr2; +t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); +cpu->isar.id_aa64mmfr2 = t; + /* Replicate the same data to the 32-bit id registers. */ u = cpu->isar.id_isar5; u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */ -- 2.20.1
[PULL 14/46] target/arm: Split out aarch32_cpsr_valid_mask
From: Richard Henderson Split this helper out of msr_mask in translate.c. At the same time, transform the negative reductive logic to positive accumulative logic. It will be usable along the exception paths. While touching msr_mask, fix up formatting. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20200208125816.14954-6-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 21 + target/arm/translate.c | 40 +--- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index 6be8b2d1a9b..4d4896fcdcf 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1061,6 +1061,27 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx) } } +static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, + const ARMISARegisters *id) +{ +uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV | CPSR_J; + +if ((features >> ARM_FEATURE_V4T) & 1) { +valid |= CPSR_T; +} +if ((features >> ARM_FEATURE_V5) & 1) { +valid |= CPSR_Q; /* V5TE in reality*/ +} +if ((features >> ARM_FEATURE_V6) & 1) { +valid |= CPSR_E | CPSR_GE; +} +if ((features >> ARM_FEATURE_THUMB2) & 1) { +valid |= CPSR_IT; +} + +return valid; +} + /* * Parameters of a given virtual address, as extracted from the * translation control register (TCR) for a given regime. diff --git a/target/arm/translate.c b/target/arm/translate.c index d58c328e08e..20f89ace2fd 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -2734,39 +2734,33 @@ static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y) /* Return the mask of PSR bits set by a MSR instruction. */ static uint32_t msr_mask(DisasContext *s, int flags, int spsr) { -uint32_t mask; +uint32_t mask = 0; -mask = 0; -if (flags & (1 << 0)) +if (flags & (1 << 0)) { mask |= 0xff; -if (flags & (1 << 1)) +} +if (flags & (1 << 1)) { mask |= 0xff00; -if (flags & (1 << 2)) +} +if (flags & (1 << 2)) { mask |= 0xff; -if (flags & (1 << 3)) +} +if (flags & (1 << 3)) { mask |= 0xff00; +} -/* Mask out undefined bits. */ -mask &= ~CPSR_RESERVED; -if (!arm_dc_feature(s, ARM_FEATURE_V4T)) { -mask &= ~CPSR_T; -} -if (!arm_dc_feature(s, ARM_FEATURE_V5)) { -mask &= ~CPSR_Q; /* V5TE in reality*/ -} -if (!arm_dc_feature(s, ARM_FEATURE_V6)) { -mask &= ~(CPSR_E | CPSR_GE); -} -if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) { -mask &= ~CPSR_IT; -} -/* Mask out execution state and reserved bits. */ +/* Mask out undefined and reserved bits. */ +mask &= aarch32_cpsr_valid_mask(s->features, s->isar); + +/* Mask out execution state. */ if (!spsr) { -mask &= ~(CPSR_EXEC | CPSR_RESERVED); +mask &= ~CPSR_EXEC; } + /* Mask out privileged bits. */ -if (IS_USER(s)) +if (IS_USER(s)) { mask &= CPSR_USER; +} return mask; } -- 2.20.1
[PULL 38/46] hw/arm/raspi: Trivial code movement
From: Philippe Mathieu-Daudé There is no point in creating the SoC object before allocating the RAM. Move the call to keep all the SoC-related calls together. Signed-off-by: Philippe Mathieu-Daudé Acked-by: Igor Mammedov Message-id: 20200208165645.15657-7-f4...@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 7a2ca97347e..b3e6f72b55a 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -227,9 +227,6 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) exit(1); } -object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), -board_soc_type(board_rev), &error_abort, NULL); - /* Allocate and map RAM */ memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram", machine->ram_size); @@ -237,6 +234,8 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) memory_region_add_subregion_overlap(get_system_memory(), 0, &s->ram, 0); /* Setup the SOC */ +object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), +board_soc_type(board_rev), &error_abort, NULL); object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram), &error_abort); object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev", -- 2.20.1
[PULL 13/46] target/arm: Move LOR regdefs to file scope
From: Richard Henderson For static const regdefs, file scope is preferred. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-5-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 57 +++-- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index bfd6c0d04bd..e4f17c7e839 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6334,6 +6334,35 @@ static CPAccessResult access_lor_other(CPUARMState *env, return access_lor_ns(env); } +/* + * A trivial implementation of ARMv8.1-LOR leaves all of these + * registers fixed at 0, which indicates that there are zero + * supported Limited Ordering regions. + */ +static const ARMCPRegInfo lor_reginfo[] = { +{ .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "LORN_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "LORC_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, +{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7, + .access = PL1_R, .accessfn = access_lorid, + .type = ARM_CP_CONST, .resetvalue = 0 }, +REGINFO_SENTINEL +}; + #ifdef TARGET_AARCH64 static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -7568,34 +7597,6 @@ void register_cp_regs_for_features(ARMCPU *cpu) } if (cpu_isar_feature(aa64_lor, cpu)) { -/* - * A trivial implementation of ARMv8.1-LOR leaves all of these - * registers fixed at 0, which indicates that there are zero - * supported Limited Ordering regions. - */ -static const ARMCPRegInfo lor_reginfo[] = { -{ .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0, - .access = PL1_RW, .accessfn = access_lor_other, - .type = ARM_CP_CONST, .resetvalue = 0 }, -{ .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1, - .access = PL1_RW, .accessfn = access_lor_other, - .type = ARM_CP_CONST, .resetvalue = 0 }, -{ .name = "LORN_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2, - .access = PL1_RW, .accessfn = access_lor_other, - .type = ARM_CP_CONST, .resetvalue = 0 }, -{ .name = "LORC_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3, - .access = PL1_RW, .accessfn = access_lor_other, - .type = ARM_CP_CONST, .resetvalue = 0 }, -{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7, - .access = PL1_R, .accessfn = access_lorid, - .type = ARM_CP_CONST, .resetvalue = 0 }, -REGINFO_SENTINEL -}; define_arm_cp_regs(cpu, lor_reginfo); } -- 2.20.1
[PULL 31/46] hw/arm: ast2600: Wire up EHCI controllers
From: Guenter Roeck Initialize EHCI controllers on AST2600 using the existing TYPE_PLATFORM_EHCI. After this change, booting ast2600-evb into Linux successfully instantiates a USB interface after the necessary changes are made to its devicetree files. ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver ehci-platform: EHCI generic platform driver ehci-platform 1e6a3000.usb: EHCI Host Controller ehci-platform 1e6a3000.usb: new USB bus registered, assigned bus number 1 ehci-platform 1e6a3000.usb: irq 25, io mem 0x1e6a3000 ehci-platform 1e6a3000.usb: USB 2.0 started, EHCI 1.00 usb usb1: Manufacturer: Linux 5.5.0-09825-ga0802f2d0ef5-dirty ehci_hcd usb 1-1: new high-speed USB device number 2 using ehci-platform Reviewed-by: Cédric Le Goater Signed-off-by: Guenter Roeck Reviewed-by: Niek Linnenbank Message-id: 20200207174548.9087-1-li...@roeck-us.net Signed-off-by: Peter Maydell --- hw/arm/aspeed_ast2600.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index 90cf1c755d3..446b44d31cf 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -31,6 +31,8 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = { [ASPEED_FMC] = 0x1E62, [ASPEED_SPI1] = 0x1E63, [ASPEED_SPI2] = 0x1E641000, +[ASPEED_EHCI1] = 0x1E6A1000, +[ASPEED_EHCI2] = 0x1E6A3000, [ASPEED_MII1] = 0x1E65, [ASPEED_MII2] = 0x1E650008, [ASPEED_MII3] = 0x1E650010, @@ -79,6 +81,8 @@ static const int aspeed_soc_ast2600_irqmap[] = { [ASPEED_ADC] = 78, [ASPEED_XDMA] = 6, [ASPEED_SDHCI] = 43, +[ASPEED_EHCI1] = 5, +[ASPEED_EHCI2] = 9, [ASPEED_EMMC] = 15, [ASPEED_GPIO] = 40, [ASPEED_GPIO_1_8V] = 11, @@ -166,6 +170,11 @@ static void aspeed_soc_ast2600_init(Object *obj) sizeof(s->spi[i]), typename); } +for (i = 0; i < sc->ehcis_num; i++) { +sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]), + sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI); +} + snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), typename); @@ -416,6 +425,19 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) s->spi[i].ctrl->flash_window_base); } +/* EHCI */ +for (i = 0; i < sc->ehcis_num; i++) { +object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized", &err); +if (err) { +error_propagate(errp, err); +return; +} +sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, +sc->memmap[ASPEED_EHCI1 + i]); +sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, + aspeed_soc_get_irq(s, ASPEED_EHCI1 + i)); +} + /* SDMC - SDRAM Memory Controller */ object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); if (err) { @@ -534,6 +556,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data) sc->silicon_rev = AST2600_A0_SILICON_REV; sc->sram_size= 0x1; sc->spis_num = 2; +sc->ehcis_num= 2; sc->wdts_num = 4; sc->macs_num = 4; sc->irqmap = aspeed_soc_ast2600_irqmap; -- 2.20.1
[PULL 23/46] target/arm: Set PAN bit as required on exception entry
From: Richard Henderson The PAN bit is preserved, or set as per SCTLR_ELx.SPAN, plus several other conditions listed in the ARM ARM. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20200208125816.14954-15-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 53 ++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 178757d2719..de16ce79add 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8763,8 +8763,12 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, uint32_t mask, uint32_t offset, uint32_t newpc) { +int new_el; + /* Change the CPU state so as to actually take the exception. */ switch_mode(env, new_mode); +new_el = arm_current_el(env); + /* * For exceptions taken to AArch32 we must clear the SS bit in both * PSTATE and in the old-state value we save to SPSR_, so zero it now. @@ -8777,7 +8781,7 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode; /* Set new mode endianness */ env->uncached_cpsr &= ~CPSR_E; -if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) { +if (env->cp15.sctlr_el[new_el] & SCTLR_EE) { env->uncached_cpsr |= CPSR_E; } /* J and IL must always be cleared for exception entry */ @@ -8788,6 +8792,25 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0; env->elr_el[2] = env->regs[15]; } else { +/* CPSR.PAN is normally preserved preserved unless... */ +if (cpu_isar_feature(aa64_pan, env_archcpu(env))) { +switch (new_el) { +case 3: +if (!arm_is_secure_below_el3(env)) { +/* ... the target is EL3, from non-secure state. */ +env->uncached_cpsr &= ~CPSR_PAN; +break; +} +/* ... the target is EL3, from secure state ... */ +/* fall through */ +case 1: +/* ... the target is EL1 and SCTLR.SPAN is 0. */ +if (!(env->cp15.sctlr_el[new_el] & SCTLR_SPAN)) { +env->uncached_cpsr |= CPSR_PAN; +} +break; +} +} /* * this is a lie, as there was no c1_sys on V4T/V5, but who cares * and we should just guard the thumb mode on V4 @@ -9050,6 +9073,7 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs) unsigned int new_el = env->exception.target_el; target_ulong addr = env->cp15.vbar_el[new_el]; unsigned int new_mode = aarch64_pstate_mode(new_el, true); +unsigned int old_mode; unsigned int cur_el = arm_current_el(env); /* @@ -9129,20 +9153,43 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs) } if (is_a64(env)) { -env->banked_spsr[aarch64_banked_spsr_index(new_el)] = pstate_read(env); +old_mode = pstate_read(env); aarch64_save_sp(env, arm_current_el(env)); env->elr_el[new_el] = env->pc; } else { -env->banked_spsr[aarch64_banked_spsr_index(new_el)] = cpsr_read(env); +old_mode = cpsr_read(env); env->elr_el[new_el] = env->regs[15]; aarch64_sync_32_to_64(env); env->condexec_bits = 0; } +env->banked_spsr[aarch64_banked_spsr_index(new_el)] = old_mode; + qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n", env->elr_el[new_el]); +if (cpu_isar_feature(aa64_pan, cpu)) { +/* The value of PSTATE.PAN is normally preserved, except when ... */ +new_mode |= old_mode & PSTATE_PAN; +switch (new_el) { +case 2: +/* ... the target is EL2 with HCR_EL2.{E2H,TGE} == '11' ... */ +if ((arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) +!= (HCR_E2H | HCR_TGE)) { +break; +} +/* fall through */ +case 1: +/* ... the target is EL1 ... */ +/* ... and SCTLR_ELx.SPAN == 0, then set to 1. */ +if ((env->cp15.sctlr_el[new_el] & SCTLR_SPAN) == 0) { +new_mode |= PSTATE_PAN; +} +break; +} +} + pstate_write(env, PSTATE_DAIF | new_mode); env->aarch64 = 1; aarch64_restore_sp(env, new_el); -- 2.20.1
[PULL 26/46] target/arm: Add ID_AA64MMFR2_EL1
From: Richard Henderson Add definitions for all of the fields, up to ARMv8.5. Convert the existing RESERVED register to a full register. Query KVM for the value of the register for the host. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-18-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h| 17 + target/arm/helper.c | 4 ++-- target/arm/kvm64.c | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 65a0ef8cd6b..71879393c22 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -871,6 +871,7 @@ struct ARMCPU { uint64_t id_aa64pfr1; uint64_t id_aa64mmfr0; uint64_t id_aa64mmfr1; +uint64_t id_aa64mmfr2; } isar; uint32_t midr; uint32_t revidr; @@ -1803,6 +1804,22 @@ FIELD(ID_AA64MMFR1, PAN, 20, 4) FIELD(ID_AA64MMFR1, SPECSEI, 24, 4) FIELD(ID_AA64MMFR1, XNX, 28, 4) +FIELD(ID_AA64MMFR2, CNP, 0, 4) +FIELD(ID_AA64MMFR2, UAO, 4, 4) +FIELD(ID_AA64MMFR2, LSM, 8, 4) +FIELD(ID_AA64MMFR2, IESB, 12, 4) +FIELD(ID_AA64MMFR2, VARANGE, 16, 4) +FIELD(ID_AA64MMFR2, CCIDX, 20, 4) +FIELD(ID_AA64MMFR2, NV, 24, 4) +FIELD(ID_AA64MMFR2, ST, 28, 4) +FIELD(ID_AA64MMFR2, AT, 32, 4) +FIELD(ID_AA64MMFR2, IDS, 36, 4) +FIELD(ID_AA64MMFR2, FWB, 40, 4) +FIELD(ID_AA64MMFR2, TTL, 48, 4) +FIELD(ID_AA64MMFR2, BBM, 52, 4) +FIELD(ID_AA64MMFR2, EVT, 56, 4) +FIELD(ID_AA64MMFR2, E0PD, 60, 4) + FIELD(ID_DFR0, COPDBG, 0, 4) FIELD(ID_DFR0, COPSDBG, 4, 4) FIELD(ID_DFR0, MMAPDBG, 8, 4) diff --git a/target/arm/helper.c b/target/arm/helper.c index d99661d4ea5..d29722d8acb 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -7073,11 +7073,11 @@ void register_cp_regs_for_features(ARMCPU *cpu) .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, .resetvalue = cpu->isar.id_aa64mmfr1 }, -{ .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, +{ .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = 0 }, + .resetvalue = cpu->isar.id_aa64mmfr2 }, { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index fb21ab9e737..3bae9e4a663 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -549,6 +549,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ARM64_SYS_REG(3, 0, 0, 7, 0)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1, ARM64_SYS_REG(3, 0, 0, 7, 1)); +err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2, + ARM64_SYS_REG(3, 0, 0, 7, 2)); /* * Note that if AArch32 support is not present in the host, -- 2.20.1
[PULL 32/46] hw/char/exynos4210_uart: Fix memleaks in exynos4210_uart_init
From: Chen Qun It's easy to reproduce as follow: virsh qemu-monitor-command vm1 --pretty '{"execute": "device-list-properties", "arguments":{"typename":"exynos4210.uart"}}' ASAN shows memory leak stack: #1 0xfffd896d71cb in g_malloc0 (/lib64/libglib-2.0.so.0+0x571cb) #2 0xaaad270beee3 in timer_new_full /qemu/include/qemu/timer.h:530 #3 0xaaad270beee3 in timer_new /qemu/include/qemu/timer.h:551 #4 0xaaad270beee3 in timer_new_ns /qemu/include/qemu/timer.h:569 #5 0xaaad270beee3 in exynos4210_uart_init /qemu/hw/char/exynos4210_uart.c:677 #6 0xaaad275c8f4f in object_initialize_with_type /qemu/qom/object.c:516 #7 0xaaad275c91bb in object_new_with_type /qemu/qom/object.c:684 #8 0xaaad2755df2f in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:152 Reported-by: Euler Robot Signed-off-by: Chen Qun Reviewed-by: Philippe Mathieu-Daudé Message-id: 20200213025603.149432-1-kuhn.chen...@huawei.com Signed-off-by: Peter Maydell --- hw/char/exynos4210_uart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index 25d6588e413..96d5180e3e2 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -674,8 +674,6 @@ static void exynos4210_uart_init(Object *obj) SysBusDevice *dev = SYS_BUS_DEVICE(obj); Exynos4210UartState *s = EXYNOS4210_UART(dev); -s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - exynos4210_uart_timeout_int, s); s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600; /* memory mapping */ @@ -691,6 +689,9 @@ static void exynos4210_uart_realize(DeviceState *dev, Error **errp) { Exynos4210UartState *s = EXYNOS4210_UART(dev); +s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + exynos4210_uart_timeout_int, s); + qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive, exynos4210_uart_receive, exynos4210_uart_event, NULL, s, NULL, true); -- 2.20.1
[PULL 24/46] target/arm: Implement ATS1E1 system registers
From: Richard Henderson This is a minor enhancement over ARMv8.1-PAN. The *_PAN mmu_idx are used with the existing do_ats_write. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-16-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 56 - 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index de16ce79add..d99661d4ea5 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3409,16 +3409,21 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) switch (ri->opc2 & 6) { case 0: -/* stage 1 current state PL1: ATS1CPR, ATS1CPW */ +/* stage 1 current state PL1: ATS1CPR, ATS1CPW, ATS1CPRP, ATS1CPWP */ switch (el) { case 3: mmu_idx = ARMMMUIdx_SE3; break; case 2: -mmu_idx = ARMMMUIdx_Stage1_E1; -break; +g_assert(!secure); /* TODO: ARMv8.4-SecEL2 */ +/* fall through */ case 1: -mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1; +if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) { +mmu_idx = (secure ? ARMMMUIdx_SE10_1_PAN + : ARMMMUIdx_Stage1_E1_PAN); +} else { +mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1; +} break; default: g_assert_not_reached(); @@ -3487,8 +3492,13 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri, switch (ri->opc2 & 6) { case 0: switch (ri->opc1) { -case 0: /* AT S1E1R, AT S1E1W */ -mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1; +case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */ +if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) { +mmu_idx = (secure ? ARMMMUIdx_SE10_1_PAN + : ARMMMUIdx_Stage1_E1_PAN); +} else { +mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1; +} break; case 4: /* AT S1E2R, AT S1E2W */ mmu_idx = ARMMMUIdx_E2; @@ -6683,6 +6693,32 @@ static const ARMCPRegInfo vhe_reginfo[] = { REGINFO_SENTINEL }; +#ifndef CONFIG_USER_ONLY +static const ARMCPRegInfo ats1e1_reginfo[] = { +{ .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, +{ .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, +REGINFO_SENTINEL +}; + +static const ARMCPRegInfo ats1cp_reginfo[] = { +{ .name = "ATS1CPRP", + .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write }, +{ .name = "ATS1CPWP", + .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write }, +REGINFO_SENTINEL +}; +#endif + void register_cp_regs_for_features(ARMCPU *cpu) { /* Register all the coprocessor registers based on feature bits */ @@ -7620,6 +7656,14 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (cpu_isar_feature(aa64_pan, cpu)) { define_one_arm_cp_reg(cpu, &pan_reginfo); } +#ifndef CONFIG_USER_ONLY +if (cpu_isar_feature(aa64_ats1e1, cpu)) { +define_arm_cp_regs(cpu, ats1e1_reginfo); +} +if (cpu_isar_feature(aa32_ats1e1, cpu)) { +define_arm_cp_regs(cpu, ats1cp_reginfo); +} +#endif if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) { define_arm_cp_regs(cpu, vhe_reginfo); -- 2.20.1
[PULL 08/46] arm/acpi: simplify the description of PCI _CRS
From: Heyi Guo The original code defines a named object for the resource template but then returns the resource template object itself; the resulted output is like below: Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings { Name (RBUF, ResourceTemplate () { WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, 0x, // Granularity 0x, // Range Minimum 0x00FF, // Range Maximum 0x, // Translation Offset 0x0100, // Length ,, ) .. }) Return (ResourceTemplate () { WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, 0x, // Granularity 0x, // Range Minimum 0x00FF, // Range Maximum 0x, // Translation Offset 0x0100, // Length ,, ) .. }) } So the named object "RBUF" is actually useless. The more natural way is to return RBUF instead, or simply drop RBUF definition. Choose the latter one to simplify the code. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-7-guoh...@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index f3e340b1729..fb4b166f82c 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -236,7 +236,6 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, size_mmio_high)); } -aml_append(method, aml_name_decl("RBUF", rbuf)); aml_append(method, aml_return(rbuf)); aml_append(dev, method); -- 2.20.1
[PULL 28/46] target/arm: Implement UAO semantics
From: Richard Henderson We need only override the current condition under which TBFLAG_A64.UNPRIV is set. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-20-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 41 + 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 11a5f0be52f..366dbcf460d 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -12198,28 +12198,29 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el, } /* Compute the condition for using AccType_UNPRIV for LDTR et al. */ -/* TODO: ARMv8.2-UAO */ -switch (mmu_idx) { -case ARMMMUIdx_E10_1: -case ARMMMUIdx_E10_1_PAN: -case ARMMMUIdx_SE10_1: -case ARMMMUIdx_SE10_1_PAN: -/* TODO: ARMv8.3-NV */ -flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1); -break; -case ARMMMUIdx_E20_2: -case ARMMMUIdx_E20_2_PAN: -/* TODO: ARMv8.4-SecEL2 */ -/* - * Note that E20_2 is gated by HCR_EL2.E2H == 1, but E20_0 is - * gated by HCR_EL2. == '11', and so is LDTR. - */ -if (env->cp15.hcr_el2 & HCR_TGE) { +if (!(env->pstate & PSTATE_UAO)) { +switch (mmu_idx) { +case ARMMMUIdx_E10_1: +case ARMMMUIdx_E10_1_PAN: +case ARMMMUIdx_SE10_1: +case ARMMMUIdx_SE10_1_PAN: +/* TODO: ARMv8.3-NV */ flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1); +break; +case ARMMMUIdx_E20_2: +case ARMMMUIdx_E20_2_PAN: +/* TODO: ARMv8.4-SecEL2 */ +/* + * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is + * gated by HCR_EL2. == '11', and so is LDTR. + */ +if (env->cp15.hcr_el2 & HCR_TGE) { +flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1); +} +break; +default: +break; } -break; -default: -break; } return rebuild_hflags_common(env, fp_el, mmu_idx, flags); -- 2.20.1
[PULL 20/46] target/arm: Update MSR access for PAN
From: Richard Henderson For aarch64, there's a dedicated msr (imm, reg) insn. For aarch32, this is done via msr to cpsr. Writes from el0 are ignored, which is already handled by the CPSR_USER mask. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-12-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 ++ target/arm/internals.h | 6 ++ target/arm/helper.c| 21 + target/arm/translate-a64.c | 14 ++ 4 files changed, 43 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c6dff1d55b6..65a0ef8cd6b 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1186,6 +1186,7 @@ void pmu_init(ARMCPU *cpu); #define CPSR_IT_2_7 (0xfc00U) #define CPSR_GE (0xfU << 16) #define CPSR_IL (1U << 20) +#define CPSR_PAN (1U << 22) #define CPSR_J (1U << 24) #define CPSR_IT_0_1 (3U << 25) #define CPSR_Q (1U << 27) @@ -1250,6 +1251,7 @@ void pmu_init(ARMCPU *cpu); #define PSTATE_BTYPE (3U << 10) #define PSTATE_IL (1U << 20) #define PSTATE_SS (1U << 21) +#define PSTATE_PAN (1U << 22) #define PSTATE_V (1U << 28) #define PSTATE_C (1U << 29) #define PSTATE_Z (1U << 30) diff --git a/target/arm/internals.h b/target/arm/internals.h index 034d98ad538..f6709a2b08d 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1081,6 +1081,9 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, if (isar_feature_jazelle(id)) { valid |= CPSR_J; } +if (isar_feature_aa32_pan(id)) { +valid |= CPSR_PAN; +} return valid; } @@ -1093,6 +1096,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) if (isar_feature_aa64_bti(id)) { valid |= PSTATE_BTYPE; } +if (isar_feature_aa64_pan(id)) { +valid |= PSTATE_PAN; +} return valid; } diff --git a/target/arm/helper.c b/target/arm/helper.c index e4f17c7e839..058fb239592 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -4163,6 +4163,24 @@ static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri, env->daif = value & PSTATE_DAIF; } +static uint64_t aa64_pan_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ +return env->pstate & PSTATE_PAN; +} + +static void aa64_pan_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +env->pstate = (env->pstate & ~PSTATE_PAN) | (value & PSTATE_PAN); +} + +static const ARMCPRegInfo pan_reginfo = { +.name = "PAN", .state = ARM_CP_STATE_AA64, +.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 3, +.type = ARM_CP_NO_RAW, .access = PL1_RW, +.readfn = aa64_pan_read, .writefn = aa64_pan_write +}; + static CPAccessResult aa64_cacheop_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -7599,6 +7617,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (cpu_isar_feature(aa64_lor, cpu)) { define_arm_cp_regs(cpu, lor_reginfo); } +if (cpu_isar_feature(aa64_pan, cpu)) { +define_one_arm_cp_reg(cpu, &pan_reginfo); +} if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) { define_arm_cp_regs(cpu, vhe_reginfo); diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 49631c23404..d8ba240a155 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1602,6 +1602,20 @@ static void handle_msr_i(DisasContext *s, uint32_t insn, s->base.is_jmp = DISAS_NEXT; break; +case 0x04: /* PAN */ +if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) { +goto do_unallocated; +} +if (crm & 1) { +set_pstate_bits(PSTATE_PAN); +} else { +clear_pstate_bits(PSTATE_PAN); +} +t1 = tcg_const_i32(s->current_el); +gen_helper_rebuild_hflags_a64(cpu_env, t1); +tcg_temp_free_i32(t1); +break; + case 0x05: /* SPSel */ if (s->current_el == 0) { goto do_unallocated; -- 2.20.1
[PULL 22/46] target/arm: Enforce PAN semantics in get_S1prot
From: Richard Henderson If we have a PAN-enforcing mmu_idx, set prot == 0 if user_rw != 0. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-14-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 13 + target/arm/helper.c| 3 +++ 2 files changed, 16 insertions(+) diff --git a/target/arm/internals.h b/target/arm/internals.h index f6709a2b08d..4a139644b54 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -893,6 +893,19 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) } } +static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx) +{ +switch (mmu_idx) { +case ARMMMUIdx_Stage1_E1_PAN: +case ARMMMUIdx_E10_1_PAN: +case ARMMMUIdx_E20_2_PAN: +case ARMMMUIdx_SE10_1_PAN: +return true; +default: +return false; +} +} + /* Return the FSR value for a debug exception (watchpoint, hardware * breakpoint or BKPT insn) targeting the specified exception level. */ diff --git a/target/arm/helper.c b/target/arm/helper.c index f6a600aa004..178757d2719 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -9569,6 +9569,9 @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64, if (is_user) { prot_rw = user_rw; } else { +if (user_rw && regime_is_pan(env, mmu_idx)) { +return 0; +} prot_rw = simple_ap_to_rw_prot_is_user(ap, false); } -- 2.20.1
[PULL 05/46] arm/virt/acpi: remove _ADR from devices identified by _HID
From: Heyi Guo According to ACPI spec, _ADR should be used for device on a bus that has a standard enumeration algorithm, but not for device which is on system bus and must be enumerated by OSPM. And it is not recommended to contain both _HID and _ADR in a single device. See ACPI 6.3, section 6.1, top of page 343: A device object must contain either an _HID object or an _ADR object, but should not contain both. (https://uefi.org/sites/default/files/resources/ACPI_6_3_May16.pdf) Signed-off-by: Heyi Guo Acked-by: Igor Mammedov Acked-by: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-4-guoh...@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 8 1 file changed, 8 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 9f4c7d1889c..be752c0ad8e 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -78,11 +78,6 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, AML_EXCLUSIVE, &uart_irq, 1)); aml_append(dev, aml_name_decl("_CRS", crs)); -/* The _ADR entry is used to link this device to the UART described - * in the SPCR table, i.e. SPCR.base_address.address == _ADR. - */ -aml_append(dev, aml_name_decl("_ADR", aml_int(uart_memmap->base))); - aml_append(scope, dev); } @@ -170,7 +165,6 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03"))); aml_append(dev, aml_name_decl("_SEG", aml_int(0))); aml_append(dev, aml_name_decl("_BBN", aml_int(0))); -aml_append(dev, aml_name_decl("_ADR", aml_int(0))); aml_append(dev, aml_name_decl("_UID", aml_string("PCI0"))); aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device"))); aml_append(dev, aml_name_decl("_CCA", aml_int(1))); @@ -334,7 +328,6 @@ static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, { Aml *dev = aml_device("GPO0"); aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0061"))); -aml_append(dev, aml_name_decl("_ADR", aml_int(0))); aml_append(dev, aml_name_decl("_UID", aml_int(0))); Aml *crs = aml_resource_template(); @@ -364,7 +357,6 @@ static void acpi_dsdt_add_power_button(Aml *scope) { Aml *dev = aml_device(ACPI_POWER_BUTTON_DEVICE); aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C0C"))); -aml_append(dev, aml_name_decl("_ADR", aml_int(0))); aml_append(dev, aml_name_decl("_UID", aml_int(0))); aml_append(scope, dev); } -- 2.20.1
[PULL 25/46] target/arm: Enable ARMv8.2-ATS1E1 in -cpu max
From: Richard Henderson This includes enablement of ARMv8.1-PAN. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-17-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.c | 4 target/arm/cpu64.c | 5 + 2 files changed, 9 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index b0762a76c4b..de733aceeb8 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2709,6 +2709,10 @@ static void arm_max_initfn(Object *obj) t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */ cpu->isar.mvfr2 = t; +t = cpu->id_mmfr3; +t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */ +cpu->id_mmfr3 = t; + t = cpu->id_mmfr4; t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */ cpu->id_mmfr4 = t; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index c80fb5fd438..57fbc5eade7 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -673,6 +673,7 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); +t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ cpu->isar.id_aa64mmfr1 = t; /* Replicate the same data to the 32-bit id registers. */ @@ -693,6 +694,10 @@ static void aarch64_max_initfn(Object *obj) u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1); cpu->isar.id_isar6 = u; +u = cpu->id_mmfr3; +u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */ +cpu->id_mmfr3 = u; + /* * FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet, * so do not set MVFR1.FPHP. Strictly speaking this is not legal, -- 2.20.1
[PULL 19/46] target/arm: Introduce aarch64_pstate_valid_mask
From: Richard Henderson Use this along the exception return path, where we previously accepted any values. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-11-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 12 target/arm/helper-a64.c | 1 + 2 files changed, 13 insertions(+) diff --git a/target/arm/internals.h b/target/arm/internals.h index 0569c96fd94..034d98ad538 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1085,6 +1085,18 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, return valid; } +static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) +{ +uint32_t valid; + +valid = PSTATE_M | PSTATE_DAIF | PSTATE_IL | PSTATE_SS | PSTATE_NZCV; +if (isar_feature_aa64_bti(id)) { +valid |= PSTATE_BTYPE; +} + +return valid; +} + /* * Parameters of a given virtual address, as extracted from the * translation control register (TCR) for a given regime. diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index 0c9feba3929..509ae930698 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -1032,6 +1032,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) cur_el, new_el, env->regs[15]); } else { env->aarch64 = 1; +spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar); pstate_write(env, spsr); if (!arm_singlestep_active(env)) { env->pstate &= ~PSTATE_SS; -- 2.20.1
[PULL 06/46] arm/acpi: fix PCI _PRT definition
From: Heyi Guo The address field in each _PRT mapping package should be constructed with high word for device# and low word for function#, so it is wrong to use bus_no as the high word. The existing code adds a bunch useless entries with device #s above 31. Enumerate all possible slots (i.e. PCI_SLOT_MAX) instead. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-5-guoh...@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index be752c0ad8e..5d157a9dd5e 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -151,7 +151,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, { int ecam_id = VIRT_ECAM_ID(highmem_ecam); Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf; -int i, bus_no; +int i, slot_no; hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base; hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size; hwaddr base_pio = memmap[VIRT_PCIE_PIO].base; @@ -170,12 +170,12 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, aml_append(dev, aml_name_decl("_CCA", aml_int(1))); /* Declare the PCI Routing Table. */ -Aml *rt_pkg = aml_varpackage(nr_pcie_buses * PCI_NUM_PINS); -for (bus_no = 0; bus_no < nr_pcie_buses; bus_no++) { +Aml *rt_pkg = aml_varpackage(PCI_SLOT_MAX * PCI_NUM_PINS); +for (slot_no = 0; slot_no < PCI_SLOT_MAX; slot_no++) { for (i = 0; i < PCI_NUM_PINS; i++) { -int gsi = (i + bus_no) % PCI_NUM_PINS; +int gsi = (i + slot_no) % PCI_NUM_PINS; Aml *pkg = aml_package(4); -aml_append(pkg, aml_int((bus_no << 16) | 0x)); +aml_append(pkg, aml_int((slot_no << 16) | 0x)); aml_append(pkg, aml_int(i)); aml_append(pkg, aml_name("GSI%d", gsi)); aml_append(pkg, aml_int(0)); -- 2.20.1
[PULL 21/46] target/arm: Update arm_mmu_idx_el for PAN
From: Richard Henderson Examine the PAN bit for EL1, EL2, and Secure EL1 to determine if it applies. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-13-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 9 + 1 file changed, 9 insertions(+) diff --git a/target/arm/helper.c b/target/arm/helper.c index 058fb239592..f6a600aa004 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11895,13 +11895,22 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el) return ARMMMUIdx_E10_0; case 1: if (arm_is_secure_below_el3(env)) { +if (env->pstate & PSTATE_PAN) { +return ARMMMUIdx_SE10_1_PAN; +} return ARMMMUIdx_SE10_1; } +if (env->pstate & PSTATE_PAN) { +return ARMMMUIdx_E10_1_PAN; +} return ARMMMUIdx_E10_1; case 2: /* TODO: ARMv8.4-SecEL2 */ /* Note that TGE does not apply at EL2. */ if ((env->cp15.hcr_el2 & HCR_E2H) && arm_el_is_aa64(env, 2)) { +if (env->pstate & PSTATE_PAN) { +return ARMMMUIdx_E20_2_PAN; +} return ARMMMUIdx_E20_2; } return ARMMMUIdx_E2; -- 2.20.1
[PULL 12/46] target/arm: Add isar_feature tests for PAN + ATS1E1
From: Richard Henderson Include definitions for all of the bits in ID_MMFR3. We already have a definition for ID_AA64MMFR1.PAN. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-4-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 29 + 1 file changed, 29 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c63bceaaa5f..08b2f5d73e4 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1727,6 +1727,15 @@ FIELD(ID_ISAR6, FHM, 8, 4) FIELD(ID_ISAR6, SB, 12, 4) FIELD(ID_ISAR6, SPECRES, 16, 4) +FIELD(ID_MMFR3, CMAINTVA, 0, 4) +FIELD(ID_MMFR3, CMAINTSW, 4, 4) +FIELD(ID_MMFR3, BPMAINT, 8, 4) +FIELD(ID_MMFR3, MAINTBCST, 12, 4) +FIELD(ID_MMFR3, PAN, 16, 4) +FIELD(ID_MMFR3, COHWALK, 20, 4) +FIELD(ID_MMFR3, CMEMSZ, 24, 4) +FIELD(ID_MMFR3, SUPERSEC, 28, 4) + FIELD(ID_MMFR4, SPECSEI, 0, 4) FIELD(ID_MMFR4, AC2, 4, 4) FIELD(ID_MMFR4, XNX, 8, 4) @@ -3443,6 +3452,16 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id) return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4; } +static inline bool isar_feature_aa32_pan(const ARMISARegisters *id) +{ +return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) != 0; +} + +static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id) +{ +return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2; +} + /* * 64-bit feature tests via id registers. */ @@ -3602,6 +3621,16 @@ static inline bool isar_feature_aa64_lor(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0; } +static inline bool isar_feature_aa64_pan(const ARMISARegisters *id) +{ +return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0; +} + +static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id) +{ +return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2; +} + static inline bool isar_feature_aa64_bti(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0; -- 2.20.1
[PULL 17/46] target/arm: Use aarch32_cpsr_valid_mask in helper_exception_return
From: Richard Henderson Using ~0 as the mask on the aarch64->aarch32 exception return was not even as correct as the CPSR_ERET_MASK that we had used on the aarch32->aarch32 exception return. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-9-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper-a64.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index bf45f8a785e..0c9feba3929 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -959,7 +959,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) { int cur_el = arm_current_el(env); unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el); -uint32_t spsr = env->banked_spsr[spsr_idx]; +uint32_t mask, spsr = env->banked_spsr[spsr_idx]; int new_el; bool return_to_aa64 = (spsr & PSTATE_nRW) == 0; @@ -1014,7 +1014,8 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) * will sort the register banks out for us, and we've already * caught all the bad-mode cases in el_from_spsr(). */ -cpsr_write(env, spsr, ~0, CPSRWriteRaw); +mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar); +cpsr_write(env, spsr, mask, CPSRWriteRaw); if (!arm_singlestep_active(env)) { env->uncached_cpsr &= ~PSTATE_SS; } -- 2.20.1
[PULL 02/46] i.MX: Add support for WDT on i.MX6
From: Roman Kapl Uses the i.MX2 rudimentary watchdog driver. Signed-off-by: Roman Kapl Message-id: 20200207095529.11309-1-...@sysgo.com Reviewed-by: Peter Maydell [PMM: removed accidental duplicate #include line] Signed-off-by: Peter Maydell --- include/hw/arm/fsl-imx6.h | 3 +++ hw/arm/fsl-imx6.c | 21 + 2 files changed, 24 insertions(+) diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h index 1265a55c3b0..60eadccb421 100644 --- a/include/hw/arm/fsl-imx6.h +++ b/include/hw/arm/fsl-imx6.h @@ -21,6 +21,7 @@ #include "hw/cpu/a9mpcore.h" #include "hw/misc/imx6_ccm.h" #include "hw/misc/imx6_src.h" +#include "hw/misc/imx2_wdt.h" #include "hw/char/imx_serial.h" #include "hw/timer/imx_gpt.h" #include "hw/timer/imx_epit.h" @@ -42,6 +43,7 @@ #define FSL_IMX6_NUM_GPIOS 7 #define FSL_IMX6_NUM_ESDHCS 4 #define FSL_IMX6_NUM_ECSPIS 5 +#define FSL_IMX6_NUM_WDTS 2 typedef struct FslIMX6State { /*< private >*/ @@ -59,6 +61,7 @@ typedef struct FslIMX6State { IMXGPIOState gpio[FSL_IMX6_NUM_GPIOS]; SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS]; IMXSPIStatespi[FSL_IMX6_NUM_ECSPIS]; +IMX2WdtState wdt[FSL_IMX6_NUM_WDTS]; IMXFECStateeth; MemoryRegion rom; MemoryRegion caam; diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c index 552145b24ec..ecc62855f2b 100644 --- a/hw/arm/fsl-imx6.c +++ b/hw/arm/fsl-imx6.c @@ -91,6 +91,12 @@ static void fsl_imx6_init(Object *obj) sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]), TYPE_IMX_SPI); } +for (i = 0; i < FSL_IMX6_NUM_WDTS; i++) { +snprintf(name, NAME_SIZE, "wdt%d", i); +sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]), + TYPE_IMX2_WDT); +} + sysbus_init_child_obj(obj, "eth", &s->eth, sizeof(s->eth), TYPE_IMX_ENET); } @@ -383,6 +389,21 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_ENET_MAC_1588_IRQ)); +/* + * Watchdog + */ +for (i = 0; i < FSL_IMX6_NUM_WDTS; i++) { +static const hwaddr FSL_IMX6_WDOGn_ADDR[FSL_IMX6_NUM_WDTS] = { +FSL_IMX6_WDOG1_ADDR, +FSL_IMX6_WDOG2_ADDR, +}; + +object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", + &error_abort); + +sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX6_WDOGn_ADDR[i]); +} + /* ROM memory */ memory_region_init_rom(&s->rom, NULL, "imx6.rom", FSL_IMX6_ROM_SIZE, &err); -- 2.20.1
[PULL 09/46] virt/acpi: update golden masters for DSDT update
From: Heyi Guo Differences between disassembled ASL files: @@ -5,13 +5,13 @@ * * Disassembling to symbolic ASL+ operators * - * Disassembly of DSDT, Thu Jan 23 16:00:04 2020 + * Disassembly of DSDT.new, Thu Jan 23 16:47:12 2020 * * Original Table Header: * Signature"DSDT" - * Length 0x481E (18462) + * Length 0x14BB (5307) * Revision 0x02 - * Checksum 0x60 + * Checksum 0xD1 * OEM ID "BOCHS " * OEM Table ID "BXPCDSDT" * OEM Revision 0x0001 (1) @@ -43,7 +43,6 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x0001) 0x0021, } }) -Name (_ADR, 0x0900) // _ADR: Address } Device (FLS0) @@ -668,11 +667,10 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x0001) Name (_CID, "PNP0A03" /* PCI Bus */) // _CID: Compatible ID Name (_SEG, Zero) // _SEG: PCI Segment Name (_BBN, Zero) // _BBN: BIOS Bus Number -Name (_ADR, Zero) // _ADR: Address Name (_UID, "PCI0") // _UID: Unique ID Name (_STR, Unicode ("PCIe 0 Device")) // _STR: Description String Name (_CCA, One) // _CCA: Cache Coherency Attribute -Name (_PRT, Package (0x0400) // _PRT: PCI Routing Table +Name (_PRT, Package (0x80) // _PRT: PCI Routing Table { Package (0x04) { @@ -1696,7174 +1694,6 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x0001) 0x03, GSI2, Zero -}, - -Package (0x04) -{ -0x0020, -Zero, -GSI0, -Zero -}, - -*Omit the other (4 * (256 - 32) - 2) packages* - -Package (0x04) -{ -0x00FF, -0x03, -GSI2, -Zero } }) Device (GSI0) @@ -8892,7 +1722,7 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x0001) Device (GSI1) { Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID -Name (_UID, Zero) // _UID: Unique ID +Name (_UID, One) // _UID: Unique ID Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings { Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) @@ -8915,7 +1745,7 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x0001) Device (GSI2) { Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID -Name (_UID, Zero) // _UID: Unique ID +Name (_UID, 0x02) // _UID: Unique ID Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings { Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) @@ -8938,7 +1768,7 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x0001) Device (GSI3) { Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID -Name (_UID, Zero) // _UID: Unique ID +Name (_UID, 0x03) // _UID: Unique ID Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings { Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) @@ -8965,37 +1795,6 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x0001) Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings { -Name (RBUF, ResourceTemplate () -{ -WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, -0x, // Granularity -0x, // Range Minimum -0x00FF, // Range Maximum -0x, // Translation Offset -0x0100, // Length -,, ) -DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, -0x, // Granularity -0x1000, // Range Minimum -0x3EFE, // Range Maximum -0x, // Translation Offset -0x2EFF, // Length -,, , AddressRangeMemory, TypeStatic) -DWordIO (Reso
[PULL 10/46] target/arm: Add arm_mmu_idx_is_stage1_of_2
From: Richard Henderson Use a common predicate for querying stage1-ness. Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-2-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 18 ++ target/arm/helper.c| 8 +++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index 6d4a942bde4..1f8ee5f573e 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1034,6 +1034,24 @@ static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env) ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env); #endif +/** + * arm_mmu_idx_is_stage1_of_2: + * @mmu_idx: The ARMMMUIdx to test + * + * Return true if @mmu_idx is a NOTLB mmu_idx that is the + * first stage of a two stage regime. + */ +static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx) +{ +switch (mmu_idx) { +case ARMMMUIdx_Stage1_E0: +case ARMMMUIdx_Stage1_E1: +return true; +default: +return false; +} +} + /* * Parameters of a given virtual address, as extracted from the * translation control register (TCR) for a given regime. diff --git a/target/arm/helper.c b/target/arm/helper.c index 7d15d5c933c..57dc7a307c0 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3261,8 +3261,7 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value, bool take_exc = false; if (fi.s1ptw && current_el == 1 && !arm_is_secure(env) -&& (mmu_idx == ARMMMUIdx_Stage1_E1 || -mmu_idx == ARMMMUIdx_Stage1_E0)) { +&& arm_mmu_idx_is_stage1_of_2(mmu_idx)) { /* * Synchronous stage 2 fault on an access made as part of the * translation table walk for AT S1E0* or AT S1E1* insn @@ -9285,8 +9284,7 @@ static inline bool regime_translation_disabled(CPUARMState *env, } } -if ((env->cp15.hcr_el2 & HCR_DC) && -(mmu_idx == ARMMMUIdx_Stage1_E0 || mmu_idx == ARMMMUIdx_Stage1_E1)) { +if ((env->cp15.hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) { /* HCR.DC means SCTLR_EL1.M behaves as 0 */ return true; } @@ -9595,7 +9593,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, hwaddr addr, MemTxAttrs txattrs, ARMMMUFaultInfo *fi) { -if ((mmu_idx == ARMMMUIdx_Stage1_E0 || mmu_idx == ARMMMUIdx_Stage1_E1) && +if (arm_mmu_idx_is_stage1_of_2(mmu_idx) && !regime_translation_disabled(env, ARMMMUIdx_Stage2)) { target_ulong s2size; hwaddr s2pa; -- 2.20.1
[PULL 16/46] target/arm: Replace CPSR_ERET_MASK with aarch32_cpsr_valid_mask
From: Richard Henderson CPSR_ERET_MASK was a useless renaming of CPSR_RESERVED. The function also takes into account bits that the cpu does not support. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-8-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 -- target/arm/op_helper.c | 5 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 08b2f5d73e4..694b0742983 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1209,8 +1209,6 @@ void pmu_init(ARMCPU *cpu); #define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE) /* Execution state bits. MRS read as zero, MSR writes ignored. */ #define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J | CPSR_IL) -/* Mask of bits which may be set by exception return copying them from SPSR */ -#define CPSR_ERET_MASK (~CPSR_RESERVED) /* Bit definitions for M profile XPSR. Most are the same as CPSR. */ #define XPSR_EXCP 0x1ffU diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 27d16ad9ad9..acf1815ea3e 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -400,11 +400,14 @@ void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) /* Write the CPSR for a 32-bit exception return */ void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val) { +uint32_t mask; + qemu_mutex_lock_iothread(); arm_call_pre_el_change_hook(env_archcpu(env)); qemu_mutex_unlock_iothread(); -cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn); +mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar); +cpsr_write(env, val, mask, CPSRWriteExceptionReturn); /* Generated code has already stored the new PC value, but * without masking out its low bits, because which bits need -- 2.20.1
[PULL 04/46] arm/virt/acpi: remove meaningless sub device "RP0" from PCI0
From: Heyi Guo The sub device "RP0" under PCI0 in ACPI/DSDT does not contain any method or property other than "_ADR", so it is safe to remove it. Signed-off-by: Heyi Guo Acked-by: "Michael S. Tsirkin" Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-3-guoh...@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 4 1 file changed, 4 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index bd5f771e9be..9f4c7d1889c 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -317,10 +317,6 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, aml_append(method, aml_return(buf)); aml_append(dev, method); -Aml *dev_rp0 = aml_device("%s", "RP0"); -aml_append(dev_rp0, aml_name_decl("_ADR", aml_int(0))); -aml_append(dev, dev_rp0); - Aml *dev_res0 = aml_device("%s", "RES0"); aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02"))); crs = aml_resource_template(); -- 2.20.1
[PULL 07/46] arm/acpi: fix duplicated _UID of PCI interrupt link devices
From: Heyi Guo Using _UID of 0 for all PCI interrupt link devices absolutely violates the spec. Simply increase one by one. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-6-guoh...@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 5d157a9dd5e..f3e340b1729 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -189,7 +189,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, uint32_t irqs = irq + i; Aml *dev_gsi = aml_device("GSI%d", i); aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F"))); -aml_append(dev_gsi, aml_name_decl("_UID", aml_int(0))); +aml_append(dev_gsi, aml_name_decl("_UID", aml_int(i))); crs = aml_resource_template(); aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, -- 2.20.1
[PULL 00/46] target-arm queue
Big pullreq this week, since it's got RTH's PAN/UAO/ATS1E1 implementation in it, and also Philippe's raspi board model cleanup patchset, as well as a scattering of smaller stuff. -- PMM The following changes since commit 7ce9ce89930ce260af839fb3e3e5f9101f5c69a0: Merge remote-tracking branch 'remotes/kraxel/tags/ui-20200212-pull-request' into staging (2020-02-13 11:06:32 +) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200213 for you to fetch changes up to dc7a88d0810ad272bdcd2e0869359af78fdd9114: target/arm: Implement ARMv8.1-VMID16 extension (2020-02-13 14:30:51 +) target-arm queue: * i.MX: Fix inverted sense of register bits in watchdog timer * i.MX: Add support for WDT on i.MX6 * arm/virt: cleanups to ACPI tables * Implement ARMv8.1-VMID16 extension * Implement ARMv8.1-PAN * Implement ARMv8.2-UAO * Implement ARMv8.2-ATS1E1 * ast2400/2500/2600: Wire up EHCI controllers * hw/char/exynos4210_uart: Fix memleaks in exynos4210_uart_init * hw/arm/raspi: Clean up the board code Chen Qun (1): hw/char/exynos4210_uart: Fix memleaks in exynos4210_uart_init Guenter Roeck (2): hw/arm: ast2400/ast2500: Wire up EHCI controllers hw/arm: ast2600: Wire up EHCI controllers Heyi Guo (7): bios-tables-test: prepare to change ARM virt ACPI DSDT arm/virt/acpi: remove meaningless sub device "RP0" from PCI0 arm/virt/acpi: remove _ADR from devices identified by _HID arm/acpi: fix PCI _PRT definition arm/acpi: fix duplicated _UID of PCI interrupt link devices arm/acpi: simplify the description of PCI _CRS virt/acpi: update golden masters for DSDT update Peter Maydell (1): target/arm: Implement ARMv8.1-VMID16 extension Philippe Mathieu-Daudé (13): hw/arm/raspi: Use BCM2708 machine type with pre Device Tree kernels hw/arm/raspi: Correct the board descriptions hw/arm/raspi: Extract the version from the board revision hw/arm/raspi: Extract the RAM size from the board revision hw/arm/raspi: Extract the processor type from the board revision hw/arm/raspi: Trivial code movement hw/arm/raspi: Make machines children of abstract RaspiMachineClass hw/arm/raspi: Make board_rev a field of RaspiMachineClass hw/arm/raspi: Let class_init() directly call raspi_machine_init() hw/arm/raspi: Set default RAM size to size encoded in board revision hw/arm/raspi: Extract the board model from the board revision hw/arm/raspi: Use a unique raspi_machine_class_init() method hw/arm/raspi: Extract the cores count from the board revision Richard Henderson (20): target/arm: Add arm_mmu_idx_is_stage1_of_2 target/arm: Add mmu_idx for EL1 and EL2 w/ PAN enabled target/arm: Add isar_feature tests for PAN + ATS1E1 target/arm: Move LOR regdefs to file scope target/arm: Split out aarch32_cpsr_valid_mask target/arm: Mask CPSR_J when Jazelle is not enabled target/arm: Replace CPSR_ERET_MASK with aarch32_cpsr_valid_mask target/arm: Use aarch32_cpsr_valid_mask in helper_exception_return target/arm: Remove CPSR_RESERVED target/arm: Introduce aarch64_pstate_valid_mask target/arm: Update MSR access for PAN target/arm: Update arm_mmu_idx_el for PAN target/arm: Enforce PAN semantics in get_S1prot target/arm: Set PAN bit as required on exception entry target/arm: Implement ATS1E1 system registers target/arm: Enable ARMv8.2-ATS1E1 in -cpu max target/arm: Add ID_AA64MMFR2_EL1 target/arm: Update MSR access to UAO target/arm: Implement UAO semantics target/arm: Enable ARMv8.2-UAO in -cpu max Roman Kapl (2): i.MX: Fix inverted register bits in wdt code. i.MX: Add support for WDT on i.MX6 include/hw/arm/aspeed_soc.h | 6 + include/hw/arm/fsl-imx6.h | 3 + target/arm/cpu-param.h| 2 +- target/arm/cpu.h | 95 --- target/arm/internals.h| 85 ++ hw/arm/aspeed_ast2600.c | 23 +++ hw/arm/aspeed_soc.c | 25 +++ hw/arm/fsl-imx6.c | 21 +++ hw/arm/raspi.c| 190 -- hw/arm/virt-acpi-build.c | 25 +-- hw/char/exynos4210_uart.c | 5 +- hw/misc/imx2_wdt.c| 2 +- target/arm/cpu.c | 4 + target/arm/cpu64.c| 10 ++ target/arm/helper-a64.c | 6 +- target/arm/helper.c | 327 +- target/arm/kvm64.c| 2 + target/arm/op_helper.c| 14 +- target/arm/translate-a64.c| 31 target/arm/translate.c| 42 +++-- tests/data
[PULL 15/46] target/arm: Mask CPSR_J when Jazelle is not enabled
From: Richard Henderson The J bit signals Jazelle mode, and so of course is RES0 when the feature is not enabled. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20200208125816.14954-7-richard.hender...@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index 4d4896fcdcf..0569c96fd94 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1064,7 +1064,7 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx) static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, const ARMISARegisters *id) { -uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV | CPSR_J; +uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV; if ((features >> ARM_FEATURE_V4T) & 1) { valid |= CPSR_T; @@ -1078,6 +1078,9 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, if ((features >> ARM_FEATURE_THUMB2) & 1) { valid |= CPSR_IT; } +if (isar_feature_jazelle(id)) { +valid |= CPSR_J; +} return valid; } -- 2.20.1
[PULL 03/46] bios-tables-test: prepare to change ARM virt ACPI DSDT
From: Heyi Guo We are going to change ARM virt ACPI DSDT table, which will cause make check to fail, so temporarily add related golden masters to ignore list. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-2-guoh...@huawei.com Signed-off-by: Peter Maydell --- tests/qtest/bios-tables-test-allowed-diff.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8bf..32a401ae35f 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,4 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/virt/DSDT", +"tests/data/acpi/virt/DSDT.memhp", +"tests/data/acpi/virt/DSDT.numamem", -- 2.20.1
[PULL 01/46] i.MX: Fix inverted register bits in wdt code.
From: Roman Kapl Documentation says for WDA '0: Assert WDOG output.' and for SRS '0: Assert system reset signal.'. Signed-off-by: Roman Kapl Message-id: 20200207095409.11227-1-...@sysgo.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/misc/imx2_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c index 5576778a323..2aedfe803a4 100644 --- a/hw/misc/imx2_wdt.c +++ b/hw/misc/imx2_wdt.c @@ -29,7 +29,7 @@ static void imx2_wdt_write(void *opaque, hwaddr addr, uint64_t value, unsigned int size) { if (addr == IMX2_WDT_WCR && -(value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) { +(~value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) { watchdog_perform_action(); } } -- 2.20.1
Re: Question about (and problem with) pflash data access
On Thu, 13 Feb 2020 at 14:26, Guenter Roeck wrote: > What really puzzles me is that there is no trace output for > flash data accesses (trace_pflash_data_read and trace_pflash_data_write), > meaning the actual flash data access must be handled elsewhere. > Can someone give me a hint where that might be ? > Clearly I am missing something about inner workings of qemu. Probably the device is in 'romd' mode. A QEMU MemoryRegion can be: * RAM (includes ROM for these purposes) -- backed by host memory, reads and writes (if permitted) go straight to the host memory via fastpath accesses * MMIO -- backed by a read and write accessor function, all accesses go to these functions * "ROM device" -- a mix of the above where there is a backing bit of host memory but also accessor functions. When the device is in "romd" mode, reads go direct to host memory, and writes still go to the accessor function. When the device is not in "romd" mode, reads also go to the accessor function. We use this in the pflash devices to make the common case ("just read the flash") fast. When the guest makes a write to flash that puts it into programming mode, we call memory_region_rom_device_set_romd(..., false) so we can intercept reads and make them do the right thing for programming mode. thanks -- PMM
Re: [PATCH v2 0/4] arm64: Add the cpufreq device to show cpufreq info to guest
On 2020/2/13 16:18, Andrew Jones wrote: On Thu, Feb 13, 2020 at 03:36:26PM +0800, Ying Fang wrote: On ARM64 platform, cpu frequency is retrieved via ACPI CPPC. A virtual cpufreq device based on ACPI CPPC is created to present cpu frequency info to the guest. The default frequency is set to host cpu nominal frequency, which is obtained from the host CPPC sysfs. Other performance data are set to the same value, since we don't support guest performance scaling here. Performance counters are also not emulated and they simply return 1 if read, and guest should fallback to use desired performance value as the current performance. Guest kernel version above 4.18 is required to make it work. This is v2 of the series, but I don't see a changelog. Hi Andrew, please forgive my carelessness, I forget to add the changelog here. Actually v2 is slightly modified with a few fixes for compilation warning and a commit message. Can you please describe the motivation for this? If I understand correctly, all of this is just to inform the guest of the host's CPU0 nominal or max (if nominal isn't present?) frequency. Why do that? Yes, you are right. The motivation is that there seems no other formal way than the CPPC feature for arm64 to present cpu frequency info to the OS. However on x86 platform we have the CPUID method to do that. Some of our VM customers and cloud developers want that information to do something. So we come up with the virtual cpufreq device way. What happens if the guest migrates somewhere where the frequency is different? If the guest is migrated to any host where the frequency is different, a next read on the CPPC related register may return the new cpufreq info. If this is for a special use case, then why not come up with a different channel (guest agent?) to pass this information? Maybe some userspace apps need it to do perf tuning or they want to know the accurate cpu nominal frequency by using tools like lshw. We use the CPPC cpufreq way because we think this is a much more standard way to do that. Thanks, drew . Thanks, Ying
Re: [PATCH v2 1/2] spapr: Disable legacy virtio devices for pseries-5.0 and later
On Thu, 13 Feb 2020 11:58:36 +1100 David Gibson wrote: > PAPR specifies a kind of odd, paravirtualized PCI bus, which looks to > the guess mostly like classic PCI, even if some of the individual > devices on the bus are PCI Express. One consequence of that is that > virtio-pci devices still default to being in transitional mode, though > legacy mode is now disabled by default on current q35 x86 machine > types. > > Legacy mode virtio devices aren't really necessary any more, and are > causing some problems for future changes. Therefore, for the > pseries-5.0 machine type (and onwards), switch to modern-only > virtio-pci devices by default. > > This does mean we no longer support guest kernels prior to 4.0, unless > they have modern virtio support backported (which some distro kernels > like that in RHEL7 do). > > Signed-off-by: David Gibson > --- > hw/ppc/spapr.c | 14 +- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index cb220fde45..6e1e467cc6 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -65,6 +65,7 @@ > > #include "hw/pci/pci.h" > #include "hw/scsi/scsi.h" > +#include "hw/virtio/virtio-pci.h" > #include "hw/virtio/virtio-scsi.h" > #include "hw/virtio/vhost-scsi-common.h" > > @@ -4567,7 +4568,14 @@ static void > spapr_machine_latest_class_options(MachineClass *mc) > */ > static void spapr_machine_5_0_class_options(MachineClass *mc) > { > -/* Defaults for the latest behaviour inherited from the base class */ Hmm... and so it seems we still have to carry this around when we add a new machine version. At least, that's what I had to do when adding a dummy 5.1 machine. This is because it is the old machine type that calls the class_options() function of the new one, not the other way around. I was thinking about adapting Michael's patch. Instead of having a class_options() function that we only call for the latest machine type, we need a function that sets the default behaviour and call it for all machine types (which can still change the behaviour in their own class_options() function). Something like the following: - diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 828e2cc1359a..27e6f79ddc40 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4559,10 +4559,9 @@ static const TypeInfo spapr_machine_info = { }, }; -static void spapr_machine_latest_class_options(MachineClass *mc) +static void spapr_machine_default_class_options(MachineClass *mc) { -mc->alias = "pseries"; -mc->is_default = 1; +/* Override non ppc specific default behaviour here. */ } #define DEFINE_SPAPR_MACHINE(suffix, verstr, latest) \ @@ -4570,9 +4569,11 @@ static void spapr_machine_latest_class_options(MachineClass *mc) void *data) \ {\ MachineClass *mc = MACHINE_CLASS(oc);\ +spapr_machine_default_class_options(mc); \ spapr_machine_##suffix##_class_options(mc); \ if (latest) {\ -spapr_machine_latest_class_options(mc); \ +mc->alias = "pseries"; \ +mc->is_default = 1; \ }\ }\ static const TypeInfo spapr_machine_##suffix##_info = { \ @@ -4591,7 +4592,11 @@ static void spapr_machine_latest_class_options(MachineClass *mc) */ static void spapr_machine_5_0_class_options(MachineClass *mc) { -/* Defaults for the latest behaviour inherited from the base class */ +/* + * Most defaults for the latest behaviour are inherited from the + * base class. If a non ppc specific default behaviour needs to + * be overriden, do it in spapr_machine_latest_class_options(). + */ } DEFINE_SPAPR_MACHINE(5_0, "5.0", true); - With the above applied... > +/* Most defaults for the latest behaviour are inherited from the > + * base class, but we need to override the (non ppc specific) > + * default behaviour for virtio */ > +static GlobalProperty compat[] = { > +{ TYPE_VIRTIO_PCI, "disable-legacy", "on", }, > +}; > + > +compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); ... this change would just need to move to spapr_machine_default_class_options() and any need machine type would have it automatically. Makes sense ? > } > > DEFINE_SPAPR_MACHINE(5_0, "5.0", true); > @@ -4578,12 +4586,16 @@ DEFINE_SPAPR_MACHINE(5_0, "5.0", true); > static void spap
Re: [PATCH v3 12/13] hw/arm/raspi: Use a unique raspi_machine_class_init() method
On Thu, 13 Feb 2020 at 14:16, Philippe Mathieu-Daudé wrote: > On 2/13/20 2:59 PM, Peter Maydell wrote: > > The natural way to implement this is to have the .class_data > > be a pointer to a struct which is in an array and defines > > relevant per-class stuff, the same way we do in > > bcm2836_register_types(). That way the struct can indicate > > both the board revision number and also "is this a legacy > > board that needs transaction-failures disabled?". > > IIUC Igor insists explaining that he doesn't accept anymore a > ".class_data pointer to a struct which is in an array and defines > relevant per-class stuff" and we should not use this pattern anymore. Huh? How else would you do this? I'm kinda dubious about the pattern this patch series uses of just stuffing a 32-bit board ID number into the class_data field, to be honest -- I let that pass partly not to hold up the series but partly because I expect that we'll need to turn it back into a proper pointer to a data struct soonish. thnaks -- PMM
Re: [RFC v3 14/25] intel_iommu: add virtual command capability support
On Thu, Feb 13, 2020 at 02:40:45AM +, Liu, Yi L wrote: > > From: Peter Xu > > Sent: Wednesday, February 12, 2020 5:57 AM > > To: Liu, Yi L > > Subject: Re: [RFC v3 14/25] intel_iommu: add virtual command capability > > support > > > > On Wed, Jan 29, 2020 at 04:16:45AM -0800, Liu, Yi L wrote: > > > +/* > > > + * The basic idea is to let hypervisor to set a range for available > > > + * PASIDs for VMs. One of the reasons is PASID #0 is reserved by > > > + * RID_PASID usage. We have no idea how many reserved PASIDs in future, > > > + * so here just an evaluated value. Honestly, set it as "1" is enough > > > + * at current stage. > > > + */ > > > +#define VTD_MIN_HPASID 1 > > > +#define VTD_MAX_HPASID 0xF > > > > One more question: I see that PASID is defined as 20bits long. It's > > fine. However I start to get confused on how the Scalable Mode PASID > > Directory could service that much of PASID entries. > > > > I'm looking at spec 3.4.3, Figure 3-8. > > > > Firstly, we only have two levels for a PASID table. The context entry > > of a device stores a pointer to the "Scalable Mode PASID Directory" > > page. I see that there're 2^14 entries in "Scalable Mode PASID > > Directory" page, each is a "Scalable Mode PASID Table". > > However... how do we fit in the 4K page if each entry is a pointer of > > x86_64 (8 bytes) while there're 2^14 entries? A simple math gives me > > 4K/8 = 512, which means the "Scalable Mode PASID Directory" page can > > only have 512 entries, then how the 2^14 come from? Hmm?? > > I checked with Kevin. The spec doesn't say the dir table is 4K. It says 4K > only for pasid table. Also, if you look at 9.4, scalabe-mode context entry > includes a PDTS field to specify the actual size of the directory table. Ah I see. Then it seems to be lost then in this series. Say, I think vtd_sm_pasid_table_walk() should also stop walking until reaching the size there, and you need to fetch that size info from the context entry before walk starts. > > > Apart of this: also I just noticed (when reading the latter part of > > the series) that the time that a pasid table walk can consume will > > depend on this value too. I'd suggest to make this as small as we > > can, as long as it satisfies the usage. We can even bump it in the > > future. > > I see. This looks to be an optimization. right? Instead of modify the > value of this macro, I think we can do this optimization by tracking > the allocated PASIDs in QEMU. Thus, the pasid table walk would be more > efficient and also no dependency on the VTD_MAX_HPASID. Does it make > sense to you? :-) Yeah sounds good. :) Thanks, -- Peter Xu
Re: [PATCH v5 7/8] multifd: Add multifd-zstd-level parameter
* Markus Armbruster (arm...@redhat.com) wrote: > "Dr. David Alan Gilbert" writes: > > > * Juan Quintela (quint...@redhat.com) wrote: > >> Signed-off-by: Juan Quintela > >> --- > >> migration/migration.c | 15 +++ > >> monitor/hmp-cmds.c| 4 > >> qapi/migration.json | 29 ++--- > >> 3 files changed, 45 insertions(+), 3 deletions(-) > >> > >> diff --git a/migration/migration.c b/migration/migration.c > >> index 3b081e8147..b690500545 100644 > >> --- a/migration/migration.c > >> +++ b/migration/migration.c > >> @@ -91,6 +91,8 @@ > >> #define DEFAULT_MIGRATE_MULTIFD_METHOD MULTIFD_METHOD_NONE > >> /*0: means nocompress, 1: best speed, ... 9: best compress ratio */ > >> #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1 > >> +/* 0: means nocompress, 1: best speed, ... 20: best compress ratio */ > >> +#define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1 > >> > >> /* Background transfer rate for postcopy, 0 means unlimited, note > >> * that page requests can still exceed this limit. > >> @@ -805,6 +807,8 @@ MigrationParameters > >> *qmp_query_migrate_parameters(Error **errp) > >> params->multifd_method = s->parameters.multifd_method; > >> params->has_multifd_zlib_level = true; > >> params->multifd_zlib_level = s->parameters.multifd_zlib_level; > >> +params->has_multifd_zstd_level = true; > >> +params->multifd_zstd_level = s->parameters.multifd_zstd_level; > > > > Do we really want different 'multifd__level's or just one > > 'multifd_compress_level' - or even just reuse the existing > > 'compress-level' parameter. > > compress-level, multifd-zlib-level, and multifd-zstd-level apply > "normal" live migration compression, multifd zlib live migration > compression, and multifd zstd live migration compression, respectively. > > Any live migration can only use one of the three compressions. > > Correct? Right. > > The only tricky thing about combining them is how to handle > > the difference in allowed ranges; When would the right time be > > to check it? > > > > Markus/Eric: Any idea? > > To have an informed opinion, I'd have to dig through the migration > code. The tricky part I see is validating settings/parameters; when someone tries to set a parameter migrate_params_check gets called and has checks like: if (params->has_compress_level && (params->compress_level > 9)) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", "is invalid, it should be in the range of 0 to 9"); return false; } now that's nice because you error when you set the parameter rather than later when you try and start a migration; the downside now though is you get more complex interaction between parameters and capabilities - so for example if you set the multifd-compression type parameter to 'zstd' and *then* set the single compression level it'll be fine taking '20' as a compresison level, but if you were to set the compression level to 20 and then set the type to 'zstd' it might error because with zlib you can't have 20. > Documentation of admissible range will become a bit awkward, too. > > Too many migration parameters... Nod; which why I was trying to make it 1. Dave -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
Re: [PATCH] hw/char/exynos4210_uart: Fix memleaks in exynos4210_uart_init
Eduardo Habkost writes: > On Wed, Feb 12, 2020 at 08:39:55AM +0100, Philippe Mathieu-Daudé wrote: >> Cc'ing Eduardo & Markus. >> >> On 2/12/20 7:44 AM, Chenqun (kuhn) wrote: >> > > -Original Message- >> > > From: Philippe Mathieu-Daudé [mailto:phi...@redhat.com] >> > > Sent: Wednesday, February 12, 2020 2:16 PM >> > > To: Chenqun (kuhn) ; qemu- >> > > de...@nongnu.org; i.mitsya...@gmail.com; peter.mayd...@linaro.org >> > > Cc: qemu-triv...@nongnu.org; Zhanghailiang >> > > >> > > Subject: Re: [PATCH] hw/char/exynos4210_uart: Fix memleaks in >> > > exynos4210_uart_init >> > > >> > > On 2/12/20 4:36 AM, kuhn.chen...@huawei.com wrote: >> > > > From: Chen Qun >> > > > >> > > > It's easy to reproduce as follow: >> > > > virsh qemu-monitor-command vm1 --pretty '{"execute": >> > > > "device-list-properties", "arguments":{"typename":"exynos4210.uart"}}' >> > > > >> > > > ASAN shows memory leak stack: >> > > > #1 0xfffd896d71cb in g_malloc0 (/lib64/libglib-2.0.so.0+0x571cb) >> > > > #2 0xaaad270beee3 in timer_new_full /qemu/include/qemu/timer.h:530 >> > > > #3 0xaaad270beee3 in timer_new /qemu/include/qemu/timer.h:551 >> > > > #4 0xaaad270beee3 in timer_new_ns /qemu/include/qemu/timer.h:569 >> > > > #5 0xaaad270beee3 in exynos4210_uart_init >> > > /qemu/hw/char/exynos4210_uart.c:677 >> > > > #6 0xaaad275c8f4f in object_initialize_with_type >> > > > /qemu/qom/object.c:516 >> > > > #7 0xaaad275c91bb in object_new_with_type /qemu/qom/object.c:684 >> > > > #8 0xaaad2755df2f in qmp_device_list_properties >> > > > /qemu/qom/qom-qmp-cmds.c:152 >> > > > >> > > > Reported-by: Euler Robot >> > > > Signed-off-by: Chen Qun >> > > > --- >> > > >hw/char/exynos4210_uart.c | 8 >> > > >1 file changed, 4 insertions(+), 4 deletions(-) >> > > > >> > > > diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c >> > > > index 25d6588e41..5048db5410 100644 >> > > > --- a/hw/char/exynos4210_uart.c >> > > > +++ b/hw/char/exynos4210_uart.c >> > > > @@ -674,10 +674,6 @@ static void exynos4210_uart_init(Object *obj) >> > > >SysBusDevice *dev = SYS_BUS_DEVICE(obj); >> > > >Exynos4210UartState *s = EXYNOS4210_UART(dev); >> > > > >> > > > -s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, >> > > > - exynos4210_uart_timeout_int, >> > > > s); >> > > > -s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600; >> > > >> > > Why are you moving s->wordtime from init() to realize()? >> > > >> > Hi Philippe, thanks for your reply! >> > >> > Because I found the variable wordtime is usually used with >> > fifo_timeout_timer. >> > Eg, they are used together in the exynos4210_uart_rx_timeout_set function. >> > >> > I didn't find anything wrong with wordtime in the realize(). >> > Does it have any other effects? >> >> IIUC when we use both init() and realize(), realize() should only contains >> on code that consumes the object properties... But maybe the design is not >> clear. Then why not move all the init() code to realize()? > > Normally I would recommend the opposite: delay as much as > possible to realize(), to avoid unwanted side effects when (e.g.) > running qom-list-properties. Sadly, our documentation on device initialization and realization is rather sparse, and developers are left guessing. Their guesses are often based on what existing code does. Some of the existing code even gets things right. A few rules from the top of my head: * Creating and immediately destroying an object must be safe and free of side effects: initialization may only touch the object itself, and finalization must clean up everything initialization creates. * unrealize() must clean up everything realize() creates. * Since initialization cannot fail, code that needs to fail gracefully must live in realize(). * Since property values get set between initialization and realization, code that uses property values must live in realize(). * Dynamic properties have to be created in initialization to be visible in introspection. > But as s->wordtime is a simple struct field (that we could even > decide to expose to the outside as a read-only QOM property), it > doesn't really matter. Personally, I would keep it where it is > just to avoid churn.
Re: Question about (and problem with) pflash data access
On 2/13/20 1:51 AM, Paolo Bonzini wrote: On 13/02/20 08:40, Alexey Kardashevskiy wrote: memory-region: system - (prio 0, i/o): system -01ff (prio 0, romd): omap_sx1.flash0-1 -01ff (prio 0, rom): omap_sx1.flash0-0 Eh two memory regions with same size and same priority... Is this legal? I'd say yes if used with memory_region_set_enabled() to make sure only one is enabled. Having both enabled is weird and we should print a warning. Yeah, it's undefined which one becomes visible. I have a patch fixing that, resulting in (qemu) info mtree -f FlatView #0 AS "I/O", root: io Root memory region: io - (prio 0, i/o): io FlatView #1 AS "memory", root: system AS "cpu-memory-0", root: system Root memory region: system -01ff (prio 0, romd): omap_sx1.flash0 0200-03ff (prio 0, i/o): sx1.cs0 0400-07ff (prio 0, i/o): sx1.cs1 0800-0bff (prio 0, i/o): sx1.cs2 0c00-0fff (prio 0, i/o): sx1.cs3 ... but unfortunately that doesn't fix my problem. The data in the omap_sx1.flash0 region is as wrong as before. What really puzzles me is that there is no trace output for flash data accesses (trace_pflash_data_read and trace_pflash_data_write), meaning the actual flash data access must be handled elsewhere. Can someone give me a hint where that might be ? Clearly I am missing something about inner workings of qemu. Thanks, Guenter
[PATCH v2 2/2] tests/tcg/multiarch: Add tests for implemented alsa sound timer ioctls
This patch adds tests for following 14 implemented alsa timer ioctls: * SNDRV_TIMER_IOCTL_PVERSION* SNDRV_TIMER_IOCTL_INFO * SNDRV_TIMER_IOCTL_NEXT_DEVICE * SNDRV_TIMER_IOCTL_PARAMS * SNDRV_TIMER_IOCTL_TREAD * SNDRV_TIMER_IOCTL_STATUS * SNDRV_TIMER_IOCTL_GINFO * SNDRV_TIMER_IOCTL_START * SNDRV_TIMER_IOCTL_GPARAMS * SNDRV_TIMER_IOCTL_STOP * SNDRV_TIMER_IOCTL_GSTATUS * SNDRV_TIMER_IOCTL_CONTINUE * SNDRV_TIMER_IOCTL_SELECT * SNDRV_TIMER_IOCTL_PAUSE Names and descriptions of these ioctls can be found in patches that implement them. Test folder for these ioctl tests is located at "tests/tcg/multiarch/alsa-timer-ioctl-tests/" There are two folders located in the test folder, one for test that was written manually ("/manual-test") and one for the test that was obtained remotely ("/remote-test"). Manual test: This test was written manually to test all the implemented alsa timer ioctls and was added at "/manual-test/alsa-timer-ioctl-manual-test.c". A separate test function was written for each ioctl. Each of these functions uses a global test macro 'TEST_ALSA_IOCTL' to run these tests. The file can be run to test all ioctls or it can test only the specified ioctls. This depends on the commands specified when running the test. For Example (assuming 'rtc-ioctl-manual-test' is the compiled .exe file): running './alsa-timer-ioctl-manual-test SNDRV_TIMER_IOCTL_TREAD' tests only the ioctl SNDRV_TIMER_IOCTL_TREAD running './alsa-timer-ioctl-manual-test SNDRV_TIMER_IOCTL_INFO SNDRV_TIMER_IOCTL_STOP SNDRV_TIMER_IOCTL_PAUSE' tests ioctls SNDRV_TIMER_IOCTL_INFO, SNDRV_TIMER_IOCTL_STOP, SNDRV_TIMER_IOCTL_PAUSE If no ioctl is specified when running the test file, all the ioctls are tested: running './rtc-ioctl-test' tests all ioctls Remote test: Besides the manual tests, a remote alsa timer ioctl test was added at "/remote-test/timer.c". This test file was downloaded from a git repository that contains alsa ioctl test suite. This repository is located at "https://github.com/takaswie/alsa-ioctl-test";. It is used to test all of the alsa timer ioctls at once by running a test macro defined in that file. The file was modified a little bit by adding an output line that shows which test passed and at which test the program aborts. It was also modified so that it doesn't have styling problems detected by 'scripts/checkpatch.pl'. Signed-off-by: Filip Bozuta --- .../manual-test/alsa-timer-ioctl-manual-test.c | 294 + .../alsa-timer-ioctl-tests/remote-test/timer.c | 158 +++ 2 files changed, 452 insertions(+) create mode 100644 tests/tcg/multiarch/alsa-timer-ioctl-tests/manual-test/alsa-timer-ioctl-manual-test.c create mode 100644 tests/tcg/multiarch/alsa-timer-ioctl-tests/remote-test/timer.c diff --git a/tests/tcg/multiarch/alsa-timer-ioctl-tests/manual-test/alsa-timer-ioctl-manual-test.c b/tests/tcg/multiarch/alsa-timer-ioctl-tests/manual-test/alsa-timer-ioctl-manual-test.c new file mode 100644 index 000..95803ff --- /dev/null +++ b/tests/tcg/multiarch/alsa-timer-ioctl-tests/manual-test/alsa-timer-ioctl-manual-test.c @@ -0,0 +1,294 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define ERROR -1 + +#define TEST_ALSA_IOCTL(fd, command, argument, supported) \ +do { \ +printf("%s:\n", #command);\ +if (ioctl(fd, command, argument) == ERROR) { \ +perror("ioctl"); \ +printf("\n"); \ +supported = false;\ +} \ +} while (0) + +static bool test_pversion(int fd, bool supported) +{ +int version = 0; + +TEST_ALSA_IOCTL(fd, SNDRV_TIMER_IOCTL_PVERSION, &version, supported); +if (supported) { +printf("Timer version: %d\n", version); +printf("\n"); +} +return supported; +} + +static bool test_next_device(int fd, bool supported) +{ +struct snd_timer_id id = {1, 0, 0, 0, 0}; + +TEST_ALSA_IOCTL(fd, SNDRV_TIMER_IOCTL_NEXT_DEVICE, &id, supported); +if (supported) { +printf("Timer dev_class: %d\n", id.dev_class); +printf("Timer dev_sclass: %d\n", id.dev_class); +printf("Timer card: %d\n", id.dev_class); +printf("Timer device: %d\n", id.dev_class); +printf("Timer subdevice: %d\n", id.dev_class); +printf("\n"); +} +return supported; +} + +static bool test_tread(int fd, bool supported) +{ +int tread = 1; + +TEST_ALSA_IOCTL(fd, SNDRV_TIMER_IOCTL_TREAD, &tread, supported); +if (supported) { +printf("Enhanced read enabled!\n"); +printf("\n"); +
[PATCH v2 0/2] tests/tcg/multiarch: Add tests for implemented real
This series covers tests for implemented rtc and alsa timer ioctls. The names of ioctls that are covered by these tests can be found in patch descriptions. The functionalities of each ioctl that is tested can be found in patches that implement them. Some of the features that are accessible through these ioctls are not supported on all test host pc's. These tests were written so that the implemented ioctls can be properly tested on pc's that support all of their features. Both rtc and alsa timer test folders have separate files for manually written and remotely obtained tests. Tests that were obtained remotely run multiple ioctl tests at once, while the manually written tests can be used to run both individual and multiple ioctl tests based on the command specified when running the test. Filip Bozuta (2): tests/tcg/multiarch: Add tests for implemented rtc ioctls tests/tcg/multiarch: Add tests for implemented alsa sound timer ioctls .../manual-test/alsa-timer-ioctl-manual-test.c | 294 + .../alsa-timer-ioctl-tests/remote-test/timer.c | 158 + .../manual-test/rtc-ioctl-manual-test.c| 352 + .../rtc-ioctl-tests/remote-test/rtc-test.c | 226 + 4 files changed, 1030 insertions(+) create mode 100644 tests/tcg/multiarch/alsa-timer-ioctl-tests/manual-test/alsa-timer-ioctl-manual-test.c create mode 100644 tests/tcg/multiarch/alsa-timer-ioctl-tests/remote-test/timer.c create mode 100644 tests/tcg/multiarch/rtc-ioctl-tests/manual-test/rtc-ioctl-manual-test.c create mode 100644 tests/tcg/multiarch/rtc-ioctl-tests/remote-test/rtc-test.c -- 2.7.4
[PATCH v2 1/2] tests/tcg/multiarch: Add tests for implemented rtc ioctls
This patch adds tests for following 22 implemented rtc ioctls: * RTC_AIE_ON * RTC_ALM_SET * RTC_WKALM_SET * RTC_AIE_OFF* RTC_ALM_READ * RTC_WKALM_RD * RTC_UIE_ON * RTC_RD_TIME * RTC_PLL_GET * RTC_UIE_OFF* RTC_SET_TIME * RTC_PLL_SET * RTC_PIE_ON * RTC_IRQP_READ* RTC_VL_READ * RTC_PIE_OFF* RTC_IRQP_SET * RTC_VL_CLR * RTC_WIE_ON * RTC_EPOCH_READ * RTC_WIE_OFF* RTC_EPOCH_SET Names and descriptions of these ioctls can be found in patches that implement them. Test folder for these ioctl tests is located at "tests/tcg/multiarch/rtc-ioctl-tests/" There are two folders located in the test folder, one for test that was written manually ("/manual-test") and one the test that was obtained remotely ("/remote-test"). Manual test: This test was written manually to test all the implemented rtc ioctls and was added at "/manual-test/rtc-ioctl-manual-test.c". A separate test function was written for each ioctl. Each of these functions uses a global test macro 'TEST_RTC_IOCTL' to run these tests. The file can be run to test all ioctls or it can test only the specified ioctls. This depends on the commands specified when running the test. For Example (assuming 'rtc-ioctl-manual-test' is the compiled .exe file): running './rtc-ioctl-manual-test RTC_AIE_ON' tests only the ioctl RTC_AIE_ON running './rtc-ioctl-manual-test RTC_AIE_ON RTC_SET_TIME RTC_ALM_READ' tests ioctls RTC_AIE_ON, RTC_SET_TIME, RTC_ALM_READ If no ioctl is specified when running the test file, all the ioctls are tested: running './rtc-ioctl-test' tests all ioctls Remote test: Besides the manual test, a remote rtc ioctl test was added at "/remote-test/rtc-test.c". The test file "rtc-test.c" was downloaded from linux kernel and is located at "linux/drivers/rtc/rtc-test.c". This file was modified a little bit so that it doesn't have styling problems identified by "scripts/checkpatch.pl". It is used to further test functionalities of some rtc ioctls by running rtc clock at different frequencies. Signed-off-by: Filip Bozuta --- .../manual-test/rtc-ioctl-manual-test.c| 352 + .../rtc-ioctl-tests/remote-test/rtc-test.c | 226 + 2 files changed, 578 insertions(+) create mode 100644 tests/tcg/multiarch/rtc-ioctl-tests/manual-test/rtc-ioctl-manual-test.c create mode 100644 tests/tcg/multiarch/rtc-ioctl-tests/remote-test/rtc-test.c diff --git a/tests/tcg/multiarch/rtc-ioctl-tests/manual-test/rtc-ioctl-manual-test.c b/tests/tcg/multiarch/rtc-ioctl-tests/manual-test/rtc-ioctl-manual-test.c new file mode 100644 index 000..f073442 --- /dev/null +++ b/tests/tcg/multiarch/rtc-ioctl-tests/manual-test/rtc-ioctl-manual-test.c @@ -0,0 +1,352 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ERROR -1 + +#define TEST_RTC_IOCTL(fd, command, argument, supported) \ +do { \ +printf("%s:\n", #command);\ +if (ioctl(fd, command, argument) == ERROR) { \ +perror("ioctl"); \ +printf("\n"); \ +supported = false;\ +} \ +} while (0) + +static bool test_aie_on(int fd, bool supported) +{ +TEST_RTC_IOCTL(fd, RTC_AIE_ON, NULL, supported); +if (supported) { +printf("Alarm interrupt enabled!\n\n"); +} +return supported; +} + +static bool test_aie_off(int fd, bool supported) +{ +TEST_RTC_IOCTL(fd, RTC_AIE_OFF, NULL, supported); +if (supported) { +printf("Alarm interrupt disabled!\n\n"); +} +return supported; +} + +static bool test_pie_on(int fd, bool supported) +{ +TEST_RTC_IOCTL(fd, RTC_PIE_ON, NULL, supported); +if (supported) { +printf("Periodic interrupt enabled!\n\n"); +} +return supported; +} + +static bool test_pie_off(int fd, bool supported) +{ +TEST_RTC_IOCTL(fd, RTC_PIE_OFF, NULL, supported); +if (supported) { +printf("Periodic interrupt disabled!\n\n"); +} +return supported; +} + +static bool test_uie_on(int fd, bool supported) +{ +TEST_RTC_IOCTL(fd, RTC_UIE_ON, NULL, supported); +if (supported) { +printf("Update interrupt enabled!\n\n"); +} +return supported; +} + +static bool test_uie_off(int fd, bool supported) +{ +TEST_RTC_IOCTL(fd, RTC_UIE_OFF, NULL, supported); +if (supported) { +printf("Update interrupt disabled!\n\n"); +} +return supported; +} + +static bool test_wie_on(int fd, bool supported) +{ +TEST_RTC_IOCTL(fd, RTC_WIE_ON, NULL, supported); +if (supported) { +printf("Watchdog interrupt enabled!\n\n"); +} +return supporte
[PATCH] uapi: fix userspace breakage, use __BITS_PER_LONG for swap
QEMU has a funny new build error message when I use the upstream kernel headers: CC block/file-posix.o In file included from /home/cborntra/REPOS/qemu/include/qemu/timer.h:4, from /home/cborntra/REPOS/qemu/include/qemu/timed-average.h:29, from /home/cborntra/REPOS/qemu/include/block/accounting.h:28, from /home/cborntra/REPOS/qemu/include/block/block_int.h:27, from /home/cborntra/REPOS/qemu/block/file-posix.c:30: /usr/include/linux/swab.h: In function ‘__swab’: /home/cborntra/REPOS/qemu/include/qemu/bitops.h:20:34: error: "sizeof" is not defined, evaluates to 0 [-Werror=undef] 20 | #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) | ^~ /home/cborntra/REPOS/qemu/include/qemu/bitops.h:20:41: error: missing binary operator before token "(" 20 | #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) | ^ cc1: all warnings being treated as errors make: *** [/home/cborntra/REPOS/qemu/rules.mak:69: block/file-posix.o] Error 1 rm tests/qemu-iotests/socket_scm_helper.o This was triggered by commit d5767057c9a ("uapi: rename ext2_swab() to swab() and share globally in swab.h") This patch is doing +#include but it uses BITS_PER_LONG. The kernel file asm/bitsperlong.h provide only __BITS_PER_LONG. Let us use the __ variant in swap.h Fixes: d5767057c9a ("uapi: rename ext2_swab() to swab() and share globally in swab.h") Cc: Yury Norov Cc: Allison Randal Cc: Joe Perches Cc: Thomas Gleixner Cc: William Breathitt Gray Signed-off-by: Christian Borntraeger --- include/uapi/linux/swab.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h index fa7f97da5b76..7272f85d6d6a 100644 --- a/include/uapi/linux/swab.h +++ b/include/uapi/linux/swab.h @@ -135,9 +135,9 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val) static __always_inline unsigned long __swab(const unsigned long y) { -#if BITS_PER_LONG == 64 +#if __BITS_PER_LONG == 64 return __swab64(y); -#else /* BITS_PER_LONG == 32 */ +#else /* __BITS_PER_LONG == 32 */ return __swab32(y); #endif } -- 2.24.1
Re: [PATCH v3 12/13] hw/arm/raspi: Use a unique raspi_machine_class_init() method
On 2/13/20 2:59 PM, Peter Maydell wrote: On Sat, 8 Feb 2020 at 16:57, Philippe Mathieu-Daudé wrote: With the exception of the ignore_memory_transaction_failures flag set for the raspi2, both machine_class_init() methods are now identical. Merge them to keep a unique method. Signed-off-by: Philippe Mathieu-Daudé --- hw/arm/raspi.c | 31 ++- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 0537fc0a2d..bee6ca0a08 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -294,7 +294,7 @@ static void raspi_machine_init(MachineState *machine) setup_boot(machine, version, machine->ram_size - vcram_size); } -static void raspi2_machine_class_init(ObjectClass *oc, void *data) +static void raspi_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); @@ -311,41 +311,22 @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data) mc->min_cpus = BCM283X_NCPUS; mc->default_cpus = BCM283X_NCPUS; mc->default_ram_size = board_ram_size(board_rev); -mc->ignore_memory_transaction_failures = true; +if (board_version(board_rev) == 2) { +mc->ignore_memory_transaction_failures = true; +} }; This isn't really the correct condition here. What we want is: * for the board named 'raspi2' which was introduced before we added the transaction-failure support to Arm CPU emulation, disable signaling transaction failures * for any other board, leave it enabled (whether that new board is BCM2836 based or anything else) (This kind of follows on from my remark on patch 3: we should be suspicious of anything that's conditional on board_version(); it should probably be testing something else.) The natural way to implement this is to have the .class_data be a pointer to a struct which is in an array and defines relevant per-class stuff, the same way we do in bcm2836_register_types(). That way the struct can indicate both the board revision number and also "is this a legacy board that needs transaction-failures disabled?". IIUC Igor insists explaining that he doesn't accept anymore a ".class_data pointer to a struct which is in an array and defines relevant per-class stuff" and we should not use this pattern anymore. The other approach here, as discussed on IRC, is that if we're confident we really have all the devices in the SoC either present or stubbed out with unimplemented-device then we could disable ignore_memory_transaction_failures for raspi2. (The flag is only there because I didn't want to try to do the auditing and fielding of potential bug reports if I changed the behaviour of a bunch of our existing not-very-maintained board models: the real correct behaviour in almost all cases would be to allow transaction failures and just make sure we have stub devices as needed.) Yes, the plan is to add all the unimplemented peripherals (patches ready, but out of scope of this series) and remove this flag. That said, this does give the right answer for our current boards, so I'm ok with taking this series if you want to address this in a followup patch. If you are OK, I prefer to address this in a later series than delaying this one more longer. Thanks!
Re: [PATCH v5 7/8] multifd: Add multifd-zstd-level parameter
"Dr. David Alan Gilbert" writes: > * Juan Quintela (quint...@redhat.com) wrote: >> Signed-off-by: Juan Quintela >> --- >> migration/migration.c | 15 +++ >> monitor/hmp-cmds.c| 4 >> qapi/migration.json | 29 ++--- >> 3 files changed, 45 insertions(+), 3 deletions(-) >> >> diff --git a/migration/migration.c b/migration/migration.c >> index 3b081e8147..b690500545 100644 >> --- a/migration/migration.c >> +++ b/migration/migration.c >> @@ -91,6 +91,8 @@ >> #define DEFAULT_MIGRATE_MULTIFD_METHOD MULTIFD_METHOD_NONE >> /*0: means nocompress, 1: best speed, ... 9: best compress ratio */ >> #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1 >> +/* 0: means nocompress, 1: best speed, ... 20: best compress ratio */ >> +#define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1 >> >> /* Background transfer rate for postcopy, 0 means unlimited, note >> * that page requests can still exceed this limit. >> @@ -805,6 +807,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error >> **errp) >> params->multifd_method = s->parameters.multifd_method; >> params->has_multifd_zlib_level = true; >> params->multifd_zlib_level = s->parameters.multifd_zlib_level; >> +params->has_multifd_zstd_level = true; >> +params->multifd_zstd_level = s->parameters.multifd_zstd_level; > > Do we really want different 'multifd__level's or just one > 'multifd_compress_level' - or even just reuse the existing > 'compress-level' parameter. compress-level, multifd-zlib-level, and multifd-zstd-level apply "normal" live migration compression, multifd zlib live migration compression, and multifd zstd live migration compression, respectively. Any live migration can only use one of the three compressions. Correct? > The only tricky thing about combining them is how to handle > the difference in allowed ranges; When would the right time be > to check it? > > Markus/Eric: Any idea? To have an informed opinion, I'd have to dig through the migration code. Documentation of admissible range will become a bit awkward, too. Too many migration parameters...
Re: [PATCH v3 00/13] hw/arm/raspi: Dynamically create machines based on the board revision
On Sat, 8 Feb 2020 at 16:57, Philippe Mathieu-Daudé wrote: > > Hi, > > This series is a preparatory to easily add the raspi0/raspi1/raspi4 > boards (see [1]). > > Igor has been working in his "refactor main RAM allocation to use > hostmem backend" series, and now v4 [2] is almost reviewed. > > His raspi patch [3] clashes with my work, Since it is easier for > him to apply his on top of mine, I am sending these patches first. > > Since v2: > - Split of bigger series (30 patches was scary) > - addressed Zoltan review comments > > Phil. > > [1] https://www.mail-archive.com/qemu-devel@nongnu.org/msg677145.html > [2] https://www.mail-archive.com/qemu-devel@nongnu.org/msg675738.html > [3] https://www.mail-archive.com/qemu-devel@nongnu.org/msg675752.html > Supersedes: <20200206011756.2413-1-f4...@amsat.org> I had one or two minor comments but I'm happy if we address those in follow-up patches. Applied to target-arm.next with the commit message tweak for patch 13 suggested by Igor. thanks -- PMM
Re: [PATCH v3 12/13] hw/arm/raspi: Use a unique raspi_machine_class_init() method
On Sat, 8 Feb 2020 at 16:57, Philippe Mathieu-Daudé wrote: > > With the exception of the ignore_memory_transaction_failures > flag set for the raspi2, both machine_class_init() methods > are now identical. Merge them to keep a unique method. > > Signed-off-by: Philippe Mathieu-Daudé > --- > hw/arm/raspi.c | 31 ++- > 1 file changed, 6 insertions(+), 25 deletions(-) > > diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c > index 0537fc0a2d..bee6ca0a08 100644 > --- a/hw/arm/raspi.c > +++ b/hw/arm/raspi.c > @@ -294,7 +294,7 @@ static void raspi_machine_init(MachineState *machine) > setup_boot(machine, version, machine->ram_size - vcram_size); > } > > -static void raspi2_machine_class_init(ObjectClass *oc, void *data) > +static void raspi_machine_class_init(ObjectClass *oc, void *data) > { > MachineClass *mc = MACHINE_CLASS(oc); > RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); > @@ -311,41 +311,22 @@ static void raspi2_machine_class_init(ObjectClass *oc, > void *data) > mc->min_cpus = BCM283X_NCPUS; > mc->default_cpus = BCM283X_NCPUS; > mc->default_ram_size = board_ram_size(board_rev); > -mc->ignore_memory_transaction_failures = true; > +if (board_version(board_rev) == 2) { > +mc->ignore_memory_transaction_failures = true; > +} > }; This isn't really the correct condition here. What we want is: * for the board named 'raspi2' which was introduced before we added the transaction-failure support to Arm CPU emulation, disable signaling transaction failures * for any other board, leave it enabled (whether that new board is BCM2836 based or anything else) (This kind of follows on from my remark on patch 3: we should be suspicious of anything that's conditional on board_version(); it should probably be testing something else.) The natural way to implement this is to have the .class_data be a pointer to a struct which is in an array and defines relevant per-class stuff, the same way we do in bcm2836_register_types(). That way the struct can indicate both the board revision number and also "is this a legacy board that needs transaction-failures disabled?". The other approach here, as discussed on IRC, is that if we're confident we really have all the devices in the SoC either present or stubbed out with unimplemented-device then we could disable ignore_memory_transaction_failures for raspi2. (The flag is only there because I didn't want to try to do the auditing and fielding of potential bug reports if I changed the behaviour of a bunch of our existing not-very-maintained board models: the real correct behaviour in almost all cases would be to allow transaction failures and just make sure we have stub devices as needed.) That said, this does give the right answer for our current boards, so I'm ok with taking this series if you want to address this in a followup patch. thanks -- PMM
Re: [PATCH] block: make BlockConf.*_size properties 32-bit
On Thu, Feb 13, 2020 at 06:47:10AM -0600, Eric Blake wrote: > On 2/13/20 2:01 AM, Roman Kagan wrote: > > On Wed, Feb 12, 2020 at 03:44:19PM -0600, Eric Blake wrote: > > > On 2/11/20 5:54 AM, Roman Kagan wrote: > > > > Devices (virtio-blk, scsi, etc.) and the block layer are happy to use > > > > 32-bit for logical_block_size, physical_block_size, and min_io_size. > > > > However, the properties in BlockConf are defined as uint16_t limiting > > > > the values to 32768. > > > > > > > > This appears unnecessary tight, and we've seen bigger block sizes handy > > > > at times. > > > > > > What larger sizes? I could see 64k or maybe even 1M block sizes,... > > > > We played exactly with these two :) > > > > > > > > > > Make them 32 bit instead and lift the limitation. > > > > > > > > Signed-off-by: Roman Kagan > > > > --- > > > >hw/core/qdev-properties.c| 21 - > > > >include/hw/block/block.h | 8 > > > >include/hw/qdev-properties.h | 2 +- > > > >3 files changed, 17 insertions(+), 14 deletions(-) > > > > > > > > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c > > > > index 7f93bfeb88..5f84e4a3b8 100644 > > > > --- a/hw/core/qdev-properties.c > > > > +++ b/hw/core/qdev-properties.c > > > > @@ -716,30 +716,32 @@ const PropertyInfo qdev_prop_pci_devfn = { > > > >/* --- blocksize --- */ > > > > +#define MIN_BLOCK_SIZE 512 > > > > +#define MAX_BLOCK_SIZE 2147483648 > > > > > > ...but 2G block sizes are going to have tremendous performance problems. > > > > > > I'm not necessarily opposed to the widening to a 32-bit type, but think > > > you > > > need more justification or a smaller number for the max block size, > > > > I thought any smaller value would just be arbitrary and hard to reason > > about, so I went ahead with the max value that fit in the type and could > > be made visibile to the guest. > > You've got bigger problems than what is visible to the guest. block/qcow2.c > operates on a cluster at a time; if you are stating that it now requires > reading multiple clusters to operate on one, qcow2 will have to do lots of > wasteful read-modify-write cycles. I'm failing to see how this is supposed to happen. The guest will issue requests bigger than the cluster size; why would it cause RMW? Big logical_block_size would cause RMW in the guest if it wants to perform smaller writes, but that's up to the user to take this tradeoff, isn't it? > You really need a strong reason to > support a maximum larger than 2M other than just "so the guest can > experiment with it". Do I get you right that your suggestion is to cap the block size property at 2MB? Thanks, Roman. > > > > Besides this is a property that is set explicitly, so I don't see a > > problem leaving this up to the user. > > > > > particularly since qcow2 refuses to use cluster sizes larger than 2M and > > > it > > > makes no sense to allow a block size larger than a cluster size. > > > > This still doesn't contradict passing a bigger value to the guest, for > > experimenting if nothing else. > > > > Thanks, > > Roman. > > > > -- > Eric Blake, Principal Software Engineer > Red Hat, Inc. +1-919-301-3226 > Virtualization: qemu.org | libvirt.org >
Re: [PATCH v3 03/13] hw/arm/raspi: Extract the version from the board revision
On 2/13/20 2:40 PM, Peter Maydell wrote: On Sat, 8 Feb 2020 at 16:57, Philippe Mathieu-Daudé wrote: The board revision encode the board version. Add a helper to extract the version, and use it. Signed-off-by: Philippe Mathieu-Daudé --- hw/arm/raspi.c | 31 +++ 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 818146fdbb..f285e2988f 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -16,6 +16,7 @@ #include "qapi/error.h" #include "cpu.h" #include "hw/arm/bcm2836.h" +#include "hw/registerfields.h" #include "qemu/error-report.h" #include "hw/boards.h" #include "hw/loader.h" @@ -37,6 +38,28 @@ typedef struct RasPiState { MemoryRegion ram; } RasPiState; +/* + * Board revision codes: + * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/ + */ +FIELD(REV_CODE, REVISION, 0, 4); +FIELD(REV_CODE, TYPE, 4, 8); +FIELD(REV_CODE, PROCESSOR, 12, 4); +FIELD(REV_CODE, MANUFACTURER, 16, 4); +FIELD(REV_CODE, MEMORY_SIZE, 20, 3); +FIELD(REV_CODE, STYLE, 23, 1); + +static int board_processor_id(uint32_t board_rev) +{ +assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ +return FIELD_EX32(board_rev, REV_CODE, PROCESSOR); +} + +static int board_version(uint32_t board_rev) +{ +return board_processor_id(board_rev) + 1; This uses the 'processor' field, which basically means the SoC (0 for BCM2835, 1 for BCM2836, 2 for BCMM2837, 3 for BCM2711). We use 'version' for a wider range of things in our code here: * do we need SMP setup? * which address does the firmware image go? * do we need to set up SMC vectors so no-op SMC works? * as well as "which SoC do we instantiate"? We think of 'version' as basically "raspi 2 or 3?", but according to the table in your url you can get a version of the raspi 2b with a BCM2837 SoC, which confuses this idea. Anyway, since what we have in this patch works OK for the set of board models we support, I'm happy to leave the patch as-is, but maybe worth checking and considering what in our code we should really be making conditional on "actually the SoC type" and what on something else... Yes you are right, version = (2, 3) was too simple, I replaced the 'version' check by 'processor_id' in the series introducing the raspi4 (with other cleanups). Eventually this file will only use the board_rev fields directly.
Re: [RFC 2/2] pci-expender-bus:Add pcie-root-port to pxb-pcie under arm.
On Thu, Feb 13, 2020 at 03:49:52PM +0800, Yubo Miao wrote: > From: miaoyubo > > Since devices could not directly plugged into pxb-pcie, under arm, one > pcie-root port is plugged into pxb-pcie. Due to the bus for each pxb-pcie > is defined as 2 in acpi dsdt tables(one for pxb-pcie, one for pcie-root-port), > only one device could be plugged into one pxb-pcie. What is the cause of this arm specific requirement for pxb-pcie and more importantly can be fix it so that we don't need this patch ? I think it is highly undesirable to have such a per-arch difference in configuration of the pxb-pcie device. It means any mgmt app which already supports pxb-pcie will be broken and need to special case arm. > > Signed-off-by: miaoyubo > --- > hw/pci-bridge/pci_expander_bridge.c | 9 + > include/hw/pci/pcie_port.h | 1 + > 2 files changed, 10 insertions(+) > > diff --git a/hw/pci-bridge/pci_expander_bridge.c > b/hw/pci-bridge/pci_expander_bridge.c > index 47aaaf8fd1..3d896dd452 100644 > --- a/hw/pci-bridge/pci_expander_bridge.c > +++ b/hw/pci-bridge/pci_expander_bridge.c > @@ -15,6 +15,7 @@ > #include "hw/pci/pci.h" > #include "hw/pci/pci_bus.h" > #include "hw/pci/pci_host.h" > +#include "hw/pci/pcie_port.h" > #include "hw/qdev-properties.h" > #include "hw/pci/pci_bridge.h" > #include "qemu/range.h" > @@ -233,7 +234,15 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool > pcie, Error **errp) > > ds = qdev_create(NULL, TYPE_PXB_HOST); > if (pcie) { > +#ifdef __aarch64__ > +bus = pci_root_bus_new(ds, "pxb-pcie-internal", > + NULL, NULL, 0, TYPE_PXB_PCIE_BUS); > +bds = qdev_create(BUS(bus), "pcie-root-port"); > +bds->id = dev_name; > +qdev_prop_set_uint8(bds, PCIE_ROOT_PORT_PROP_CHASSIS, pxb->bus_nr); > +#else > bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, > TYPE_PXB_PCIE_BUS); > +#endif > } else { > bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, > TYPE_PXB_BUS); > bds = qdev_create(BUS(bus), "pci-bridge"); > diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h > index 4b3d254b08..b41d473220 100644 > --- a/include/hw/pci/pcie_port.h > +++ b/include/hw/pci/pcie_port.h > @@ -64,6 +64,7 @@ int pcie_chassis_add_slot(struct PCIESlot *slot); > void pcie_chassis_del_slot(PCIESlot *s); > > #define TYPE_PCIE_ROOT_PORT "pcie-root-port-base" > +#define PCIE_ROOT_PORT_PROP_CHASSIS "chassis" > #define PCIE_ROOT_PORT_CLASS(klass) \ > OBJECT_CLASS_CHECK(PCIERootPortClass, (klass), TYPE_PCIE_ROOT_PORT) > #define PCIE_ROOT_PORT_GET_CLASS(obj) \ > -- > 2.19.1 > > > Regards, Daniel -- |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o-https://fstop138.berrange.com :| |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
Re: [PATCH/RFC 0/1] Vhost User Cross Cable: Intro
On Tue, 14 Jan 2020 at 10:20 Stefan Hajnoczi wrote: > On Fri, Jan 10, 2020 at 10:34 AM Marc-André Lureau > wrote: > > On Wed, Jan 8, 2020 at 5:57 AM V. wrote: > > Hi V., > I think I remember you from Etherboot/gPXE days :). > > > > 3. > > > Now if Cross Cable is actually a new and (after a code-rewrite of 10) a > > > viable way to connect 2 QEMU's together, could I actually > > > suggest a better way? > > > I am thinking of a '-netdev vhost-user-slave' option to connect (as client > > > or server) to a master QEMU running '-netdev vhost-user'. > > > This way there is no need for any external program at all, the master can > > > have it's memory unshared and everything would just work > > > and be fast. > > > Also the whole thing can fall back to normal virtio if memory is not shared > > > and it would even work in pure usermode without any > > > context switch. > > > > > > Building a patch for this idea I could maybe get around to, don't clearly > > > have an idea how much work this would be but I've done > > > crazier things. > > > But is this is something that someone might be able to whip up in an hour > > > or two? Someone who actually does have a clue about vhost > > > and virtio maybe? ;-) > > > > I believe https://wiki.qemu.org/Features/VirtioVhostUser is what you > > are after. It's still being discussed and non-trivial, but not very > > active lately afaik. > > virtio-vhost-user is being experimented with in the SPDK community but > there has been no activity on VIRTIO standardization or the QEMU > patches for some time. More info here: > https://ndragazis.github.io/spdk.html > > I think the new ivshmem v2 feature may provide the functionality you > are looking for, but I haven't looked at them yet. Here is the link: > https://www.mail-archive.com/address@hidden/msg668749.html > > And here is Jan's KVM Forum presentation on ivshmem v2: > https://www.youtube.com/watch?v=TiZrngLUFMA > > Stefan Hi Stefan, First of all, sorry for the delayed response. The mail got lost somewhere in my inbox. Please keep Cc-ing me on all threads related to virtio-vhost-user. As you correctly pointed out, I have been experimenting with virtio-vhost-user on SPDK and [1] is a working demo on this matter. I have been working on getting it merged with SPDK and, to this end, I have been interacting with the SPDK team [2][3] and mostly with Darek Stojaczyk (Cc-ing him). The reason that you haven’t seen any activity for the last months is that I got a job and hence my schedule has become tighter. But I will definitely find some space and fit it into my schedule. Let me give you a heads up, so that we get synced: Originally, I created and sent a patch (influenced from your DPDK patch [4]) to SPDK that was enhancing SPDK’s internal rte_vhost library with the virtio-vhost-user transport. However, a few weeks later, the SPDK team decided to switch from their internal rte_vhost library to using DPDK’s rte_vhost library directly [3]. Given that, I refactored and sent the patch for the virtio-vhost-user transport to the DPDK mailing list [5]. Regarding the virtio-vhost-user device, I have made some enhancements [6] on your original RFC device implementation and, as you may remember, I have sent some revised versions of the spec to the virtio mailing list [7]. At the moment, the blocker is the virtio spec. The last update on this was my discussion with Michael Tsirkin (Cc-ing him as well) about the need for the VIRTIO_PCI_CAP_DOORBELL_CFG and VIRTIO_PCI_CAP_NOTIFICATION_CFG configuration structures [8]. So, I think the next steps should be the following: 1. merging the spec 2. adding the device on QEMU 3. adding the vvu transport on DPDK 4. extending SPDK to make use of the new vhost-user transport To conclude, I still believe that this device is useful and should be part of virtio/qemu/dpdk/spdk and I will continue working on this direction. Best regards, Nikos [1] https://ndragazis.github.io/spdk.html [2] https://lists.01.org/hyperkitty/list/s...@lists.01.org/thread/UR4FM45LEQIBJNQ4MTDZFH6SLTXHTGDR/#ZGPRKS47QWHXHFBEKSCA7Z66E2AGSLHN [3] https://lists.01.org/hyperkitty/list/s...@lists.01.org/thread/WLUREJGPK5UJVTHIQ5GRL3CDWR5NN5BI/#G7P3D4KF6OQDI2RYASXQOZCMITKT5DEP [4] http://mails.dpdk.org/archives/dev/2018-January/088155.html [5] https://lore.kernel.org/dpdk-dev/e03dcc29-d472-340a-9825-48d13e472...@redhat.com/T/ [6] https://lists.gnu.org/archive/html/qemu-devel/2019-04/msg02910.html [7] https://lists.oasis-open.org/archives/virtio-dev/201906/msg00036.html [8] https://lists.oasis-open.org/archives/virtio-dev/201908/msg00014.html
Re: [PATCH] tracing: only allow -trace to override -D if set
On Wed, Feb 12, 2020 at 11:31:00PM +0100, Philippe Mathieu-Daudé wrote: > On 2/12/20 4:34 PM, Stefan Hajnoczi wrote: > > On Tue, Feb 11, 2020 at 11:10:54AM +, Alex Bennée wrote: > > > Otherwise any -D settings the user may have made get ignored. > > > > > > Signed-off-by: Alex Bennée > > > --- > > > trace/control.c | 11 --- > > > 1 file changed, 8 insertions(+), 3 deletions(-) > > > > Thanks, applied to my tracing tree: > > https://github.com/stefanha/qemu/commits/tracing > > If possible, please add 'Fixes: e144a605a'. Done! Stefan signature.asc Description: PGP signature
Re: [PATCH v15 8/9] hw/arm/virt: Add the virtio-iommu device tree mappings
Hi Peter, Michael, On 2/11/20 6:31 PM, Auger Eric wrote: > Hi Peter, > > On 2/11/20 4:00 PM, Peter Maydell wrote: >> On Sat, 8 Feb 2020 at 12:01, Eric Auger wrote: >>> >>> Adds the "virtio,pci-iommu" node in the host bridge node and >>> the RID mapping, excluding the IOMMU RID. >>> >>> This is done in the virtio-iommu-pci hotplug handler which >>> gets called only if no firmware is loaded or if -no-acpi is >>> passed on the command line. As non DT integration is >>> not yet supported by the kernel we must make sure we >>> are in DT mode. This limitation will be removed as soon >>> as the topology description feature gets supported. >>> >>> Signed-off-by: Eric Auger >>> >>> +static void create_virtio_iommu(VirtMachineState *vms, Error **errp) >>> +{ >>> +const char compat[] = "virtio,pci-iommu"; >>> +uint16_t bdf = vms->virtio_iommu_bdf; >>> +char *node; >>> + >>> +vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt); >>> + >>> +node = g_strdup_printf("%s/virtio_iommu@%d", vms->pciehb_nodename, >>> bdf); >>> +qemu_fdt_add_subnode(vms->fdt, node); >>> +qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat)); >>> +qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", >>> + 1, bdf << 8, 1, 0, 1, 0, >>> + 1, 0, 1, 0); >>> + >>> +qemu_fdt_setprop_cell(vms->fdt, node, "#iommu-cells", 1); >>> +qemu_fdt_setprop_cell(vms->fdt, node, "phandle", vms->iommu_phandle); >>> +g_free(node); >>> + >>> +qemu_fdt_setprop_cells(vms->fdt, vms->pciehb_nodename, "iommu-map", >>> + 0x0, vms->iommu_phandle, 0x0, bdf, >>> + bdf + 1, vms->iommu_phandle, bdf + 1, 0x - >>> bdf); >>> +} >> >> This function name implies that we're creating the IOMMU device >> here (which would be a weird thing to do in a hotplug callback >> for some other device), but it looks like we're only adding >> device tree nodes ? > yes the actual iommu device is created through the -device option. I can > rename into create_iommu_dt_bindings So I renamed it into create_virtio_iommu_dt_bindings() >> >> Given that we write the FDT blob into the guest RAM on bootup, >> how does making changes to it here on hotplug (which I assume >> to be 'after boot, whenever the user hot-plugs something') work? > > the virtio-iommu is not supposed to be hotplugged but rather > cold-plugged. I use this hotplug mechanism to detect its presence and > add the related dt mappings. Maybe I can add a check to detect if the > bootup is over? I added in virtio-iommu-pci virtio_iommu_pci_class_init() dc->hotpluggable = false; As far as I understand this makes the virtio-iommu-pci device not hotpluggable (same is used for intel-iommu): (QEMU) device_add id=hot0 driver=virtio-iommu-pci bus=head.0 addr=4 {"error": {"class": "GenericError", "desc": "Parameter 'driver' expects pluggable device type"}} Is that OK? Thanks Eric > > Thoughts? > > Eric >> >> thanks >> -- PMM >> > >
[RFC 1/2] arm: acpi: pci-expender-bus: Make arm to support PXB-PCIE
From: miaoyubo Currently virt machine is not supported by pxb-pcie, and only one main host bridge described in ACPI tables. Under this circumstance, different io numas for differnt devices is not possible, in order to present io numas to the guest, especially for host pssthrough devices. PXB-PCIE is supproted by arm and certain resource is allocated for each pxb-pcie in acpi table. Signed-off-by: miaoyubo --- hw/arm/virt-acpi-build.c | 234 +-- hw/pci-host/gpex.c | 4 + include/hw/arm/virt.h| 1 + 3 files changed, 228 insertions(+), 11 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index bd5f771e9b..2e449d0098 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -49,6 +49,8 @@ #include "kvm_arm.h" #include "migration/vmstate.h" +#include "hw/arm/virt.h" +#include "hw/pci/pci_bus.h" #define ARM_SPI_BASE 32 static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus) @@ -152,20 +154,227 @@ static void acpi_dsdt_add_virtio(Aml *scope, } static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, - uint32_t irq, bool use_highmem, bool highmem_ecam) + uint32_t irq, bool use_highmem, bool highmem_ecam, + VirtMachineState *vms) { int ecam_id = VIRT_ECAM_ID(highmem_ecam); -Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf; +Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf, *dev; int i, bus_no; +int count = 0; hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base; hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size; hwaddr base_pio = memmap[VIRT_PCIE_PIO].base; hwaddr size_pio = memmap[VIRT_PCIE_PIO].size; hwaddr base_ecam = memmap[ecam_id].base; hwaddr size_ecam = memmap[ecam_id].size; +/* + * 0x60 would be enough for pxb device + * if it is too small, there is no enough space + * for a pcie device plugged in a pcie-root port + */ +hwaddr size_addr = 0x60; +hwaddr size_io = 0x4000; int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN; +int root_bus_limit = 0xFF; +PCIBus *bus = NULL; +bus = VIRT_MACHINE(vms)->bus; + +if (bus) { +QLIST_FOREACH(bus, &bus->child, sibling) { +uint8_t bus_num = pci_bus_num(bus); +uint8_t numa_node = pci_bus_numa_node(bus); + +if (!pci_bus_is_root(bus)) { +continue; +} +if (bus_num < root_bus_limit) { +root_bus_limit = bus_num - 1; +} +count++; +dev = aml_device("PC%.02X", bus_num); +aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A08"))); +aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03"))); +aml_append(dev, aml_name_decl("_ADR", aml_int(0))); +aml_append(dev, aml_name_decl("_CCA", aml_int(1))); +aml_append(dev, aml_name_decl("_SEG", aml_int(0))); +aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num))); +aml_append(dev, aml_name_decl("_UID", aml_int(bus_num))); +aml_append(dev, aml_name_decl("_STR", aml_unicode("pxb Device"))); +if (numa_node != NUMA_NODE_UNASSIGNED) { +method = aml_method("_PXM", 0, AML_NOTSERIALIZED); +aml_append(method, aml_return(aml_int(numa_node))); +aml_append(dev, method); +} +/* Declare the PCI Routing Table. */ +Aml *rt_pkg = aml_varpackage(nr_pcie_buses * PCI_NUM_PINS); +for (bus_no = 0; bus_no < nr_pcie_buses; bus_no++) { +for (i = 0; i < PCI_NUM_PINS; i++) { +int gsi = (i + bus_no) % (PCI_NUM_PINS); +Aml *pkg = aml_package(4); +aml_append(pkg, aml_int((bus_no << 16) | 0x)); +aml_append(pkg, aml_int(i)); +aml_append(pkg, aml_name("GSI%d", gsi)); +aml_append(pkg, aml_int(0)); +aml_append(rt_pkg, pkg); +} +} +aml_append(dev, aml_name_decl("_PRT", rt_pkg)); + +for (i = 0; i < PCI_NUM_PINS; i++) { +uint32_t irqs = irq + i; +Aml *dev_gsi = aml_device("GSI%d", i); +aml_append(dev_gsi, aml_name_decl("_HID", + aml_string("PNP0C0F"))); +aml_append(dev_gsi, aml_name_decl("_UID", aml_int(0))); +crs = aml_resource_template(); +aml_append(crs, + aml_interrupt(AML_CONSUMER, AML_LEVEL, + AML_ACTIVE_HIGH, + AML_EXCLUSIVE, &irqs, 1)); +aml_append(dev_gsi, aml_name_decl("_PRS", crs)); +crs = aml_resource_template(); +aml_appe
[Bug 1805256] Re: qemu-img hangs on rcu_call_ready_event logic in Aarch64 when converting images
** Tags added: ikeradar -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1805256 Title: qemu-img hangs on rcu_call_ready_event logic in Aarch64 when converting images Status in kunpeng920: Incomplete Status in QEMU: In Progress Status in qemu package in Ubuntu: Incomplete Status in qemu source package in Bionic: Incomplete Status in qemu source package in Disco: Incomplete Status in qemu source package in Eoan: Incomplete Status in qemu source package in Focal: Incomplete Bug description: Command: qemu-img convert -f qcow2 -O qcow2 ./disk01.qcow2 ./output.qcow2 Hangs indefinitely approximately 30% of the runs. Workaround: qemu-img convert -m 1 -f qcow2 -O qcow2 ./disk01.qcow2 ./output.qcow2 Run "qemu-img convert" with "a single coroutine" to avoid this issue. (gdb) thread 1 ... (gdb) bt #0 0xbf1ad81c in __GI_ppoll #1 0xaabcf73c in ppoll #2 qemu_poll_ns #3 0xaabd0764 in os_host_main_loop_wait #4 main_loop_wait ... (gdb) thread 2 ... (gdb) bt #0 syscall () #1 0xaabd41cc in qemu_futex_wait #2 qemu_event_wait (ev=ev@entry=0xaac86ce8 ) #3 0xaabed05c in call_rcu_thread #4 0xaabd34c8 in qemu_thread_start #5 0xbf25c880 in start_thread #6 0xbf1b6b9c in thread_start () (gdb) thread 3 ... (gdb) bt #0 0xbf11aa20 in __GI___sigtimedwait #1 0xbf2671b4 in __sigwait #2 0xaabd1ddc in sigwait_compat #3 0xaabd34c8 in qemu_thread_start #4 0xbf25c880 in start_thread #5 0xbf1b6b9c in thread_start (gdb) run Starting program: /usr/bin/qemu-img convert -f qcow2 -O qcow2 ./disk01.ext4.qcow2 ./output.qcow2 [New Thread 0xbec5ad90 (LWP 72839)] [New Thread 0xbe459d90 (LWP 72840)] [New Thread 0xbdb57d90 (LWP 72841)] [New Thread 0xacac9d90 (LWP 72859)] [New Thread 0xa7ffed90 (LWP 72860)] [New Thread 0xa77fdd90 (LWP 72861)] [New Thread 0xa6ffcd90 (LWP 72862)] [New Thread 0xa67fbd90 (LWP 72863)] [New Thread 0xa5ffad90 (LWP 72864)] [Thread 0xa5ffad90 (LWP 72864) exited] [Thread 0xa6ffcd90 (LWP 72862) exited] [Thread 0xa77fdd90 (LWP 72861) exited] [Thread 0xbdb57d90 (LWP 72841) exited] [Thread 0xa67fbd90 (LWP 72863) exited] [Thread 0xacac9d90 (LWP 72859) exited] [Thread 0xa7ffed90 (LWP 72860) exited] """ All the tasks left are blocked in a system call, so no task left to call qemu_futex_wake() to unblock thread #2 (in futex()), which would unblock thread #1 (doing poll() in a pipe with thread #2). Those 7 threads exit before disk conversion is complete (sometimes in the beginning, sometimes at the end). [ Original Description ] On the HiSilicon D06 system - a 96 core NUMA arm64 box - qemu-img frequently hangs (~50% of the time) with this command: qemu-img convert -f qcow2 -O qcow2 /tmp/cloudimg /tmp/cloudimg2 Where "cloudimg" is a standard qcow2 Ubuntu cloud image. This qcow2->qcow2 conversion happens to be something uvtool does every time it fetches images. Once hung, attaching gdb gives the following backtrace: (gdb) bt #0 0xae4f8154 in __GI_ppoll (fds=0xe8a67dc0, nfds=187650274213760, timeout=, timeout@entry=0x0, sigmask=0xc123b950) at ../sysdeps/unix/sysv/linux/ppoll.c:39 #1 0xbbefaf00 in ppoll (__ss=0x0, __timeout=0x0, __nfds=, __fds=) at /usr/include/aarch64-linux-gnu/bits/poll2.h:77 #2 qemu_poll_ns (fds=, nfds=, timeout=timeout@entry=-1) at util/qemu-timer.c:322 #3 0xbbefbf80 in os_host_main_loop_wait (timeout=-1) at util/main-loop.c:233 #4 main_loop_wait (nonblocking=) at util/main-loop.c:497 #5 0xbbe2aa30 in convert_do_copy (s=0xc123bb58) at qemu-img.c:1980 #6 img_convert (argc=, argv=) at qemu-img.c:2456 #7 0xbbe2333c in main (argc=7, argv=) at qemu-img.c:4975 Reproduced w/ latest QEMU git (@ 53744e0a182) To manage notifications about this bug go to: https://bugs.launchpad.net/kunpeng920/+bug/1805256/+subscriptions
[RFC 2/2] pci-expender-bus:Add pcie-root-port to pxb-pcie under arm.
From: miaoyubo Since devices could not directly plugged into pxb-pcie, under arm, one pcie-root port is plugged into pxb-pcie. Due to the bus for each pxb-pcie is defined as 2 in acpi dsdt tables(one for pxb-pcie, one for pcie-root-port), only one device could be plugged into one pxb-pcie. Signed-off-by: miaoyubo --- hw/pci-bridge/pci_expander_bridge.c | 9 + include/hw/pci/pcie_port.h | 1 + 2 files changed, 10 insertions(+) diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 47aaaf8fd1..3d896dd452 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -15,6 +15,7 @@ #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" #include "hw/pci/pci_host.h" +#include "hw/pci/pcie_port.h" #include "hw/qdev-properties.h" #include "hw/pci/pci_bridge.h" #include "qemu/range.h" @@ -233,7 +234,15 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp) ds = qdev_create(NULL, TYPE_PXB_HOST); if (pcie) { +#ifdef __aarch64__ +bus = pci_root_bus_new(ds, "pxb-pcie-internal", + NULL, NULL, 0, TYPE_PXB_PCIE_BUS); +bds = qdev_create(BUS(bus), "pcie-root-port"); +bds->id = dev_name; +qdev_prop_set_uint8(bds, PCIE_ROOT_PORT_PROP_CHASSIS, pxb->bus_nr); +#else bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS); +#endif } else { bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS); bds = qdev_create(BUS(bus), "pci-bridge"); diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h index 4b3d254b08..b41d473220 100644 --- a/include/hw/pci/pcie_port.h +++ b/include/hw/pci/pcie_port.h @@ -64,6 +64,7 @@ int pcie_chassis_add_slot(struct PCIESlot *slot); void pcie_chassis_del_slot(PCIESlot *s); #define TYPE_PCIE_ROOT_PORT "pcie-root-port-base" +#define PCIE_ROOT_PORT_PROP_CHASSIS "chassis" #define PCIE_ROOT_PORT_CLASS(klass) \ OBJECT_CLASS_CHECK(PCIERootPortClass, (klass), TYPE_PCIE_ROOT_PORT) #define PCIE_ROOT_PORT_GET_CLASS(obj) \ -- 2.19.1
[RFC 0/2] pci_expander_brdige:acpi:Support pxb-pcie for ARM
From: miaoyubo Currently pxb-pcie is not supported by arm and only one main host bridge is described in acpi tables, which means it is not impossible to present different io numas for different devices. This series of patches make arm to support PXB-PCIE. Users can configure pxb-pcie with certain numa, Example command is: -device pxb-pcie,id=pci.7,bus_nr=128,numa_node=0,bus=pcie.0,addr=0x9 Since devices could not be plugged into pxb-pcie directly, one pcie-root-port is auto plugged into the pxb, therefore, the devices could be plugged into pxb-pcie. With the patches,io numa could be presented to the guest by define a pxb-pcie with the numa and plug the device into the pxb-pcie. miaoyubo (2): arm: acpi: pci-expender-bus: Make arm to support PXB-PCIE pci-expender-bus:Add pcie-root-port to pxb-pcie under arm. hw/arm/virt-acpi-build.c| 234 ++-- hw/pci-bridge/pci_expander_bridge.c | 9 ++ hw/pci-host/gpex.c | 4 + include/hw/arm/virt.h | 1 + include/hw/pci/pcie_port.h | 1 + 5 files changed, 238 insertions(+), 11 deletions(-) -- 2.19.1
Re: [PATCH v9 22/23] fuzz: add virtio-scsi fuzz target
On Tue, Feb 11, 2020 at 03:35:09PM -0500, Alexander Bulekov wrote: > diff --git a/tests/qtest/fuzz/virtio_scsi_fuzz.c > b/tests/qtest/fuzz/virtio_scsi_fuzz.c > new file mode 100644 > index 00..f62f512a26 > --- /dev/null > +++ b/tests/qtest/fuzz/virtio_scsi_fuzz.c > @@ -0,0 +1,214 @@ > +/* > + * virtio-serial Fuzzing Target > + * > + * Copyright Red Hat Inc., 2019 > + * > + * Authors: > + * Alexander Bulekov > + * > + * 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 "tests/qtest/libqtest.h" > +#include "tests/qtest/libqos/virtio-net.h" virtio-net? > +static void register_virtio_scsi_fuzz_targets(void) > +{ > +fuzz_add_qos_target(&(FuzzTarget){ > +.name = "virtio-scsi-fuzz", > +.description = "Fuzz the virtio-net virtual queues, forking" s/net/scsi/ > +"for each fuzz run", > +.pre_vm_init = &counter_shm_init, > +.pre_fuzz = &virtio_scsi_pre_fuzz, > +.fuzz = virtio_scsi_fork_fuzz,}, > +"virtio-scsi", > +&(QOSGraphTestOptions){.before = virtio_scsi_test_setup} > +); > + > +fuzz_add_qos_target(&(FuzzTarget){ > +.name = "virtio-scsi-flags-fuzz", > +.description = "Fuzz the virtio-net virtual queues, forking" s/net/scsi/ signature.asc Description: PGP signature
Re: [PATCH v3 03/13] hw/arm/raspi: Extract the version from the board revision
On Sat, 8 Feb 2020 at 16:57, Philippe Mathieu-Daudé wrote: > > The board revision encode the board version. Add a helper > to extract the version, and use it. > > Signed-off-by: Philippe Mathieu-Daudé > --- > hw/arm/raspi.c | 31 +++ > 1 file changed, 27 insertions(+), 4 deletions(-) > > diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c > index 818146fdbb..f285e2988f 100644 > --- a/hw/arm/raspi.c > +++ b/hw/arm/raspi.c > @@ -16,6 +16,7 @@ > #include "qapi/error.h" > #include "cpu.h" > #include "hw/arm/bcm2836.h" > +#include "hw/registerfields.h" > #include "qemu/error-report.h" > #include "hw/boards.h" > #include "hw/loader.h" > @@ -37,6 +38,28 @@ typedef struct RasPiState { > MemoryRegion ram; > } RasPiState; > > +/* > + * Board revision codes: > + * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/ > + */ > +FIELD(REV_CODE, REVISION, 0, 4); > +FIELD(REV_CODE, TYPE, 4, 8); > +FIELD(REV_CODE, PROCESSOR, 12, 4); > +FIELD(REV_CODE, MANUFACTURER, 16, 4); > +FIELD(REV_CODE, MEMORY_SIZE, 20, 3); > +FIELD(REV_CODE, STYLE, 23, 1); > + > +static int board_processor_id(uint32_t board_rev) > +{ > +assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ > +return FIELD_EX32(board_rev, REV_CODE, PROCESSOR); > +} > + > +static int board_version(uint32_t board_rev) > +{ > +return board_processor_id(board_rev) + 1; This uses the 'processor' field, which basically means the SoC (0 for BCM2835, 1 for BCM2836, 2 for BCMM2837, 3 for BCM2711). We use 'version' for a wider range of things in our code here: * do we need SMP setup? * which address does the firmware image go? * do we need to set up SMC vectors so no-op SMC works? * as well as "which SoC do we instantiate"? We think of 'version' as basically "raspi 2 or 3?", but according to the table in your url you can get a version of the raspi 2b with a BCM2837 SoC, which confuses this idea. Anyway, since what we have in this patch works OK for the set of board models we support, I'm happy to leave the patch as-is, but maybe worth checking and considering what in our code we should really be making conditional on "actually the SoC type" and what on something else... thanks -- PMM
Re: [PULL 00/10] Ui 20200212 patches
On Wed, 12 Feb 2020 at 16:18, Gerd Hoffmann wrote: > > The following changes since commit e18e5501d8ac692d32657a3e1ef545b14e72b730: > > Merge remote-tracking branch > 'remotes/dgilbert-gitlab/tags/pull-virtiofs-20200210' into staging > (2020-02-10 18:09:14 +) > > are available in the Git repository at: > > git://git.kraxel.org/qemu tags/ui-20200212-pull-request > > for you to fetch changes up to 483644c25b932360018d15818d8bcd8c85ba70b8: > > ui/cocoa: Drop workarounds for pre-10.12 OSX (2020-02-12 13:27:08 +0100) > > > gtk: refresh rate fix. > cocoa: drop pre-10.12 support. > ui: rework show-cursor option. > Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/5.0 for any user-visible changes. -- PMM
Re: [PATCH v2 fixed 00/16] Ram blocks with resizable anonymous allocations under POSIX
On 12.02.20 19:03, David Hildenbrand wrote: > On 12.02.20 14:42, David Hildenbrand wrote: >> We already allow resizable ram blocks for anonymous memory, however, they >> are not actually resized. All memory is mmaped() R/W, including the memory >> exceeding the used_length, up to the max_length. >> >> When resizing, effectively only the boundary is moved. Implement actually >> resizable anonymous allocations and make use of them in resizable ram >> blocks when possible. Memory exceeding the used_length will be >> inaccessible. Especially ram block notifiers require care. >> >> Having actually resizable anonymous allocations (via mmap-hackery) allows >> to reserve a big region in virtual address space and grow the >> accessible/usable part on demand. Even if "/proc/sys/vm/overcommit_memory" >> is set to "never" under Linux, huge reservations will succeed. If there is >> not enough memory when resizing (to populate parts of the reserved region), >> trying to resize will fail. Only the actually used size is reserved in the >> OS. >> >> E.g., virtio-mem [1] wants to reserve big resizable memory regions and >> grow the usable part on demand. I think this change is worth sending out >> individually. Accompanied by a bunch of minor fixes and cleanups. >> >> Especially, memory notifiers already handle resizing by first removing >> the old region, and then re-adding the resized region. prealloc is >> currently not possible with resizable ram blocks. mlock() should continue >> to work as is. Resizing is currently rare and must only happen on the >> start of an incoming migration, or during resets. No code path (except >> HAX and SEV ram block notifiers) should access memory outside of the usable >> range - and if we ever find one, that one has to be fixed (I did not >> identify any). >> >> v1 -> v2: >> - Add "util: vfio-helpers: Fix qemu_vfio_close()" >> - Add "util: vfio-helpers: Remove Error parameter from >>qemu_vfio_undo_mapping()" >> - Add "util: vfio-helpers: Factor out removal from >>qemu_vfio_undo_mapping()" >> - "util/mmap-alloc: ..." >> -- Minor changes due to review feedback (e.g., assert alignment, return >> bool when resizing) >> - "util: vfio-helpers: Implement ram_block_resized()" >> -- Reserve max_size in the IOVA address space. >> -- On resize, undo old mapping and do new mapping. We can later implement >> a new ioctl to resize the mapping directly. >> - "numa: Teach ram block notifiers about resizable ram blocks" >> -- Pass size/max_size to ram block notifiers, which makes things easier an >> cleaner >> - "exec: Ram blocks with resizable anonymous allocations under POSIX" >> -- Adapt to new ram block notifiers >> -- Shrink after notifying. Always trigger ram block notifiers on resizes >> -- Add a safety net that all ram block notifiers registered at runtime >> support resizes. >> >> [1] https://lore.kernel.org/kvm/20191212171137.13872-1-da...@redhat.com/ >> >> David Hildenbrand (16): >> util: vfio-helpers: Factor out and fix processing of existing ram >> blocks >> util: vfio-helpers: Fix qemu_vfio_close() >> util: vfio-helpers: Remove Error parameter from >> qemu_vfio_undo_mapping() >> util: vfio-helpers: Factor out removal from qemu_vfio_undo_mapping() >> exec: Factor out setting ram settings (madvise ...) into >> qemu_ram_apply_settings() >> exec: Reuse qemu_ram_apply_settings() in qemu_ram_remap() >> exec: Drop "shared" parameter from ram_block_add() >> util/mmap-alloc: Factor out calculation of pagesize to mmap_pagesize() >> util/mmap-alloc: Factor out reserving of a memory region to >> mmap_reserve() >> util/mmap-alloc: Factor out populating of memory to mmap_populate() >> util/mmap-alloc: Prepare for resizable mmaps >> util/mmap-alloc: Implement resizable mmaps >> numa: Teach ram block notifiers about resizable ram blocks >> util: vfio-helpers: Implement ram_block_resized() >> util: oslib: Resizable anonymous allocations under POSIX >> exec: Ram blocks with resizable anonymous allocations under POSIX >> >> exec.c | 104 +++ >> hw/core/numa.c | 53 +++- >> hw/i386/xen/xen-mapcache.c | 7 +- >> include/exec/cpu-common.h | 3 + >> include/exec/memory.h | 8 ++ >> include/exec/ramlist.h | 14 +++- >> include/qemu/mmap-alloc.h | 21 +++-- >> include/qemu/osdep.h | 6 +- >> stubs/ram-block.c | 20 - >> target/i386/hax-mem.c | 5 +- >> target/i386/sev.c | 18 ++-- >> util/mmap-alloc.c | 165 +++-- >> util/oslib-posix.c | 37 - >> util/oslib-win32.c | 14 >> util/trace-events | 9 +- >> util/vfio-helpers.c| 145 +--- >> 16 files changed, 450 insertions(+), 179 deletions(-) >> > > 1. I will do resizable -> resizeable > 2. I think migration might indeed need some care regarding >
Re: [PATCH v5 0/6] small vhost changes and in-band notifications
On Thu, Feb 13, 2020 at 02:26:10PM +0100, Johannes Berg wrote: > On Thu, 2020-01-23 at 09:17 +0100, Johannes Berg wrote: > > Hi, > > > > Here's a repost of all the patches I sent back in August, with the > > in-band notifications rebased over the reset patch, so IDs have now > > changed a bit. > > Ping? > > The patches still apply on top of latest qemu. > > I wanted to send some corresponding kernel patches, but without the > protocol nailed down ... > > johannes Queued, thanks!
Re: [PATCH v5 4/8] multifd: Add multifd-zlib-level parameter
Daniel P. Berrangé writes: > On Thu, Jan 30, 2020 at 09:03:00AM +0100, Markus Armbruster wrote: >> Juan Quintela writes: >> >> > It will indicate which level use for compression. >> > >> > Signed-off-by: Juan Quintela >> >> This is slightly confusing (there is no zlib compression), unless you >> peek at the next patch (which adds zlib compression). >> >> Three ways to make it less confusing: >> >> * Squash the two commits >> >> * Swap them: first add zlib compression with level hardcoded to 1, then >> make the level configurable. >> >> * Have the first commit explain itself better. Something like >> >> multifd: Add multifd-zlib-level parameter >> >> This parameter specifies zlib compression level. The next patch >> will put it to use. > > Wouldn't the "normal" best practice for QAPI design be to use a > enum and discriminated union. eg > > { 'enum': 'MigrationCompression', > 'data': ['none', 'zlib'] } > > { 'struct': 'MigrationCompressionParamsZLib', > 'data': { 'compression-level' } } > > { 'union': 'MigrationCompressionParams', > 'base': { 'mode': 'MigrationCompression' }, > 'discriminator': 'mode', > 'data': { > 'zlib': 'MigrationCompressionParamsZLib', > } This expresses the connection between compression mode and level. In general, we prefer that to a bunch of optional members where the comments say things like "member A can be present only when member B has value V", or worse "member A is silently ignored unless member B has value V". However: > Of course this is quite different from how migration parameters are > done today. Maybe it makes sense to stick with the flat list of > migration parameters for consistency & ignore normal QAPI design > practice ? Unsure. It's certainly ugly now. Each parameter is defined in three places: enum MigrationParameter (for HMP), struct MigrateSetParameters (for QMP migrate-set-parameters), and struct MigrationParameters (for QMP query-migrate-parameters). I don't know how to make this better other than by starting over. I don't know whether starting over would result in enough of an improvement to make it worthwhile.
Re: [PATCH v2 1/2] target/arm: Fix select for aa64_va_parameters_both
On Thu, 13 Feb 2020 at 13:12, Peter Maydell wrote: > > On Tue, 11 Feb 2020 at 19:42, Richard Henderson > wrote: > > > > Select should always be 0 for a regime with one range. > > > > Signed-off-by: Richard Henderson > > This change makes sense, and matches what aa32_va_parameters() does, > but I think we need to update some of the callsites. > > (1) In get_phys_addr_lpae() we have the check: > > if (-top_bits != param.select || (param.select && !ttbr1_valid)) { > > where ttbr1_valid is the return value of (effectively) > aarch64 ? regime_has_2_ranges() : (el != 2); > but I think it's no longer possible to get here with param.select == 1 > and !ttbr1_valid, so this becomes a dead check. ...or should the code instead be checking literal pointer bit 55 against ttbr1_valid now ? thanks -- PMM
Re: [PATCH v5 0/6] small vhost changes and in-band notifications
On Thu, 2020-01-23 at 09:17 +0100, Johannes Berg wrote: > Hi, > > Here's a repost of all the patches I sent back in August, with the > in-band notifications rebased over the reset patch, so IDs have now > changed a bit. Ping? The patches still apply on top of latest qemu. I wanted to send some corresponding kernel patches, but without the protocol nailed down ... johannes
[PULL 6/6] git: Make submodule check only needed modules
If one is compiling more than one tree from the same source, it is possible that they need different submodules. Change the check to see that all modules that we are interested in are updated, discarding the ones that we don't care about. Signed-off-by: Juan Quintela --- v1->v2: patchw insists in not using modules --- scripts/git-submodule.sh | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/git-submodule.sh b/scripts/git-submodule.sh index 98ca0f2737..65ed877aef 100755 --- a/scripts/git-submodule.sh +++ b/scripts/git-submodule.sh @@ -59,10 +59,14 @@ status) fi test -f "$substat" || exit 1 -CURSTATUS=$($GIT submodule status $modules) -OLDSTATUS=$(cat $substat) -test "$CURSTATUS" = "$OLDSTATUS" -exit $? +for module in $modules; do +CURSTATUS=$($GIT submodule status $module) +OLDSTATUS=$(cat $substat | grep $module) +if test "$CURSTATUS" != "$OLDSTATUS"; then +exit 1 +fi +done +exit 0 ;; update) if test -z "$maybe_modules" -- 2.24.1
[PULL 1/6] migration: Maybe VM is paused when migration is cancelled
From: Zhimin Feng If the migration is cancelled when it is in the completion phase, the migration state is set to MIGRATION_STATUS_CANCELLING. The VM maybe wait for the 'pause_sem' semaphore in migration_maybe_pause function, so that VM always is paused. Reported-by: Euler Robot Signed-off-by: Zhimin Feng Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- migration/migration.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 3a21a4686c..1ca6be2323 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -2797,14 +2797,22 @@ static int migration_maybe_pause(MigrationState *s, /* This block intentionally left blank */ } -qemu_mutex_unlock_iothread(); -migrate_set_state(&s->state, *current_active_state, - MIGRATION_STATUS_PRE_SWITCHOVER); -qemu_sem_wait(&s->pause_sem); -migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER, - new_state); -*current_active_state = new_state; -qemu_mutex_lock_iothread(); +/* + * If the migration is cancelled when it is in the completion phase, + * the migration state is set to MIGRATION_STATUS_CANCELLING. + * So we don't need to wait a semaphore, otherwise we would always + * wait for the 'pause_sem' semaphore. + */ +if (s->state != MIGRATION_STATUS_CANCELLING) { +qemu_mutex_unlock_iothread(); +migrate_set_state(&s->state, *current_active_state, + MIGRATION_STATUS_PRE_SWITCHOVER); +qemu_sem_wait(&s->pause_sem); +migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER, + new_state); +*current_active_state = new_state; +qemu_mutex_lock_iothread(); +} return s->state == new_state ? 0 : -EINVAL; } -- 2.24.1
[PULL 5/6] migration-test: fix some memleaks in migration-test
From: Pan Nengyuan spotted by asan, 'check-qtest-aarch64' runs fail if sanitizers is enabled. Reported-by: Euler Robot Signed-off-by: Pan Nengyuan Reviewed-by: Juan Quintela Reviewed-by: Laurent Vivier Signed-off-by: Juan Quintela --- tests/qtest/migration-test.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index a78ac0c7da..ccf313f288 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -498,11 +498,13 @@ static int test_migrate_start(QTestState **from, QTestState **to, const char *arch = qtest_get_arch(); const char *machine_opts = NULL; const char *memory_size; +int ret = 0; if (args->use_shmem) { if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) { g_test_skip("/dev/shm is not supported"); -return -1; +ret = -1; +goto out; } } @@ -611,8 +613,9 @@ static int test_migrate_start(QTestState **from, QTestState **to, g_free(shmem_path); } +out: migrate_start_destroy(args); -return 0; +return ret; } static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest) @@ -1134,6 +1137,8 @@ static void test_validate_uuid(void) { MigrateStart *args = migrate_start_new(); +g_free(args->opts_source); +g_free(args->opts_target); args->opts_source = g_strdup("-uuid ----"); args->opts_target = g_strdup("-uuid ----"); do_test_validate_uuid(args, false); @@ -1143,6 +1148,8 @@ static void test_validate_uuid_error(void) { MigrateStart *args = migrate_start_new(); +g_free(args->opts_source); +g_free(args->opts_target); args->opts_source = g_strdup("-uuid ----"); args->opts_target = g_strdup("-uuid ----"); args->hide_stderr = true; @@ -1153,6 +1160,7 @@ static void test_validate_uuid_src_not_set(void) { MigrateStart *args = migrate_start_new(); +g_free(args->opts_target); args->opts_target = g_strdup("-uuid ----"); args->hide_stderr = true; do_test_validate_uuid(args, false); @@ -1162,6 +1170,7 @@ static void test_validate_uuid_dst_not_set(void) { MigrateStart *args = migrate_start_new(); +g_free(args->opts_source); args->opts_source = g_strdup("-uuid ----"); args->hide_stderr = true; do_test_validate_uuid(args, false); @@ -1380,6 +1389,7 @@ static void test_multifd_tcp_cancel(void) " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}"); qobject_unref(rsp); +g_free(uri); uri = migrate_get_socket_address(to2, "socket-address"); wait_for_migration_status(from, "cancelled", NULL); -- 2.24.1
[PULL 4/6] tests/migration: Add some slack to auto converge
From: "Dr. David Alan Gilbert" There's an assert in autoconverge that checks that we quit the iteration when we go below the expected threshold. Philippe saw a case where this assert fired with the measured value slightly over the threshold. (about 3k out of a few million). I can think of two reasons: a) Rounding errors b) That after we make the decision to quit iteration we do one more sync and that sees a few more dirty pages. So add 1% slack to the assertion, that should cover a and most cases of b, probably all we'll see for the test. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Juan Quintela Reviewed-by: Peter Xu Signed-off-by: Juan Quintela --- tests/qtest/migration-test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index cf27ebbc9d..a78ac0c7da 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -1237,7 +1237,8 @@ static void test_migrate_auto_converge(void) g_assert_cmpint(percentage, <=, max_pct); remaining = read_ram_property_int(from, "remaining"); -g_assert_cmpint(remaining, <, expected_threshold); +g_assert_cmpint(remaining, <, +(expected_threshold + expected_threshold / 100)); migrate_continue(from, "pre-switchover"); -- 2.24.1
[PULL 0/6] Pull migration patches
The following changes since commit e18e5501d8ac692d32657a3e1ef545b14e72b730: Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-virtiofs-20200210' into staging (2020-02-10 18:09:14 +) are available in the Git repository at: https://github.com/juanquintela/qemu.git tags/pull-migration-pull-request for you to fetch changes up to 1a920d2b633e13df8961328b3b3e128989a34570: git: Make submodule check only needed modules (2020-02-13 11:31:58 +0100) Migration pull request - don't pause when migration has been cancelled (Zhimin) - fix memleaks in tests (pan)( - optimize wait-unplug (keqian) - improve rdma error handling/messages (dave) - add some flexibility in autoconverge test (dave) - git-submodule: allow compiliation from same tree with different number of git-submodules (juan) Please, Apply. Dr. David Alan Gilbert (2): migration/rdma: rdma_accept_incoming_migration fix error handling tests/migration: Add some slack to auto converge Juan Quintela (1): git: Make submodule check only needed modules Keqian Zhu (1): migration: Optimization about wait-unplug migration state Pan Nengyuan (1): migration-test: fix some memleaks in migration-test Zhimin Feng (1): migration: Maybe VM is paused when migration is cancelled migration/migration.c| 26 +- migration/rdma.c | 11 +++ migration/savevm.c | 24 +++- migration/savevm.h | 1 - scripts/git-submodule.sh | 12 tests/qtest/migration-test.c | 17 ++--- 6 files changed, 49 insertions(+), 42 deletions(-) -- 2.24.1
[PULL 3/6] migration/rdma: rdma_accept_incoming_migration fix error handling
From: "Dr. David Alan Gilbert" rdma_accept_incoming_migration is called from an fd handler and can't return an Error * anywhere. Currently it's leaking Error's in errp/local_err - there's no point putting them in there unless we can report them. Turn most into fprintf's, and the last into an error_reportf_err where it's coming up from another function. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- migration/rdma.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index 2379b8345b..f61587891b 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -3980,13 +3980,13 @@ static void rdma_accept_incoming_migration(void *opaque) RDMAContext *rdma = opaque; int ret; QEMUFile *f; -Error *local_err = NULL, **errp = &local_err; +Error *local_err = NULL; trace_qemu_rdma_accept_incoming_migration(); ret = qemu_rdma_accept(rdma); if (ret) { -ERROR(errp, "RDMA Migration initialization failed!"); +fprintf(stderr, "RDMA ERROR: Migration initialization failed\n"); return; } @@ -3998,13 +3998,16 @@ static void rdma_accept_incoming_migration(void *opaque) f = qemu_fopen_rdma(rdma, "rb"); if (f == NULL) { -ERROR(errp, "could not qemu_fopen_rdma!"); +fprintf(stderr, "RDMA ERROR: could not qemu_fopen_rdma\n"); qemu_rdma_cleanup(rdma); return; } rdma->migration_started_on_destination = 1; -migration_fd_process_incoming(f, errp); +migration_fd_process_incoming(f, &local_err); +if (local_err) { +error_reportf_err(local_err, "RDMA ERROR:"); +} } void rdma_start_incoming_migration(const char *host_port, Error **errp) -- 2.24.1
[PULL 2/6] migration: Optimization about wait-unplug migration state
From: Keqian Zhu qemu_savevm_nr_failover_devices() is originally designed to get the number of failover devices, but it actually returns the number of "unplug-pending" failover devices now. Moreover, what drives migration state to wait-unplug should be the number of "unplug-pending" failover devices, not all failover devices. We can also notice that qemu_savevm_state_guest_unplug_pending() and qemu_savevm_nr_failover_devices() is equivalent almost (from the code view). So the latter is incorrect semantically and useless, just delete it. In the qemu_savevm_state_guest_unplug_pending(), once hit a unplug-pending failover device, then it can return true right now to save cpu time. Signed-off-by: Keqian Zhu Reviewed-by: Juan Quintela Tested-by: Jens Freimann Reviewed-by: Jens Freimann Signed-off-by: Juan Quintela --- migration/migration.c | 2 +- migration/savevm.c| 24 +++- migration/savevm.h| 1 - 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 1ca6be2323..8fb68795dc 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -3341,7 +3341,7 @@ static void *migration_thread(void *opaque) qemu_savevm_state_setup(s->to_dst_file); -if (qemu_savevm_nr_failover_devices()) { +if (qemu_savevm_state_guest_unplug_pending()) { migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_WAIT_UNPLUG); diff --git a/migration/savevm.c b/migration/savevm.c index f19cb9ec7a..1d4220ece8 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1140,36 +1140,18 @@ void qemu_savevm_state_header(QEMUFile *f) } } -int qemu_savevm_nr_failover_devices(void) +bool qemu_savevm_state_guest_unplug_pending(void) { SaveStateEntry *se; -int n = 0; QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { if (se->vmsd && se->vmsd->dev_unplug_pending && se->vmsd->dev_unplug_pending(se->opaque)) { -n++; -} -} - -return n; -} - -bool qemu_savevm_state_guest_unplug_pending(void) -{ -SaveStateEntry *se; -int n = 0; - -QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { -if (!se->vmsd || !se->vmsd->dev_unplug_pending) { -continue; -} -if (se->vmsd->dev_unplug_pending(se->opaque)) { -n++; +return true; } } -return n > 0; +return false; } void qemu_savevm_state_setup(QEMUFile *f) diff --git a/migration/savevm.h b/migration/savevm.h index c42b9c80ee..ba64a7e271 100644 --- a/migration/savevm.h +++ b/migration/savevm.h @@ -31,7 +31,6 @@ bool qemu_savevm_state_blocked(Error **errp); void qemu_savevm_state_setup(QEMUFile *f); -int qemu_savevm_nr_failover_devices(void); bool qemu_savevm_state_guest_unplug_pending(void); int qemu_savevm_state_resume_prepare(MigrationState *s); void qemu_savevm_state_header(QEMUFile *f); -- 2.24.1
Re: [PATCH v2] hw/char/exynos4210_uart: Fix memleaks in exynos4210_uart_init
On Thu, 13 Feb 2020 at 10:09, Philippe Mathieu-Daudé wrote: > > On 2/13/20 3:56 AM, kuhn.chen...@huawei.com wrote: > > From: Chen Qun > > > > It's easy to reproduce as follow: > > virsh qemu-monitor-command vm1 --pretty '{"execute": > > "device-list-properties", > > "arguments":{"typename":"exynos4210.uart"}}' > > > > ASAN shows memory leak stack: > >#1 0xfffd896d71cb in g_malloc0 (/lib64/libglib-2.0.so.0+0x571cb) > >#2 0xaaad270beee3 in timer_new_full /qemu/include/qemu/timer.h:530 > >#3 0xaaad270beee3 in timer_new /qemu/include/qemu/timer.h:551 > >#4 0xaaad270beee3 in timer_new_ns /qemu/include/qemu/timer.h:569 > >#5 0xaaad270beee3 in exynos4210_uart_init > > /qemu/hw/char/exynos4210_uart.c:677 > >#6 0xaaad275c8f4f in object_initialize_with_type /qemu/qom/object.c:516 > >#7 0xaaad275c91bb in object_new_with_type /qemu/qom/object.c:684 > >#8 0xaaad2755df2f in qmp_device_list_properties > > /qemu/qom/qom-qmp-cmds.c:152 > > > > Reported-by: Euler Robot > > Signed-off-by: Chen Qun > > --- > > Changes V2 to V1: > > -Keep s->wordtime in exynos4210_uart_init (Base on Eduardo and Philippe's > > comments). > > Thanks. > > Reviewed-by: Philippe Mathieu-Daudé Applied to target-arm.next, thanks. -- PMM
Re: [PATCH v2 1/2] target/arm: Fix select for aa64_va_parameters_both
On Thu, 13 Feb 2020 at 13:12, Peter Maydell wrote: > > On Tue, 11 Feb 2020 at 19:42, Richard Henderson > wrote: > > > > Select should always be 0 for a regime with one range. > > > > Signed-off-by: Richard Henderson > > This change makes sense, and matches what aa32_va_parameters() does, > but I think we need to update some of the callsites. Assuming those changes are done in separate patches, for this patch itself: Reviewed-by: Peter Maydell thanks -- PMM
Re: [PATCH v2 1/2] target/arm: Fix select for aa64_va_parameters_both
On Tue, 11 Feb 2020 at 19:42, Richard Henderson wrote: > > Select should always be 0 for a regime with one range. > > Signed-off-by: Richard Henderson This change makes sense, and matches what aa32_va_parameters() does, but I think we need to update some of the callsites. (1) In get_phys_addr_lpae() we have the check: if (-top_bits != param.select || (param.select && !ttbr1_valid)) { where ttbr1_valid is the return value of (effectively) aarch64 ? regime_has_2_ranges() : (el != 2); but I think it's no longer possible to get here with param.select == 1 and !ttbr1_valid, so this becomes a dead check. (Side note, could we pull "ttbr1_valid = regime_has_2_ranges(mmu_idx);" out of the "if (aarch64) {...} else {...}" ? -- I think it works for aarch32 too, right?) (2) in pauth_original_ptr() we do uint64_t extfield = -param.select; but in the pseudocode Auth() function the extfield is unconditionally calculated based on bit 55 of the address, regardless of whether the regime has 1 range or 2. So I think this code can't use param.select any more but should simply pull out and replicate bit 55 of its 'ptr' argument, now that param.select is not simply the value of bit 55. Change 1 would need to be done after this patch and change 2 before it. thanks -- PMM
Re: [PATCH v2 2/2] target/arm: Split out aa64_va_parameter_tbi, aa64_va_parameter_tbid
On Tue, 11 Feb 2020 at 19:42, Richard Henderson wrote: > > For the purpose of rebuild_hflags_a64, we do not need to compute > all of the va parameters, only tbi. Moreover, we can compute them > in a form that is more useful to storing in hflags. > > This eliminates the need for aa64_va_parameter_both, so fold that > in to aa64_va_parameter. The remaining calls to aa64_va_parameter > are in get_phys_addr_lpae and in pauth_helper.c. > > This reduces the total cpu consumption of aa64_va_parameter in a > kernel boot plus a kvm guest kernel boot from 3% to 0.5%. > > Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell thanks -- PMM
Re: [PATCH] console: make QMP screendump use coroutine
Gerd Hoffmann writes: > Hi, > >> Thanks to the QMP coroutine support, the screendump handler can >> trigger a graphic_hw_update(), yield and let the main loop run until >> update is done. Then the handler is resumed, and the ppm_save() will >> write the screen image to disk in the coroutine context (thus >> non-blocking). >> >> For now, HMP doesn't have coroutine support, so it remains potentially >> outdated or glitched. >> >> Fixes: >> https://bugzilla.redhat.com/show_bug.cgi?id=1230527 >> >> Based-on: <20200109183545.27452-2-kw...@redhat.com> > > What is the status here? Tried to apply (worked) and build (failed), > seems Kevins patches are not merged yet? I reviewed v3, Kevin worked in improvements promptly, and I failed to review v4 promptly. Sorry about that.
[Bug 1863096] [NEW] vhost-user multi-queues interrupt failed when Qemu reconnection happens
Public bug reported: After upgrade qemu to v4.2.0, vhost-user multi-queues interrupt failed with event idx interrupt mode when reconnection happens. Test Environment: DPDK version: DPDK v19.11 Other software versions: qemu 4.2.0. OS: Linux 4.15.0-20-generic Compiler: gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 Hardware platform: Purley. The reproduce step is: 1. Launch l3fwd-power example app with client mode:: ./l3fwd-power -l 1-16 \ -n 4 --socket-mem 1024,1024 --legacy-mem --no-pci\ --log-level=9 \ --vdev 'eth_vhost0,iface=/vhost-net0,queues=16,client=1' \ -- -p 0x1 \ --parse-ptype 1 \ --config "(0,0,1),(0,1,2),(0,2,3),(0,3,4),(0,4,5),(0,5,6),(0,6,7),(0,7,8),(0,8,9),(0,9,10),(0,10,11),(0,11,12),(0,12,13),(0,13,14),(0,14,15),(0,15,16)" 2. Launch VM1 with server mode: 3. Relauch l3fwd-power sample to for reconnection: ./l3fwd-power -l 1-16 \ -n 4 --socket-mem 1024,1024 --legacy-mem --no-pci\ --log-level=9 \ --vdev 'eth_vhost0,iface=/vhost-net0,queues=16,client=1' \ -- -p 0x1 \ --parse-ptype 1 \ --config "(0,0,1),(0,1,2),(0,2,3),(0,3,4),(0,4,5),(0,5,6),(0,6,7),(0,7,8),(0,8,9),(0,9,10),(0,10,11),(0,11,12),(0,12,13),(0,13,14),(0,14,15),(0,15,16)" 4. Set vitio-net with 16 quques and give vitio-net ip address: ethtool -L [ens3] combined 16# [ens3] is the name of virtio-net ifconfig [ens3] 1.1.1.1 5. Send packets with different IPs from virtio-net, notice to bind each vcpu to different send packets process:: taskset -c 0 ping 1.1.1.2 taskset -c 1 ping 1.1.1.3 taskset -c 2 ping 1.1.1.4 taskset -c 3 ping 1.1.1.5 taskset -c 4 ping 1.1.1.6 taskset -c 5 ping 1.1.1.7 taskset -c 6 ping 1.1.1.8 taskset -c 7 ping 1.1.1.9 taskset -c 8 ping 1.1.1.2 taskset -c 9 ping 1.1.1.2 taskset -c 10 ping 1.1.1.2 taskset -c 11 ping 1.1.1.2 taskset -c 12 ping 1.1.1.2 taskset -c 13 ping 1.1.1.2 taskset -c 14 ping 1.1.1.2 taskset -c 15 ping 1.1.1.2 If everything ok, then we can see the result such as following: L3FWD_POWER: lcore 0 is waked up from rx interrupt on port 0 queue 0 ... ... L3FWD_POWER: lcore 15 is waked up from rx interrupt on port 0 queue 15 But we can't see the log above because of the bug. ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1863096 Title: vhost-user multi-queues interrupt failed when Qemu reconnection happens Status in QEMU: New Bug description: After upgrade qemu to v4.2.0, vhost-user multi-queues interrupt failed with event idx interrupt mode when reconnection happens. Test Environment: DPDK version: DPDK v19.11 Other software versions: qemu 4.2.0. OS: Linux 4.15.0-20-generic Compiler: gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 Hardware platform: Purley. The reproduce step is: 1. Launch l3fwd-power example app with client mode:: ./l3fwd-power -l 1-16 \ -n 4 --socket-mem 1024,1024 --legacy-mem --no-pci\ --log-level=9 \ --vdev 'eth_vhost0,iface=/vhost-net0,queues=16,client=1' \ -- -p 0x1 \ --parse-ptype 1 \ --config "(0,0,1),(0,1,2),(0,2,3),(0,3,4),(0,4,5),(0,5,6),(0,6,7),(0,7,8),(0,8,9),(0,9,10),(0,10,11),(0,11,12),(0,12,13),(0,13,14),(0,14,15),(0,15,16)" 2. Launch VM1 with server mode: 3. Relauch l3fwd-power sample to for reconnection: ./l3fwd-power -l 1-16 \ -n 4 --socket-mem 1024,1024 --legacy-mem --no-pci\ --log-level=9 \ --vdev 'eth_vhost0,iface=/vhost-net0,queues=16,client=1' \ -- -p 0x1 \ --parse-ptype 1 \ --config "(0,0,1),(0,1,2),(0,2,3),(0,3,4),(0,4,5),(0,5,6),(0,6,7),(0,7,8),(0,8,9),(0,9,10),(0,10,11),(0,11,12),(0,12,13),(0,13,14),(0,14,15),(0,15,16)" 4. Set vitio-net with 16 quques and give vitio-net ip address: ethtool -L [ens3] combined 16# [ens3] is the name of virtio-net ifconfig [ens3] 1.1.1.1 5. Send packets with different IPs from virtio-net, notice to bind each vcpu to different send packets process:: taskset -c 0 ping 1.1.1.2 taskset -c 1 ping 1.1.1.3 taskset -c 2 ping 1.1.1.4 taskset -c 3 ping 1.1.1.5 taskset -c 4 ping 1.1.1.6 taskset -c 5 ping 1.1.1.7 taskset -c 6 ping 1.1.1.8 taskset -c 7 ping 1.1.1.9 taskset -c 8 ping 1.1.1.2 taskset -c 9 ping 1.1.1.2 taskset -c 10 ping 1.1.1.2 taskset -c 11 ping 1.1.1.2 taskset -c 12 ping 1.1.1.2 taskset -c 13 ping 1.1.1.2 taskset -c 14 ping 1.1.1.2 taskset -c 15 ping 1.1.1.2 If everything ok, then we can see the result such as following: L3FWD_POWER: lcore 0 is waked up from rx interrupt on port 0 queue 0 ... ... L3FWD_POWER: lcore 15 is waked up from rx interrupt on port 0 queue 15 But we can't see the log above because of the bug. To manage notifications about this bug
Re: [PATCH] block: make BlockConf.*_size properties 32-bit
On 2/13/20 2:01 AM, Roman Kagan wrote: On Wed, Feb 12, 2020 at 03:44:19PM -0600, Eric Blake wrote: On 2/11/20 5:54 AM, Roman Kagan wrote: Devices (virtio-blk, scsi, etc.) and the block layer are happy to use 32-bit for logical_block_size, physical_block_size, and min_io_size. However, the properties in BlockConf are defined as uint16_t limiting the values to 32768. This appears unnecessary tight, and we've seen bigger block sizes handy at times. What larger sizes? I could see 64k or maybe even 1M block sizes,... We played exactly with these two :) Make them 32 bit instead and lift the limitation. Signed-off-by: Roman Kagan --- hw/core/qdev-properties.c| 21 - include/hw/block/block.h | 8 include/hw/qdev-properties.h | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 7f93bfeb88..5f84e4a3b8 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -716,30 +716,32 @@ const PropertyInfo qdev_prop_pci_devfn = { /* --- blocksize --- */ +#define MIN_BLOCK_SIZE 512 +#define MAX_BLOCK_SIZE 2147483648 ...but 2G block sizes are going to have tremendous performance problems. I'm not necessarily opposed to the widening to a 32-bit type, but think you need more justification or a smaller number for the max block size, I thought any smaller value would just be arbitrary and hard to reason about, so I went ahead with the max value that fit in the type and could be made visibile to the guest. You've got bigger problems than what is visible to the guest. block/qcow2.c operates on a cluster at a time; if you are stating that it now requires reading multiple clusters to operate on one, qcow2 will have to do lots of wasteful read-modify-write cycles. You really need a strong reason to support a maximum larger than 2M other than just "so the guest can experiment with it". Besides this is a property that is set explicitly, so I don't see a problem leaving this up to the user. particularly since qcow2 refuses to use cluster sizes larger than 2M and it makes no sense to allow a block size larger than a cluster size. This still doesn't contradict passing a bigger value to the guest, for experimenting if nothing else. Thanks, Roman. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Re: [PATCH v3 0/9] linux-user: Update syscall numbers to kernel 5.5 level
Le 13/02/2020 à 13:29, Aleksandar Markovic a écrit : > From: Aleksandar Markovic > > v2->v3: > > - corrected number of arguments for two mips syscalls > > v1->v2: > > - corrected mips parts based on Laurent's review > > This series is a spin-off of another larger linux-user series > that become too large to handle, hence these patches related to > syscall numbers are now in this, separate, series. > > This series covers updating syscall numbers defined in the following > files: > > - linux-user/alpha/syscall_nr.h > - linux-user/arm/syscall_nr.h > - linux-user/m68k/syscall_nr.h > - linux-user/microblaze/syscall_nr.h > - linux-user/mips/cpu_loop.c > - linux-user/mips/syscall_nr.h > - linux-user/mips64/syscall_nr.h > - linux-user/sh4/syscall_nr.h > - linux-user/x86_64/syscall_nr.h > - linux-user/xtensa/syscall_nr.h > > -- > > Aleksandar Markovic (9): > linux-user: alpha: Update syscall numbers to kernel 5.5 level > linux-user: arm: Update syscall numbers to kernel 5.5 level > linux-user: m68k: Update syscall numbers to kernel 5.5 level > linux-user: microblaze: Update syscall numbers to kernel 5.5 level > linux-user: mips: Update syscall numbers to kernel 5.5 level > linux-user: sh4: Update syscall numbers to kernel 5.5 level > linux-user: x86_64: Update syscall numbers to kernel 5.5 level > linux-user: xtensa: Update syscall numbers to kernel 5.5 level > linux-user: xtensa: Remove unused constant TARGET_NR_syscall_count > > linux-user/alpha/syscall_nr.h | 35 > linux-user/arm/syscall_nr.h| 44 > linux-user/m68k/syscall_nr.h | 50 ++- > linux-user/microblaze/syscall_nr.h | 45 + > linux-user/mips/syscall_nr.h | 45 + > linux-user/mips64/syscall_nr.h | 50 ++- > linux-user/sh4/syscall_nr.h| 48 ++ > linux-user/x86_64/syscall_nr.h | 24 +++ > linux-user/xtensa/syscall_nr.h | 36 - > linux-user/mips/cpu_loop.c | 83 > +- > 10 files changed, 454 insertions(+), 6 deletions(-) > I've applied the series to my linux-user for 5.0 branch. Thanks, Laurent
Re: [PATCH v2 fixed 13/16] numa: Teach ram block notifiers about resizable ram blocks
On Wed, 12 Feb 2020 at 14:44, David Hildenbrand wrote: > > We want to actually resize ram blocks (make everything between > used_length and max_length inaccessible) - however, not all ram block > notifiers will support that. Let's teach the notifier that ram blocks > are indeed resizable, but keep using max_size in the existing notifiers. > > Supply the max_size when adding and removing ram blocks. Also, notify on > resizes. Introduce a way to detect if any registered notifier does not > support resizes - ram_block_notifiers_support_resize() - which we can later > use to fallback to legacy handling if a registered notifier (esp., SEV and > HAX) does not support actual resizes. > > Cc: Richard Henderson > Cc: Paolo Bonzini > Cc: "Dr. David Alan Gilbert" > Cc: Eduardo Habkost > Cc: Marcel Apfelbaum > Cc: Stefano Stabellini > Cc: Anthony Perard > Cc: Paul Durrant > Cc: "Michael S. Tsirkin" > Cc: xen-de...@lists.xenproject.org > Cc: Igor Mammedov > Signed-off-by: David Hildenbrand Xen parts... Acked-by: Paul Durrant
Re: [PATCH v2] virtio: increase virtuqueue size for virtio-scsi and virtio-blk
On 13.02.2020 14:45, Stefan Hajnoczi wrote: On Thu, Feb 13, 2020 at 12:28:25PM +0300, Denis Plotnikov wrote: On 13.02.2020 12:08, Stefan Hajnoczi wrote: On Thu, Feb 13, 2020 at 11:08:35AM +0300, Denis Plotnikov wrote: On 12.02.2020 18:43, Stefan Hajnoczi wrote: On Tue, Feb 11, 2020 at 05:14:14PM +0300, Denis Plotnikov wrote: The goal is to reduce the amount of requests issued by a guest on 1M reads/writes. This rises the performance up to 4% on that kind of disk access pattern. The maximum chunk size to be used for the guest disk accessing is limited with seg_max parameter, which represents the max amount of pices in the scatter-geather list in one guest disk request. Since seg_max is virqueue_size dependent, increasing the virtqueue size increases seg_max, which, in turn, increases the maximum size of data to be read/write from a guest disk. More details in the original problem statment: https://lists.gnu.org/archive/html/qemu-devel/2017-12/msg03721.html Suggested-by: Denis V. Lunev Signed-off-by: Denis Plotnikov --- hw/block/virtio-blk.c | 4 ++-- hw/core/machine.c | 2 ++ hw/scsi/virtio-scsi.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 09f46ed85f..6df3a7a6df 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -914,7 +914,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) memset(&blkcfg, 0, sizeof(blkcfg)); virtio_stq_p(vdev, &blkcfg.capacity, capacity); virtio_stl_p(vdev, &blkcfg.seg_max, - s->conf.seg_max_adjust ? s->conf.queue_size - 2 : 128 - 2); + s->conf.seg_max_adjust ? s->conf.queue_size - 2 : 256 - 2); This value must not change on older machine types. Yes, that's true, but .. So does this patch need to turn seg-max-adjust *on* in hw_compat_4_2 so that old machine types get 126 instead of 254? If we set seg-max-adjust "on" in older machine types, the setups using them and having queue_sizes set , for example, 1024 will also set seg_max to 1024 - 2 which isn't the expected behavior: older mt didn't change seg_max in that case and stuck with 128 - 2. So, should we, instead, leave the default 128 - 2, for seg_max? Argh! Good point :-). How about a seg_max_default property that is initialized to 254 for modern machines and 126 to old machines? Hmm, but we'll achieve the same but with more code changes, don't we? 254 is because the queue-size is 256. We gonna leave 128-2 for older machine types just for not breaking anything. All other seg_max adjustment is provided by seg_max_adjust which is "on" by default in modern machine types. to summarize: modern mt defaults: seg_max_adjust = on queue_size = 256 => default seg_max = 254 => changing queue-size will change seg_max = queue_size - 2 old mt defaults: seg_max_adjust = off queue_size = 128 => default seg_max = 126 => changing queue-size won't change seg_max, it's always = 126 like it was before You're right! The only strange case is a modern machine type with seg_max_adjust=off, where queue_size will be 256 but seg_max will be 126. But no user would want to disable seg_max_adjust, so it's okay. I agree with you that the line of code can remain unchanged: /* * Only old machine types use seg_max_adjust=off and there the default * value of queue_size is 128. */ virtio_stl_p(vdev, &blkcfg.seg_max, s->conf.seg_max_adjust ? s->conf.queue_size - 2 : 128 - 2); Stefan Ok, I'll resend the patch sortly Thanks! Denis
Re: [PULL] RISC-V Patches for the 5.0 Soft Freeze, Part 2
Hi Palmer, On Thu, Feb 13, 2020 at 1:30 AM Palmer Dabbelt wrote: > > The following changes since commit 81a23caf47956778c5a5056ad656d1ef92bf9659: > > Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' > into staging (2020-02-10 17:08:51 +) > > are available in the Git repository at: > > g...@github.com:palmer-dabbelt/qemu.git tags/riscv-for-master-5.0-sf2 > > for you to fetch changes up to 9c8fdcece53e05590441785ab22d91a22da36e29: > > MAINTAINERS: Add maintainer entry for Goldfish RTC (2020-02-10 12:01:39 > -0800) > > > RISC-V Patches for the 5.0 Soft Freeze, Part 2 > > This is a fairly light-weight pull request, but I wanted to send it out to > avoid the Goldfish stuff getting buried as the next PR should contain the H > extension implementation. > > As far as this PR goes, it contains: > > * The addition of syscon device tree nodes for reboot and poweroff, which > allows Linux to control QEMU without an additional driver. The existing > device was already compatible with the syscon interface. > * A fix to our GDB stub to avoid confusing XLEN and FLEN, specifically useful > for rv32id-based systems. > * A device emulation for the Goldfish RTC device, a simple memory-mapped RTC. > * The addition of the Goldfish RTC device to the RISC-V virt board. > > This passes "make check" and boots buildroot for me. > This PR is still missing: http://patchwork.ozlabs.org/patch/1199516/ > > > Peter: I'm sending hw/rtc code because it was suggested that the Goldfish > implementation gets handled via the RISC-V tree as our virt board is the only > user. I'm happy to do things differently in the future (maybe send > goldfish-specific PRs?) if that's better for you. Just LMK what makes sense, > I > anticipate that this'll be a pretty low traffic device so I'm fine with pretty > much anything. > Regards, Bin
[PATCH v3 7/9] linux-user: x86_64: Update syscall numbers to kernel 5.5 level
From: Aleksandar Markovic Update x86_64 syscall numbers based on Linux kernel v5.5. CC: Paolo Bonzini CC: Richard Henderson CC: Eduardo Habkost Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier --- linux-user/x86_64/syscall_nr.h | 24 1 file changed, 24 insertions(+) diff --git a/linux-user/x86_64/syscall_nr.h b/linux-user/x86_64/syscall_nr.h index 9b6981e..e5d14ec 100644 --- a/linux-user/x86_64/syscall_nr.h +++ b/linux-user/x86_64/syscall_nr.h @@ -328,5 +328,29 @@ #define TARGET_NR_membarrier324 #define TARGET_NR_mlock2325 #define TARGET_NR_copy_file_range 326 +#define TARGET_NR_preadv2 327 +#define TARGET_NR_pwritev2 328 +#define TARGET_NR_pkey_mprotect 329 +#define TARGET_NR_pkey_alloc330 +#define TARGET_NR_pkey_free 331 +#define TARGET_NR_statx 332 +#define TARGET_NR_io_pgetevents 333 +#define TARGET_NR_rseq 334 +/* + * don't use numbers 387 through 423, add new calls after the last + * 'common' entry + */ +#define TARGET_NR_pidfd_send_signal 424 +#define TARGET_NR_io_uring_setup425 +#define TARGET_NR_io_uring_enter426 +#define TARGET_NR_io_uring_register 427 +#define TARGET_NR_open_tree 428 +#define TARGET_NR_move_mount429 +#define TARGET_NR_fsopen430 +#define TARGET_NR_fsconfig 431 +#define TARGET_NR_fsmount 432 +#define TARGET_NR_fspick433 +#define TARGET_NR_pidfd_open434 +#define TARGET_NR_clone3435 #endif -- 2.7.4
[PATCH v3 8/9] linux-user: xtensa: Update syscall numbers to kernel 5.5 level
From: Aleksandar Markovic Update xtensa syscall numbers based on Linux kernel v5.5. CC: Max Filippov Acked-by: Max Filippov Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier --- linux-user/xtensa/syscall_nr.h | 38 -- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/linux-user/xtensa/syscall_nr.h b/linux-user/xtensa/syscall_nr.h index 27645be..3d19d0c 100644 --- a/linux-user/xtensa/syscall_nr.h +++ b/linux-user/xtensa/syscall_nr.h @@ -431,7 +431,41 @@ #define TARGET_NR_pkey_free 350 #define TARGET_NR_statx 351 - -#define TARGET_NR_syscall_count 352 +#define TARGET_NR_rseq 352 +/* 353 through 402 are unassigned to sync up with generic numbers */ +#define TARGET_NR_clock_gettime64403 +#define TARGET_NR_clock_settime64404 +#define TARGET_NR_clock_adjtime64405 +#define TARGET_NR_clock_getres_time64406 +#define TARGET_NR_clock_nanosleep_time64 407 +#define TARGET_NR_timer_gettime64408 +#define TARGET_NR_timer_settime64409 +#define TARGET_NR_timerfd_gettime64 410 +#define TARGET_NR_timerfd_settime64 411 +#define TARGET_NR_utimensat_time64 412 +#define TARGET_NR_pselect6_time64413 +#define TARGET_NR_ppoll_time64 414 +#define TARGET_NR_io_pgetevents_time64 416 +#define TARGET_NR_recvmmsg_time64417 +#define TARGET_NR_mq_timedsend_time64418 +#define TARGET_NR_mq_timedreceive_time64 419 +#define TARGET_NR_semtimedop_time64 420 +#define TARGET_NR_rt_sigtimedwait_time64 421 +#define TARGET_NR_futex_time64 422 +#define TARGET_NR_sched_rr_get_interval_time64 423 +#define TARGET_NR_pidfd_send_signal 424 +#define TARGET_NR_io_uring_setup 425 +#define TARGET_NR_io_uring_enter 426 +#define TARGET_NR_io_uring_register 427 +#define TARGET_NR_open_tree 428 +#define TARGET_NR_move_mount 429 +#define TARGET_NR_fsopen 430 +#define TARGET_NR_fsconfig 431 +#define TARGET_NR_fsmount432 +#define TARGET_NR_fspick 433 +#define TARGET_NR_pidfd_open 434 +#define TARGET_NR_clone3 435 + +#define TARGET_NR_syscall_count 436 #endif /* XTENSA_SYSCALL_NR_H */ -- 2.7.4
[PATCH v3 9/9] linux-user: xtensa: Remove unused constant TARGET_NR_syscall_count
From: Aleksandar Markovic Currently, there is no usage of TARGET_NR_syscall_count for target xtensa, and there is no obvious indication if there is some planned usage in future. CC: Max Filippov Acked-by: Max Filippov Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier --- linux-user/xtensa/syscall_nr.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/linux-user/xtensa/syscall_nr.h b/linux-user/xtensa/syscall_nr.h index 3d19d0c..39bff65 100644 --- a/linux-user/xtensa/syscall_nr.h +++ b/linux-user/xtensa/syscall_nr.h @@ -466,6 +466,4 @@ #define TARGET_NR_pidfd_open 434 #define TARGET_NR_clone3 435 -#define TARGET_NR_syscall_count 436 - #endif /* XTENSA_SYSCALL_NR_H */ -- 2.7.4
[PATCH v3 2/9] linux-user: arm: Update syscall numbers to kernel 5.5 level
From: Aleksandar Markovic Update arm syscall numbers based on Linux kernel v5.5. CC: Peter Maydell Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier --- linux-user/arm/syscall_nr.h | 44 1 file changed, 44 insertions(+) diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h index e7eda0d..6db9235 100644 --- a/linux-user/arm/syscall_nr.h +++ b/linux-user/arm/syscall_nr.h @@ -399,5 +399,49 @@ #define TARGET_NR_userfaultfd (388) #define TARGET_NR_membarrier (389) #define TARGET_NR_mlock2 (390) +#define TARGET_NR_copy_file_range (391) +#define TARGET_NR_preadv2 (392) +#define TARGET_NR_pwritev2 (393) +#define TARGET_NR_pkey_mprotect(394) +#define TARGET_NR_pkey_alloc (395) +#define TARGET_NR_pkey_free(396) +#define TARGET_NR_statx(397) +#define TARGET_NR_rseq (398) +#define TARGET_NR_io_pgetevents(399) +#define TARGET_NR_migrate_pages(400) +#define TARGET_NR_kexec_file_load (401) +/* 402 is unused */ +#define TARGET_NR_clock_gettime64 (403) +#define TARGET_NR_clock_settime64 (404) +#define TARGET_NR_clock_adjtime64 (405) +#define TARGET_NR_clock_getres_time64 (406) +#define TARGET_NR_clock_nanosleep_time64 (407) +#define TARGET_NR_timer_gettime64 (408) +#define TARGET_NR_timer_settime64 (409) +#define TARGET_NR_timerfd_gettime64(410) +#define TARGET_NR_timerfd_settime64(411) +#define TARGET_NR_utimensat_time64 (412) +#define TARGET_NR_pselect6_time64 (413) +#define TARGET_NR_ppoll_time64 (414) +#define TARGET_NR_io_pgetevents_time64 (416) +#define TARGET_NR_recvmmsg_time64 (417) +#define TARGET_NR_mq_timedsend_time64 (418) +#define TARGET_NR_mq_timedreceive_time64 (419) +#define TARGET_NR_semtimedop_time64(420) +#define TARGET_NR_rt_sigtimedwait_time64 (421) +#define TARGET_NR_futex_time64 (422) +#define TARGET_NR_sched_rr_get_interval_time64 (423) +#define TARGET_NR_pidfd_send_signal(424) +#define TARGET_NR_io_uring_setup (425) +#define TARGET_NR_io_uring_enter (426) +#define TARGET_NR_io_uring_register(427) +#define TARGET_NR_open_tree(428) +#define TARGET_NR_move_mount (429) +#define TARGET_NR_fsopen (430) +#define TARGET_NR_fsconfig (431) +#define TARGET_NR_fsmount (432) +#define TARGET_NR_fspick (433) +#define TARGET_NR_pidfd_open (434) +#define TARGET_NR_clone3 (435) #endif -- 2.7.4