^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sys/resource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <as-layout.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <kern_util.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <os.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <um_malloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define PGD_BOUND (4 * 1024 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define STACKSIZE (8 * 1024 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define THREAD_NAME_LEN (256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) long elf_aux_hwcap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static void set_stklim(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct rlimit lim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (getrlimit(RLIMIT_STACK, &lim) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) perror("getrlimit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if ((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) lim.rlim_cur = STACKSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (setrlimit(RLIMIT_STACK, &lim) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) perror("setrlimit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static void last_ditch_exit(int sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) uml_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static void install_fatal_handler(int sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct sigaction action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* All signals are enabled in this handler ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) sigemptyset(&action.sa_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * ... including the signal being handled, plus we want the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * handler reset to the default behavior, so that if an exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * handler is hanging for some reason, the UML will just die
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * after this signal is sent a second time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) action.sa_flags = SA_RESETHAND | SA_NODEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) action.sa_restorer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) action.sa_handler = last_ditch_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (sigaction(sig, &action, NULL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) os_warn("failed to install handler for signal %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "- errno = %d\n", sig, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define UML_LIB_PATH ":" OS_LIB_PATH "/uml"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static void setup_env_path(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) char *new_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) char *old_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int path_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) old_path = getenv("PATH");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * if no PATH variable is set or it has an empty value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * just use the default + /usr/lib/uml
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!old_path || (path_len = strlen(old_path)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (putenv("PATH=:/bin:/usr/bin/" UML_LIB_PATH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) perror("couldn't putenv");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* append /usr/lib/uml to the existing path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) path_len += strlen("PATH=" UML_LIB_PATH) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) new_path = malloc(path_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (!new_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) perror("couldn't malloc to set a new PATH");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) snprintf(new_path, path_len, "PATH=%s" UML_LIB_PATH, old_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (putenv(new_path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) perror("couldn't putenv to set a new PATH");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) free(new_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) extern void scan_elf_aux( char **envp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int __init main(int argc, char **argv, char **envp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) char **new_argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int ret, i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) set_stklim();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) setup_env_path();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) setsid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) new_argv = malloc((argc + 1) * sizeof(char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (new_argv == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) perror("Mallocing argv");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) for (i = 0; i < argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) new_argv[i] = strdup(argv[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (new_argv[i] == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) perror("Mallocing an arg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) new_argv[argc] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Allow these signals to bring down a UML if all other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * methods of control fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) install_fatal_handler(SIGINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) install_fatal_handler(SIGTERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) scan_elf_aux(envp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) change_sig(SIGPIPE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ret = linux_main(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * Disable SIGPROF - I have no idea why libc doesn't do this or turn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * off the profiling time, but UML dies with a SIGPROF just before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * exiting when profiling is active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) change_sig(SIGPROF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * This signal stuff used to be in the reboot case. However,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * sometimes a timer signal can come in when we're halting (reproducably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * when writing out gcov information, presumably because that takes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * some time) and cause a segfault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* stop timers and set timer signal to be ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) os_timer_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* disable SIGIO for the fds and set SIGIO to be ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) err = deactivate_all_fds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) os_warn("deactivate_all_fds failed, errno = %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * Let any pending signals fire now. This ensures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * that they won't be delivered after the exec, when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * they are definitely not expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) unblock_signals();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) os_info("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* Reboot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) execvp(new_argv[0], new_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) perror("Failed to exec kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return uml_exitcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) extern void *__real_malloc(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) void *__wrap_malloc(int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (!kmalloc_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return __real_malloc(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) else if (size <= UM_KERN_PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* finding contiguous pages can be hard*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ret = uml_kmalloc(size, UM_GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) else ret = vmalloc(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * glibc people insist that if malloc fails, errno should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * set by malloc as well. So we do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (ret == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) errno = ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) void *__wrap_calloc(int n, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) void *ptr = __wrap_malloc(n * size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (ptr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) memset(ptr, 0, n * size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) extern void __real_free(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) extern unsigned long high_physmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) void __wrap_free(void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned long addr = (unsigned long) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * We need to know how the allocation happened, so it can be correctly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * freed. This is done by seeing what region of memory the pointer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * in -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * physical memory - kmalloc/kfree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * kernel virtual memory - vmalloc/vfree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * anywhere else - malloc/free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * If kmalloc is not yet possible, then either high_physmem and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * end_vm are still 0 (as at startup), in which case we call free, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * we have set them, but anyway addr has not been allocated from those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * areas. So, in both cases __real_free is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * CAN_KMALLOC is checked because it would be bad to free a buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * with kmalloc/vmalloc after they have been turned off during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * shutdown.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * XXX: However, we sometimes shutdown CAN_KMALLOC temporarily, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * there is a possibility for memory leaks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if ((addr >= uml_physmem) && (addr < high_physmem)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (kmalloc_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) kfree(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) else if ((addr >= start_vm) && (addr < end_vm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (kmalloc_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) vfree(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else __real_free(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }