1 /* 2 * BSD process related system call helpers 3 * 4 * Copyright (c) 2013-14 Stacey D. Son 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 #include "qemu/osdep.h" 20 21 #include <sys/param.h> 22 #include <sys/types.h> 23 #include <sys/cpuset.h> 24 #include <sys/resource.h> 25 #include <sys/wait.h> 26 27 #include "qemu.h" 28 #include "qemu-bsd.h" 29 #include "signal-common.h" 30 31 #include "bsd-proc.h" 32 33 /* 34 * resource/rusage conversion 35 */ 36 int target_to_host_resource(int code) 37 { 38 return code; 39 } 40 41 rlim_t target_to_host_rlim(abi_llong target_rlim) 42 { 43 return tswap64(target_rlim); 44 } 45 46 abi_llong host_to_target_rlim(rlim_t rlim) 47 { 48 return tswap64(rlim); 49 } 50 51 void h2g_rusage(const struct rusage *rusage, 52 struct target_freebsd_rusage *target_rusage) 53 { 54 __put_user(rusage->ru_utime.tv_sec, &target_rusage->ru_utime.tv_sec); 55 __put_user(rusage->ru_utime.tv_usec, &target_rusage->ru_utime.tv_usec); 56 57 __put_user(rusage->ru_stime.tv_sec, &target_rusage->ru_stime.tv_sec); 58 __put_user(rusage->ru_stime.tv_usec, &target_rusage->ru_stime.tv_usec); 59 60 __put_user(rusage->ru_maxrss, &target_rusage->ru_maxrss); 61 __put_user(rusage->ru_idrss, &target_rusage->ru_idrss); 62 __put_user(rusage->ru_idrss, &target_rusage->ru_idrss); 63 __put_user(rusage->ru_isrss, &target_rusage->ru_isrss); 64 __put_user(rusage->ru_minflt, &target_rusage->ru_minflt); 65 __put_user(rusage->ru_majflt, &target_rusage->ru_majflt); 66 __put_user(rusage->ru_nswap, &target_rusage->ru_nswap); 67 __put_user(rusage->ru_inblock, &target_rusage->ru_inblock); 68 __put_user(rusage->ru_oublock, &target_rusage->ru_oublock); 69 __put_user(rusage->ru_msgsnd, &target_rusage->ru_msgsnd); 70 __put_user(rusage->ru_msgrcv, &target_rusage->ru_msgrcv); 71 __put_user(rusage->ru_nsignals, &target_rusage->ru_nsignals); 72 __put_user(rusage->ru_nvcsw, &target_rusage->ru_nvcsw); 73 __put_user(rusage->ru_nivcsw, &target_rusage->ru_nivcsw); 74 } 75 76 abi_long host_to_target_rusage(abi_ulong target_addr, 77 const struct rusage *rusage) 78 { 79 struct target_freebsd_rusage *target_rusage; 80 81 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) { 82 return -TARGET_EFAULT; 83 } 84 h2g_rusage(rusage, target_rusage); 85 unlock_user_struct(target_rusage, target_addr, 1); 86 87 return 0; 88 } 89 90 abi_long host_to_target_wrusage(abi_ulong target_addr, 91 const struct __wrusage *wrusage) 92 { 93 struct target_freebsd__wrusage *target_wrusage; 94 95 if (!lock_user_struct(VERIFY_WRITE, target_wrusage, target_addr, 0)) { 96 return -TARGET_EFAULT; 97 } 98 h2g_rusage(&wrusage->wru_self, &target_wrusage->wru_self); 99 h2g_rusage(&wrusage->wru_children, &target_wrusage->wru_children); 100 unlock_user_struct(target_wrusage, target_addr, 1); 101 102 return 0; 103 } 104 105 /* 106 * wait status conversion. 107 * 108 * Map host to target signal numbers for the wait family of syscalls. 109 * Assume all other status bits are the same. 110 */ 111 int host_to_target_waitstatus(int status) 112 { 113 if (WIFSIGNALED(status)) { 114 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); 115 } 116 if (WIFSTOPPED(status)) { 117 return (host_to_target_signal(WSTOPSIG(status)) << 8) | (status & 0xff); 118 } 119 return status; 120 } 121 122 int bsd_get_ncpu(void) 123 { 124 int ncpu = -1; 125 cpuset_t mask; 126 127 CPU_ZERO(&mask); 128 129 if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mask), 130 &mask) == 0) { 131 ncpu = CPU_COUNT(&mask); 132 } 133 134 if (ncpu == -1) { 135 ncpu = sysconf(_SC_NPROCESSORS_ONLN); 136 } 137 138 if (ncpu == -1) { 139 gemu_log("XXX Missing bsd_get_ncpu() implementation\n"); 140 ncpu = 1; 141 } 142 143 return ncpu; 144 } 145 146