linux-user: Rewrite elf coredump
tcg/aarch64: Apple does not align __int128_t in even registers accel/tcg: Fixes for page tables in mmio memory linux-user: Remove qemu_host_page_{size,mask}, HOST_PAGE_ALIGN migration: Remove qemu_host_page_size hw/tpm: Remove qemu_host_page_size softmmu: Remove qemu_host_page_{size,mask}, HOST_PAGE_ALIGN linux-user: Split and reorganize target_mmap. *-user: Deprecate and disable -p pagesize linux-user: Allow TARGET_PAGE_BITS_VARY target/alpha: Enable TARGET_PAGE_BITS_VARY for user-only target/arm: Enable TARGET_PAGE_BITS_VARY for AArch64 user-only target/ppc: Enable TARGET_PAGE_BITS_VARY for user-only linux-user: Remove pgb_dynamic alignment assertion tcg/optimize: fix uninitialized variable linux-user: Rewrite shmat -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmXiXxQdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/H3QgApu4OgadviJuOBenT yaGiq+iG4wTL5vVZFK8CgMtq59dJbgJSCooh7U8dn5hIhVuvOU7odUm6embt+4WZ 0fDZIjrRvdDMM3LdLFhfdZszMNg6w2ceN9dn5iLkW3wxjRBpTzZNbxhh2Sg308+Q oNd+MlYLijDvQP97+tlQ/PBtndLfV5FkpU74ZinWRgcpcT6oH9sP6TRlAVttefy7 3GsIXhDKGoDa/0Jpy86qE//3FUaVRqqcNlAIPXMf47ABQ2y2lZlwsfyty7s55sVW KgdXdH1GiCgxIonVg4bYvovnwKVH5xHlpsJY48jQtBXR/4exPBFBpeTc422E0Sed swpayg== =W3pb -----END PGP SIGNATURE----- Merge tag 'pull-tcg-20240301' of https://gitlab.com/rth7680/qemu into staging linux-user: Rewrite elf coredump tcg/aarch64: Apple does not align __int128_t in even registers accel/tcg: Fixes for page tables in mmio memory linux-user: Remove qemu_host_page_{size,mask}, HOST_PAGE_ALIGN migration: Remove qemu_host_page_size hw/tpm: Remove qemu_host_page_size softmmu: Remove qemu_host_page_{size,mask}, HOST_PAGE_ALIGN linux-user: Split and reorganize target_mmap. *-user: Deprecate and disable -p pagesize linux-user: Allow TARGET_PAGE_BITS_VARY target/alpha: Enable TARGET_PAGE_BITS_VARY for user-only target/arm: Enable TARGET_PAGE_BITS_VARY for AArch64 user-only target/ppc: Enable TARGET_PAGE_BITS_VARY for user-only linux-user: Remove pgb_dynamic alignment assertion tcg/optimize: fix uninitialized variable linux-user: Rewrite shmat # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmXiXxQdHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/H3QgApu4OgadviJuOBenT # yaGiq+iG4wTL5vVZFK8CgMtq59dJbgJSCooh7U8dn5hIhVuvOU7odUm6embt+4WZ # 0fDZIjrRvdDMM3LdLFhfdZszMNg6w2ceN9dn5iLkW3wxjRBpTzZNbxhh2Sg308+Q # oNd+MlYLijDvQP97+tlQ/PBtndLfV5FkpU74ZinWRgcpcT6oH9sP6TRlAVttefy7 # 3GsIXhDKGoDa/0Jpy86qE//3FUaVRqqcNlAIPXMf47ABQ2y2lZlwsfyty7s55sVW # KgdXdH1GiCgxIonVg4bYvovnwKVH5xHlpsJY48jQtBXR/4exPBFBpeTc422E0Sed # swpayg== # =W3pb # -----END PGP SIGNATURE----- # gpg: Signature made Fri 01 Mar 2024 23:04:52 GMT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full] # Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F * tag 'pull-tcg-20240301' of https://gitlab.com/rth7680/qemu: (60 commits) tests/tcg: Check that shmat() does not break /proc/self/maps linux-user: Rewrite target_shmat linux-user: Add strace for shmat linux-user/loongarch64: Remove TARGET_FORCE_SHMLBA linux-user/x86_64: Handle the vsyscall page in open_self_maps_{2,4} tcg/optimize: fix uninitialized variable linux-user: Remove pgb_dynamic alignment assertion target/alpha: Enable TARGET_PAGE_BITS_VARY for user-only target/ppc: Enable TARGET_PAGE_BITS_VARY for user-only linux-user: Bound mmap_min_addr by host page size target/arm: Enable TARGET_PAGE_BITS_VARY for AArch64 user-only linux-user: Allow TARGET_PAGE_BITS_VARY accel/tcg: Disconnect TargetPageDataNode from page size cpu: Remove page_size_init *-user: Deprecate and disable -p pagesize tests/tcg: Extend file in linux-madvise.c tests/tcg: Remove run-test-mmap-* linux-user: Split out mmap_h_gt_g linux-user: Split out mmap_h_lt_g linux-user: Split out mmap_h_eq_g ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
4eac9dfbd7
@ -396,6 +396,14 @@ const void *HELPER(lookup_tb_ptr)(CPUArchState *env)
|
||||
uint64_t cs_base;
|
||||
uint32_t flags, cflags;
|
||||
|
||||
/*
|
||||
* By definition we've just finished a TB, so I/O is OK.
|
||||
* Avoid the possibility of calling cpu_io_recompile() if
|
||||
* a page table walk triggered by tb_lookup() calling
|
||||
* probe_access_internal() happens to touch an MMIO device.
|
||||
* The next TB, if we chain to it, will clear the flag again.
|
||||
*/
|
||||
cpu->neg.can_do_io = true;
|
||||
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
|
||||
|
||||
cflags = curr_cflags(cpu);
|
||||
|
@ -2022,7 +2022,6 @@ static uint64_t do_ld_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
MemoryRegion *mr;
|
||||
hwaddr mr_offset;
|
||||
MemTxAttrs attrs;
|
||||
uint64_t ret;
|
||||
|
||||
tcg_debug_assert(size > 0 && size <= 8);
|
||||
|
||||
@ -2030,12 +2029,9 @@ static uint64_t do_ld_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra);
|
||||
mr = section->mr;
|
||||
|
||||
bql_lock();
|
||||
ret = int_ld_mmio_beN(cpu, full, ret_be, addr, size, mmu_idx,
|
||||
type, ra, mr, mr_offset);
|
||||
bql_unlock();
|
||||
|
||||
return ret;
|
||||
BQL_LOCK_GUARD();
|
||||
return int_ld_mmio_beN(cpu, full, ret_be, addr, size, mmu_idx,
|
||||
type, ra, mr, mr_offset);
|
||||
}
|
||||
|
||||
static Int128 do_ld16_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
@ -2054,13 +2050,11 @@ static Int128 do_ld16_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra);
|
||||
mr = section->mr;
|
||||
|
||||
bql_lock();
|
||||
BQL_LOCK_GUARD();
|
||||
a = int_ld_mmio_beN(cpu, full, ret_be, addr, size - 8, mmu_idx,
|
||||
MMU_DATA_LOAD, ra, mr, mr_offset);
|
||||
b = int_ld_mmio_beN(cpu, full, ret_be, addr + size - 8, 8, mmu_idx,
|
||||
MMU_DATA_LOAD, ra, mr, mr_offset + size - 8);
|
||||
bql_unlock();
|
||||
|
||||
return int128_make128(b, a);
|
||||
}
|
||||
|
||||
@ -2569,7 +2563,6 @@ static uint64_t do_st_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
hwaddr mr_offset;
|
||||
MemoryRegion *mr;
|
||||
MemTxAttrs attrs;
|
||||
uint64_t ret;
|
||||
|
||||
tcg_debug_assert(size > 0 && size <= 8);
|
||||
|
||||
@ -2577,12 +2570,9 @@ static uint64_t do_st_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra);
|
||||
mr = section->mr;
|
||||
|
||||
bql_lock();
|
||||
ret = int_st_mmio_leN(cpu, full, val_le, addr, size, mmu_idx,
|
||||
ra, mr, mr_offset);
|
||||
bql_unlock();
|
||||
|
||||
return ret;
|
||||
BQL_LOCK_GUARD();
|
||||
return int_st_mmio_leN(cpu, full, val_le, addr, size, mmu_idx,
|
||||
ra, mr, mr_offset);
|
||||
}
|
||||
|
||||
static uint64_t do_st16_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
@ -2593,7 +2583,6 @@ static uint64_t do_st16_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
MemoryRegion *mr;
|
||||
hwaddr mr_offset;
|
||||
MemTxAttrs attrs;
|
||||
uint64_t ret;
|
||||
|
||||
tcg_debug_assert(size > 8 && size <= 16);
|
||||
|
||||
@ -2601,14 +2590,11 @@ static uint64_t do_st16_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
|
||||
section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra);
|
||||
mr = section->mr;
|
||||
|
||||
bql_lock();
|
||||
BQL_LOCK_GUARD();
|
||||
int_st_mmio_leN(cpu, full, int128_getlo(val_le), addr, 8,
|
||||
mmu_idx, ra, mr, mr_offset);
|
||||
ret = int_st_mmio_leN(cpu, full, int128_gethi(val_le), addr + 8,
|
||||
size - 8, mmu_idx, ra, mr, mr_offset + 8);
|
||||
bql_unlock();
|
||||
|
||||
return ret;
|
||||
return int_st_mmio_leN(cpu, full, int128_gethi(val_le), addr + 8,
|
||||
size - 8, mmu_idx, ra, mr, mr_offset + 8);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -256,7 +256,6 @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data)
|
||||
|
||||
void page_init(void)
|
||||
{
|
||||
page_size_init();
|
||||
page_table_config_init();
|
||||
}
|
||||
|
||||
|
@ -651,16 +651,17 @@ void page_protect(tb_page_addr_t address)
|
||||
{
|
||||
PageFlagsNode *p;
|
||||
target_ulong start, last;
|
||||
int host_page_size = qemu_real_host_page_size();
|
||||
int prot;
|
||||
|
||||
assert_memory_lock();
|
||||
|
||||
if (qemu_host_page_size <= TARGET_PAGE_SIZE) {
|
||||
if (host_page_size <= TARGET_PAGE_SIZE) {
|
||||
start = address & TARGET_PAGE_MASK;
|
||||
last = start + TARGET_PAGE_SIZE - 1;
|
||||
} else {
|
||||
start = address & qemu_host_page_mask;
|
||||
last = start + qemu_host_page_size - 1;
|
||||
start = address & -host_page_size;
|
||||
last = start + host_page_size - 1;
|
||||
}
|
||||
|
||||
p = pageflags_find(start, last);
|
||||
@ -671,7 +672,7 @@ void page_protect(tb_page_addr_t address)
|
||||
|
||||
if (unlikely(p->itree.last < last)) {
|
||||
/* More than one protection region covers the one host page. */
|
||||
assert(TARGET_PAGE_SIZE < qemu_host_page_size);
|
||||
assert(TARGET_PAGE_SIZE < host_page_size);
|
||||
while ((p = pageflags_next(p, start, last)) != NULL) {
|
||||
prot |= p->flags;
|
||||
}
|
||||
@ -679,7 +680,7 @@ void page_protect(tb_page_addr_t address)
|
||||
|
||||
if (prot & PAGE_WRITE) {
|
||||
pageflags_set_clear(start, last, 0, PAGE_WRITE);
|
||||
mprotect(g2h_untagged(start), qemu_host_page_size,
|
||||
mprotect(g2h_untagged(start), last - start + 1,
|
||||
prot & (PAGE_READ | PAGE_EXEC) ? PROT_READ : PROT_NONE);
|
||||
}
|
||||
}
|
||||
@ -725,18 +726,19 @@ int page_unprotect(target_ulong address, uintptr_t pc)
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
int host_page_size = qemu_real_host_page_size();
|
||||
target_ulong start, len, i;
|
||||
int prot;
|
||||
|
||||
if (qemu_host_page_size <= TARGET_PAGE_SIZE) {
|
||||
if (host_page_size <= TARGET_PAGE_SIZE) {
|
||||
start = address & TARGET_PAGE_MASK;
|
||||
len = TARGET_PAGE_SIZE;
|
||||
prot = p->flags | PAGE_WRITE;
|
||||
pageflags_set_clear(start, start + len - 1, PAGE_WRITE, 0);
|
||||
current_tb_invalidated = tb_invalidate_phys_page_unwind(start, pc);
|
||||
} else {
|
||||
start = address & qemu_host_page_mask;
|
||||
len = qemu_host_page_size;
|
||||
start = address & -host_page_size;
|
||||
len = host_page_size;
|
||||
prot = 0;
|
||||
|
||||
for (i = 0; i < len; i += TARGET_PAGE_SIZE) {
|
||||
@ -862,7 +864,7 @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, vaddr addr,
|
||||
typedef struct TargetPageDataNode {
|
||||
struct rcu_head rcu;
|
||||
IntervalTreeNode itree;
|
||||
char data[TPD_PAGES][TARGET_PAGE_DATA_SIZE] __attribute__((aligned));
|
||||
char data[] __attribute__((aligned));
|
||||
} TargetPageDataNode;
|
||||
|
||||
static IntervalTreeRoot targetdata_root;
|
||||
@ -900,7 +902,8 @@ void page_reset_target_data(target_ulong start, target_ulong last)
|
||||
n_last = MIN(last, n->last);
|
||||
p_len = (n_last + 1 - n_start) >> TARGET_PAGE_BITS;
|
||||
|
||||
memset(t->data[p_ofs], 0, p_len * TARGET_PAGE_DATA_SIZE);
|
||||
memset(t->data + p_ofs * TARGET_PAGE_DATA_SIZE, 0,
|
||||
p_len * TARGET_PAGE_DATA_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -908,7 +911,7 @@ void *page_get_target_data(target_ulong address)
|
||||
{
|
||||
IntervalTreeNode *n;
|
||||
TargetPageDataNode *t;
|
||||
target_ulong page, region;
|
||||
target_ulong page, region, p_ofs;
|
||||
|
||||
page = address & TARGET_PAGE_MASK;
|
||||
region = address & TBD_MASK;
|
||||
@ -924,7 +927,8 @@ void *page_get_target_data(target_ulong address)
|
||||
mmap_lock();
|
||||
n = interval_tree_iter_first(&targetdata_root, page, page);
|
||||
if (!n) {
|
||||
t = g_new0(TargetPageDataNode, 1);
|
||||
t = g_malloc0(sizeof(TargetPageDataNode)
|
||||
+ TPD_PAGES * TARGET_PAGE_DATA_SIZE);
|
||||
n = &t->itree;
|
||||
n->start = region;
|
||||
n->last = region | ~TBD_MASK;
|
||||
@ -934,7 +938,8 @@ void *page_get_target_data(target_ulong address)
|
||||
}
|
||||
|
||||
t = container_of(n, TargetPageDataNode, itree);
|
||||
return t->data[(page - region) >> TARGET_PAGE_BITS];
|
||||
p_ofs = (page - region) >> TARGET_PAGE_BITS;
|
||||
return t->data + p_ofs * TARGET_PAGE_DATA_SIZE;
|
||||
}
|
||||
#else
|
||||
void page_reset_target_data(target_ulong start, target_ulong last) { }
|
||||
|
@ -49,6 +49,13 @@
|
||||
#include "host-os.h"
|
||||
#include "target_arch_cpu.h"
|
||||
|
||||
|
||||
/*
|
||||
* TODO: Remove these and rely only on qemu_real_host_page_size().
|
||||
*/
|
||||
uintptr_t qemu_host_page_size;
|
||||
intptr_t qemu_host_page_mask;
|
||||
|
||||
static bool opt_one_insn_per_tb;
|
||||
uintptr_t guest_base;
|
||||
bool have_guest_base;
|
||||
@ -307,6 +314,9 @@ int main(int argc, char **argv)
|
||||
(void) envlist_setenv(envlist, *wrk);
|
||||
}
|
||||
|
||||
qemu_host_page_size = getpagesize();
|
||||
qemu_host_page_size = MAX(qemu_host_page_size, TARGET_PAGE_SIZE);
|
||||
|
||||
cpu_model = NULL;
|
||||
|
||||
qemu_add_opts(&qemu_trace_opts);
|
||||
@ -364,11 +374,12 @@ int main(int argc, char **argv)
|
||||
} else if (!strcmp(r, "L")) {
|
||||
interp_prefix = argv[optind++];
|
||||
} else if (!strcmp(r, "p")) {
|
||||
qemu_host_page_size = atoi(argv[optind++]);
|
||||
if (qemu_host_page_size == 0 ||
|
||||
(qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
|
||||
fprintf(stderr, "page size must be a power of two\n");
|
||||
exit(1);
|
||||
unsigned size, want = qemu_real_host_page_size();
|
||||
|
||||
r = argv[optind++];
|
||||
if (qemu_strtoui(r, NULL, 10, &size) || size != want) {
|
||||
warn_report("Deprecated page size option cannot "
|
||||
"change host page size (%u)", want);
|
||||
}
|
||||
} else if (!strcmp(r, "g")) {
|
||||
gdbstub = g_strdup(argv[optind++]);
|
||||
@ -403,6 +414,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
qemu_host_page_mask = -qemu_host_page_size;
|
||||
|
||||
/* init debug */
|
||||
{
|
||||
int mask = 0;
|
||||
|
@ -39,6 +39,13 @@ extern char **environ;
|
||||
#include "qemu/clang-tsa.h"
|
||||
|
||||
#include "qemu-os.h"
|
||||
/*
|
||||
* TODO: Remove these and rely only on qemu_real_host_page_size().
|
||||
*/
|
||||
extern uintptr_t qemu_host_page_size;
|
||||
extern intptr_t qemu_host_page_mask;
|
||||
#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_host_page_size)
|
||||
|
||||
/*
|
||||
* This struct is used to hold certain information about the image. Basically,
|
||||
* it replicates in user space what would be certain task_struct fields in the
|
||||
|
16
cpu-target.c
16
cpu-target.c
@ -45,9 +45,6 @@
|
||||
#include "trace/trace-root.h"
|
||||
#include "qemu/accel.h"
|
||||
|
||||
uintptr_t qemu_host_page_size;
|
||||
intptr_t qemu_host_page_mask;
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static int cpu_common_post_load(void *opaque, int version_id)
|
||||
{
|
||||
@ -474,16 +471,3 @@ const char *target_name(void)
|
||||
{
|
||||
return TARGET_NAME;
|
||||
}
|
||||
|
||||
void page_size_init(void)
|
||||
{
|
||||
/* NOTE: we can always suppose that qemu_host_page_size >=
|
||||
TARGET_PAGE_SIZE */
|
||||
if (qemu_host_page_size == 0) {
|
||||
qemu_host_page_size = qemu_real_host_page_size();
|
||||
}
|
||||
if (qemu_host_page_size < TARGET_PAGE_SIZE) {
|
||||
qemu_host_page_size = TARGET_PAGE_SIZE;
|
||||
}
|
||||
qemu_host_page_mask = -(intptr_t)qemu_host_page_size;
|
||||
}
|
||||
|
@ -63,6 +63,16 @@ as short-form boolean values, and passed to plugins as ``arg_name=on``.
|
||||
However, short-form booleans are deprecated and full explicit ``arg_name=on``
|
||||
form is preferred.
|
||||
|
||||
User-mode emulator command line arguments
|
||||
-----------------------------------------
|
||||
|
||||
``-p`` (since 9.0)
|
||||
''''''''''''''''''
|
||||
|
||||
The ``-p`` option pretends to control the host page size. However,
|
||||
it is not possible to change the host page size, and using the
|
||||
option only causes failures.
|
||||
|
||||
QEMU Machine Protocol (QMP) commands
|
||||
------------------------------------
|
||||
|
||||
|
@ -87,9 +87,6 @@ Debug options:
|
||||
Activate logging of the specified items (use '-d help' for a list of
|
||||
log items)
|
||||
|
||||
``-p pagesize``
|
||||
Act as if the host page size was 'pagesize' bytes
|
||||
|
||||
``-g port``
|
||||
Wait gdb connection to port
|
||||
|
||||
|
@ -47,8 +47,10 @@ void tpm_ppi_reset(TPMPPI *tpmppi)
|
||||
void tpm_ppi_init(TPMPPI *tpmppi, MemoryRegion *m,
|
||||
hwaddr addr, Object *obj)
|
||||
{
|
||||
tpmppi->buf = qemu_memalign(qemu_real_host_page_size(),
|
||||
HOST_PAGE_ALIGN(TPM_PPI_ADDR_SIZE));
|
||||
size_t host_page_size = qemu_real_host_page_size();
|
||||
|
||||
tpmppi->buf = qemu_memalign(host_page_size,
|
||||
ROUND_UP(TPM_PPI_ADDR_SIZE, host_page_size));
|
||||
memory_region_init_ram_device_ptr(&tpmppi->ram, obj, "tpm-ppi",
|
||||
TPM_PPI_ADDR_SIZE, tpmppi->buf);
|
||||
vmstate_register_ram(&tpmppi->ram, DEVICE(obj));
|
||||
|
@ -20,13 +20,6 @@
|
||||
void cpu_exec_init_all(void);
|
||||
void cpu_exec_step_atomic(CPUState *cpu);
|
||||
|
||||
/* Using intptr_t ensures that qemu_*_page_mask is sign-extended even
|
||||
* when intptr_t is 32-bit and we are aligning a long long.
|
||||
*/
|
||||
extern uintptr_t qemu_host_page_size;
|
||||
extern intptr_t qemu_host_page_mask;
|
||||
|
||||
#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_host_page_size)
|
||||
#define REAL_HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_real_host_page_size())
|
||||
|
||||
/* The CPU list lock nests outside page_(un)lock or mmap_(un)lock */
|
||||
|
@ -1179,8 +1179,6 @@ bool target_words_bigendian(void);
|
||||
|
||||
const char *target_name(void);
|
||||
|
||||
void page_size_init(void);
|
||||
|
||||
#ifdef NEED_CPU_H
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,11 +38,4 @@ struct target_pt_regs {
|
||||
#define TARGET_MCL_FUTURE 2
|
||||
#define TARGET_MCL_ONFAULT 4
|
||||
|
||||
#define TARGET_FORCE_SHMLBA
|
||||
|
||||
static inline abi_ulong target_shmlba(CPULoongArchState *env)
|
||||
{
|
||||
return 64 * KiB;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "loader.h"
|
||||
#include "user-mmap.h"
|
||||
#include "tcg/perf.h"
|
||||
#include "exec/page-vary.h"
|
||||
|
||||
#ifdef CONFIG_SEMIHOSTING
|
||||
#include "semihosting/semihost.h"
|
||||
@ -332,11 +333,11 @@ static void handle_arg_ld_prefix(const char *arg)
|
||||
|
||||
static void handle_arg_pagesize(const char *arg)
|
||||
{
|
||||
qemu_host_page_size = atoi(arg);
|
||||
if (qemu_host_page_size == 0 ||
|
||||
(qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
|
||||
fprintf(stderr, "page size must be a power of two\n");
|
||||
exit(EXIT_FAILURE);
|
||||
unsigned size, want = qemu_real_host_page_size();
|
||||
|
||||
if (qemu_strtoui(arg, NULL, 10, &size) || size != want) {
|
||||
warn_report("Deprecated page size option cannot "
|
||||
"change host page size (%u)", want);
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,7 +497,7 @@ static const struct qemu_argument arg_table[] = {
|
||||
{"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
|
||||
"logfile", "write logs to 'logfile' (default stderr)"},
|
||||
{"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
|
||||
"pagesize", "set the host page size to 'pagesize'"},
|
||||
"pagesize", "deprecated change to host page size"},
|
||||
{"one-insn-per-tb",
|
||||
"QEMU_ONE_INSN_PER_TB", false, handle_arg_one_insn_per_tb,
|
||||
"", "run with one guest instruction per emulated TB"},
|
||||
@ -680,6 +681,7 @@ int main(int argc, char **argv, char **envp)
|
||||
int i;
|
||||
int ret;
|
||||
int execfd;
|
||||
int host_page_size;
|
||||
unsigned long max_reserved_va;
|
||||
bool preserve_argv0;
|
||||
|
||||
@ -781,7 +783,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
cpu_type = parse_cpu_option(cpu_model);
|
||||
|
||||
/* init tcg before creating CPUs and to get qemu_host_page_size */
|
||||
/* init tcg before creating CPUs */
|
||||
{
|
||||
AccelState *accel = current_accel();
|
||||
AccelClass *ac = ACCEL_GET_CLASS(accel);
|
||||
@ -791,6 +793,16 @@ int main(int argc, char **argv, char **envp)
|
||||
opt_one_insn_per_tb, &error_abort);
|
||||
ac->init_machine(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finalize page size before creating CPUs.
|
||||
* This will do nothing if !TARGET_PAGE_BITS_VARY.
|
||||
* The most efficient setting is to match the host.
|
||||
*/
|
||||
host_page_size = qemu_real_host_page_size();
|
||||
set_preferred_target_page_bits(ctz32(host_page_size));
|
||||
finalize_target_page_bits();
|
||||
|
||||
cpu = cpu_create(cpu_type);
|
||||
env = cpu_env(cpu);
|
||||
cpu_reset(cpu);
|
||||
@ -804,8 +816,8 @@ int main(int argc, char **argv, char **envp)
|
||||
*/
|
||||
max_reserved_va = MAX_RESERVED_VA(cpu);
|
||||
if (reserved_va != 0) {
|
||||
if ((reserved_va + 1) % qemu_host_page_size) {
|
||||
char *s = size_to_str(qemu_host_page_size);
|
||||
if ((reserved_va + 1) % host_page_size) {
|
||||
char *s = size_to_str(host_page_size);
|
||||
fprintf(stderr, "Reserved virtual address not aligned mod %s\n", s);
|
||||
g_free(s);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -889,7 +901,7 @@ int main(int argc, char **argv, char **envp)
|
||||
if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
|
||||
unsigned long tmp;
|
||||
if (fscanf(fp, "%lu", &tmp) == 1 && tmp != 0) {
|
||||
mmap_min_addr = tmp;
|
||||
mmap_min_addr = MAX(tmp, host_page_size);
|
||||
qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n",
|
||||
mmap_min_addr);
|
||||
}
|
||||
@ -902,7 +914,7 @@ int main(int argc, char **argv, char **envp)
|
||||
* If we're in a chroot with no /proc, fall back to 1 page.
|
||||
*/
|
||||
if (mmap_min_addr == 0) {
|
||||
mmap_min_addr = qemu_host_page_size;
|
||||
mmap_min_addr = host_page_size;
|
||||
qemu_log_mask(CPU_LOG_PAGE,
|
||||
"host mmap_min_addr=0x%lx (fallback)\n",
|
||||
mmap_min_addr);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -670,6 +670,26 @@ print_semctl(CPUArchState *cpu_env, const struct syscallname *name,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
print_shmat(CPUArchState *cpu_env, const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
static const struct flags shmat_flags[] = {
|
||||
FLAG_GENERIC(SHM_RND),
|
||||
FLAG_GENERIC(SHM_REMAP),
|
||||
FLAG_GENERIC(SHM_RDONLY),
|
||||
FLAG_GENERIC(SHM_EXEC),
|
||||
FLAG_END
|
||||
};
|
||||
|
||||
print_syscall_prologue(name);
|
||||
print_raw_param(TARGET_ABI_FMT_ld, arg0, 0);
|
||||
print_pointer(arg1, 0);
|
||||
print_flags(shmat_flags, arg2, 1);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
|
||||
#ifdef TARGET_NR_ipc
|
||||
static void
|
||||
print_ipc(CPUArchState *cpu_env, const struct syscallname *name,
|
||||
@ -683,6 +703,10 @@ print_ipc(CPUArchState *cpu_env, const struct syscallname *name,
|
||||
print_ipc_cmd(arg3);
|
||||
qemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
|
||||
break;
|
||||
case IPCOP_shmat:
|
||||
print_shmat(cpu_env, &(const struct syscallname){ .name = "shmat" },
|
||||
arg1, arg4, arg2, 0, 0, 0);
|
||||
break;
|
||||
default:
|
||||
qemu_log(("%s("
|
||||
TARGET_ABI_FMT_ld ","
|
||||
|
@ -1398,7 +1398,7 @@
|
||||
{ TARGET_NR_sgetmask, "sgetmask" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_shmat
|
||||
{ TARGET_NR_shmat, "shmat" , NULL, NULL, print_syscall_ret_addr },
|
||||
{ TARGET_NR_shmat, "shmat" , NULL, print_shmat, print_syscall_ret_addr },
|
||||
#endif
|
||||
#ifdef TARGET_NR_shmctl
|
||||
{ TARGET_NR_shmctl, "shmctl" , NULL, NULL, NULL },
|
||||
|
@ -7994,6 +7994,10 @@ static void open_self_maps_4(const struct open_self_maps_data *d,
|
||||
path = "[heap]";
|
||||
} else if (start == info->vdso) {
|
||||
path = "[vdso]";
|
||||
#ifdef TARGET_X86_64
|
||||
} else if (start == TARGET_VSYSCALL_PAGE) {
|
||||
path = "[vsyscall]";
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Except null device (MAP_ANON), adjust offset for this fragment. */
|
||||
@ -8082,6 +8086,18 @@ static int open_self_maps_2(void *opaque, target_ulong guest_start,
|
||||
uintptr_t host_start = (uintptr_t)g2h_untagged(guest_start);
|
||||
uintptr_t host_last = (uintptr_t)g2h_untagged(guest_end - 1);
|
||||
|
||||
#ifdef TARGET_X86_64
|
||||
/*
|
||||
* Because of the extremely high position of the page within the guest
|
||||
* virtual address space, this is not backed by host memory at all.
|
||||
* Therefore the loop below would fail. This is the only instance
|
||||
* of not having host backing memory.
|
||||
*/
|
||||
if (guest_start == TARGET_VSYSCALL_PAGE) {
|
||||
return open_self_maps_3(opaque, guest_start, guest_end, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
IntervalTreeNode *n =
|
||||
interval_tree_iter_first(d->host_maps, host_start, host_start);
|
||||
|
@ -2934,7 +2934,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
||||
{
|
||||
RAMState **rsp = opaque;
|
||||
RAMBlock *block;
|
||||
int ret;
|
||||
int ret, max_hg_page_size;
|
||||
|
||||
if (compress_threads_save_setup()) {
|
||||
return -1;
|
||||
@ -2949,6 +2949,12 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
||||
}
|
||||
(*rsp)->pss[RAM_CHANNEL_PRECOPY].pss_channel = f;
|
||||
|
||||
/*
|
||||
* ??? Mirrors the previous value of qemu_host_page_size,
|
||||
* but is this really what was intended for the migration?
|
||||
*/
|
||||
max_hg_page_size = MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE);
|
||||
|
||||
WITH_RCU_READ_LOCK_GUARD() {
|
||||
qemu_put_be64(f, ram_bytes_total_with_ignored()
|
||||
| RAM_SAVE_FLAG_MEM_SIZE);
|
||||
@ -2957,8 +2963,8 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
||||
qemu_put_byte(f, strlen(block->idstr));
|
||||
qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
|
||||
qemu_put_be64(f, block->used_length);
|
||||
if (migrate_postcopy_ram() && block->page_size !=
|
||||
qemu_host_page_size) {
|
||||
if (migrate_postcopy_ram() &&
|
||||
block->page_size != max_hg_page_size) {
|
||||
qemu_put_be64(f, block->page_size);
|
||||
}
|
||||
if (migrate_ignore_shared()) {
|
||||
@ -3791,6 +3797,7 @@ static int parse_ramblock(QEMUFile *f, RAMBlock *block, ram_addr_t length)
|
||||
int ret = 0;
|
||||
/* ADVISE is earlier, it shows the source has the postcopy capability on */
|
||||
bool postcopy_advised = migration_incoming_postcopy_advised();
|
||||
int max_hg_page_size;
|
||||
|
||||
assert(block);
|
||||
|
||||
@ -3808,9 +3815,16 @@ static int parse_ramblock(QEMUFile *f, RAMBlock *block, ram_addr_t length)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ??? Mirrors the previous value of qemu_host_page_size,
|
||||
* but is this really what was intended for the migration?
|
||||
*/
|
||||
max_hg_page_size = MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE);
|
||||
|
||||
/* For postcopy we need to check hugepage sizes match */
|
||||
if (postcopy_advised && migrate_postcopy_ram() &&
|
||||
block->page_size != qemu_host_page_size) {
|
||||
block->page_size != max_hg_page_size) {
|
||||
uint64_t remote_page_size = qemu_get_be64(f);
|
||||
if (remote_page_size != block->page_size) {
|
||||
error_report("Mismatched RAM page size %s "
|
||||
|
@ -1680,7 +1680,8 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
|
||||
|
||||
assert(block);
|
||||
|
||||
newsize = HOST_PAGE_ALIGN(newsize);
|
||||
newsize = TARGET_PAGE_ALIGN(newsize);
|
||||
newsize = REAL_HOST_PAGE_ALIGN(newsize);
|
||||
|
||||
if (block->used_length == newsize) {
|
||||
/*
|
||||
@ -1916,7 +1917,9 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = HOST_PAGE_ALIGN(size);
|
||||
size = TARGET_PAGE_ALIGN(size);
|
||||
size = REAL_HOST_PAGE_ALIGN(size);
|
||||
|
||||
file_size = get_file_size(fd);
|
||||
if (file_size > offset && file_size < (offset + size)) {
|
||||
error_setg(errp, "backing store size 0x%" PRIx64
|
||||
@ -2014,13 +2017,17 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
|
||||
{
|
||||
RAMBlock *new_block;
|
||||
Error *local_err = NULL;
|
||||
int align;
|
||||
|
||||
assert((ram_flags & ~(RAM_SHARED | RAM_RESIZEABLE | RAM_PREALLOC |
|
||||
RAM_NORESERVE)) == 0);
|
||||
assert(!host ^ (ram_flags & RAM_PREALLOC));
|
||||
|
||||
size = HOST_PAGE_ALIGN(size);
|
||||
max_size = HOST_PAGE_ALIGN(max_size);
|
||||
align = qemu_real_host_page_size();
|
||||
align = MAX(align, TARGET_PAGE_SIZE);
|
||||
size = ROUND_UP(size, align);
|
||||
max_size = ROUND_UP(max_size, align);
|
||||
|
||||
new_block = g_malloc0(sizeof(*new_block));
|
||||
new_block->mr = mr;
|
||||
new_block->resized = resized;
|
||||
@ -3511,7 +3518,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length)
|
||||
* fallocate works on hugepages and shmem
|
||||
* shared anonymous memory requires madvise REMOVE
|
||||
*/
|
||||
need_madvise = (rb->page_size == qemu_host_page_size);
|
||||
need_madvise = (rb->page_size == qemu_real_host_page_size());
|
||||
need_fallocate = rb->fd != -1;
|
||||
if (need_fallocate) {
|
||||
/* For a file, this causes the area of the file to be zero'd
|
||||
|
@ -2118,7 +2118,6 @@ static void qemu_create_machine(QDict *qdict)
|
||||
}
|
||||
|
||||
cpu_exec_init_all();
|
||||
page_size_init();
|
||||
|
||||
if (machine_class->hw_version) {
|
||||
qemu_set_hw_version(machine_class->hw_version);
|
||||
|
@ -9,10 +9,22 @@
|
||||
#define ALPHA_CPU_PARAM_H
|
||||
|
||||
#define TARGET_LONG_BITS 64
|
||||
#define TARGET_PAGE_BITS 13
|
||||
|
||||
/* ??? EV4 has 34 phys addr bits, EV5 has 40, EV6 has 44. */
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 44
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS (30 + TARGET_PAGE_BITS)
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/*
|
||||
* Allow user-only to vary page size. Real hardware allows only 8k and 64k,
|
||||
* but since any variance means guests cannot assume a fixed value, allow
|
||||
* a 4k minimum to match x86 host, which can minimize emulation issues.
|
||||
*/
|
||||
# define TARGET_PAGE_BITS_VARY
|
||||
# define TARGET_PAGE_BITS_MIN 12
|
||||
# define TARGET_VIRT_ADDR_SPACE_BITS 63
|
||||
#else
|
||||
# define TARGET_PAGE_BITS 13
|
||||
# define TARGET_VIRT_ADDR_SPACE_BITS (30 + TARGET_PAGE_BITS)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -19,9 +19,13 @@
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
#define TARGET_PAGE_BITS 12
|
||||
# ifdef TARGET_AARCH64
|
||||
# define TARGET_TAGGED_ADDRESSES
|
||||
/* Allow user-only to vary page size from 4k */
|
||||
# define TARGET_PAGE_BITS_VARY
|
||||
# define TARGET_PAGE_BITS_MIN 12
|
||||
# else
|
||||
# define TARGET_PAGE_BITS 12
|
||||
# endif
|
||||
#else
|
||||
/*
|
||||
|
@ -1809,7 +1809,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
ARMCPU *cpu = ARM_CPU(dev);
|
||||
ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
|
||||
CPUARMState *env = &cpu->env;
|
||||
int pagebits;
|
||||
Error *local_err = NULL;
|
||||
|
||||
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
|
||||
@ -2100,28 +2099,36 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
!cpu_isar_feature(aa32_vfp_simd, cpu) ||
|
||||
!arm_feature(env, ARM_FEATURE_XSCALE));
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_V7) &&
|
||||
!arm_feature(env, ARM_FEATURE_M) &&
|
||||
!arm_feature(env, ARM_FEATURE_PMSA)) {
|
||||
/* v7VMSA drops support for the old ARMv5 tiny pages, so we
|
||||
* can use 4K pages.
|
||||
*/
|
||||
pagebits = 12;
|
||||
} else {
|
||||
/* For CPUs which might have tiny 1K pages, or which have an
|
||||
* MPU and might have small region sizes, stick with 1K pages.
|
||||
*/
|
||||
pagebits = 10;
|
||||
}
|
||||
if (!set_preferred_target_page_bits(pagebits)) {
|
||||
/* This can only ever happen for hotplugging a CPU, or if
|
||||
* the board code incorrectly creates a CPU which it has
|
||||
* promised via minimum_page_size that it will not.
|
||||
*/
|
||||
error_setg(errp, "This CPU requires a smaller page size than the "
|
||||
"system is using");
|
||||
return;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
{
|
||||
int pagebits;
|
||||
if (arm_feature(env, ARM_FEATURE_V7) &&
|
||||
!arm_feature(env, ARM_FEATURE_M) &&
|
||||
!arm_feature(env, ARM_FEATURE_PMSA)) {
|
||||
/*
|
||||
* v7VMSA drops support for the old ARMv5 tiny pages,
|
||||
* so we can use 4K pages.
|
||||
*/
|
||||
pagebits = 12;
|
||||
} else {
|
||||
/*
|
||||
* For CPUs which might have tiny 1K pages, or which have an
|
||||
* MPU and might have small region sizes, stick with 1K pages.
|
||||
*/
|
||||
pagebits = 10;
|
||||
}
|
||||
if (!set_preferred_target_page_bits(pagebits)) {
|
||||
/*
|
||||
* This can only ever happen for hotplugging a CPU, or if
|
||||
* the board code incorrectly creates a CPU which it has
|
||||
* promised via minimum_page_size that it will not.
|
||||
*/
|
||||
error_setg(errp, "This CPU requires a smaller page size "
|
||||
"than the system is using");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This cpu-id-to-MPIDR affinity is used only for TCG; KVM will override it.
|
||||
* We don't support setting cluster ID ([16..23]) (known as Aff2
|
||||
|
@ -31,6 +31,13 @@
|
||||
# define TARGET_PHYS_ADDR_SPACE_BITS 36
|
||||
# define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#endif
|
||||
#define TARGET_PAGE_BITS 12
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/* Allow user-only to vary page size from 4k */
|
||||
# define TARGET_PAGE_BITS_VARY
|
||||
# define TARGET_PAGE_BITS_MIN 12
|
||||
#else
|
||||
# define TARGET_PAGE_BITS 12
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -55,7 +55,11 @@ typedef enum {
|
||||
#define TCG_TARGET_CALL_STACK_OFFSET 0
|
||||
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
|
||||
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
|
||||
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
|
||||
#ifdef CONFIG_DARWIN
|
||||
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
|
||||
#else
|
||||
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
|
||||
#endif
|
||||
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
|
||||
|
||||
#define have_lse (cpuinfo & CPUINFO_LSE)
|
||||
|
@ -2102,7 +2102,8 @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
|
||||
|
||||
static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
|
||||
{
|
||||
TCGOpcode and_opc, sub_opc, xor_opc, neg_opc, shr_opc, uext_opc, sext_opc;
|
||||
TCGOpcode and_opc, sub_opc, xor_opc, neg_opc, shr_opc;
|
||||
TCGOpcode uext_opc = 0, sext_opc = 0;
|
||||
TCGCond cond = op->args[3];
|
||||
TCGArg ret, src1, src2;
|
||||
TCGOp *op2;
|
||||
|
@ -13,6 +13,3 @@ test-cmov: test-cond.c
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
||||
|
||||
run-test-cmov: test-cmov
|
||||
|
||||
# On Alpha Linux only supports 8k pages
|
||||
EXTRA_RUNS+=run-test-mmap-8192
|
||||
|
@ -79,6 +79,3 @@ sha512-vector: sha512.c
|
||||
ARM_TESTS += sha512-vector
|
||||
|
||||
TESTS += $(ARM_TESTS)
|
||||
|
||||
# On ARM Linux only supports 4k pages
|
||||
EXTRA_RUNS+=run-test-mmap-4096
|
||||
|
@ -2,9 +2,6 @@
|
||||
#
|
||||
# HPPA specific tweaks - specifically masking out broken tests
|
||||
|
||||
# On parisc Linux supports 4K/16K/64K (but currently only 4k works)
|
||||
EXTRA_RUNS+=run-test-mmap-4096 # run-test-mmap-16384 run-test-mmap-65536
|
||||
|
||||
# This triggers failures for hppa-linux about 1% of the time
|
||||
# HPPA is the odd target that can't use the sigtramp page;
|
||||
# it requires the full vdso with dwarf2 unwind info.
|
||||
|
@ -71,9 +71,6 @@ endif
|
||||
I386_TESTS:=$(filter-out $(SKIP_I386_TESTS), $(ALL_X86_TESTS))
|
||||
TESTS=$(MULTIARCH_TESTS) $(I386_TESTS)
|
||||
|
||||
# On i386 and x86_64 Linux only supports 4k pages (large pages are a different hack)
|
||||
EXTRA_RUNS+=run-test-mmap-4096
|
||||
|
||||
sha512-sse: CFLAGS=-msse4.1 -O3
|
||||
sha512-sse: sha512.c
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
||||
|
@ -5,6 +5,3 @@
|
||||
|
||||
VPATH += $(SRC_PATH)/tests/tcg/m68k
|
||||
TESTS += trap denormal
|
||||
|
||||
# On m68k Linux supports 4k and 8k pages (but 8k is currently broken)
|
||||
EXTRA_RUNS+=run-test-mmap-4096 # run-test-mmap-8192
|
||||
|
@ -51,18 +51,9 @@ run-plugin-vma-pthread-with-%: vma-pthread
|
||||
$(call skip-test, $<, "flaky on CI?")
|
||||
endif
|
||||
|
||||
# We define the runner for test-mmap after the individual
|
||||
# architectures have defined their supported pages sizes. If no
|
||||
# additional page sizes are defined we only run the default test.
|
||||
|
||||
# default case (host page size)
|
||||
run-test-mmap: test-mmap
|
||||
$(call run-test, test-mmap, $(QEMU) $<, $< (default))
|
||||
|
||||
# additional page sizes (defined by each architecture adding to EXTRA_RUNS)
|
||||
run-test-mmap-%: test-mmap
|
||||
$(call run-test, test-mmap-$*, $(QEMU) -p $* $<, $< ($* byte pages))
|
||||
|
||||
ifneq ($(GDB),)
|
||||
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
|
||||
|
||||
|
@ -42,6 +42,8 @@ static void test_file(void)
|
||||
assert(ret == 0);
|
||||
written = write(fd, &c, sizeof(c));
|
||||
assert(written == sizeof(c));
|
||||
ret = ftruncate(fd, pagesize);
|
||||
assert(ret == 0);
|
||||
page = mmap(NULL, pagesize, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
assert(page != MAP_FAILED);
|
||||
|
||||
|
55
tests/tcg/multiarch/linux/linux-shmat-maps.c
Normal file
55
tests/tcg/multiarch/linux/linux-shmat-maps.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Test that shmat() does not break /proc/self/maps.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char buf[128];
|
||||
int err, fd;
|
||||
int shmid;
|
||||
ssize_t n;
|
||||
void *p;
|
||||
|
||||
shmid = shmget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
|
||||
assert(shmid != -1);
|
||||
|
||||
/*
|
||||
* The original bug required a non-NULL address, which skipped the
|
||||
* mmap_find_vma step, which could result in a host mapping smaller
|
||||
* than the target mapping. Choose an address at random.
|
||||
*/
|
||||
p = shmat(shmid, (void *)0x800000, SHM_RND);
|
||||
if (p == (void *)-1) {
|
||||
/*
|
||||
* Because we are now running the testcase for all guests for which
|
||||
* we have a cross-compiler, the above random address might conflict
|
||||
* with the guest executable in some way. Rather than stopping,
|
||||
* continue with a system supplied address, which should never fail.
|
||||
*/
|
||||
p = shmat(shmid, NULL, 0);
|
||||
assert(p != (void *)-1);
|
||||
}
|
||||
|
||||
fd = open("/proc/self/maps", O_RDONLY);
|
||||
assert(fd != -1);
|
||||
do {
|
||||
n = read(fd, buf, sizeof(buf));
|
||||
assert(n >= 0);
|
||||
} while (n != 0);
|
||||
close(fd);
|
||||
|
||||
err = shmdt(p);
|
||||
assert(err == 0);
|
||||
err = shmctl(shmid, IPC_RMID, NULL);
|
||||
assert(err == 0);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
# -*- Mode: makefile -*-
|
||||
#
|
||||
# PPC - included from tests/tcg/Makefile
|
||||
#
|
||||
|
||||
ifneq (,$(findstring 64,$(TARGET_NAME)))
|
||||
# On PPC64 Linux can be configured with 4k (default) or 64k pages (currently broken)
|
||||
EXTRA_RUNS+=run-test-mmap-4096 #run-test-mmap-65536
|
||||
else
|
||||
# On PPC32 Linux supports 4K/16K/64K/256K (but currently only 4k works)
|
||||
EXTRA_RUNS+=run-test-mmap-4096 #run-test-mmap-16384 run-test-mmap-65536 run-test-mmap-262144
|
||||
endif
|
@ -3,9 +3,6 @@
|
||||
# SuperH specific tweaks
|
||||
#
|
||||
|
||||
# On sh Linux supports 4k, 8k, 16k and 64k pages (but only 4k currently works)
|
||||
EXTRA_RUNS+=run-test-mmap-4096 # run-test-mmap-8192 run-test-mmap-16384 run-test-mmap-65536
|
||||
|
||||
# This triggers failures for sh4-linux about 10% of the time.
|
||||
# Random SIGSEGV at unpredictable guest address, cause unknown.
|
||||
run-signals: signals
|
||||
|
@ -1,6 +0,0 @@
|
||||
# -*- Mode: makefile -*-
|
||||
#
|
||||
# sparc specific tweaks
|
||||
|
||||
# On Sparc64 Linux support 8k pages
|
||||
EXTRA_RUNS+=run-test-mmap-8192
|
Loading…
Reference in New Issue
Block a user