linux-user: Use PGBRange for commpage
This simplifies check for no commpage to a NULL pointer check, rather than reserved values for LO_COMMPAGE and HI_COMMPAGE. Unify {LO,HI}_COMMPAGE into a single COMMPAGE define. Acked-by: Warner Losh <imp@bsdimp.com> Tested-by: Helge Deller <deller@gmx.de> Reviewed-by: Helge Deller <deller@gmx.de> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Richard Henderson committed
May 29, 2026 at 16:10 UTC
6fe7a5bba780196f52956dc976744b37f529ad17
5 files changed
+30
-44
linux-user/arm/elfload.c
+1
-1
@@ -220,7 +220,7 @@ bool init_guest_commpage(void)
220
return true;
221
}
222
223
- commpage = HI_COMMPAGE & -host_page_size;
223
+ commpage = COMMPAGE & -host_page_size;
224
want = g2h_untagged(commpage);
225
addr = mmap(want, host_page_size, PROT_READ | PROT_WRITE,
226
MAP_ANONYMOUS | MAP_PRIVATE |
linux-user/arm/target_elf.h
+1
-1
@@ -20,7 +20,7 @@
20
#define HAVE_ELF_CORE_DUMP 1
21
#define HAVE_VDSO_IMAGE_INFO 1
22
23
-#define HI_COMMPAGE ((intptr_t)0xffff0f00u)
23
+#define COMMPAGE ((intptr_t)0xffff0f00u)
24
25
/*
26
* See linux kernel: arch/arm/include/asm/elf.h, where
linux-user/elfload.c
+25
-39
@@ -757,17 +757,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
757
return sp;
758
}
759
760
-#if defined(HI_COMMPAGE)
761
-#define LO_COMMPAGE -1
762
-#elif defined(LO_COMMPAGE)
763
-#define HI_COMMPAGE 0
764
-#else
765
-#define HI_COMMPAGE 0
766
-#define LO_COMMPAGE -1
767
-#ifndef HAVE_GUEST_COMMPAGE
760
+#if !defined(COMMPAGE) && !defined(HAVE_GUEST_COMMPAGE)
761
bool init_guest_commpage(void) { return true; }
762
#endif
770
-#endif
763
764
/**
765
* pgb_try_mmap:
@@ -853,7 +845,7 @@ static bool pgb_try_mmap_set(const PGBAddrs *ga, uintptr_t base, uintptr_t brk)
845
* Fill in @ga with the image, COMMPAGE and NULL page.
846
*/
847
static bool pgb_addr_set(PGBAddrs *ga, const PGBRange *image_range,
856
- bool try_identity)
848
+ const PGBRange *commpage_range, bool try_identity)
849
{
850
int n;
851
@@ -862,7 +854,7 @@ static bool pgb_addr_set(PGBAddrs *ga, const PGBRange *image_range,
854
* we may not be able to use the identity map.
855
*/
856
if (try_identity) {
865
- if (LO_COMMPAGE != -1 && LO_COMMPAGE < mmap_min_addr) {
857
+ if (commpage_range && commpage_range->lo < mmap_min_addr) {
858
return false;
859
}
860
if (image_range && image_range->lo < mmap_min_addr) {
@@ -877,14 +869,10 @@ static bool pgb_addr_set(PGBAddrs *ga, const PGBRange *image_range,
869
ga->bounds[n].lo = try_identity ? mmap_min_addr : 0;
870
ga->bounds[n].hi = reserved_va;
871
n++;
880
- /* LO_COMMPAGE and NULL handled by reserving from 0. */
872
+ /* Low COMMPAGE and NULL handled by reserving from 0. */
873
} else {
882
- /* Add any LO_COMMPAGE or NULL page. */
883
- if (LO_COMMPAGE != -1) {
884
- ga->bounds[n].lo = 0;
885
- ga->bounds[n].hi = LO_COMMPAGE + TARGET_PAGE_SIZE - 1;
886
- n++;
887
- } else if (!try_identity) {
874
+ /* Add any low COMMPAGE or NULL page. */
875
+ if (!try_identity || (commpage_range && commpage_range->lo == 0)) {
876
ga->bounds[n].lo = 0;
877
ga->bounds[n].hi = TARGET_PAGE_SIZE - 1;
878
n++;
@@ -896,23 +884,13 @@ static bool pgb_addr_set(PGBAddrs *ga, const PGBRange *image_range,
884
}
885
}
886
899
- /*
900
- * Temporarily disable
901
- * "comparison is always false due to limited range of data type"
902
- * due to comparison between unsigned and (possible) 0.
903
- */
904
-#pragma GCC diagnostic push
905
-#pragma GCC diagnostic ignored "-Wtype-limits"
906
-
907
- /* Add any HI_COMMPAGE not covered by reserved_va. */
908
- if (reserved_va < HI_COMMPAGE) {
909
- ga->bounds[n].lo = HI_COMMPAGE & qemu_real_host_page_mask();
910
- ga->bounds[n].hi = HI_COMMPAGE + TARGET_PAGE_SIZE - 1;
887
+ /* Add any high COMMPAGE not covered by reserved_va. */
888
+ if (commpage_range && reserved_va < commpage_range->hi) {
889
+ ga->bounds[n].lo = commpage_range->lo & qemu_real_host_page_mask();
890
+ ga->bounds[n].hi = commpage_range->hi;
891
n++;
892
}
893
914
-#pragma GCC diagnostic pop
915
-
894
ga->nbounds = n;
895
return true;
896
}
@@ -926,7 +904,7 @@ static void pgb_fail_in_use(const char *image_name)
904
}
905
906
static void pgb_fixed(const char *image_name, const PGBRange *image_range,
929
- uintptr_t align)
907
+ const PGBRange *commpage_range, uintptr_t align)
908
{
909
PGBAddrs ga;
910
uintptr_t brk = (uintptr_t)sbrk(0);
@@ -938,7 +916,7 @@ static void pgb_fixed(const char *image_name, const PGBRange *image_range,
916
exit(EXIT_FAILURE);
917
}
918
941
- if (!pgb_addr_set(&ga, image_range, !guest_base)
919
+ if (!pgb_addr_set(&ga, image_range, commpage_range, !guest_base)
920
|| !pgb_try_mmap_set(&ga, guest_base, brk)) {
921
pgb_fail_in_use(image_name);
922
}
@@ -1024,14 +1002,14 @@ static uintptr_t pgb_find_itree(const PGBAddrs *ga, IntervalTreeRoot *root,
1002
}
1003
1004
static void pgb_dynamic(const char *image_name, const PGBRange *image_range,
1027
- uintptr_t align)
1005
+ const PGBRange *commpage_range, uintptr_t align)
1006
{
1007
IntervalTreeRoot *root;
1008
uintptr_t brk, ret;
1009
PGBAddrs ga;
1010
1011
/* Try the identity map first. */
1034
- if (pgb_addr_set(&ga, image_range, true)) {
1012
+ if (pgb_addr_set(&ga, image_range, commpage_range, true)) {
1013
brk = (uintptr_t)sbrk(0);
1014
if (pgb_try_mmap_set(&ga, 0, brk)) {
1015
guest_base = 0;
@@ -1043,7 +1021,7 @@ static void pgb_dynamic(const char *image_name, const PGBRange *image_range,
1021
* Rebuild the address set for non-identity map.
1022
* This differs in the mapping of the guest NULL page.
1023
*/
1046
- pgb_addr_set(&ga, image_range, false);
1024
+ pgb_addr_set(&ga, image_range, commpage_range, false);
1025
1026
root = read_self_maps();
1027
@@ -1084,6 +1062,14 @@ static void pgb_dynamic(const char *image_name, const PGBRange *image_range,
1062
1063
void probe_guest_base(const char *image_name, const PGBRange *image_range)
1064
{
1065
+#ifdef COMMPAGE
1066
+ const PGBRange * const commpage_range = &(PGBRange){
1067
+ COMMPAGE, COMMPAGE + TARGET_PAGE_SIZE - 1
1068
+ };
1069
+#else
1070
+ const PGBRange * const commpage_range = NULL;
1071
+#endif
1072
+
1073
/* In order to use host shmat, we must be able to honor SHMLBA. */
1074
uintptr_t align = MAX(SHMLBA, TARGET_PAGE_SIZE);
1075
@@ -1096,9 +1082,9 @@ void probe_guest_base(const char *image_name, const PGBRange *image_range)
1082
}
1083
1084
if (have_guest_base) {
1099
- pgb_fixed(image_name, image_range, align);
1085
+ pgb_fixed(image_name, image_range, commpage_range, align);
1086
} else {
1101
- pgb_dynamic(image_name, image_range, align);
1087
+ pgb_dynamic(image_name, image_range, commpage_range, align);
1088
}
1089
1090
/* Reserve and initialize the commpage. */
linux-user/hppa/elfload.c
+2
-2
@@ -36,7 +36,7 @@ bool init_guest_commpage(void)
36
if (!reserved_va) {
37
void *want, *addr;
38
39
- want = g2h_untagged(LO_COMMPAGE);
39
+ want = g2h_untagged(COMMPAGE);
40
addr = mmap(want, TARGET_PAGE_SIZE, PROT_NONE,
41
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE, -1, 0);
42
if (addr == MAP_FAILED) {
@@ -55,7 +55,7 @@ bool init_guest_commpage(void)
55
* and implement syscalls. Here, simply mark the page executable.
56
* Special case the entry points during translation (see do_page_zero).
57
*/
58
- page_set_flags(LO_COMMPAGE, LO_COMMPAGE | ~TARGET_PAGE_MASK,
58
+ page_set_flags(COMMPAGE, COMMPAGE | ~TARGET_PAGE_MASK,
59
PAGE_EXEC | PAGE_VALID, PAGE_VALID);
60
return true;
61
}
linux-user/hppa/target_elf.h
+1
-1
@@ -34,7 +34,7 @@ typedef struct target_elf_gregset_t {
34
abi_ulong pad[16]; /* pad to 80 elements [64..79] */
35
} target_elf_gregset_t;
36
37
-#define LO_COMMPAGE 0
37
+#define COMMPAGE 0
38
#define STACK_GROWS_DOWN 0
39
#define STACK_ALIGNMENT 64
40
#define VDSO_HEADER "vdso.c.inc"