diff options
31 files changed, 221 insertions, 156 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c52df9f76c..ff1238bb98 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -131,6 +131,17 @@ K: ^Subject:.*(?i)mips F: docs/system/target-mips.rst F: configs/targets/mips* +X86 general architecture support +M: Paolo Bonzini <pbonzini@redhat.com> +S: Maintained +F: configs/devices/i386-softmmu/default.mak +F: configs/targets/i386-softmmu.mak +F: configs/targets/x86_64-softmmu.mak +F: docs/system/target-i386* +F: target/i386/*.[ch] +F: target/i386/Kconfig +F: target/i386/meson.build + Guest CPU cores (TCG) --------------------- Overall TCG CPUs @@ -657,6 +668,7 @@ F: include/hw/dma/pl080.h F: hw/dma/pl330.c F: hw/gpio/pl061.c F: hw/input/pl050.c +F: include/hw/input/pl050.h F: hw/intc/pl190.c F: hw/sd/pl181.c F: hw/ssi/pl022.c @@ -927,6 +939,7 @@ F: hw/*/pxa2xx* F: hw/display/tc6393xb.c F: hw/gpio/max7310.c F: hw/gpio/zaurus.c +F: hw/input/ads7846.c F: hw/misc/mst_fpga.c F: hw/adc/max111x.c F: include/hw/adc/max111x.h @@ -979,7 +992,9 @@ M: Peter Maydell <peter.maydell@linaro.org> L: qemu-arm@nongnu.org S: Maintained F: hw/*/stellaris* +F: hw/display/ssd03* F: include/hw/input/gamepad.h +F: include/hw/timer/stellaris-gptm.h F: docs/system/arm/stellaris.rst STM32VLDISCOVERY @@ -994,6 +1009,7 @@ M: Peter Maydell <peter.maydell@linaro.org> L: qemu-arm@nongnu.org S: Maintained F: hw/arm/vexpress.c +F: hw/display/sii9022.c F: docs/system/arm/vexpress.rst Versatile PB diff --git a/block/snapshot.c b/block/snapshot.c index 6e16eb803a..55974273ae 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -629,7 +629,6 @@ int bdrv_all_goto_snapshot(const char *name, while (iterbdrvs) { BlockDriverState *bs = iterbdrvs->data; AioContext *ctx = bdrv_get_aio_context(bs); - int ret = 0; bool all_snapshots_includes_bs; aio_context_acquire(ctx); @@ -637,9 +636,8 @@ int bdrv_all_goto_snapshot(const char *name, all_snapshots_includes_bs = bdrv_all_snapshots_includes_bs(bs); bdrv_graph_rdunlock_main_loop(); - if (devices || all_snapshots_includes_bs) { - ret = bdrv_snapshot_goto(bs, name, errp); - } + ret = (devices || all_snapshots_includes_bs) ? + bdrv_snapshot_goto(bs, name, errp) : 0; aio_context_release(ctx); if (ret < 0) { bdrv_graph_rdlock_main_loop(); diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index b0680cbb22..fef64accc1 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -668,11 +668,11 @@ suppressing it. More information on the file format can be found here: https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions -tests/tsan/blacklist.tsan - Has TSan warnings we wish to disable +tests/tsan/ignore.tsan - Has TSan warnings we wish to disable at compile time for test or debug. Add flags to configure to enable: -"--extra-cflags=-fsanitize-blacklist=<src path>/tests/tsan/blacklist.tsan" +"--extra-cflags=-fsanitize-blacklist=<src path>/tests/tsan/ignore.tsan" More information on the file format can be found here under "Blacklist Format": diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 8f3b9997a1..658c288f8f 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -515,7 +515,7 @@ class QAPIDocDirective(Directive): except QAPIError as err: # Launder QAPI parse errors into Sphinx extension errors # so they are displayed nicely to the user - raise ExtensionError(str(err)) + raise ExtensionError(str(err)) from err def do_parse(self, rstlist, node): """Parse rST source lines and add them to the specified node diff --git a/host/include/generic/host/atomic128-cas.h b/host/include/generic/host/atomic128-cas.h index 991d3da082..6b40cc2271 100644 --- a/host/include/generic/host/atomic128-cas.h +++ b/host/include/generic/host/atomic128-cas.h @@ -28,7 +28,7 @@ atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new) static inline Int128 ATTRIBUTE_ATOMIC128_OPT atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new) { - __int128_t *ptr_align = __builtin_assume_aligned(ptr, 16); + Int128Aligned *ptr_align = __builtin_assume_aligned(ptr, 16); Int128Alias r, c, n; c.s = cmp; diff --git a/host/include/generic/host/atomic128-ldst.h b/host/include/generic/host/atomic128-ldst.h index 80fff0643a..691e6a8531 100644 --- a/host/include/generic/host/atomic128-ldst.h +++ b/host/include/generic/host/atomic128-ldst.h @@ -58,7 +58,7 @@ atomic16_read_rw(Int128 *ptr) static inline void ATTRIBUTE_ATOMIC128_OPT atomic16_set(Int128 *ptr, Int128 val) { - __int128_t *ptr_align = __builtin_assume_aligned(ptr, 16); + Int128Aligned *ptr_align = __builtin_assume_aligned(ptr, 16); __int128_t old; Int128Alias new; diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 85e3c5ba9d..be2856c018 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -576,7 +576,8 @@ static void fdt_add_gic_node(VirtMachineState *vms) if (vms->virt) { qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", - GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ, + GIC_FDT_IRQ_TYPE_PPI, + INTID_TO_PPI(ARCH_GIC_MAINT_IRQ), GIC_FDT_IRQ_FLAGS_LEVEL_HI); } } else { @@ -600,7 +601,8 @@ static void fdt_add_gic_node(VirtMachineState *vms) 2, vms->memmap[VIRT_GIC_VCPU].base, 2, vms->memmap[VIRT_GIC_VCPU].size); qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", - GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ, + GIC_FDT_IRQ_TYPE_PPI, + INTID_TO_PPI(ARCH_GIC_MAINT_IRQ), GIC_FDT_IRQ_FLAGS_LEVEL_HI); } } diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 91c47330ad..fad5541211 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -670,8 +670,13 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, cnt += (transferred + d->leftover) >> 2; if (s->sctl & loop_sel) { - /* Bah, how stupid is that having a 0 represent true value? - i just spent few hours on this shit */ + /* + * loop_sel tells us which bit in the SCTL register to look at + * (either P1_LOOP_SEL, P2_LOOP_SEL or R1_LOOP_SEL). The sense + * of these bits is 0 for loop mode (set interrupt and keep recording + * when the sample count reaches zero) or 1 for stop mode (set + * interrupt and stop recording). + */ AUD_log ("es1370: warning", "non looping mode\n"); } else { d->frame_cnt = size; diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index a3222d3a96..9d08f39490 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -34,9 +34,10 @@ #include "net/net.h" #include "qemu/log.h" -#define MIN_SEABIOS_HPPA_VERSION 10 /* require at least this fw version */ +#define MIN_SEABIOS_HPPA_VERSION 12 /* require at least this fw version */ -#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10) +/* Power button address at &PAGE0->pad[4] */ +#define HPA_POWER_BUTTON (0x40 + 4 * sizeof(uint32_t)) #define enable_lasi_lan() 0 diff --git a/hw/pci-host/astro.c b/hw/pci-host/astro.c index bd226581af..7d68ccee7e 100644 --- a/hw/pci-host/astro.c +++ b/hw/pci-host/astro.c @@ -32,6 +32,7 @@ #include "hw/pci-host/astro.h" #include "hw/hppa/hppa_hardware.h" #include "migration/vmstate.h" +#include "target/hppa/cpu.h" #include "trace.h" #include "qom/object.h" @@ -268,22 +269,6 @@ static const MemoryRegionOps elroy_config_addr_ops = { }; -/* - * A subroutine of astro_translate_iommu that builds an IOMMUTLBEntry using the - * given translated address and mask. - */ -static bool make_iommu_tlbe(hwaddr addr, hwaddr taddr, hwaddr mask, - IOMMUTLBEntry *ret) -{ - hwaddr tce_mask = ~((1ull << 12) - 1); - ret->target_as = &address_space_memory; - ret->iova = addr & tce_mask; - ret->translated_addr = taddr & tce_mask; - ret->addr_mask = ~tce_mask; - ret->perm = IOMMU_RW; - return true; -} - /* Handle PCI-to-system address translation. */ static IOMMUTLBEntry astro_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr, @@ -291,53 +276,59 @@ static IOMMUTLBEntry astro_translate_iommu(IOMMUMemoryRegion *iommu, int iommu_idx) { AstroState *s = container_of(iommu, AstroState, iommu); - IOMMUTLBEntry ret = { - .target_as = &address_space_memory, - .iova = addr, - .translated_addr = 0, - .addr_mask = ~(hwaddr)0, - .perm = IOMMU_NONE, - }; - hwaddr pdir_ptr, index, a, ibase; + hwaddr pdir_ptr, index, ibase; hwaddr addr_mask = 0xfff; /* 4k translation */ uint64_t entry; #define IOVP_SHIFT 12 /* equals PAGE_SHIFT */ #define PDIR_INDEX(iovp) ((iovp) >> IOVP_SHIFT) -#define IOVP_MASK PAGE_MASK #define SBA_PDIR_VALID_BIT 0x8000000000000000ULL + addr &= ~addr_mask; + + /* + * Default translation: "32-bit PCI Addressing on 40-bit Runway". + * For addresses in the 32-bit memory address range ... and then + * language which not-coincidentally matches the PSW.W=0 mapping. + */ + if (addr <= UINT32_MAX) { + entry = hppa_abs_to_phys_pa2_w0(addr); + } else { + entry = addr; + } + /* "range enable" flag cleared? */ if ((s->tlb_ibase & 1) == 0) { - make_iommu_tlbe(addr, addr, addr_mask, &ret); - return ret; + goto skip; } - a = addr; ibase = s->tlb_ibase & ~1ULL; - if ((a & s->tlb_imask) != ibase) { + if ((addr & s->tlb_imask) != ibase) { /* do not translate this one! */ - make_iommu_tlbe(addr, addr, addr_mask, &ret); - return ret; + goto skip; } - index = PDIR_INDEX(a); + + index = PDIR_INDEX(addr); pdir_ptr = s->tlb_pdir_base + index * sizeof(entry); entry = ldq_le_phys(&address_space_memory, pdir_ptr); + if (!(entry & SBA_PDIR_VALID_BIT)) { /* I/O PDIR entry valid ? */ - g_assert_not_reached(); - goto failure; + /* failure */ + return (IOMMUTLBEntry) { .perm = IOMMU_NONE }; } + entry &= ~SBA_PDIR_VALID_BIT; entry >>= IOVP_SHIFT; entry <<= 12; - entry |= addr & 0xfff; - make_iommu_tlbe(addr, entry, addr_mask, &ret); - goto success; - failure: - ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE }; - success: - return ret; + skip: + return (IOMMUTLBEntry) { + .target_as = &address_space_memory, + .iova = addr, + .translated_addr = entry, + .addr_mask = addr_mask, + .perm = IOMMU_RW, + }; } static AddressSpace *elroy_pcihost_set_iommu(PCIBus *bus, void *opaque, diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build index de7bfb5a62..36d5ab756f 100644 --- a/hw/pci-host/meson.build +++ b/hw/pci-host/meson.build @@ -29,7 +29,7 @@ pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c')) pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c')) # HPPA devices -pci_ss.add(when: 'CONFIG_ASTRO', if_true: files('astro.c')) +specific_ss.add(when: 'CONFIG_ASTRO', if_true: files('astro.c')) pci_ss.add(when: 'CONFIG_DINO', if_true: files('dino.c')) system_ss.add_all(when: 'CONFIG_PCI', if_true: pci_ss) diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c index 59a2e03873..7dbbc76823 100644 --- a/hw/s390x/s390-pci-vfio.c +++ b/hw/s390x/s390-pci-vfio.c @@ -66,6 +66,10 @@ S390PCIDMACount *s390_pci_start_dma_count(S390pciState *s, assert(vpdev); + if (!vpdev->vbasedev.group) { + return NULL; + } + id = vpdev->vbasedev.group->container->fd; if (!s390_pci_update_dma_avail(id, &avail)) { @@ -132,7 +136,7 @@ static void s390_pci_read_base(S390PCIBusDevice *pbdev, * to the guest based upon the vfio DMA limit. */ vfio_size = pbdev->iommu->max_dma_limit << TARGET_PAGE_BITS; - if (vfio_size < (cap->end_dma - cap->start_dma + 1)) { + if (vfio_size > 0 && vfio_size < cap->end_dma - cap->start_dma + 1) { pbdev->zpci_fn.edma = cap->start_dma + vfio_size - 1; } } diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index a5ea3be414..75ee38aa46 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -525,9 +525,7 @@ static void virtio_mem_activate_memslots_to_plug(VirtIOMEM *vmem, vmem->memslot_size; unsigned int idx; - if (!vmem->dynamic_memslots) { - return; - } + assert(vmem->dynamic_memslots); /* Activate all involved memslots in a single transaction. */ memory_region_transaction_begin(); @@ -547,9 +545,7 @@ static void virtio_mem_deactivate_unplugged_memslots(VirtIOMEM *vmem, vmem->memslot_size; unsigned int idx; - if (!vmem->dynamic_memslots) { - return; - } + assert(vmem->dynamic_memslots); /* Deactivate all memslots with unplugged blocks in a single transaction. */ memory_region_transaction_begin(); @@ -598,7 +594,9 @@ static int virtio_mem_set_block_state(VirtIOMEM *vmem, uint64_t start_gpa, virtio_mem_notify_unplug(vmem, offset, size); virtio_mem_set_range_unplugged(vmem, start_gpa, size); /* Deactivate completely unplugged memslots after updating the state. */ - virtio_mem_deactivate_unplugged_memslots(vmem, offset, size); + if (vmem->dynamic_memslots) { + virtio_mem_deactivate_unplugged_memslots(vmem, offset, size); + } return 0; } @@ -635,9 +633,11 @@ static int virtio_mem_set_block_state(VirtIOMEM *vmem, uint64_t start_gpa, * blocks we are plugging here. The following notification will inform * registered listeners about the blocks we're plugging. */ - virtio_mem_activate_memslots_to_plug(vmem, offset, size); + if (vmem->dynamic_memslots) { + virtio_mem_activate_memslots_to_plug(vmem, offset, size); + } ret = virtio_mem_notify_plug(vmem, offset, size); - if (ret) { + if (ret && vmem->dynamic_memslots) { virtio_mem_deactivate_unplugged_memslots(vmem, offset, size); } } @@ -749,7 +749,9 @@ static int virtio_mem_unplug_all(VirtIOMEM *vmem) notifier_list_notify(&vmem->size_change_notifiers, &vmem->size); /* Deactivate all memslots after updating the state. */ - virtio_mem_deactivate_unplugged_memslots(vmem, 0, region_size); + if (vmem->dynamic_memslots) { + virtio_mem_deactivate_unplugged_memslots(vmem, 0, region_size); + } } trace_virtio_mem_unplugged_all(); diff --git a/include/qemu/int128.h b/include/qemu/int128.h index 73624e8be7..174bd7dafb 100644 --- a/include/qemu/int128.h +++ b/include/qemu/int128.h @@ -10,6 +10,7 @@ */ #if defined(CONFIG_INT128) && !defined(CONFIG_TCG_INTERPRETER) typedef __int128_t Int128; +typedef __int128_t __attribute__((aligned(16))) Int128Aligned; static inline Int128 int128_make64(uint64_t a) { @@ -224,6 +225,7 @@ static inline Int128 int128_rems(Int128 a, Int128 b) #else /* !CONFIG_INT128 */ typedef struct Int128 Int128; +typedef struct Int128 __attribute__((aligned(16))) Int128Aligned; /* * We guarantee that the in-memory byte representation of an diff --git a/meson.build b/meson.build index d7d841e71e..ec01f8b138 100644 --- a/meson.build +++ b/meson.build @@ -462,6 +462,7 @@ warn_flags = [ '-Wno-tautological-type-limit-compare', '-Wno-psabi', '-Wno-gnu-variable-sized-type-not-at-end', + '-Wshadow=local', ] if targetos != 'darwin' diff --git a/pc-bios/hppa-firmware.img b/pc-bios/hppa-firmware.img Binary files differindex e976c0cc93..9a2d54f26b 100644 --- a/pc-bios/hppa-firmware.img +++ b/pc-bios/hppa-firmware.img diff --git a/roms/seabios-hppa b/roms/seabios-hppa -Subproject fd5b6cf82369a1e53d68302fb6ede2b9e2afccd +Subproject 2a23dd388fcc1068f9c4a3077e0662803743e1c diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index d739e558e9..6a836950a9 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -76,7 +76,8 @@ class QAPISchemaEntity: def __repr__(self): if self.name is None: return "<%s at 0x%x>" % (type(self).__name__, id(self)) - return "<%s:%s at 0x%x>" % type(self).__name__, self.name, id(self) + return "<%s:%s at 0x%x>" % (type(self).__name__, self.name, + id(self)) def c_name(self): return c_name(self.name) diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c index 0d5d8e307d..d9e0e2a4dd 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c @@ -351,6 +351,7 @@ static void cortex_a8_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_EL3); + set_feature(&cpu->env, ARM_FEATURE_PMU); cpu->midr = 0x410fc080; cpu->reset_fpsid = 0x410330c0; cpu->isar.mvfr0 = 0x11110222; @@ -418,6 +419,7 @@ static void cortex_a9_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_NEON); set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); set_feature(&cpu->env, ARM_FEATURE_EL3); + set_feature(&cpu->env, ARM_FEATURE_PMU); /* * Note that A9 supports the MP extensions even for * A9UP and single-core A9MP (which are both different diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c index 70ac876105..ffb8ea1c34 100644 --- a/target/arm/tcg/mte_helper.c +++ b/target/arm/tcg/mte_helper.c @@ -1101,10 +1101,18 @@ uint64_t mte_mops_probe_rev(CPUARMState *env, uint64_t ptr, uint64_t size, uint32_t n; mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX); - /* True probe; this will never fault */ + /* + * True probe; this will never fault. Note that our caller passes + * us a pointer to the end of the region, but allocation_tag_mem_probe() + * wants a pointer to the start. Because we know we don't span a page + * boundary and that allocation_tag_mem_probe() doesn't otherwise care + * about the size, pass in a size of 1 byte. This is simpler than + * adjusting the ptr to point to the start of the region and then having + * to adjust the returned 'mem' to get the end of the tag memory. + */ mem = allocation_tag_mem_probe(env, mmu_idx, ptr, w ? MMU_DATA_STORE : MMU_DATA_LOAD, - size, MMU_DATA_LOAD, true, 0); + 1, MMU_DATA_LOAD, true, 0); if (!mem) { return size; } diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 41484d8ae5..a2e49c39f9 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -2351,6 +2351,8 @@ static bool trans_SVC(DisasContext *s, arg_i *a) static bool trans_HVC(DisasContext *s, arg_i *a) { + int target_el = s->current_el == 3 ? 3 : 2; + if (s->current_el == 0) { unallocated_encoding(s); return true; @@ -2363,7 +2365,7 @@ static bool trans_HVC(DisasContext *s, arg_i *a) gen_helper_pre_hvc(tcg_env); /* Architecture requires ss advance before we do the actual work */ gen_ss_advance(s); - gen_exception_insn_el(s, 4, EXCP_HVC, syn_aa64_hvc(a->imm), 2); + gen_exception_insn_el(s, 4, EXCP_HVC, syn_aa64_hvc(a->imm), target_el); return true; } diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h index 6746869a3b..bb3d7ef6f7 100644 --- a/target/hppa/cpu-param.h +++ b/target/hppa/cpu-param.h @@ -14,7 +14,8 @@ # define TARGET_PHYS_ADDR_SPACE_BITS 32 # define TARGET_VIRT_ADDR_SPACE_BITS 32 #else -# define TARGET_PHYS_ADDR_SPACE_BITS 64 +/* ??? PA-8000 through 8600 have 40 bits; PA-8700 and 8900 have 44 bits. */ +# define TARGET_PHYS_ADDR_SPACE_BITS 40 # define TARGET_VIRT_ADDR_SPACE_BITS 64 #endif diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index cecec59700..bcfed04f7c 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -31,23 +31,25 @@ basis. It's probably easier to fall back to a strong memory model. */ #define TCG_GUEST_DEFAULT_MO TCG_MO_ALL -#define MMU_KERNEL_IDX 7 -#define MMU_KERNEL_P_IDX 8 -#define MMU_PL1_IDX 9 -#define MMU_PL1_P_IDX 10 -#define MMU_PL2_IDX 11 -#define MMU_PL2_P_IDX 12 -#define MMU_USER_IDX 13 -#define MMU_USER_P_IDX 14 -#define MMU_PHYS_IDX 15 - +#define MMU_ABS_W_IDX 6 +#define MMU_ABS_IDX 7 +#define MMU_KERNEL_IDX 8 +#define MMU_KERNEL_P_IDX 9 +#define MMU_PL1_IDX 10 +#define MMU_PL1_P_IDX 11 +#define MMU_PL2_IDX 12 +#define MMU_PL2_P_IDX 13 +#define MMU_USER_IDX 14 +#define MMU_USER_P_IDX 15 + +#define MMU_IDX_MMU_DISABLED(MIDX) ((MIDX) < MMU_KERNEL_IDX) #define MMU_IDX_TO_PRIV(MIDX) (((MIDX) - MMU_KERNEL_IDX) / 2) #define MMU_IDX_TO_P(MIDX) (((MIDX) - MMU_KERNEL_IDX) & 1) #define PRIV_P_TO_MMU_IDX(PRIV, P) ((PRIV) * 2 + !!(P) + MMU_KERNEL_IDX) #define TARGET_INSN_START_EXTRA_WORDS 2 -/* No need to flush MMU_PHYS_IDX */ +/* No need to flush MMU_ABS*_IDX */ #define HPPA_MMU_FLUSH_MASK \ (1 << MMU_KERNEL_IDX | 1 << MMU_KERNEL_P_IDX | \ 1 << MMU_PL1_IDX | 1 << MMU_PL1_P_IDX | \ @@ -287,7 +289,8 @@ static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch) if (env->psw & (ifetch ? PSW_C : PSW_D)) { return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P); } - return MMU_PHYS_IDX; /* mmu disabled */ + /* mmu disabled */ + return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX; #endif } diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index 467ee7daf5..98e9d688f6 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -126,7 +126,7 @@ void hppa_cpu_do_interrupt(CPUState *cs) env->cr[CR_IIASQ] = hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32; env->cr_back[0] = - hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32; + hppa_form_gva_psw(old_psw, env->iasq_b, env->iaoq_b) >> 32; } else { env->cr[CR_IIASQ] = 0; env->cr_back[0] = 0; diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 858ce6ec7f..08abd1a9f9 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -27,41 +27,39 @@ hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr) { - if (likely(extract64(addr, 58, 4) != 0xf)) { - /* Memory address space */ - return addr & MAKE_64BIT_MASK(0, 62); - } - if (extract64(addr, 54, 4) != 0) { - /* I/O address space */ - return addr | MAKE_64BIT_MASK(62, 2); - } - /* PDC address space */ - return (addr & MAKE_64BIT_MASK(0, 54)) | MAKE_64BIT_MASK(60, 4); + /* + * Figure H-8 "62-bit Absolute Accesses when PSW W-bit is 1" describes + * an algorithm in which a 62-bit absolute address is transformed to + * a 64-bit physical address. This must then be combined with that + * pictured in Figure H-11 "Physical Address Space Mapping", in which + * the full physical address is truncated to the N-bit physical address + * supported by the implementation. + * + * Since the supported physical address space is below 54 bits, the + * H-8 algorithm is moot and all that is left is to truncate. + */ + QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 54); + return sextract64(addr, 0, TARGET_PHYS_ADDR_SPACE_BITS); } hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr) { + /* + * See Figure H-10, "Absolute Accesses when PSW W-bit is 0", + * combined with Figure H-11, as above. + */ if (likely(extract32(addr, 28, 4) != 0xf)) { /* Memory address space */ - return addr & MAKE_64BIT_MASK(0, 32); - } - if (extract32(addr, 24, 4) != 0) { + addr = (uint32_t)addr; + } else if (extract32(addr, 24, 4) != 0) { /* I/O address space */ - return addr | MAKE_64BIT_MASK(32, 32); - } - /* PDC address space */ - return (addr & MAKE_64BIT_MASK(0, 24)) | MAKE_64BIT_MASK(60, 4); -} - -static hwaddr hppa_abs_to_phys(CPUHPPAState *env, vaddr addr) -{ - if (!hppa_is_pa20(env)) { - return addr; - } else if (env->psw & PSW_W) { - return hppa_abs_to_phys_pa2_w1(addr); + addr = (int32_t)addr; } else { - return hppa_abs_to_phys_pa2_w0(addr); + /* PDC address space */ + addr &= MAKE_64BIT_MASK(0, 24); + addr |= -1ull << (TARGET_PHYS_ADDR_SPACE_BITS - 4); } + return addr; } static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr) @@ -161,9 +159,22 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, *tlb_entry = NULL; } - /* Virtual translation disabled. Direct map virtual to physical. */ - if (mmu_idx == MMU_PHYS_IDX) { - phys = addr; + /* Virtual translation disabled. Map absolute to physical. */ + if (MMU_IDX_MMU_DISABLED(mmu_idx)) { + switch (mmu_idx) { + case MMU_ABS_W_IDX: + phys = hppa_abs_to_phys_pa2_w1(addr); + break; + case MMU_ABS_IDX: + if (hppa_is_pa20(env)) { + phys = hppa_abs_to_phys_pa2_w0(addr); + } else { + phys = (uint32_t)addr; + } + break; + default: + g_assert_not_reached(); + } prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; goto egress; } @@ -261,7 +272,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, } egress: - *pphys = phys = hppa_abs_to_phys(env, phys); + *pphys = phys; *pprot = prot; trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys); return ret; @@ -271,16 +282,15 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { HPPACPU *cpu = HPPA_CPU(cs); hwaddr phys; - int prot, excp; + int prot, excp, mmu_idx; /* If the (data) mmu is disabled, bypass translation. */ /* ??? We really ought to know if the code mmu is disabled too, in order to get the correct debugging dumps. */ - if (!(cpu->env.psw & PSW_D)) { - return hppa_abs_to_phys(&cpu->env, addr); - } + mmu_idx = (cpu->env.psw & PSW_D ? MMU_KERNEL_IDX : + cpu->env.psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX); - excp = hppa_get_physical_address(&cpu->env, addr, MMU_KERNEL_IDX, 0, + excp = hppa_get_physical_address(&cpu->env, addr, mmu_idx, 0, &phys, &prot, NULL); /* Since we're translating for debugging, the only error that is a @@ -367,8 +377,8 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx); /* Failure. Raise the indicated exception. */ - raise_exception_with_ior(env, excp, retaddr, - addr, mmu_idx == MMU_PHYS_IDX); + raise_exception_with_ior(env, excp, retaddr, addr, + MMU_IDX_MMU_DISABLED(mmu_idx)); } trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK, @@ -450,7 +460,7 @@ static void itlbt_pa20(CPUHPPAState *env, target_ulong r1, int mask_shift; mask_shift = 2 * (r1 & 0xf); - va_size = TARGET_PAGE_SIZE << mask_shift; + va_size = (uint64_t)TARGET_PAGE_SIZE << mask_shift; va_b &= -va_size; va_e = va_b + va_size - 1; @@ -459,7 +469,14 @@ static void itlbt_pa20(CPUHPPAState *env, target_ulong r1, ent->itree.start = va_b; ent->itree.last = va_e; - ent->pa = (r1 << 7) & (TARGET_PAGE_MASK << mask_shift); + + /* Extract all 52 bits present in the page table entry. */ + ent->pa = r1 << (TARGET_PAGE_BITS - 5); + /* Align per the page size. */ + ent->pa &= TARGET_PAGE_MASK << mask_shift; + /* Ignore the bits beyond physical address space. */ + ent->pa = sextract64(ent->pa, 0, TARGET_PHYS_ADDR_SPACE_BITS); + ent->t = extract64(r2, 61, 1); ent->d = extract64(r2, 60, 1); ent->b = extract64(r2, 59, 1); @@ -505,7 +522,7 @@ static void ptlb_work(CPUState *cpu, run_on_cpu_data data) */ end = start & 0xf; start &= TARGET_PAGE_MASK; - end = TARGET_PAGE_SIZE << (2 * end); + end = (vaddr)TARGET_PAGE_SIZE << (2 * end); end = start + end - 1; hppa_flush_tlb_range(env, start, end); diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index a0e31c0c25..7f607c3afd 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -338,7 +338,7 @@ target_ulong HELPER(probe)(CPUHPPAState *env, target_ulong addr, #ifdef CONFIG_USER_ONLY return page_check_range(addr, 1, want); #else - int prot, excp; + int prot, excp, mmu_idx; hwaddr phys; trace_hppa_tlb_probe(addr, level, want); @@ -347,7 +347,8 @@ target_ulong HELPER(probe)(CPUHPPAState *env, target_ulong addr, return 0; } - excp = hppa_get_physical_address(env, addr, level, 0, &phys, + mmu_idx = PRIV_P_TO_MMU_IDX(level, env->psw & PSW_P); + excp = hppa_get_physical_address(env, addr, mmu_idx, 0, &phys, &prot, NULL); if (excp >= 0) { if (env->psw & PSW_Q) { diff --git a/target/hppa/translate.c b/target/hppa/translate.c index bcce65d587..4a4830c3e3 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -69,19 +69,24 @@ typedef struct DisasContext { } DisasContext; #ifdef CONFIG_USER_ONLY -#define UNALIGN(C) (C)->unalign +#define UNALIGN(C) (C)->unalign +#define MMU_DISABLED(C) false #else -#define UNALIGN(C) MO_ALIGN +#define UNALIGN(C) MO_ALIGN +#define MMU_DISABLED(C) MMU_IDX_MMU_DISABLED((C)->mmu_idx) #endif /* Note that ssm/rsm instructions number PSW_W and PSW_E differently. */ static int expand_sm_imm(DisasContext *ctx, int val) { - if (val & PSW_SM_E) { - val = (val & ~PSW_SM_E) | PSW_E; - } - if (val & PSW_SM_W) { - val = (val & ~PSW_SM_W) | PSW_W; + /* Keep unimplemented bits disabled -- see cpu_hppa_put_psw. */ + if (ctx->is_pa20) { + if (val & PSW_SM_W) { + val |= PSW_W; + } + val &= ~(PSW_SM_W | PSW_SM_E | PSW_G); + } else { + val &= ~(PSW_SM_W | PSW_SM_E | PSW_O); } return val; } @@ -1372,7 +1377,7 @@ static void do_load_32(DisasContext *ctx, TCGv_i32 dest, unsigned rb, assert(ctx->null_cond.c == TCG_COND_NEVER); form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify, - ctx->mmu_idx == MMU_PHYS_IDX); + MMU_DISABLED(ctx)); tcg_gen_qemu_ld_i32(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx)); if (modify) { save_gpr(ctx, rb, ofs); @@ -1390,7 +1395,7 @@ static void do_load_64(DisasContext *ctx, TCGv_i64 dest, unsigned rb, assert(ctx->null_cond.c == TCG_COND_NEVER); form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify, - ctx->mmu_idx == MMU_PHYS_IDX); + MMU_DISABLED(ctx)); tcg_gen_qemu_ld_i64(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx)); if (modify) { save_gpr(ctx, rb, ofs); @@ -1408,7 +1413,7 @@ static void do_store_32(DisasContext *ctx, TCGv_i32 src, unsigned rb, assert(ctx->null_cond.c == TCG_COND_NEVER); form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify, - ctx->mmu_idx == MMU_PHYS_IDX); + MMU_DISABLED(ctx)); tcg_gen_qemu_st_i32(src, addr, ctx->mmu_idx, mop | UNALIGN(ctx)); if (modify) { save_gpr(ctx, rb, ofs); @@ -1426,7 +1431,7 @@ static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb, assert(ctx->null_cond.c == TCG_COND_NEVER); form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify, - ctx->mmu_idx == MMU_PHYS_IDX); + MMU_DISABLED(ctx)); tcg_gen_qemu_st_i64(src, addr, ctx->mmu_idx, mop | UNALIGN(ctx)); if (modify) { save_gpr(ctx, rb, ofs); @@ -2294,7 +2299,7 @@ static bool trans_probe(DisasContext *ctx, arg_probe *a) form_gva(ctx, &addr, &ofs, a->b, 0, 0, 0, a->sp, 0, false); if (a->imm) { - level = tcg_constant_i32(a->ri); + level = tcg_constant_i32(a->ri & 3); } else { level = tcg_temp_new_i32(); tcg_gen_extrl_i64_i32(level, load_gpr(ctx, a->ri)); @@ -3075,7 +3080,7 @@ static bool trans_ldc(DisasContext *ctx, arg_ldst *a) } form_gva(ctx, &addr, &ofs, a->b, a->x, a->scale ? a->size : 0, - a->disp, a->sp, a->m, ctx->mmu_idx == MMU_PHYS_IDX); + a->disp, a->sp, a->m, MMU_DISABLED(ctx)); /* * For hppa1.1, LDCW is undefined unless aligned mod 16. @@ -3105,7 +3110,7 @@ static bool trans_stby(DisasContext *ctx, arg_stby *a) nullify_over(ctx); form_gva(ctx, &addr, &ofs, a->b, 0, 0, a->disp, a->sp, a->m, - ctx->mmu_idx == MMU_PHYS_IDX); + MMU_DISABLED(ctx)); val = load_gpr(ctx, a->r); if (a->a) { if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { @@ -3139,7 +3144,7 @@ static bool trans_stdby(DisasContext *ctx, arg_stby *a) nullify_over(ctx); form_gva(ctx, &addr, &ofs, a->b, 0, 0, a->disp, a->sp, a->m, - ctx->mmu_idx == MMU_PHYS_IDX); + MMU_DISABLED(ctx)); val = load_gpr(ctx, a->r); if (a->a) { if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { @@ -3167,7 +3172,7 @@ static bool trans_lda(DisasContext *ctx, arg_ldst *a) int hold_mmu_idx = ctx->mmu_idx; CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR); - ctx->mmu_idx = MMU_PHYS_IDX; + ctx->mmu_idx = ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX; trans_ld(ctx, a); ctx->mmu_idx = hold_mmu_idx; return true; @@ -3178,7 +3183,7 @@ static bool trans_sta(DisasContext *ctx, arg_ldst *a) int hold_mmu_idx = ctx->mmu_idx; CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR); - ctx->mmu_idx = MMU_PHYS_IDX; + ctx->mmu_idx = ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX; trans_st(ctx, a); ctx->mmu_idx = hold_mmu_idx; return true; @@ -4430,7 +4435,7 @@ static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3; ctx->mmu_idx = (ctx->tb_flags & PSW_D ? PRIV_P_TO_MMU_IDX(ctx->privilege, ctx->tb_flags & PSW_P) - : MMU_PHYS_IDX); + : ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX); /* Recover the IAOQ values from the GVA + PRIV. */ uint64_t cs_base = ctx->base.tb->cs_base; diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index d58c31f539..14f7b62a44 100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -136,12 +136,11 @@ def test_frontend(fname): def open_test_result(dir_name, file_name, update): mode = 'r+' if update else 'r' try: - fp = open(os.path.join(dir_name, file_name), mode) + return open(os.path.join(dir_name, file_name), mode, encoding='utf-8') except FileNotFoundError: if not update: raise - fp = open(os.path.join(dir_name, file_name), 'w+') - return fp + return open(os.path.join(dir_name, file_name), 'w+', encoding='utf-8') def test_and_diff(test_name, dir_name, update): @@ -218,9 +217,9 @@ def main(argv): test_name = os.path.splitext(base_name)[0] status |= test_and_diff(test_name, dir_name, args.update) - exit(status) + sys.exit(status) if __name__ == '__main__': main(sys.argv) - exit(0) + sys.exit(0) diff --git a/tests/tsan/blacklist.tsan b/tests/tsan/ignore.tsan index 75e444f5dc..423e482d2f 100644 --- a/tests/tsan/blacklist.tsan +++ b/tests/tsan/ignore.tsan @@ -1,6 +1,6 @@ -# This is an example blacklist. -# To enable use of the blacklist add this to configure: -# "--extra-cflags=-fsanitize-blacklist=<src path>/tests/tsan/blacklist.tsan" +# This is an example ignore list. +# To enable use of the ignore list add this to configure: +# "--extra-cflags=-fsanitize-blacklist=<src path>/tests/tsan/ignore.tsan" # The eventual goal would be to fix these warnings. # TSan is not happy about setting/getting of dirty bits, diff --git a/tests/unit/test-resv-mem.c b/tests/unit/test-resv-mem.c index 5963274e2c..cd8f7318cc 100644 --- a/tests/unit/test-resv-mem.c +++ b/tests/unit/test-resv-mem.c @@ -44,6 +44,10 @@ static void compare_ranges(const char *prefix, GList *ranges, print_ranges("out", ranges); print_ranges("expected", expected); #endif + if (!expected) { + g_assert_true(!ranges); + return; + } g_assert_cmpint(g_list_length(ranges), ==, g_list_length(expected)); for (l = ranges, e = expected; l ; l = l->next, e = e->next) { Range *r = (Range *)l->data; diff --git a/tests/vm/netbsd b/tests/vm/netbsd index 40b27a3469..649fcad353 100755 --- a/tests/vm/netbsd +++ b/tests/vm/netbsd @@ -30,8 +30,8 @@ class NetBSDVM(basevm.BaseVM): "git-base", "pkgconf", "xz", - "python310", - "py310-expat", + "python311", + "py311-expat", "ninja-build", # gnu tools |