bsd-user/elfload.c | 25 ++--------- bsd-user/main.c | 14 ++----- bsd-user/mmap.c | 102 ++++++++++++++++----------------------------- bsd-user/qemu.h | 10 ++--- 4 files changed, 46 insertions(+), 105 deletions(-)
The bsd-user implementation previously cached host page size and mask
in global variables (qemu_host_page_size and qemu_host_page_mask),
which duplicated information already available through
qemu_real_host_page_size().
This introduces unnecessary global state and potential inconsistencies
if the host page size is queried or changes during initialization.
Replace all usages of qemu_host_page_size and qemu_host_page_mask with
qemu_real_host_page_size() and derived expressions, and update all
alignment and masking logic accordingly.
This simplifies the code and ensures a single source of truth for host
page size handling across bsd-user memory management paths.
No functional change intended.
Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com>
---
bsd-user/elfload.c | 25 ++---------
bsd-user/main.c | 14 ++-----
bsd-user/mmap.c | 102 ++++++++++++++++-----------------------------
bsd-user/qemu.h | 10 ++---
4 files changed, 46 insertions(+), 105 deletions(-)
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 3bca0cc9ed..00250fc3c1 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -192,14 +192,14 @@ static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
*/
size = target_dflssiz;
stack_base = TARGET_USRSTACK - size;
- addr = target_mmap(stack_base , size + qemu_host_page_size,
+ addr = target_mmap(stack_base , size + HOST_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (addr == -1) {
perror("stk mmap");
exit(-1);
}
/* we reserve one extra page at the top of the stack as guard */
- target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
+ target_mprotect(addr + size, HOST_PAGE_SIZE, PROT_NONE);
target_stksiz = size;
target_stkbas = addr;
@@ -239,27 +239,10 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
return;
}
- /*
- * XXX: this is really a hack : if the real host page size is
- * smaller than the target page size, some pages after the end
- * of the file may not be mapped. A better fix would be to
- * patch target_mmap(), but it is more complicated as the file
- * size must be known.
- */
- if (qemu_real_host_page_size() < qemu_host_page_size) {
- abi_ulong end_addr, end_addr1;
- end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
- end_addr = HOST_PAGE_ALIGN(elf_bss);
- if (end_addr1 < end_addr) {
- mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
- }
- }
- nbyte = elf_bss & (qemu_host_page_size - 1);
+ nbyte = elf_bss & (HOST_PAGE_SIZE - 1);
if (nbyte) {
- nbyte = qemu_host_page_size - nbyte;
+ nbyte = HOST_PAGE_SIZE - nbyte;
do {
/* FIXME - what to do if put_user() fails? */
put_user_u8(0, elf_bss);
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 73aae8c327..3f5141e794 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -54,11 +54,6 @@
#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;
static unsigned long opt_tb_size;
@@ -302,8 +297,6 @@ 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;
@@ -405,7 +398,6 @@ int main(int argc, char **argv)
}
}
- qemu_host_page_mask = -qemu_host_page_size;
/* init debug */
{
@@ -452,7 +444,7 @@ int main(int argc, char **argv)
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);
@@ -534,7 +526,7 @@ int main(int argc, char **argv)
* proper page alignment for guest_base.
*/
if (have_guest_base) {
- if (guest_base & ~qemu_host_page_mask) {
+ if (guest_base & ~HOST_PAGE_MASK) {
error_report("Selected guest base not host page aligned");
exit(1);
}
@@ -573,7 +565,7 @@ int main(int argc, char **argv)
/* Ensure that mmap_next_start is within range. */
if (reserved_va <= mmap_next_start) {
mmap_next_start = (reserved_va / 4 * 3)
- & TARGET_PAGE_MASK & qemu_host_page_mask;
+ & TARGET_PAGE_MASK & HOST_PAGE_MASK;
}
}
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index fe77eceb48..59c70083a4 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -84,7 +84,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
return 0;
mmap_lock();
- host_start = start & qemu_host_page_mask;
+ host_start = start & HOST_PAGE_MASK;
host_end = HOST_PAGE_ALIGN(end);
if (start > host_start) {
/* handle host page containing start */
@@ -92,28 +92,28 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- if (host_end == host_start + qemu_host_page_size) {
+ if (host_end == host_start + HOST_PAGE_SIZE) {
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
end = host_end;
}
ret = mprotect(g2h_untagged(host_start),
- qemu_host_page_size, prot1 & PAGE_RWX);
+ HOST_PAGE_SIZE, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
- host_start += qemu_host_page_size;
+ host_start += HOST_PAGE_SIZE;
}
if (end < host_end) {
prot1 = prot;
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
- qemu_host_page_size, prot1 & PAGE_RWX);
+ ret = mprotect(g2h_untagged(host_end - HOST_PAGE_SIZE),
+ HOST_PAGE_SIZE, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
- host_end -= qemu_host_page_size;
+ host_end -= HOST_PAGE_SIZE;
}
/* handle the pages in the middle */
@@ -193,7 +193,7 @@ static int mmap_frag(abi_ulong real_start,
void *host_start;
int prot1, prot_new;
- real_end = real_start + qemu_host_page_size;
+ real_end = real_start + HOST_PAGE_SIZE;
host_start = g2h_untagged(real_start);
/* get the protection of the target pages outside the mapping */
@@ -205,7 +205,7 @@ static int mmap_frag(abi_ulong real_start,
if (prot1 == 0) {
/* no page was there, so we allocate one. See also above. */
- void *p = mmap(host_start, qemu_host_page_size, prot,
+ void *p = mmap(host_start, HOST_PAGE_SIZE, prot,
flags | ((fd != -1) ? MAP_ANON : 0), -1, 0);
if (p == MAP_FAILED)
return -1;
@@ -223,7 +223,7 @@ static int mmap_frag(abi_ulong real_start,
/* adjust protection to be able to read */
if (!(prot1 & PROT_WRITE))
- mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
+ mprotect(host_start, HOST_PAGE_SIZE, prot1 | PROT_WRITE);
/* read the corresponding file data */
if (!mmap_pread(fd, g2h_untagged(start), end - start, offset, true)) {
@@ -232,10 +232,10 @@ static int mmap_frag(abi_ulong real_start,
/* put final protection */
if (prot_new != (prot1 | PROT_WRITE))
- mprotect(host_start, qemu_host_page_size, prot_new);
+ mprotect(host_start, HOST_PAGE_SIZE, prot_new);
} else {
if (prot_new != prot1) {
- mprotect(host_start, qemu_host_page_size, prot_new);
+ mprotect(host_start, HOST_PAGE_SIZE, prot_new);
}
if (prot_new & PROT_WRITE) {
memset(g2h_untagged(start), 0, end - start);
@@ -289,7 +289,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
if (start == 0) {
start = mmap_next_start;
} else {
- start &= qemu_host_page_mask;
+ start &= HOST_PAGE_MASK;
}
size = HOST_PAGE_ALIGN(size);
@@ -297,7 +297,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
if (reserved_va) {
return mmap_find_vma_reserved(start, size,
(alignment != 0 ? 1 << alignment :
- MAX(qemu_host_page_size, TARGET_PAGE_SIZE)));
+ MAX(HOST_PAGE_SIZE, TARGET_PAGE_SIZE)));
}
addr = start;
@@ -478,8 +478,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
goto fail;
}
- real_start = start & qemu_host_page_mask;
- host_offset = offset & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
+ host_offset = offset & HOST_PAGE_MASK;
/*
* If the user is asking for the kernel to find a location, do that
@@ -498,38 +498,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
}
}
- /*
- * When mapping files into a memory area larger than the file, accesses
- * to pages beyond the file size will cause a SIGBUS.
- *
- * For example, if mmaping a file of 100 bytes on a host with 4K pages
- * emulating a target with 8K pages, the target expects to be able to
- * access the first 8K. But the host will trap us on any access beyond
- * 4K.
- *
- * When emulating a target with a larger page-size than the hosts, we
- * may need to truncate file maps at EOF and add extra anonymous pages
- * up to the targets page boundary.
- */
-
- if ((qemu_real_host_page_size() < qemu_host_page_size) && fd != -1) {
- struct stat sb;
-
- if (fstat(fd, &sb) == -1) {
- goto fail;
- }
-
- /* Are we trying to create a map beyond EOF?. */
- if (offset + len > sb.st_size) {
- /*
- * If so, truncate the file map at eof aligned with
- * the hosts real pagesize. Additional anonymous maps
- * will be created beyond EOF.
- */
- len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);
- }
- }
-
if (!(flags & MAP_FIXED)) {
unsigned long host_start;
void *p;
@@ -539,8 +507,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
/*
* Note: we prefer to control the mapping address. It is
- * especially important if qemu_host_page_size >
- * qemu_real_host_page_size
+ * especially important if HOST_PAGE_SIZE >
+ * TARGET_PAGE_SIZE
*/
p = mmap(g2h_untagged(start), host_len, prot,
flags | MAP_FIXED | ((fd != -1) ? MAP_ANON : 0), -1, 0);
@@ -581,7 +549,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
* aligned, so we read it
*/
if (fd != -1 &&
- (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) {
+ (offset & ~HOST_PAGE_MASK) != (start & ~HOST_PAGE_MASK)) {
/*
* msync() won't work here, so we return an error if write is
* possible while it is a shared mapping
@@ -614,7 +582,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
/* handle the start of the mapping */
if (start > real_start) {
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
/* one single host page */
ret = mmap_frag(real_start, start, end,
prot, flags, fd, offset);
@@ -622,21 +590,21 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
goto fail;
goto the_end1;
}
- ret = mmap_frag(real_start, start, real_start + qemu_host_page_size,
+ ret = mmap_frag(real_start, start, real_start + HOST_PAGE_SIZE,
prot, flags, fd, offset);
if (ret == -1)
goto fail;
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
/* handle the end of the mapping */
if (end < real_end) {
- ret = mmap_frag(real_end - qemu_host_page_size,
- real_end - qemu_host_page_size, end,
+ ret = mmap_frag(real_end - HOST_PAGE_SIZE,
+ real_end - HOST_PAGE_SIZE, end,
prot, flags, fd,
- offset + real_end - qemu_host_page_size - start);
+ offset + real_end - HOST_PAGE_SIZE - start);
if (ret == -1)
goto fail;
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
/* map the middle (easier) */
@@ -676,7 +644,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
abi_ulong end;
int prot;
- real_start = start & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
real_end = HOST_PAGE_ALIGN(start + size);
end = start + size;
if (start > real_start) {
@@ -685,14 +653,14 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
end = real_end;
}
if (prot != 0) {
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
}
if (end < real_end) {
@@ -701,7 +669,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
prot |= page_get_flags(addr);
}
if (prot != 0) {
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
}
if (real_start != real_end) {
@@ -727,7 +695,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
return -EINVAL;
mmap_lock();
end = start + len;
- real_start = start & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
real_end = HOST_PAGE_ALIGN(end);
if (start > real_start) {
@@ -736,14 +704,14 @@ int target_munmap(abi_ulong start, abi_ulong len)
for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
end = real_end;
}
if (prot != 0)
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
if (end < real_end) {
prot = 0;
@@ -751,7 +719,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
prot |= page_get_flags(addr);
}
if (prot != 0)
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
ret = 0;
@@ -784,6 +752,6 @@ int target_msync(abi_ulong start, abi_ulong len, int flags)
if (end == start)
return 0;
- start &= qemu_host_page_mask;
+ start &= HOST_PAGE_MASK;
return msync(g2h_untagged(start), end - start, flags);
}
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index b0b2c249fb..41ac5e3eab 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -44,12 +44,10 @@ extern char **environ;
#include "accel/tcg/vcpu-state.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)
+
+#define HOST_PAGE_SIZE qemu_real_host_page_size()
+#define HOST_PAGE_MASK (~(HOST_PAGE_SIZE - 1))
+#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1))
/*
* This struct is used to hold certain information about the image. Basically,
--
2.34.1
On Thu, Apr 30, 2026 at 10:29 AM Mohamed Ayman <
mohamedaymanworkspace@gmail.com> wrote:
> The bsd-user implementation previously cached host page size and mask
> in global variables (qemu_host_page_size and qemu_host_page_mask),
> which duplicated information already available through
> qemu_real_host_page_size().
>
> This introduces unnecessary global state and potential inconsistencies
> if the host page size is queried or changes during initialization.
>
> Replace all usages of qemu_host_page_size and qemu_host_page_mask with
> qemu_real_host_page_size() and derived expressions, and update all
> alignment and masking logic accordingly.
>
> This simplifies the code and ensures a single source of truth for host
> page size handling across bsd-user memory management paths.
>
> No functional change intended.
>
> Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com>
> ---
> bsd-user/elfload.c | 25 ++---------
> bsd-user/main.c | 14 ++-----
> bsd-user/mmap.c | 102 ++++++++++++++++-----------------------------
> bsd-user/qemu.h | 10 ++---
> 4 files changed, 46 insertions(+), 105 deletions(-)
>
> diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
> index 3bca0cc9ed..00250fc3c1 100644
> --- a/bsd-user/elfload.c
> +++ b/bsd-user/elfload.c
> @@ -192,14 +192,14 @@ static void setup_arg_pages(struct bsd_binprm *bprm,
> struct image_info *info,
> */
> size = target_dflssiz;
> stack_base = TARGET_USRSTACK - size;
> - addr = target_mmap(stack_base , size + qemu_host_page_size,
> + addr = target_mmap(stack_base , size + HOST_PAGE_SIZE,
> PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
> if (addr == -1) {
> perror("stk mmap");
> exit(-1);
> }
> /* we reserve one extra page at the top of the stack as guard */
> - target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
> + target_mprotect(addr + size, HOST_PAGE_SIZE, PROT_NONE);
>
> target_stksiz = size;
> target_stkbas = addr;
> @@ -239,27 +239,10 @@ static void padzero(abi_ulong elf_bss, abi_ulong
> last_bss)
> return;
> }
>
> - /*
> - * XXX: this is really a hack : if the real host page size is
> - * smaller than the target page size, some pages after the end
> - * of the file may not be mapped. A better fix would be to
> - * patch target_mmap(), but it is more complicated as the file
> - * size must be known.
> - */
> - if (qemu_real_host_page_size() < qemu_host_page_size) {
> - abi_ulong end_addr, end_addr1;
> - end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
> - end_addr = HOST_PAGE_ALIGN(elf_bss);
> - if (end_addr1 < end_addr) {
> - mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
> - PROT_READ | PROT_WRITE | PROT_EXEC,
> - MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
> - }
> - }
>
The commit message says it's a noop, but this looks like it does
something. aarch64 can have 16k pages, and binaries built for
that, and amd64 has 4k page sizes. I'm curious how that would work
out.
> - nbyte = elf_bss & (qemu_host_page_size - 1);
> + nbyte = elf_bss & (HOST_PAGE_SIZE - 1);
> if (nbyte) {
> - nbyte = qemu_host_page_size - nbyte;
> + nbyte = HOST_PAGE_SIZE - nbyte;
> do {
> /* FIXME - what to do if put_user() fails? */
> put_user_u8(0, elf_bss);
> diff --git a/bsd-user/main.c b/bsd-user/main.c
> index 73aae8c327..3f5141e794 100644
> --- a/bsd-user/main.c
> +++ b/bsd-user/main.c
> @@ -54,11 +54,6 @@
> #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;
> static unsigned long opt_tb_size;
> @@ -302,8 +297,6 @@ 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;
>
> @@ -405,7 +398,6 @@ int main(int argc, char **argv)
> }
> }
>
> - qemu_host_page_mask = -qemu_host_page_size;
>
> /* init debug */
> {
> @@ -452,7 +444,7 @@ int main(int argc, char **argv)
>
> 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);
> @@ -534,7 +526,7 @@ int main(int argc, char **argv)
> * proper page alignment for guest_base.
> */
> if (have_guest_base) {
> - if (guest_base & ~qemu_host_page_mask) {
> + if (guest_base & ~HOST_PAGE_MASK) {
> error_report("Selected guest base not host page aligned");
> exit(1);
> }
> @@ -573,7 +565,7 @@ int main(int argc, char **argv)
> /* Ensure that mmap_next_start is within range. */
> if (reserved_va <= mmap_next_start) {
> mmap_next_start = (reserved_va / 4 * 3)
> - & TARGET_PAGE_MASK & qemu_host_page_mask;
> + & TARGET_PAGE_MASK & HOST_PAGE_MASK;
> }
> }
>
> diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
> index fe77eceb48..59c70083a4 100644
> --- a/bsd-user/mmap.c
> +++ b/bsd-user/mmap.c
> @@ -84,7 +84,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int
> prot)
> return 0;
>
> mmap_lock();
> - host_start = start & qemu_host_page_mask;
> + host_start = start & HOST_PAGE_MASK;
> host_end = HOST_PAGE_ALIGN(end);
> if (start > host_start) {
> /* handle host page containing start */
> @@ -92,28 +92,28 @@ int target_mprotect(abi_ulong start, abi_ulong len,
> int prot)
> for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
> prot1 |= page_get_flags(addr);
> }
> - if (host_end == host_start + qemu_host_page_size) {
> + if (host_end == host_start + HOST_PAGE_SIZE) {
> for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
> prot1 |= page_get_flags(addr);
> }
> end = host_end;
> }
> ret = mprotect(g2h_untagged(host_start),
> - qemu_host_page_size, prot1 & PAGE_RWX);
> + HOST_PAGE_SIZE, prot1 & PAGE_RWX);
> if (ret != 0)
> goto error;
> - host_start += qemu_host_page_size;
> + host_start += HOST_PAGE_SIZE;
> }
> if (end < host_end) {
> prot1 = prot;
> for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
> prot1 |= page_get_flags(addr);
> }
> - ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
> - qemu_host_page_size, prot1 & PAGE_RWX);
> + ret = mprotect(g2h_untagged(host_end - HOST_PAGE_SIZE),
> + HOST_PAGE_SIZE, prot1 & PAGE_RWX);
> if (ret != 0)
> goto error;
> - host_end -= qemu_host_page_size;
> + host_end -= HOST_PAGE_SIZE;
> }
>
> /* handle the pages in the middle */
> @@ -193,7 +193,7 @@ static int mmap_frag(abi_ulong real_start,
> void *host_start;
> int prot1, prot_new;
>
> - real_end = real_start + qemu_host_page_size;
> + real_end = real_start + HOST_PAGE_SIZE;
> host_start = g2h_untagged(real_start);
>
> /* get the protection of the target pages outside the mapping */
> @@ -205,7 +205,7 @@ static int mmap_frag(abi_ulong real_start,
>
> if (prot1 == 0) {
> /* no page was there, so we allocate one. See also above. */
> - void *p = mmap(host_start, qemu_host_page_size, prot,
> + void *p = mmap(host_start, HOST_PAGE_SIZE, prot,
> flags | ((fd != -1) ? MAP_ANON : 0), -1, 0);
> if (p == MAP_FAILED)
> return -1;
> @@ -223,7 +223,7 @@ static int mmap_frag(abi_ulong real_start,
>
> /* adjust protection to be able to read */
> if (!(prot1 & PROT_WRITE))
> - mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
> + mprotect(host_start, HOST_PAGE_SIZE, prot1 | PROT_WRITE);
>
> /* read the corresponding file data */
> if (!mmap_pread(fd, g2h_untagged(start), end - start, offset,
> true)) {
> @@ -232,10 +232,10 @@ static int mmap_frag(abi_ulong real_start,
>
> /* put final protection */
> if (prot_new != (prot1 | PROT_WRITE))
> - mprotect(host_start, qemu_host_page_size, prot_new);
> + mprotect(host_start, HOST_PAGE_SIZE, prot_new);
> } else {
> if (prot_new != prot1) {
> - mprotect(host_start, qemu_host_page_size, prot_new);
> + mprotect(host_start, HOST_PAGE_SIZE, prot_new);
> }
> if (prot_new & PROT_WRITE) {
> memset(g2h_untagged(start), 0, end - start);
> @@ -289,7 +289,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong
> size, abi_ulong alignment)
> if (start == 0) {
> start = mmap_next_start;
> } else {
> - start &= qemu_host_page_mask;
> + start &= HOST_PAGE_MASK;
> }
>
> size = HOST_PAGE_ALIGN(size);
> @@ -297,7 +297,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong
> size, abi_ulong alignment)
> if (reserved_va) {
> return mmap_find_vma_reserved(start, size,
> (alignment != 0 ? 1 << alignment :
> - MAX(qemu_host_page_size, TARGET_PAGE_SIZE)));
> + MAX(HOST_PAGE_SIZE, TARGET_PAGE_SIZE)));
> }
>
> addr = start;
> @@ -478,8 +478,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
> goto fail;
> }
>
> - real_start = start & qemu_host_page_mask;
> - host_offset = offset & qemu_host_page_mask;
> + real_start = start & HOST_PAGE_MASK;
> + host_offset = offset & HOST_PAGE_MASK;
>
> /*
> * If the user is asking for the kernel to find a location, do that
> @@ -498,38 +498,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
> }
> }
>
> - /*
> - * When mapping files into a memory area larger than the file,
> accesses
> - * to pages beyond the file size will cause a SIGBUS.
> - *
> - * For example, if mmaping a file of 100 bytes on a host with 4K pages
> - * emulating a target with 8K pages, the target expects to be able to
> - * access the first 8K. But the host will trap us on any access beyond
> - * 4K.
> - *
> - * When emulating a target with a larger page-size than the hosts, we
> - * may need to truncate file maps at EOF and add extra anonymous pages
> - * up to the targets page boundary.
> - */
> -
> - if ((qemu_real_host_page_size() < qemu_host_page_size) && fd != -1) {
> - struct stat sb;
> -
> - if (fstat(fd, &sb) == -1) {
> - goto fail;
> - }
> -
> - /* Are we trying to create a map beyond EOF?. */
> - if (offset + len > sb.st_size) {
> - /*
> - * If so, truncate the file map at eof aligned with
> - * the hosts real pagesize. Additional anonymous maps
> - * will be created beyond EOF.
> - */
> - len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);
> - }
> - }
> -
> if (!(flags & MAP_FIXED)) {
> unsigned long host_start;
> void *p;
> @@ -539,8 +507,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
>
> /*
> * Note: we prefer to control the mapping address. It is
> - * especially important if qemu_host_page_size >
> - * qemu_real_host_page_size
> + * especially important if HOST_PAGE_SIZE >
> + * TARGET_PAGE_SIZE
> */
> p = mmap(g2h_untagged(start), host_len, prot,
> flags | MAP_FIXED | ((fd != -1) ? MAP_ANON : 0), -1, 0);
> @@ -581,7 +549,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
> * aligned, so we read it
> */
> if (fd != -1 &&
> - (offset & ~qemu_host_page_mask) != (start &
> ~qemu_host_page_mask)) {
> + (offset & ~HOST_PAGE_MASK) != (start & ~HOST_PAGE_MASK)) {
> /*
> * msync() won't work here, so we return an error if write is
> * possible while it is a shared mapping
> @@ -614,7 +582,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
>
> /* handle the start of the mapping */
> if (start > real_start) {
> - if (real_end == real_start + qemu_host_page_size) {
> + if (real_end == real_start + HOST_PAGE_SIZE) {
> /* one single host page */
> ret = mmap_frag(real_start, start, end,
> prot, flags, fd, offset);
> @@ -622,21 +590,21 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
> goto fail;
> goto the_end1;
> }
> - ret = mmap_frag(real_start, start, real_start +
> qemu_host_page_size,
> + ret = mmap_frag(real_start, start, real_start +
> HOST_PAGE_SIZE,
> prot, flags, fd, offset);
> if (ret == -1)
> goto fail;
> - real_start += qemu_host_page_size;
> + real_start += HOST_PAGE_SIZE;
> }
> /* handle the end of the mapping */
> if (end < real_end) {
> - ret = mmap_frag(real_end - qemu_host_page_size,
> - real_end - qemu_host_page_size, end,
> + ret = mmap_frag(real_end - HOST_PAGE_SIZE,
> + real_end - HOST_PAGE_SIZE, end,
> prot, flags, fd,
> - offset + real_end - qemu_host_page_size -
> start);
> + offset + real_end - HOST_PAGE_SIZE - start);
> if (ret == -1)
> goto fail;
> - real_end -= qemu_host_page_size;
> + real_end -= HOST_PAGE_SIZE;
> }
>
> /* map the middle (easier) */
> @@ -676,7 +644,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> abi_ulong end;
> int prot;
>
> - real_start = start & qemu_host_page_mask;
> + real_start = start & HOST_PAGE_MASK;
> real_end = HOST_PAGE_ALIGN(start + size);
> end = start + size;
> if (start > real_start) {
> @@ -685,14 +653,14 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
> prot |= page_get_flags(addr);
> }
> - if (real_end == real_start + qemu_host_page_size) {
> + if (real_end == real_start + HOST_PAGE_SIZE) {
> for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
> prot |= page_get_flags(addr);
> }
> end = real_end;
> }
> if (prot != 0) {
> - real_start += qemu_host_page_size;
> + real_start += HOST_PAGE_SIZE;
> }
> }
> if (end < real_end) {
> @@ -701,7 +669,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> prot |= page_get_flags(addr);
> }
> if (prot != 0) {
> - real_end -= qemu_host_page_size;
> + real_end -= HOST_PAGE_SIZE;
> }
> }
> if (real_start != real_end) {
> @@ -727,7 +695,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
> return -EINVAL;
> mmap_lock();
> end = start + len;
> - real_start = start & qemu_host_page_mask;
> + real_start = start & HOST_PAGE_MASK;
> real_end = HOST_PAGE_ALIGN(end);
>
> if (start > real_start) {
> @@ -736,14 +704,14 @@ int target_munmap(abi_ulong start, abi_ulong len)
> for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
> prot |= page_get_flags(addr);
> }
> - if (real_end == real_start + qemu_host_page_size) {
> + if (real_end == real_start + HOST_PAGE_SIZE) {
> for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
> prot |= page_get_flags(addr);
> }
> end = real_end;
> }
> if (prot != 0)
> - real_start += qemu_host_page_size;
> + real_start += HOST_PAGE_SIZE;
> }
> if (end < real_end) {
> prot = 0;
> @@ -751,7 +719,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
> prot |= page_get_flags(addr);
> }
> if (prot != 0)
> - real_end -= qemu_host_page_size;
> + real_end -= HOST_PAGE_SIZE;
> }
>
> ret = 0;
> @@ -784,6 +752,6 @@ int target_msync(abi_ulong start, abi_ulong len, int
> flags)
> if (end == start)
> return 0;
>
> - start &= qemu_host_page_mask;
> + start &= HOST_PAGE_MASK;
> return msync(g2h_untagged(start), end - start, flags);
> }
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index b0b2c249fb..41ac5e3eab 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -44,12 +44,10 @@ extern char **environ;
> #include "accel/tcg/vcpu-state.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)
> +
> +#define HOST_PAGE_SIZE qemu_real_host_page_size()
> +#define HOST_PAGE_MASK (~(HOST_PAGE_SIZE - 1))
> +#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1))
>
HOST_PAGE_MASK appears to be defined twice.
As I said before, I love the direction here. Thanks for working it out.
Are you using bsd-user for anything?
Warner
> /*
> * This struct is used to hold certain information about the image.
> Basically,
> --
> 2.34.1
>
>
On Thu, 30 Apr 2026 at 18:08, Mohamed Ayman <mohamedaymanworkspace@gmail.com> wrote: > > The bsd-user implementation previously cached host page size and mask > in global variables (qemu_host_page_size and qemu_host_page_mask), > which duplicated information already available through > qemu_real_host_page_size(). > > This introduces unnecessary global state and potential inconsistencies > if the host page size is queried or changes during initialization. > > Replace all usages of qemu_host_page_size and qemu_host_page_mask with > qemu_real_host_page_size() and derived expressions, and update all > alignment and masking logic accordingly. > > This simplifies the code and ensures a single source of truth for host > page size handling across bsd-user memory management paths. > > No functional change intended. > > Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com> > --- This would be a nice change to have to the bsd-user code, because it opens the way for us to rename qemu_real_host_page_size() to qemu_host_page_size(), and similarly qemu_real_host_page_mask(). (If I remember a recent IRC conversation correctly, they only have the _real_ infix for historical reasons and because the bsd-user globals are currently using the more obvious names.) thanks -- PMM
On Thu, Apr 30, 2026 at 11:46 AM Peter Maydell <peter.maydell@linaro.org> wrote: > On Thu, 30 Apr 2026 at 18:08, Mohamed Ayman > <mohamedaymanworkspace@gmail.com> wrote: > > > > The bsd-user implementation previously cached host page size and mask > > in global variables (qemu_host_page_size and qemu_host_page_mask), > > which duplicated information already available through > > qemu_real_host_page_size(). > > > > This introduces unnecessary global state and potential inconsistencies > > if the host page size is queried or changes during initialization. > > > > Replace all usages of qemu_host_page_size and qemu_host_page_mask with > > qemu_real_host_page_size() and derived expressions, and update all > > alignment and masking logic accordingly. > > > > This simplifies the code and ensures a single source of truth for host > > page size handling across bsd-user memory management paths. > > > > No functional change intended. > > > > Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com> > > --- > > This would be a nice change to have to the bsd-user code, > because it opens the way for us to rename qemu_real_host_page_size() > to qemu_host_page_size(), and similarly qemu_real_host_page_mask(). > (If I remember a recent IRC conversation correctly, they only have > the _real_ infix for historical reasons and because the bsd-user > globals are currently using the more obvious names.) I'd love to see this as well. This has been one of my todo items for far too long since I've been distracted with other things (like upstreaming). I wonder if these changes have been tried against the blitz branch at https://github.com/qemu-bsd-user/qemu-bsd-user? I just pushed an 11.0-based version of that branch, but have only lightly tested it. Theres some pending issues with some shared libraries on riscv (IIRC the issue correctly) whose fixes break shared libraries on other platforms). If you could test against that, I'd love to bring them in with this quarter's upstream pull request that I'm planning on doing once I get the ioctl patch series sorted out (and it seems like I made several mistakes somewhere with it that I need to go patch up). Warner
The bsd-user implementation previously cached host page size and mask
in global variables (qemu_host_page_size and qemu_host_page_mask),
which duplicated information already available through
qemu_real_host_page_size().
This introduced unnecessary global state and potential inconsistencies
if the host page size is queried or changes during initialization.
Replace all usages of qemu_host_page_size and qemu_host_page_mask with
HOST_PAGE_SIZE and HOST_PAGE_MASK macros defined as:
MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
This preserves the original behavior where the effective host page size
is the maximum of the real host page size and the target page size,
which matters on targets like aarch64 with 16K pages running on an
amd64 host with 4K pages.
This also opens the way for renaming qemu_real_host_page_size() to
qemu_host_page_size() now that the bsd-user globals no longer occupy
that name.
Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com>
---
bsd-user/elfload.c | 25 ++---------
bsd-user/main.c | 14 ++-----
bsd-user/mmap.c | 102 ++++++++++++++++-----------------------------
bsd-user/qemu.h | 10 ++---
4 files changed, 46 insertions(+), 105 deletions(-)
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 3bca0cc9ed..00250fc3c1 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -192,14 +192,14 @@ static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
*/
size = target_dflssiz;
stack_base = TARGET_USRSTACK - size;
- addr = target_mmap(stack_base , size + qemu_host_page_size,
+ addr = target_mmap(stack_base , size + HOST_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (addr == -1) {
perror("stk mmap");
exit(-1);
}
/* we reserve one extra page at the top of the stack as guard */
- target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
+ target_mprotect(addr + size, HOST_PAGE_SIZE, PROT_NONE);
target_stksiz = size;
target_stkbas = addr;
@@ -239,27 +239,10 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
return;
}
- /*
- * XXX: this is really a hack : if the real host page size is
- * smaller than the target page size, some pages after the end
- * of the file may not be mapped. A better fix would be to
- * patch target_mmap(), but it is more complicated as the file
- * size must be known.
- */
- if (qemu_real_host_page_size() < qemu_host_page_size) {
- abi_ulong end_addr, end_addr1;
- end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
- end_addr = HOST_PAGE_ALIGN(elf_bss);
- if (end_addr1 < end_addr) {
- mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
- }
- }
- nbyte = elf_bss & (qemu_host_page_size - 1);
+ nbyte = elf_bss & (HOST_PAGE_SIZE - 1);
if (nbyte) {
- nbyte = qemu_host_page_size - nbyte;
+ nbyte = HOST_PAGE_SIZE - nbyte;
do {
/* FIXME - what to do if put_user() fails? */
put_user_u8(0, elf_bss);
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 73aae8c327..3f5141e794 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -54,11 +54,6 @@
#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;
static unsigned long opt_tb_size;
@@ -302,8 +297,6 @@ 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;
@@ -405,7 +398,6 @@ int main(int argc, char **argv)
}
}
- qemu_host_page_mask = -qemu_host_page_size;
/* init debug */
{
@@ -452,7 +444,7 @@ int main(int argc, char **argv)
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);
@@ -534,7 +526,7 @@ int main(int argc, char **argv)
* proper page alignment for guest_base.
*/
if (have_guest_base) {
- if (guest_base & ~qemu_host_page_mask) {
+ if (guest_base & ~HOST_PAGE_MASK) {
error_report("Selected guest base not host page aligned");
exit(1);
}
@@ -573,7 +565,7 @@ int main(int argc, char **argv)
/* Ensure that mmap_next_start is within range. */
if (reserved_va <= mmap_next_start) {
mmap_next_start = (reserved_va / 4 * 3)
- & TARGET_PAGE_MASK & qemu_host_page_mask;
+ & TARGET_PAGE_MASK & HOST_PAGE_MASK;
}
}
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index fe77eceb48..59c70083a4 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -84,7 +84,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
return 0;
mmap_lock();
- host_start = start & qemu_host_page_mask;
+ host_start = start & HOST_PAGE_MASK;
host_end = HOST_PAGE_ALIGN(end);
if (start > host_start) {
/* handle host page containing start */
@@ -92,28 +92,28 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- if (host_end == host_start + qemu_host_page_size) {
+ if (host_end == host_start + HOST_PAGE_SIZE) {
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
end = host_end;
}
ret = mprotect(g2h_untagged(host_start),
- qemu_host_page_size, prot1 & PAGE_RWX);
+ HOST_PAGE_SIZE, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
- host_start += qemu_host_page_size;
+ host_start += HOST_PAGE_SIZE;
}
if (end < host_end) {
prot1 = prot;
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
- qemu_host_page_size, prot1 & PAGE_RWX);
+ ret = mprotect(g2h_untagged(host_end - HOST_PAGE_SIZE),
+ HOST_PAGE_SIZE, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
- host_end -= qemu_host_page_size;
+ host_end -= HOST_PAGE_SIZE;
}
/* handle the pages in the middle */
@@ -193,7 +193,7 @@ static int mmap_frag(abi_ulong real_start,
void *host_start;
int prot1, prot_new;
- real_end = real_start + qemu_host_page_size;
+ real_end = real_start + HOST_PAGE_SIZE;
host_start = g2h_untagged(real_start);
/* get the protection of the target pages outside the mapping */
@@ -205,7 +205,7 @@ static int mmap_frag(abi_ulong real_start,
if (prot1 == 0) {
/* no page was there, so we allocate one. See also above. */
- void *p = mmap(host_start, qemu_host_page_size, prot,
+ void *p = mmap(host_start, HOST_PAGE_SIZE, prot,
flags | ((fd != -1) ? MAP_ANON : 0), -1, 0);
if (p == MAP_FAILED)
return -1;
@@ -223,7 +223,7 @@ static int mmap_frag(abi_ulong real_start,
/* adjust protection to be able to read */
if (!(prot1 & PROT_WRITE))
- mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
+ mprotect(host_start, HOST_PAGE_SIZE, prot1 | PROT_WRITE);
/* read the corresponding file data */
if (!mmap_pread(fd, g2h_untagged(start), end - start, offset, true)) {
@@ -232,10 +232,10 @@ static int mmap_frag(abi_ulong real_start,
/* put final protection */
if (prot_new != (prot1 | PROT_WRITE))
- mprotect(host_start, qemu_host_page_size, prot_new);
+ mprotect(host_start, HOST_PAGE_SIZE, prot_new);
} else {
if (prot_new != prot1) {
- mprotect(host_start, qemu_host_page_size, prot_new);
+ mprotect(host_start, HOST_PAGE_SIZE, prot_new);
}
if (prot_new & PROT_WRITE) {
memset(g2h_untagged(start), 0, end - start);
@@ -289,7 +289,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
if (start == 0) {
start = mmap_next_start;
} else {
- start &= qemu_host_page_mask;
+ start &= HOST_PAGE_MASK;
}
size = HOST_PAGE_ALIGN(size);
@@ -297,7 +297,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
if (reserved_va) {
return mmap_find_vma_reserved(start, size,
(alignment != 0 ? 1 << alignment :
- MAX(qemu_host_page_size, TARGET_PAGE_SIZE)));
+ MAX(HOST_PAGE_SIZE, TARGET_PAGE_SIZE)));
}
addr = start;
@@ -478,8 +478,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
goto fail;
}
- real_start = start & qemu_host_page_mask;
- host_offset = offset & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
+ host_offset = offset & HOST_PAGE_MASK;
/*
* If the user is asking for the kernel to find a location, do that
@@ -498,38 +498,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
}
}
- /*
- * When mapping files into a memory area larger than the file, accesses
- * to pages beyond the file size will cause a SIGBUS.
- *
- * For example, if mmaping a file of 100 bytes on a host with 4K pages
- * emulating a target with 8K pages, the target expects to be able to
- * access the first 8K. But the host will trap us on any access beyond
- * 4K.
- *
- * When emulating a target with a larger page-size than the hosts, we
- * may need to truncate file maps at EOF and add extra anonymous pages
- * up to the targets page boundary.
- */
-
- if ((qemu_real_host_page_size() < qemu_host_page_size) && fd != -1) {
- struct stat sb;
-
- if (fstat(fd, &sb) == -1) {
- goto fail;
- }
-
- /* Are we trying to create a map beyond EOF?. */
- if (offset + len > sb.st_size) {
- /*
- * If so, truncate the file map at eof aligned with
- * the hosts real pagesize. Additional anonymous maps
- * will be created beyond EOF.
- */
- len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);
- }
- }
-
if (!(flags & MAP_FIXED)) {
unsigned long host_start;
void *p;
@@ -539,8 +507,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
/*
* Note: we prefer to control the mapping address. It is
- * especially important if qemu_host_page_size >
- * qemu_real_host_page_size
+ * especially important if HOST_PAGE_SIZE >
+ * TARGET_PAGE_SIZE
*/
p = mmap(g2h_untagged(start), host_len, prot,
flags | MAP_FIXED | ((fd != -1) ? MAP_ANON : 0), -1, 0);
@@ -581,7 +549,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
* aligned, so we read it
*/
if (fd != -1 &&
- (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) {
+ (offset & ~HOST_PAGE_MASK) != (start & ~HOST_PAGE_MASK)) {
/*
* msync() won't work here, so we return an error if write is
* possible while it is a shared mapping
@@ -614,7 +582,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
/* handle the start of the mapping */
if (start > real_start) {
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
/* one single host page */
ret = mmap_frag(real_start, start, end,
prot, flags, fd, offset);
@@ -622,21 +590,21 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
goto fail;
goto the_end1;
}
- ret = mmap_frag(real_start, start, real_start + qemu_host_page_size,
+ ret = mmap_frag(real_start, start, real_start + HOST_PAGE_SIZE,
prot, flags, fd, offset);
if (ret == -1)
goto fail;
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
/* handle the end of the mapping */
if (end < real_end) {
- ret = mmap_frag(real_end - qemu_host_page_size,
- real_end - qemu_host_page_size, end,
+ ret = mmap_frag(real_end - HOST_PAGE_SIZE,
+ real_end - HOST_PAGE_SIZE, end,
prot, flags, fd,
- offset + real_end - qemu_host_page_size - start);
+ offset + real_end - HOST_PAGE_SIZE - start);
if (ret == -1)
goto fail;
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
/* map the middle (easier) */
@@ -676,7 +644,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
abi_ulong end;
int prot;
- real_start = start & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
real_end = HOST_PAGE_ALIGN(start + size);
end = start + size;
if (start > real_start) {
@@ -685,14 +653,14 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
end = real_end;
}
if (prot != 0) {
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
}
if (end < real_end) {
@@ -701,7 +669,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
prot |= page_get_flags(addr);
}
if (prot != 0) {
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
}
if (real_start != real_end) {
@@ -727,7 +695,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
return -EINVAL;
mmap_lock();
end = start + len;
- real_start = start & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
real_end = HOST_PAGE_ALIGN(end);
if (start > real_start) {
@@ -736,14 +704,14 @@ int target_munmap(abi_ulong start, abi_ulong len)
for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
end = real_end;
}
if (prot != 0)
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
if (end < real_end) {
prot = 0;
@@ -751,7 +719,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
prot |= page_get_flags(addr);
}
if (prot != 0)
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
ret = 0;
@@ -784,6 +752,6 @@ int target_msync(abi_ulong start, abi_ulong len, int flags)
if (end == start)
return 0;
- start &= qemu_host_page_mask;
+ start &= HOST_PAGE_MASK;
return msync(g2h_untagged(start), end - start, flags);
}
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index b0b2c249fb..7553ac154c 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -44,12 +44,10 @@ extern char **environ;
#include "accel/tcg/vcpu-state.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)
+
+#define HOST_PAGE_SIZE MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
+#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1))
+#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), HOST_PAGE_SIZE)
/*
* This struct is used to hold certain information about the image. Basically,
--
2.34.1
On 5/1/26 11:11, Mohamed Ayman wrote: > +++ b/bsd-user/qemu.h > @@ -44,12 +44,10 @@ extern char **environ; > #include "accel/tcg/vcpu-state.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) > + > +#define HOST_PAGE_SIZE MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE) > +#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1)) > +#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), HOST_PAGE_SIZE) This is a bad idea, hiding the true size of the host page. There are oodles of corner cases that require the exact size of the host page. If you hide this in a macro, you are going to stumble over them all of the time. r~
On Tue, May 5, 2026 at 4:40 PM Richard Henderson < richard.henderson@linaro.org> wrote: > On 5/1/26 11:11, Mohamed Ayman wrote: > > +++ b/bsd-user/qemu.h > > @@ -44,12 +44,10 @@ extern char **environ; > > #include "accel/tcg/vcpu-state.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) > > + > > +#define HOST_PAGE_SIZE MAX(qemu_real_host_page_size(), > TARGET_PAGE_SIZE) > > +#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1)) > > +#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), HOST_PAGE_SIZE) > > This is a bad idea, hiding the true size of the host page. > > There are oodles of corner cases that require the exact size of the host > page. If you > hide this in a macro, you are going to stumble over them all of the time. > Yes. I've thought about writing test cases for maybe aarch64 16k page binaries on a 4k x86_64 mahine. I don't suppose there's tests like that for linux-user today? Thinking about it for a couple of minutes, I think not hiding it, and keeping the chunk that was deleted will make sense. But I've not pondered all the edge cases in detail yet. Warner
On 5/5/26 17:52, Warner Losh wrote: > > > On Tue, May 5, 2026 at 4:40 PM Richard Henderson <richard.henderson@linaro.org > <mailto:richard.henderson@linaro.org>> wrote: > > On 5/1/26 11:11, Mohamed Ayman wrote: > > +++ b/bsd-user/qemu.h > > @@ -44,12 +44,10 @@ extern char **environ; > > #include "accel/tcg/vcpu-state.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) > > + > > +#define HOST_PAGE_SIZE MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE) > > +#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1)) > > +#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), HOST_PAGE_SIZE) > > This is a bad idea, hiding the true size of the host page. > > There are oodles of corner cases that require the exact size of the host page. If you > hide this in a macro, you are going to stumble over them all of the time. > > > Yes. I've thought about writing test cases for maybe aarch64 16k page binaries on a 4k > x86_64 mahine. > I don't suppose there's tests like that for linux-user today? No, because it doesn't really work there either. r~
On 5/6/26 07:56, Richard Henderson wrote:
> On 5/5/26 17:52, Warner Losh wrote:
>> Yes. I've thought about writing test cases for maybe aarch64 16k page binaries on a 4k
>> x86_64 mahine.
>> I don't suppose there's tests like that for linux-user today?
Actually, what we have today that makes this specific case "work" is by allowing the guest
page size to mirror the host for various guests. See
/*
* 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();
So, on an x86_64 host, aarch64 guests will always use 4k pages.
r~
Hi Warner and Peter,
Thanks for the review. :)
Here is v2 addressing your comments:
- Fixed the duplicate HOST_PAGE_MASK definition
- HOST_PAGE_SIZE now uses:
MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
This preserves correct behavior for cases where the target page size
exceeds the host page size (e.g. aarch64 16K pages on a 4K amd64 host)
- Updated the commit message to clarify behavior and remove the incorrect
"No functional change intended" wording
Regarding your question, I am not currently using bsd-user in production;
this started as a cleanup/contribution effort while working through the code.
Thanks again for the feedback.
Mohamed Ayman
On Fri, May 1, 2026 at 7:11 PM Mohamed Ayman
<mohamedaymanworkspace@gmail.com> wrote:
>
> The bsd-user implementation previously cached host page size and mask
> in global variables (qemu_host_page_size and qemu_host_page_mask),
> which duplicated information already available through
> qemu_real_host_page_size().
>
> This introduced unnecessary global state and potential inconsistencies
> if the host page size is queried or changes during initialization.
>
> Replace all usages of qemu_host_page_size and qemu_host_page_mask with
> HOST_PAGE_SIZE and HOST_PAGE_MASK macros defined as:
>
> MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
>
> This preserves the original behavior where the effective host page size
> is the maximum of the real host page size and the target page size,
> which matters on targets like aarch64 with 16K pages running on an
> amd64 host with 4K pages.
>
> This also opens the way for renaming qemu_real_host_page_size() to
> qemu_host_page_size() now that the bsd-user globals no longer occupy
> that name.
>
> Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com>
> ---
> bsd-user/elfload.c | 25 ++---------
> bsd-user/main.c | 14 ++-----
> bsd-user/mmap.c | 102 ++++++++++++++++-----------------------------
> bsd-user/qemu.h | 10 ++---
> 4 files changed, 46 insertions(+), 105 deletions(-)
>
> diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
> index 3bca0cc9ed..00250fc3c1 100644
> --- a/bsd-user/elfload.c
> +++ b/bsd-user/elfload.c
> @@ -192,14 +192,14 @@ static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
> */
> size = target_dflssiz;
> stack_base = TARGET_USRSTACK - size;
> - addr = target_mmap(stack_base , size + qemu_host_page_size,
> + addr = target_mmap(stack_base , size + HOST_PAGE_SIZE,
> PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
> if (addr == -1) {
> perror("stk mmap");
> exit(-1);
> }
> /* we reserve one extra page at the top of the stack as guard */
> - target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
> + target_mprotect(addr + size, HOST_PAGE_SIZE, PROT_NONE);
>
> target_stksiz = size;
> target_stkbas = addr;
> @@ -239,27 +239,10 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
> return;
> }
>
> - /*
> - * XXX: this is really a hack : if the real host page size is
> - * smaller than the target page size, some pages after the end
> - * of the file may not be mapped. A better fix would be to
> - * patch target_mmap(), but it is more complicated as the file
> - * size must be known.
> - */
> - if (qemu_real_host_page_size() < qemu_host_page_size) {
> - abi_ulong end_addr, end_addr1;
> - end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
> - end_addr = HOST_PAGE_ALIGN(elf_bss);
> - if (end_addr1 < end_addr) {
> - mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
> - PROT_READ | PROT_WRITE | PROT_EXEC,
> - MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
> - }
> - }
>
> - nbyte = elf_bss & (qemu_host_page_size - 1);
> + nbyte = elf_bss & (HOST_PAGE_SIZE - 1);
> if (nbyte) {
> - nbyte = qemu_host_page_size - nbyte;
> + nbyte = HOST_PAGE_SIZE - nbyte;
> do {
> /* FIXME - what to do if put_user() fails? */
> put_user_u8(0, elf_bss);
> diff --git a/bsd-user/main.c b/bsd-user/main.c
> index 73aae8c327..3f5141e794 100644
> --- a/bsd-user/main.c
> +++ b/bsd-user/main.c
> @@ -54,11 +54,6 @@
> #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;
> static unsigned long opt_tb_size;
> @@ -302,8 +297,6 @@ 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;
>
> @@ -405,7 +398,6 @@ int main(int argc, char **argv)
> }
> }
>
> - qemu_host_page_mask = -qemu_host_page_size;
>
> /* init debug */
> {
> @@ -452,7 +444,7 @@ int main(int argc, char **argv)
>
> 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);
> @@ -534,7 +526,7 @@ int main(int argc, char **argv)
> * proper page alignment for guest_base.
> */
> if (have_guest_base) {
> - if (guest_base & ~qemu_host_page_mask) {
> + if (guest_base & ~HOST_PAGE_MASK) {
> error_report("Selected guest base not host page aligned");
> exit(1);
> }
> @@ -573,7 +565,7 @@ int main(int argc, char **argv)
> /* Ensure that mmap_next_start is within range. */
> if (reserved_va <= mmap_next_start) {
> mmap_next_start = (reserved_va / 4 * 3)
> - & TARGET_PAGE_MASK & qemu_host_page_mask;
> + & TARGET_PAGE_MASK & HOST_PAGE_MASK;
> }
> }
>
> diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
> index fe77eceb48..59c70083a4 100644
> --- a/bsd-user/mmap.c
> +++ b/bsd-user/mmap.c
> @@ -84,7 +84,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
> return 0;
>
> mmap_lock();
> - host_start = start & qemu_host_page_mask;
> + host_start = start & HOST_PAGE_MASK;
> host_end = HOST_PAGE_ALIGN(end);
> if (start > host_start) {
> /* handle host page containing start */
> @@ -92,28 +92,28 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
> for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
> prot1 |= page_get_flags(addr);
> }
> - if (host_end == host_start + qemu_host_page_size) {
> + if (host_end == host_start + HOST_PAGE_SIZE) {
> for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
> prot1 |= page_get_flags(addr);
> }
> end = host_end;
> }
> ret = mprotect(g2h_untagged(host_start),
> - qemu_host_page_size, prot1 & PAGE_RWX);
> + HOST_PAGE_SIZE, prot1 & PAGE_RWX);
> if (ret != 0)
> goto error;
> - host_start += qemu_host_page_size;
> + host_start += HOST_PAGE_SIZE;
> }
> if (end < host_end) {
> prot1 = prot;
> for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
> prot1 |= page_get_flags(addr);
> }
> - ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
> - qemu_host_page_size, prot1 & PAGE_RWX);
> + ret = mprotect(g2h_untagged(host_end - HOST_PAGE_SIZE),
> + HOST_PAGE_SIZE, prot1 & PAGE_RWX);
> if (ret != 0)
> goto error;
> - host_end -= qemu_host_page_size;
> + host_end -= HOST_PAGE_SIZE;
> }
>
> /* handle the pages in the middle */
> @@ -193,7 +193,7 @@ static int mmap_frag(abi_ulong real_start,
> void *host_start;
> int prot1, prot_new;
>
> - real_end = real_start + qemu_host_page_size;
> + real_end = real_start + HOST_PAGE_SIZE;
> host_start = g2h_untagged(real_start);
>
> /* get the protection of the target pages outside the mapping */
> @@ -205,7 +205,7 @@ static int mmap_frag(abi_ulong real_start,
>
> if (prot1 == 0) {
> /* no page was there, so we allocate one. See also above. */
> - void *p = mmap(host_start, qemu_host_page_size, prot,
> + void *p = mmap(host_start, HOST_PAGE_SIZE, prot,
> flags | ((fd != -1) ? MAP_ANON : 0), -1, 0);
> if (p == MAP_FAILED)
> return -1;
> @@ -223,7 +223,7 @@ static int mmap_frag(abi_ulong real_start,
>
> /* adjust protection to be able to read */
> if (!(prot1 & PROT_WRITE))
> - mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
> + mprotect(host_start, HOST_PAGE_SIZE, prot1 | PROT_WRITE);
>
> /* read the corresponding file data */
> if (!mmap_pread(fd, g2h_untagged(start), end - start, offset, true)) {
> @@ -232,10 +232,10 @@ static int mmap_frag(abi_ulong real_start,
>
> /* put final protection */
> if (prot_new != (prot1 | PROT_WRITE))
> - mprotect(host_start, qemu_host_page_size, prot_new);
> + mprotect(host_start, HOST_PAGE_SIZE, prot_new);
> } else {
> if (prot_new != prot1) {
> - mprotect(host_start, qemu_host_page_size, prot_new);
> + mprotect(host_start, HOST_PAGE_SIZE, prot_new);
> }
> if (prot_new & PROT_WRITE) {
> memset(g2h_untagged(start), 0, end - start);
> @@ -289,7 +289,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
> if (start == 0) {
> start = mmap_next_start;
> } else {
> - start &= qemu_host_page_mask;
> + start &= HOST_PAGE_MASK;
> }
>
> size = HOST_PAGE_ALIGN(size);
> @@ -297,7 +297,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
> if (reserved_va) {
> return mmap_find_vma_reserved(start, size,
> (alignment != 0 ? 1 << alignment :
> - MAX(qemu_host_page_size, TARGET_PAGE_SIZE)));
> + MAX(HOST_PAGE_SIZE, TARGET_PAGE_SIZE)));
> }
>
> addr = start;
> @@ -478,8 +478,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
> goto fail;
> }
>
> - real_start = start & qemu_host_page_mask;
> - host_offset = offset & qemu_host_page_mask;
> + real_start = start & HOST_PAGE_MASK;
> + host_offset = offset & HOST_PAGE_MASK;
>
> /*
> * If the user is asking for the kernel to find a location, do that
> @@ -498,38 +498,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
> }
> }
>
> - /*
> - * When mapping files into a memory area larger than the file, accesses
> - * to pages beyond the file size will cause a SIGBUS.
> - *
> - * For example, if mmaping a file of 100 bytes on a host with 4K pages
> - * emulating a target with 8K pages, the target expects to be able to
> - * access the first 8K. But the host will trap us on any access beyond
> - * 4K.
> - *
> - * When emulating a target with a larger page-size than the hosts, we
> - * may need to truncate file maps at EOF and add extra anonymous pages
> - * up to the targets page boundary.
> - */
> -
> - if ((qemu_real_host_page_size() < qemu_host_page_size) && fd != -1) {
> - struct stat sb;
> -
> - if (fstat(fd, &sb) == -1) {
> - goto fail;
> - }
> -
> - /* Are we trying to create a map beyond EOF?. */
> - if (offset + len > sb.st_size) {
> - /*
> - * If so, truncate the file map at eof aligned with
> - * the hosts real pagesize. Additional anonymous maps
> - * will be created beyond EOF.
> - */
> - len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);
> - }
> - }
> -
> if (!(flags & MAP_FIXED)) {
> unsigned long host_start;
> void *p;
> @@ -539,8 +507,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
>
> /*
> * Note: we prefer to control the mapping address. It is
> - * especially important if qemu_host_page_size >
> - * qemu_real_host_page_size
> + * especially important if HOST_PAGE_SIZE >
> + * TARGET_PAGE_SIZE
> */
> p = mmap(g2h_untagged(start), host_len, prot,
> flags | MAP_FIXED | ((fd != -1) ? MAP_ANON : 0), -1, 0);
> @@ -581,7 +549,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
> * aligned, so we read it
> */
> if (fd != -1 &&
> - (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) {
> + (offset & ~HOST_PAGE_MASK) != (start & ~HOST_PAGE_MASK)) {
> /*
> * msync() won't work here, so we return an error if write is
> * possible while it is a shared mapping
> @@ -614,7 +582,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
>
> /* handle the start of the mapping */
> if (start > real_start) {
> - if (real_end == real_start + qemu_host_page_size) {
> + if (real_end == real_start + HOST_PAGE_SIZE) {
> /* one single host page */
> ret = mmap_frag(real_start, start, end,
> prot, flags, fd, offset);
> @@ -622,21 +590,21 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
> goto fail;
> goto the_end1;
> }
> - ret = mmap_frag(real_start, start, real_start + qemu_host_page_size,
> + ret = mmap_frag(real_start, start, real_start + HOST_PAGE_SIZE,
> prot, flags, fd, offset);
> if (ret == -1)
> goto fail;
> - real_start += qemu_host_page_size;
> + real_start += HOST_PAGE_SIZE;
> }
> /* handle the end of the mapping */
> if (end < real_end) {
> - ret = mmap_frag(real_end - qemu_host_page_size,
> - real_end - qemu_host_page_size, end,
> + ret = mmap_frag(real_end - HOST_PAGE_SIZE,
> + real_end - HOST_PAGE_SIZE, end,
> prot, flags, fd,
> - offset + real_end - qemu_host_page_size - start);
> + offset + real_end - HOST_PAGE_SIZE - start);
> if (ret == -1)
> goto fail;
> - real_end -= qemu_host_page_size;
> + real_end -= HOST_PAGE_SIZE;
> }
>
> /* map the middle (easier) */
> @@ -676,7 +644,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> abi_ulong end;
> int prot;
>
> - real_start = start & qemu_host_page_mask;
> + real_start = start & HOST_PAGE_MASK;
> real_end = HOST_PAGE_ALIGN(start + size);
> end = start + size;
> if (start > real_start) {
> @@ -685,14 +653,14 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
> prot |= page_get_flags(addr);
> }
> - if (real_end == real_start + qemu_host_page_size) {
> + if (real_end == real_start + HOST_PAGE_SIZE) {
> for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
> prot |= page_get_flags(addr);
> }
> end = real_end;
> }
> if (prot != 0) {
> - real_start += qemu_host_page_size;
> + real_start += HOST_PAGE_SIZE;
> }
> }
> if (end < real_end) {
> @@ -701,7 +669,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> prot |= page_get_flags(addr);
> }
> if (prot != 0) {
> - real_end -= qemu_host_page_size;
> + real_end -= HOST_PAGE_SIZE;
> }
> }
> if (real_start != real_end) {
> @@ -727,7 +695,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
> return -EINVAL;
> mmap_lock();
> end = start + len;
> - real_start = start & qemu_host_page_mask;
> + real_start = start & HOST_PAGE_MASK;
> real_end = HOST_PAGE_ALIGN(end);
>
> if (start > real_start) {
> @@ -736,14 +704,14 @@ int target_munmap(abi_ulong start, abi_ulong len)
> for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
> prot |= page_get_flags(addr);
> }
> - if (real_end == real_start + qemu_host_page_size) {
> + if (real_end == real_start + HOST_PAGE_SIZE) {
> for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
> prot |= page_get_flags(addr);
> }
> end = real_end;
> }
> if (prot != 0)
> - real_start += qemu_host_page_size;
> + real_start += HOST_PAGE_SIZE;
> }
> if (end < real_end) {
> prot = 0;
> @@ -751,7 +719,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
> prot |= page_get_flags(addr);
> }
> if (prot != 0)
> - real_end -= qemu_host_page_size;
> + real_end -= HOST_PAGE_SIZE;
> }
>
> ret = 0;
> @@ -784,6 +752,6 @@ int target_msync(abi_ulong start, abi_ulong len, int flags)
> if (end == start)
> return 0;
>
> - start &= qemu_host_page_mask;
> + start &= HOST_PAGE_MASK;
> return msync(g2h_untagged(start), end - start, flags);
> }
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index b0b2c249fb..7553ac154c 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -44,12 +44,10 @@ extern char **environ;
> #include "accel/tcg/vcpu-state.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)
> +
> +#define HOST_PAGE_SIZE MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
> +#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1))
> +#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), HOST_PAGE_SIZE)
>
> /*
> * This struct is used to hold certain information about the image. Basically,
> --
> 2.34.1
>
On Fri, May 1, 2026 at 10:23 AM MOHAMED AYMAN <
mohamedaymanworkspace@gmail.com> wrote:
> Hi Warner and Peter,
>
> Thanks for the review. :)
>
> Here is v2 addressing your comments:
>
> - Fixed the duplicate HOST_PAGE_MASK definition
> - HOST_PAGE_SIZE now uses:
> MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
>
> This preserves correct behavior for cases where the target page size
> exceeds the host page size (e.g. aarch64 16K pages on a 4K amd64 host)
>
> - Updated the commit message to clarify behavior and remove the incorrect
> "No functional change intended" wording
>
> Regarding your question, I am not currently using bsd-user in production;
> this started as a cleanup/contribution effort while working through the
> code.
>
> Thanks again for the feedback.
>
Hi Mohamed,
I was getting ready to create a pull request when I recalled you'd sent
this in. However, it looks
like you didn't attach v2 of the path. Can you please resend it? All that
was here was what appeared
to be an email quoted copy of the first patch.
Thanks a lot!
Warner
> Mohamed Ayman
>
> On Fri, May 1, 2026 at 7:11 PM Mohamed Ayman
> <mohamedaymanworkspace@gmail.com> wrote:
> >
> > The bsd-user implementation previously cached host page size and mask
> > in global variables (qemu_host_page_size and qemu_host_page_mask),
> > which duplicated information already available through
> > qemu_real_host_page_size().
> >
> > This introduced unnecessary global state and potential inconsistencies
> > if the host page size is queried or changes during initialization.
> >
> > Replace all usages of qemu_host_page_size and qemu_host_page_mask with
> > HOST_PAGE_SIZE and HOST_PAGE_MASK macros defined as:
> >
> > MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
> >
> > This preserves the original behavior where the effective host page size
> > is the maximum of the real host page size and the target page size,
> > which matters on targets like aarch64 with 16K pages running on an
> > amd64 host with 4K pages.
> >
> > This also opens the way for renaming qemu_real_host_page_size() to
> > qemu_host_page_size() now that the bsd-user globals no longer occupy
> > that name.
> >
> > Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com>
> > ---
> > bsd-user/elfload.c | 25 ++---------
> > bsd-user/main.c | 14 ++-----
> > bsd-user/mmap.c | 102 ++++++++++++++++-----------------------------
> > bsd-user/qemu.h | 10 ++---
> > 4 files changed, 46 insertions(+), 105 deletions(-)
> >
> > diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
> > index 3bca0cc9ed..00250fc3c1 100644
> > --- a/bsd-user/elfload.c
> > +++ b/bsd-user/elfload.c
> > @@ -192,14 +192,14 @@ static void setup_arg_pages(struct bsd_binprm
> *bprm, struct image_info *info,
> > */
> > size = target_dflssiz;
> > stack_base = TARGET_USRSTACK - size;
> > - addr = target_mmap(stack_base , size + qemu_host_page_size,
> > + addr = target_mmap(stack_base , size + HOST_PAGE_SIZE,
> > PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
> > if (addr == -1) {
> > perror("stk mmap");
> > exit(-1);
> > }
> > /* we reserve one extra page at the top of the stack as guard */
> > - target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
> > + target_mprotect(addr + size, HOST_PAGE_SIZE, PROT_NONE);
> >
> > target_stksiz = size;
> > target_stkbas = addr;
> > @@ -239,27 +239,10 @@ static void padzero(abi_ulong elf_bss, abi_ulong
> last_bss)
> > return;
> > }
> >
> > - /*
> > - * XXX: this is really a hack : if the real host page size is
> > - * smaller than the target page size, some pages after the end
> > - * of the file may not be mapped. A better fix would be to
> > - * patch target_mmap(), but it is more complicated as the file
> > - * size must be known.
> > - */
> > - if (qemu_real_host_page_size() < qemu_host_page_size) {
> > - abi_ulong end_addr, end_addr1;
> > - end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
> > - end_addr = HOST_PAGE_ALIGN(elf_bss);
> > - if (end_addr1 < end_addr) {
> > - mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
> > - PROT_READ | PROT_WRITE | PROT_EXEC,
> > - MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
> > - }
> > - }
> >
> > - nbyte = elf_bss & (qemu_host_page_size - 1);
> > + nbyte = elf_bss & (HOST_PAGE_SIZE - 1);
> > if (nbyte) {
> > - nbyte = qemu_host_page_size - nbyte;
> > + nbyte = HOST_PAGE_SIZE - nbyte;
> > do {
> > /* FIXME - what to do if put_user() fails? */
> > put_user_u8(0, elf_bss);
> > diff --git a/bsd-user/main.c b/bsd-user/main.c
> > index 73aae8c327..3f5141e794 100644
> > --- a/bsd-user/main.c
> > +++ b/bsd-user/main.c
> > @@ -54,11 +54,6 @@
> > #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;
> > static unsigned long opt_tb_size;
> > @@ -302,8 +297,6 @@ 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;
> >
> > @@ -405,7 +398,6 @@ int main(int argc, char **argv)
> > }
> > }
> >
> > - qemu_host_page_mask = -qemu_host_page_size;
> >
> > /* init debug */
> > {
> > @@ -452,7 +444,7 @@ int main(int argc, char **argv)
> >
> > 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);
> > @@ -534,7 +526,7 @@ int main(int argc, char **argv)
> > * proper page alignment for guest_base.
> > */
> > if (have_guest_base) {
> > - if (guest_base & ~qemu_host_page_mask) {
> > + if (guest_base & ~HOST_PAGE_MASK) {
> > error_report("Selected guest base not host page aligned");
> > exit(1);
> > }
> > @@ -573,7 +565,7 @@ int main(int argc, char **argv)
> > /* Ensure that mmap_next_start is within range. */
> > if (reserved_va <= mmap_next_start) {
> > mmap_next_start = (reserved_va / 4 * 3)
> > - & TARGET_PAGE_MASK & qemu_host_page_mask;
> > + & TARGET_PAGE_MASK & HOST_PAGE_MASK;
> > }
> > }
> >
> > diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
> > index fe77eceb48..59c70083a4 100644
> > --- a/bsd-user/mmap.c
> > +++ b/bsd-user/mmap.c
> > @@ -84,7 +84,7 @@ int target_mprotect(abi_ulong start, abi_ulong len,
> int prot)
> > return 0;
> >
> > mmap_lock();
> > - host_start = start & qemu_host_page_mask;
> > + host_start = start & HOST_PAGE_MASK;
> > host_end = HOST_PAGE_ALIGN(end);
> > if (start > host_start) {
> > /* handle host page containing start */
> > @@ -92,28 +92,28 @@ int target_mprotect(abi_ulong start, abi_ulong len,
> int prot)
> > for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE)
> {
> > prot1 |= page_get_flags(addr);
> > }
> > - if (host_end == host_start + qemu_host_page_size) {
> > + if (host_end == host_start + HOST_PAGE_SIZE) {
> > for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE)
> {
> > prot1 |= page_get_flags(addr);
> > }
> > end = host_end;
> > }
> > ret = mprotect(g2h_untagged(host_start),
> > - qemu_host_page_size, prot1 & PAGE_RWX);
> > + HOST_PAGE_SIZE, prot1 & PAGE_RWX);
> > if (ret != 0)
> > goto error;
> > - host_start += qemu_host_page_size;
> > + host_start += HOST_PAGE_SIZE;
> > }
> > if (end < host_end) {
> > prot1 = prot;
> > for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
> > prot1 |= page_get_flags(addr);
> > }
> > - ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
> > - qemu_host_page_size, prot1 & PAGE_RWX);
> > + ret = mprotect(g2h_untagged(host_end - HOST_PAGE_SIZE),
> > + HOST_PAGE_SIZE, prot1 & PAGE_RWX);
> > if (ret != 0)
> > goto error;
> > - host_end -= qemu_host_page_size;
> > + host_end -= HOST_PAGE_SIZE;
> > }
> >
> > /* handle the pages in the middle */
> > @@ -193,7 +193,7 @@ static int mmap_frag(abi_ulong real_start,
> > void *host_start;
> > int prot1, prot_new;
> >
> > - real_end = real_start + qemu_host_page_size;
> > + real_end = real_start + HOST_PAGE_SIZE;
> > host_start = g2h_untagged(real_start);
> >
> > /* get the protection of the target pages outside the mapping */
> > @@ -205,7 +205,7 @@ static int mmap_frag(abi_ulong real_start,
> >
> > if (prot1 == 0) {
> > /* no page was there, so we allocate one. See also above. */
> > - void *p = mmap(host_start, qemu_host_page_size, prot,
> > + void *p = mmap(host_start, HOST_PAGE_SIZE, prot,
> > flags | ((fd != -1) ? MAP_ANON : 0), -1, 0);
> > if (p == MAP_FAILED)
> > return -1;
> > @@ -223,7 +223,7 @@ static int mmap_frag(abi_ulong real_start,
> >
> > /* adjust protection to be able to read */
> > if (!(prot1 & PROT_WRITE))
> > - mprotect(host_start, qemu_host_page_size, prot1 |
> PROT_WRITE);
> > + mprotect(host_start, HOST_PAGE_SIZE, prot1 | PROT_WRITE);
> >
> > /* read the corresponding file data */
> > if (!mmap_pread(fd, g2h_untagged(start), end - start, offset,
> true)) {
> > @@ -232,10 +232,10 @@ static int mmap_frag(abi_ulong real_start,
> >
> > /* put final protection */
> > if (prot_new != (prot1 | PROT_WRITE))
> > - mprotect(host_start, qemu_host_page_size, prot_new);
> > + mprotect(host_start, HOST_PAGE_SIZE, prot_new);
> > } else {
> > if (prot_new != prot1) {
> > - mprotect(host_start, qemu_host_page_size, prot_new);
> > + mprotect(host_start, HOST_PAGE_SIZE, prot_new);
> > }
> > if (prot_new & PROT_WRITE) {
> > memset(g2h_untagged(start), 0, end - start);
> > @@ -289,7 +289,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong
> size, abi_ulong alignment)
> > if (start == 0) {
> > start = mmap_next_start;
> > } else {
> > - start &= qemu_host_page_mask;
> > + start &= HOST_PAGE_MASK;
> > }
> >
> > size = HOST_PAGE_ALIGN(size);
> > @@ -297,7 +297,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong
> size, abi_ulong alignment)
> > if (reserved_va) {
> > return mmap_find_vma_reserved(start, size,
> > (alignment != 0 ? 1 << alignment :
> > - MAX(qemu_host_page_size, TARGET_PAGE_SIZE)));
> > + MAX(HOST_PAGE_SIZE, TARGET_PAGE_SIZE)));
> > }
> >
> > addr = start;
> > @@ -478,8 +478,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
> > goto fail;
> > }
> >
> > - real_start = start & qemu_host_page_mask;
> > - host_offset = offset & qemu_host_page_mask;
> > + real_start = start & HOST_PAGE_MASK;
> > + host_offset = offset & HOST_PAGE_MASK;
> >
> > /*
> > * If the user is asking for the kernel to find a location, do that
> > @@ -498,38 +498,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong
> len, int prot,
> > }
> > }
> >
> > - /*
> > - * When mapping files into a memory area larger than the file,
> accesses
> > - * to pages beyond the file size will cause a SIGBUS.
> > - *
> > - * For example, if mmaping a file of 100 bytes on a host with 4K
> pages
> > - * emulating a target with 8K pages, the target expects to be able
> to
> > - * access the first 8K. But the host will trap us on any access
> beyond
> > - * 4K.
> > - *
> > - * When emulating a target with a larger page-size than the hosts,
> we
> > - * may need to truncate file maps at EOF and add extra anonymous
> pages
> > - * up to the targets page boundary.
> > - */
> > -
> > - if ((qemu_real_host_page_size() < qemu_host_page_size) && fd != -1)
> {
> > - struct stat sb;
> > -
> > - if (fstat(fd, &sb) == -1) {
> > - goto fail;
> > - }
> > -
> > - /* Are we trying to create a map beyond EOF?. */
> > - if (offset + len > sb.st_size) {
> > - /*
> > - * If so, truncate the file map at eof aligned with
> > - * the hosts real pagesize. Additional anonymous maps
> > - * will be created beyond EOF.
> > - */
> > - len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);
> > - }
> > - }
> > -
> > if (!(flags & MAP_FIXED)) {
> > unsigned long host_start;
> > void *p;
> > @@ -539,8 +507,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
> >
> > /*
> > * Note: we prefer to control the mapping address. It is
> > - * especially important if qemu_host_page_size >
> > - * qemu_real_host_page_size
> > + * especially important if HOST_PAGE_SIZE >
> > + * TARGET_PAGE_SIZE
> > */
> > p = mmap(g2h_untagged(start), host_len, prot,
> > flags | MAP_FIXED | ((fd != -1) ? MAP_ANON : 0), -1,
> 0);
> > @@ -581,7 +549,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
> > * aligned, so we read it
> > */
> > if (fd != -1 &&
> > - (offset & ~qemu_host_page_mask) != (start &
> ~qemu_host_page_mask)) {
> > + (offset & ~HOST_PAGE_MASK) != (start & ~HOST_PAGE_MASK)) {
> > /*
> > * msync() won't work here, so we return an error if write
> is
> > * possible while it is a shared mapping
> > @@ -614,7 +582,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len,
> int prot,
> >
> > /* handle the start of the mapping */
> > if (start > real_start) {
> > - if (real_end == real_start + qemu_host_page_size) {
> > + if (real_end == real_start + HOST_PAGE_SIZE) {
> > /* one single host page */
> > ret = mmap_frag(real_start, start, end,
> > prot, flags, fd, offset);
> > @@ -622,21 +590,21 @@ abi_long target_mmap(abi_ulong start, abi_ulong
> len, int prot,
> > goto fail;
> > goto the_end1;
> > }
> > - ret = mmap_frag(real_start, start, real_start +
> qemu_host_page_size,
> > + ret = mmap_frag(real_start, start, real_start +
> HOST_PAGE_SIZE,
> > prot, flags, fd, offset);
> > if (ret == -1)
> > goto fail;
> > - real_start += qemu_host_page_size;
> > + real_start += HOST_PAGE_SIZE;
> > }
> > /* handle the end of the mapping */
> > if (end < real_end) {
> > - ret = mmap_frag(real_end - qemu_host_page_size,
> > - real_end - qemu_host_page_size, end,
> > + ret = mmap_frag(real_end - HOST_PAGE_SIZE,
> > + real_end - HOST_PAGE_SIZE, end,
> > prot, flags, fd,
> > - offset + real_end - qemu_host_page_size -
> start);
> > + offset + real_end - HOST_PAGE_SIZE - start);
> > if (ret == -1)
> > goto fail;
> > - real_end -= qemu_host_page_size;
> > + real_end -= HOST_PAGE_SIZE;
> > }
> >
> > /* map the middle (easier) */
> > @@ -676,7 +644,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> > abi_ulong end;
> > int prot;
> >
> > - real_start = start & qemu_host_page_mask;
> > + real_start = start & HOST_PAGE_MASK;
> > real_end = HOST_PAGE_ALIGN(start + size);
> > end = start + size;
> > if (start > real_start) {
> > @@ -685,14 +653,14 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> > for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE)
> {
> > prot |= page_get_flags(addr);
> > }
> > - if (real_end == real_start + qemu_host_page_size) {
> > + if (real_end == real_start + HOST_PAGE_SIZE) {
> > for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE)
> {
> > prot |= page_get_flags(addr);
> > }
> > end = real_end;
> > }
> > if (prot != 0) {
> > - real_start += qemu_host_page_size;
> > + real_start += HOST_PAGE_SIZE;
> > }
> > }
> > if (end < real_end) {
> > @@ -701,7 +669,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
> > prot |= page_get_flags(addr);
> > }
> > if (prot != 0) {
> > - real_end -= qemu_host_page_size;
> > + real_end -= HOST_PAGE_SIZE;
> > }
> > }
> > if (real_start != real_end) {
> > @@ -727,7 +695,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
> > return -EINVAL;
> > mmap_lock();
> > end = start + len;
> > - real_start = start & qemu_host_page_mask;
> > + real_start = start & HOST_PAGE_MASK;
> > real_end = HOST_PAGE_ALIGN(end);
> >
> > if (start > real_start) {
> > @@ -736,14 +704,14 @@ int target_munmap(abi_ulong start, abi_ulong len)
> > for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE)
> {
> > prot |= page_get_flags(addr);
> > }
> > - if (real_end == real_start + qemu_host_page_size) {
> > + if (real_end == real_start + HOST_PAGE_SIZE) {
> > for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE)
> {
> > prot |= page_get_flags(addr);
> > }
> > end = real_end;
> > }
> > if (prot != 0)
> > - real_start += qemu_host_page_size;
> > + real_start += HOST_PAGE_SIZE;
> > }
> > if (end < real_end) {
> > prot = 0;
> > @@ -751,7 +719,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
> > prot |= page_get_flags(addr);
> > }
> > if (prot != 0)
> > - real_end -= qemu_host_page_size;
> > + real_end -= HOST_PAGE_SIZE;
> > }
> >
> > ret = 0;
> > @@ -784,6 +752,6 @@ int target_msync(abi_ulong start, abi_ulong len, int
> flags)
> > if (end == start)
> > return 0;
> >
> > - start &= qemu_host_page_mask;
> > + start &= HOST_PAGE_MASK;
> > return msync(g2h_untagged(start), end - start, flags);
> > }
> > diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> > index b0b2c249fb..7553ac154c 100644
> > --- a/bsd-user/qemu.h
> > +++ b/bsd-user/qemu.h
> > @@ -44,12 +44,10 @@ extern char **environ;
> > #include "accel/tcg/vcpu-state.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)
> > +
> > +#define HOST_PAGE_SIZE MAX(qemu_real_host_page_size(),
> TARGET_PAGE_SIZE)
> > +#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1))
> > +#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), HOST_PAGE_SIZE)
> >
> > /*
> > * This struct is used to hold certain information about the image.
> Basically,
> > --
> > 2.34.1
> >
>
Hi Warner,
Apologies for the missing patch, This is v2 of the patch.
Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com>
---
bsd-user/elfload.c | 25 ++---------
bsd-user/main.c | 14 ++-----
bsd-user/mmap.c | 102 ++++++++++++++++-----------------------------
bsd-user/qemu.h | 10 ++---
4 files changed, 46 insertions(+), 105 deletions(-)
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 3bca0cc9ed..00250fc3c1 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -192,14 +192,14 @@ static void setup_arg_pages(struct bsd_binprm
*bprm, struct image_info *info,
*/
size = target_dflssiz;
stack_base = TARGET_USRSTACK - size;
- addr = target_mmap(stack_base , size + qemu_host_page_size,
+ addr = target_mmap(stack_base , size + HOST_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (addr == -1) {
perror("stk mmap");
exit(-1);
}
/* we reserve one extra page at the top of the stack as guard */
- target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
+ target_mprotect(addr + size, HOST_PAGE_SIZE, PROT_NONE);
target_stksiz = size;
target_stkbas = addr;
@@ -239,27 +239,10 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
return;
}
- /*
- * XXX: this is really a hack : if the real host page size is
- * smaller than the target page size, some pages after the end
- * of the file may not be mapped. A better fix would be to
- * patch target_mmap(), but it is more complicated as the file
- * size must be known.
- */
- if (qemu_real_host_page_size() < qemu_host_page_size) {
- abi_ulong end_addr, end_addr1;
- end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
- end_addr = HOST_PAGE_ALIGN(elf_bss);
- if (end_addr1 < end_addr) {
- mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
- }
- }
- nbyte = elf_bss & (qemu_host_page_size - 1);
+ nbyte = elf_bss & (HOST_PAGE_SIZE - 1);
if (nbyte) {
- nbyte = qemu_host_page_size - nbyte;
+ nbyte = HOST_PAGE_SIZE - nbyte;
do {
/* FIXME - what to do if put_user() fails? */
put_user_u8(0, elf_bss);
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 73aae8c327..3f5141e794 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -54,11 +54,6 @@
#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;
static unsigned long opt_tb_size;
@@ -302,8 +297,6 @@ 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;
@@ -405,7 +398,6 @@ int main(int argc, char **argv)
}
}
- qemu_host_page_mask = -qemu_host_page_size;
/* init debug */
{
@@ -452,7 +444,7 @@ int main(int argc, char **argv)
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);
@@ -534,7 +526,7 @@ int main(int argc, char **argv)
* proper page alignment for guest_base.
*/
if (have_guest_base) {
- if (guest_base & ~qemu_host_page_mask) {
+ if (guest_base & ~HOST_PAGE_MASK) {
error_report("Selected guest base not host page aligned");
exit(1);
}
@@ -573,7 +565,7 @@ int main(int argc, char **argv)
/* Ensure that mmap_next_start is within range. */
if (reserved_va <= mmap_next_start) {
mmap_next_start = (reserved_va / 4 * 3)
- & TARGET_PAGE_MASK & qemu_host_page_mask;
+ & TARGET_PAGE_MASK & HOST_PAGE_MASK;
}
}
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index fe77eceb48..59c70083a4 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -84,7 +84,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
return 0;
mmap_lock();
- host_start = start & qemu_host_page_mask;
+ host_start = start & HOST_PAGE_MASK;
host_end = HOST_PAGE_ALIGN(end);
if (start > host_start) {
/* handle host page containing start */
@@ -92,28 +92,28 @@ int target_mprotect(abi_ulong start, abi_ulong
len, int prot)
for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- if (host_end == host_start + qemu_host_page_size) {
+ if (host_end == host_start + HOST_PAGE_SIZE) {
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
end = host_end;
}
ret = mprotect(g2h_untagged(host_start),
- qemu_host_page_size, prot1 & PAGE_RWX);
+ HOST_PAGE_SIZE, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
- host_start += qemu_host_page_size;
+ host_start += HOST_PAGE_SIZE;
}
if (end < host_end) {
prot1 = prot;
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
- qemu_host_page_size, prot1 & PAGE_RWX);
+ ret = mprotect(g2h_untagged(host_end - HOST_PAGE_SIZE),
+ HOST_PAGE_SIZE, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
- host_end -= qemu_host_page_size;
+ host_end -= HOST_PAGE_SIZE;
}
/* handle the pages in the middle */
@@ -193,7 +193,7 @@ static int mmap_frag(abi_ulong real_start,
void *host_start;
int prot1, prot_new;
- real_end = real_start + qemu_host_page_size;
+ real_end = real_start + HOST_PAGE_SIZE;
host_start = g2h_untagged(real_start);
/* get the protection of the target pages outside the mapping */
@@ -205,7 +205,7 @@ static int mmap_frag(abi_ulong real_start,
if (prot1 == 0) {
/* no page was there, so we allocate one. See also above. */
- void *p = mmap(host_start, qemu_host_page_size, prot,
+ void *p = mmap(host_start, HOST_PAGE_SIZE, prot,
flags | ((fd != -1) ? MAP_ANON : 0), -1, 0);
if (p == MAP_FAILED)
return -1;
@@ -223,7 +223,7 @@ static int mmap_frag(abi_ulong real_start,
/* adjust protection to be able to read */
if (!(prot1 & PROT_WRITE))
- mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
+ mprotect(host_start, HOST_PAGE_SIZE, prot1 | PROT_WRITE);
/* read the corresponding file data */
if (!mmap_pread(fd, g2h_untagged(start), end - start, offset, true)) {
@@ -232,10 +232,10 @@ static int mmap_frag(abi_ulong real_start,
/* put final protection */
if (prot_new != (prot1 | PROT_WRITE))
- mprotect(host_start, qemu_host_page_size, prot_new);
+ mprotect(host_start, HOST_PAGE_SIZE, prot_new);
} else {
if (prot_new != prot1) {
- mprotect(host_start, qemu_host_page_size, prot_new);
+ mprotect(host_start, HOST_PAGE_SIZE, prot_new);
}
if (prot_new & PROT_WRITE) {
memset(g2h_untagged(start), 0, end - start);
@@ -289,7 +289,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong
size, abi_ulong alignment)
if (start == 0) {
start = mmap_next_start;
} else {
- start &= qemu_host_page_mask;
+ start &= HOST_PAGE_MASK;
}
size = HOST_PAGE_ALIGN(size);
@@ -297,7 +297,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong
size, abi_ulong alignment)
if (reserved_va) {
return mmap_find_vma_reserved(start, size,
(alignment != 0 ? 1 << alignment :
- MAX(qemu_host_page_size, TARGET_PAGE_SIZE)));
+ MAX(HOST_PAGE_SIZE, TARGET_PAGE_SIZE)));
}
addr = start;
@@ -478,8 +478,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong
len, int prot,
goto fail;
}
- real_start = start & qemu_host_page_mask;
- host_offset = offset & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
+ host_offset = offset & HOST_PAGE_MASK;
/*
* If the user is asking for the kernel to find a location, do that
@@ -498,38 +498,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong
len, int prot,
}
}
- /*
- * When mapping files into a memory area larger than the file, accesses
- * to pages beyond the file size will cause a SIGBUS.
- *
- * For example, if mmaping a file of 100 bytes on a host with 4K pages
- * emulating a target with 8K pages, the target expects to be able to
- * access the first 8K. But the host will trap us on any access beyond
- * 4K.
- *
- * When emulating a target with a larger page-size than the hosts, we
- * may need to truncate file maps at EOF and add extra anonymous pages
- * up to the targets page boundary.
- */
-
- if ((qemu_real_host_page_size() < qemu_host_page_size) && fd != -1) {
- struct stat sb;
-
- if (fstat(fd, &sb) == -1) {
- goto fail;
- }
-
- /* Are we trying to create a map beyond EOF?. */
- if (offset + len > sb.st_size) {
- /*
- * If so, truncate the file map at eof aligned with
- * the hosts real pagesize. Additional anonymous maps
- * will be created beyond EOF.
- */
- len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);
- }
- }
-
if (!(flags & MAP_FIXED)) {
unsigned long host_start;
void *p;
@@ -539,8 +507,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong
len, int prot,
/*
* Note: we prefer to control the mapping address. It is
- * especially important if qemu_host_page_size >
- * qemu_real_host_page_size
+ * especially important if HOST_PAGE_SIZE >
+ * TARGET_PAGE_SIZE
*/
p = mmap(g2h_untagged(start), host_len, prot,
flags | MAP_FIXED | ((fd != -1) ? MAP_ANON : 0), -1, 0);
@@ -581,7 +549,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong
len, int prot,
* aligned, so we read it
*/
if (fd != -1 &&
- (offset & ~qemu_host_page_mask) != (start &
~qemu_host_page_mask)) {
+ (offset & ~HOST_PAGE_MASK) != (start & ~HOST_PAGE_MASK)) {
/*
* msync() won't work here, so we return an error if write is
* possible while it is a shared mapping
@@ -614,7 +582,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong
len, int prot,
/* handle the start of the mapping */
if (start > real_start) {
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
/* one single host page */
ret = mmap_frag(real_start, start, end,
prot, flags, fd, offset);
@@ -622,21 +590,21 @@ abi_long target_mmap(abi_ulong start, abi_ulong
len, int prot,
goto fail;
goto the_end1;
}
- ret = mmap_frag(real_start, start, real_start +
qemu_host_page_size,
+ ret = mmap_frag(real_start, start, real_start + HOST_PAGE_SIZE,
prot, flags, fd, offset);
if (ret == -1)
goto fail;
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
/* handle the end of the mapping */
if (end < real_end) {
- ret = mmap_frag(real_end - qemu_host_page_size,
- real_end - qemu_host_page_size, end,
+ ret = mmap_frag(real_end - HOST_PAGE_SIZE,
+ real_end - HOST_PAGE_SIZE, end,
prot, flags, fd,
- offset + real_end - qemu_host_page_size - start);
+ offset + real_end - HOST_PAGE_SIZE - start);
if (ret == -1)
goto fail;
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
/* map the middle (easier) */
@@ -676,7 +644,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
abi_ulong end;
int prot;
- real_start = start & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
real_end = HOST_PAGE_ALIGN(start + size);
end = start + size;
if (start > real_start) {
@@ -685,14 +653,14 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
end = real_end;
}
if (prot != 0) {
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
}
if (end < real_end) {
@@ -701,7 +669,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
prot |= page_get_flags(addr);
}
if (prot != 0) {
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
}
if (real_start != real_end) {
@@ -727,7 +695,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
return -EINVAL;
mmap_lock();
end = start + len;
- real_start = start & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
real_end = HOST_PAGE_ALIGN(end);
if (start > real_start) {
@@ -736,14 +704,14 @@ int target_munmap(abi_ulong start, abi_ulong len)
for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
end = real_end;
}
if (prot != 0)
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
if (end < real_end) {
prot = 0;
@@ -751,7 +719,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
prot |= page_get_flags(addr);
}
if (prot != 0)
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
ret = 0;
@@ -784,6 +752,6 @@ int target_msync(abi_ulong start, abi_ulong len, int flags)
if (end == start)
return 0;
- start &= qemu_host_page_mask;
+ start &= HOST_PAGE_MASK;
return msync(g2h_untagged(start), end - start, flags);
}
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index b0b2c249fb..7553ac154c 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -44,12 +44,10 @@ extern char **environ;
#include "accel/tcg/vcpu-state.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)
+
+#define HOST_PAGE_SIZE MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
+#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1))
+#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), HOST_PAGE_SIZE)
/*
* This struct is used to hold certain information about the image. Basically,
--
2.34.1
Fix duplicate HOST_PAGE_MASK definition and replace all remaining uses
of qemu_host_page_size/qemu_host_page_mask with HOST_PAGE_SIZE/HOST_PAGE_MASK.
HOST_PAGE_SIZE is now defined as:
MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
This preserves correct behavior when the target page size exceeds the
host page size (e.g. aarch64 16K pages on a 4K amd64 host).
Signed-off-by: Mohamed Ayman <mohamedaymanworkspace@gmail.com>
---
bsd-user/elfload.c | 25 ++---------
bsd-user/main.c | 14 ++-----
bsd-user/mmap.c | 102 ++++++++++++++++-----------------------------
bsd-user/qemu.h | 10 ++---
4 files changed, 46 insertions(+), 105 deletions(-)
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 3bca0cc9ed..00250fc3c1 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -192,14 +192,14 @@ static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
*/
size = target_dflssiz;
stack_base = TARGET_USRSTACK - size;
- addr = target_mmap(stack_base , size + qemu_host_page_size,
+ addr = target_mmap(stack_base , size + HOST_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (addr == -1) {
perror("stk mmap");
exit(-1);
}
/* we reserve one extra page at the top of the stack as guard */
- target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
+ target_mprotect(addr + size, HOST_PAGE_SIZE, PROT_NONE);
target_stksiz = size;
target_stkbas = addr;
@@ -239,27 +239,10 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
return;
}
- /*
- * XXX: this is really a hack : if the real host page size is
- * smaller than the target page size, some pages after the end
- * of the file may not be mapped. A better fix would be to
- * patch target_mmap(), but it is more complicated as the file
- * size must be known.
- */
- if (qemu_real_host_page_size() < qemu_host_page_size) {
- abi_ulong end_addr, end_addr1;
- end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
- end_addr = HOST_PAGE_ALIGN(elf_bss);
- if (end_addr1 < end_addr) {
- mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
- }
- }
- nbyte = elf_bss & (qemu_host_page_size - 1);
+ nbyte = elf_bss & (HOST_PAGE_SIZE - 1);
if (nbyte) {
- nbyte = qemu_host_page_size - nbyte;
+ nbyte = HOST_PAGE_SIZE - nbyte;
do {
/* FIXME - what to do if put_user() fails? */
put_user_u8(0, elf_bss);
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 73aae8c327..3f5141e794 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -54,11 +54,6 @@
#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;
static unsigned long opt_tb_size;
@@ -302,8 +297,6 @@ 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;
@@ -405,7 +398,6 @@ int main(int argc, char **argv)
}
}
- qemu_host_page_mask = -qemu_host_page_size;
/* init debug */
{
@@ -452,7 +444,7 @@ int main(int argc, char **argv)
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);
@@ -534,7 +526,7 @@ int main(int argc, char **argv)
* proper page alignment for guest_base.
*/
if (have_guest_base) {
- if (guest_base & ~qemu_host_page_mask) {
+ if (guest_base & ~HOST_PAGE_MASK) {
error_report("Selected guest base not host page aligned");
exit(1);
}
@@ -573,7 +565,7 @@ int main(int argc, char **argv)
/* Ensure that mmap_next_start is within range. */
if (reserved_va <= mmap_next_start) {
mmap_next_start = (reserved_va / 4 * 3)
- & TARGET_PAGE_MASK & qemu_host_page_mask;
+ & TARGET_PAGE_MASK & HOST_PAGE_MASK;
}
}
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index fe77eceb48..59c70083a4 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -84,7 +84,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
return 0;
mmap_lock();
- host_start = start & qemu_host_page_mask;
+ host_start = start & HOST_PAGE_MASK;
host_end = HOST_PAGE_ALIGN(end);
if (start > host_start) {
/* handle host page containing start */
@@ -92,28 +92,28 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- if (host_end == host_start + qemu_host_page_size) {
+ if (host_end == host_start + HOST_PAGE_SIZE) {
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
end = host_end;
}
ret = mprotect(g2h_untagged(host_start),
- qemu_host_page_size, prot1 & PAGE_RWX);
+ HOST_PAGE_SIZE, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
- host_start += qemu_host_page_size;
+ host_start += HOST_PAGE_SIZE;
}
if (end < host_end) {
prot1 = prot;
for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
- qemu_host_page_size, prot1 & PAGE_RWX);
+ ret = mprotect(g2h_untagged(host_end - HOST_PAGE_SIZE),
+ HOST_PAGE_SIZE, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
- host_end -= qemu_host_page_size;
+ host_end -= HOST_PAGE_SIZE;
}
/* handle the pages in the middle */
@@ -193,7 +193,7 @@ static int mmap_frag(abi_ulong real_start,
void *host_start;
int prot1, prot_new;
- real_end = real_start + qemu_host_page_size;
+ real_end = real_start + HOST_PAGE_SIZE;
host_start = g2h_untagged(real_start);
/* get the protection of the target pages outside the mapping */
@@ -205,7 +205,7 @@ static int mmap_frag(abi_ulong real_start,
if (prot1 == 0) {
/* no page was there, so we allocate one. See also above. */
- void *p = mmap(host_start, qemu_host_page_size, prot,
+ void *p = mmap(host_start, HOST_PAGE_SIZE, prot,
flags | ((fd != -1) ? MAP_ANON : 0), -1, 0);
if (p == MAP_FAILED)
return -1;
@@ -223,7 +223,7 @@ static int mmap_frag(abi_ulong real_start,
/* adjust protection to be able to read */
if (!(prot1 & PROT_WRITE))
- mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
+ mprotect(host_start, HOST_PAGE_SIZE, prot1 | PROT_WRITE);
/* read the corresponding file data */
if (!mmap_pread(fd, g2h_untagged(start), end - start, offset, true)) {
@@ -232,10 +232,10 @@ static int mmap_frag(abi_ulong real_start,
/* put final protection */
if (prot_new != (prot1 | PROT_WRITE))
- mprotect(host_start, qemu_host_page_size, prot_new);
+ mprotect(host_start, HOST_PAGE_SIZE, prot_new);
} else {
if (prot_new != prot1) {
- mprotect(host_start, qemu_host_page_size, prot_new);
+ mprotect(host_start, HOST_PAGE_SIZE, prot_new);
}
if (prot_new & PROT_WRITE) {
memset(g2h_untagged(start), 0, end - start);
@@ -289,7 +289,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
if (start == 0) {
start = mmap_next_start;
} else {
- start &= qemu_host_page_mask;
+ start &= HOST_PAGE_MASK;
}
size = HOST_PAGE_ALIGN(size);
@@ -297,7 +297,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
if (reserved_va) {
return mmap_find_vma_reserved(start, size,
(alignment != 0 ? 1 << alignment :
- MAX(qemu_host_page_size, TARGET_PAGE_SIZE)));
+ MAX(HOST_PAGE_SIZE, TARGET_PAGE_SIZE)));
}
addr = start;
@@ -478,8 +478,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
goto fail;
}
- real_start = start & qemu_host_page_mask;
- host_offset = offset & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
+ host_offset = offset & HOST_PAGE_MASK;
/*
* If the user is asking for the kernel to find a location, do that
@@ -498,38 +498,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
}
}
- /*
- * When mapping files into a memory area larger than the file, accesses
- * to pages beyond the file size will cause a SIGBUS.
- *
- * For example, if mmaping a file of 100 bytes on a host with 4K pages
- * emulating a target with 8K pages, the target expects to be able to
- * access the first 8K. But the host will trap us on any access beyond
- * 4K.
- *
- * When emulating a target with a larger page-size than the hosts, we
- * may need to truncate file maps at EOF and add extra anonymous pages
- * up to the targets page boundary.
- */
-
- if ((qemu_real_host_page_size() < qemu_host_page_size) && fd != -1) {
- struct stat sb;
-
- if (fstat(fd, &sb) == -1) {
- goto fail;
- }
-
- /* Are we trying to create a map beyond EOF?. */
- if (offset + len > sb.st_size) {
- /*
- * If so, truncate the file map at eof aligned with
- * the hosts real pagesize. Additional anonymous maps
- * will be created beyond EOF.
- */
- len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);
- }
- }
-
if (!(flags & MAP_FIXED)) {
unsigned long host_start;
void *p;
@@ -539,8 +507,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
/*
* Note: we prefer to control the mapping address. It is
- * especially important if qemu_host_page_size >
- * qemu_real_host_page_size
+ * especially important if HOST_PAGE_SIZE >
+ * TARGET_PAGE_SIZE
*/
p = mmap(g2h_untagged(start), host_len, prot,
flags | MAP_FIXED | ((fd != -1) ? MAP_ANON : 0), -1, 0);
@@ -581,7 +549,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
* aligned, so we read it
*/
if (fd != -1 &&
- (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) {
+ (offset & ~HOST_PAGE_MASK) != (start & ~HOST_PAGE_MASK)) {
/*
* msync() won't work here, so we return an error if write is
* possible while it is a shared mapping
@@ -614,7 +582,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
/* handle the start of the mapping */
if (start > real_start) {
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
/* one single host page */
ret = mmap_frag(real_start, start, end,
prot, flags, fd, offset);
@@ -622,21 +590,21 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
goto fail;
goto the_end1;
}
- ret = mmap_frag(real_start, start, real_start + qemu_host_page_size,
+ ret = mmap_frag(real_start, start, real_start + HOST_PAGE_SIZE,
prot, flags, fd, offset);
if (ret == -1)
goto fail;
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
/* handle the end of the mapping */
if (end < real_end) {
- ret = mmap_frag(real_end - qemu_host_page_size,
- real_end - qemu_host_page_size, end,
+ ret = mmap_frag(real_end - HOST_PAGE_SIZE,
+ real_end - HOST_PAGE_SIZE, end,
prot, flags, fd,
- offset + real_end - qemu_host_page_size - start);
+ offset + real_end - HOST_PAGE_SIZE - start);
if (ret == -1)
goto fail;
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
/* map the middle (easier) */
@@ -676,7 +644,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
abi_ulong end;
int prot;
- real_start = start & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
real_end = HOST_PAGE_ALIGN(start + size);
end = start + size;
if (start > real_start) {
@@ -685,14 +653,14 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
end = real_end;
}
if (prot != 0) {
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
}
if (end < real_end) {
@@ -701,7 +669,7 @@ void mmap_reserve(abi_ulong start, abi_ulong size)
prot |= page_get_flags(addr);
}
if (prot != 0) {
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
}
if (real_start != real_end) {
@@ -727,7 +695,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
return -EINVAL;
mmap_lock();
end = start + len;
- real_start = start & qemu_host_page_mask;
+ real_start = start & HOST_PAGE_MASK;
real_end = HOST_PAGE_ALIGN(end);
if (start > real_start) {
@@ -736,14 +704,14 @@ int target_munmap(abi_ulong start, abi_ulong len)
for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
- if (real_end == real_start + qemu_host_page_size) {
+ if (real_end == real_start + HOST_PAGE_SIZE) {
for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr);
}
end = real_end;
}
if (prot != 0)
- real_start += qemu_host_page_size;
+ real_start += HOST_PAGE_SIZE;
}
if (end < real_end) {
prot = 0;
@@ -751,7 +719,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
prot |= page_get_flags(addr);
}
if (prot != 0)
- real_end -= qemu_host_page_size;
+ real_end -= HOST_PAGE_SIZE;
}
ret = 0;
@@ -784,6 +752,6 @@ int target_msync(abi_ulong start, abi_ulong len, int flags)
if (end == start)
return 0;
- start &= qemu_host_page_mask;
+ start &= HOST_PAGE_MASK;
return msync(g2h_untagged(start), end - start, flags);
}
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index b0b2c249fb..7553ac154c 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -44,12 +44,10 @@ extern char **environ;
#include "accel/tcg/vcpu-state.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)
+
+#define HOST_PAGE_SIZE MAX(qemu_real_host_page_size(), TARGET_PAGE_SIZE)
+#define HOST_PAGE_MASK ((intptr_t)~(HOST_PAGE_SIZE - 1))
+#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), HOST_PAGE_SIZE)
/*
* This struct is used to hold certain information about the image. Basically,
--
2.34.1
© 2016 - 2026 Red Hat, Inc.