mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
@@ -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);
|
||||
|
||||
+10
-24
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+18
-13
@@ -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) { }
|
||||
|
||||
+18
-5
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+4
-2
@@ -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
|
||||
|
||||
+257
-532
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
|
||||
|
||||
+23
-11
@@ -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);
|
||||
|
||||
+610
-329
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);
|
||||
|
||||
+18
-4
@@ -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 "
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user