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:
Peter Maydell 2024-03-05 09:45:22 +00:00
commit 4eac9dfbd7
39 changed files with 1156 additions and 1036 deletions

View File

@ -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);

View File

@ -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);
}
/*

View File

@ -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();
}

View File

@ -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) { }

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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
------------------------------------

View File

@ -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

View File

@ -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));

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ","

View File

@ -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 },

View File

@ -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);

View File

@ -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 "

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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
/*

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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);

View 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;
}

View File

@ -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

View File

@ -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

View File

@ -1,6 +0,0 @@
# -*- Mode: makefile -*-
#
# sparc specific tweaks
# On Sparc64 Linux support 8k pages
EXTRA_RUNS+=run-test-mmap-8192