@samitouri / QOSamiQemu / commits / 6fe7a5bba7

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"