1 /* The kernel call implemented in this file: 2 * m_type: SYS_GETINFO 3 * 4 * The parameters for this kernel call are: 5 * m_lsys_krn_sys_getinfo.request (what info to get) 6 * m_lsys_krn_sys_getinfo.val_ptr (where to put it) 7 * m_lsys_krn_sys_getinfo.val_len (maximum length expected, optional) 8 * m_lsys_krn_sys_getinfo.val_ptr2 (second, optional pointer) 9 * m_lsys_krn_sys_getinfo.val_len2_e (second length or process nr) 10 * 11 * Upon return of the GETWHOAMI request the following parameters are used: 12 * m_krn_lsys_sys_getwhoami.endpt (the caller endpoint) 13 * m_krn_lsys_sys_getwhoami.privflags (the caller priviledes) 14 * m_krn_lsys_sys_getwhoami.initflags (the caller initflags) 15 * m_krn_lsys_sys_getwhoami.name (the caller process name) 16 * 17 */ 18 19 #include <string.h> 20 21 #include "kernel/system.h" 22 23 24 #if USE_GETINFO 25 26 #include <minix/u64.h> 27 #include <sys/resource.h> 28 29 /*===========================================================================* 30 * update_idle_time * 31 *===========================================================================*/ 32 static void update_idle_time(void) 33 { 34 int i; 35 struct proc * idl = proc_addr(IDLE); 36 37 idl->p_cycles = make64(0, 0); 38 39 for (i = 0; i < CONFIG_MAX_CPUS ; i++) { 40 idl->p_cycles += get_cpu_var(i, idle_proc).p_cycles; 41 } 42 } 43 44 /*===========================================================================* 45 * do_getinfo * 46 *===========================================================================*/ 47 int do_getinfo(struct proc * caller, message * m_ptr) 48 { 49 /* Request system information to be copied to caller's address space. This 50 * call simply copies entire data structures to the caller. 51 */ 52 size_t length; 53 vir_bytes src_vir; 54 int nr_e, nr, r; 55 int wipe_rnd_bin = -1; 56 struct proc *p; 57 struct rusage r_usage; 58 59 /* Set source address and length based on request type. */ 60 switch (m_ptr->m_lsys_krn_sys_getinfo.request) { 61 case GET_MACHINE: { 62 length = sizeof(struct machine); 63 src_vir = (vir_bytes) &machine; 64 break; 65 } 66 case GET_KINFO: { 67 length = sizeof(struct kinfo); 68 src_vir = (vir_bytes) &kinfo; 69 break; 70 } 71 case GET_LOADINFO: { 72 length = sizeof(struct loadinfo); 73 src_vir = (vir_bytes) &kloadinfo; 74 break; 75 } 76 case GET_CPUINFO: { 77 length = sizeof(cpu_info); 78 src_vir = (vir_bytes) &cpu_info; 79 break; 80 } 81 case GET_HZ: { 82 length = sizeof(system_hz); 83 src_vir = (vir_bytes) &system_hz; 84 break; 85 } 86 case GET_IMAGE: { 87 length = sizeof(struct boot_image) * NR_BOOT_PROCS; 88 src_vir = (vir_bytes) image; 89 break; 90 } 91 case GET_IRQHOOKS: { 92 length = sizeof(struct irq_hook) * NR_IRQ_HOOKS; 93 src_vir = (vir_bytes) irq_hooks; 94 break; 95 } 96 case GET_PROCTAB: { 97 update_idle_time(); 98 length = sizeof(struct proc) * (NR_PROCS + NR_TASKS); 99 src_vir = (vir_bytes) proc; 100 break; 101 } 102 case GET_PRIVTAB: { 103 length = sizeof(struct priv) * (NR_SYS_PROCS); 104 src_vir = (vir_bytes) priv; 105 break; 106 } 107 case GET_PROC: { 108 nr_e = (m_ptr->m_lsys_krn_sys_getinfo.val_len2_e == SELF) ? 109 caller->p_endpoint : m_ptr->m_lsys_krn_sys_getinfo.val_len2_e; 110 if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */ 111 length = sizeof(struct proc); 112 src_vir = (vir_bytes) proc_addr(nr); 113 break; 114 } 115 case GET_PRIV: { 116 nr_e = (m_ptr->m_lsys_krn_sys_getinfo.val_len2_e == SELF) ? 117 caller->p_endpoint : m_ptr->m_lsys_krn_sys_getinfo.val_len2_e; 118 if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */ 119 length = sizeof(struct priv); 120 src_vir = (vir_bytes) priv_addr(nr_to_id(nr)); 121 break; 122 } 123 case GET_REGS: { 124 nr_e = (m_ptr->m_lsys_krn_sys_getinfo.val_len2_e == SELF) ? 125 caller->p_endpoint : m_ptr->m_lsys_krn_sys_getinfo.val_len2_e; 126 if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */ 127 p = proc_addr(nr); 128 length = sizeof(p->p_reg); 129 src_vir = (vir_bytes) &p->p_reg; 130 break; 131 } 132 case GET_WHOAMI: { 133 int len; 134 m_ptr->m_krn_lsys_sys_getwhoami.endpt = caller->p_endpoint; 135 len = MIN(sizeof(m_ptr->m_krn_lsys_sys_getwhoami.name), 136 sizeof(caller->p_name))-1; 137 strncpy(m_ptr->m_krn_lsys_sys_getwhoami.name, caller->p_name, len); 138 m_ptr->m_krn_lsys_sys_getwhoami.name[len] = '\0'; 139 m_ptr->m_krn_lsys_sys_getwhoami.privflags = priv(caller)->s_flags; 140 m_ptr->m_krn_lsys_sys_getwhoami.initflags = priv(caller)->s_init_flags; 141 return OK; 142 } 143 case GET_MONPARAMS: { 144 src_vir = (vir_bytes) kinfo.param_buf; 145 length = sizeof(kinfo.param_buf); 146 break; 147 } 148 case GET_RANDOMNESS: { 149 static struct k_randomness copy; /* copy to keep counters */ 150 int i; 151 152 copy = krandom; 153 for (i= 0; i<RANDOM_SOURCES; i++) { 154 krandom.bin[i].r_size = 0; /* invalidate random data */ 155 krandom.bin[i].r_next = 0; 156 } 157 length = sizeof(copy); 158 src_vir = (vir_bytes) © 159 break; 160 } 161 case GET_RANDOMNESS_BIN: { 162 int bin = m_ptr->m_lsys_krn_sys_getinfo.val_len2_e; 163 164 if(bin < 0 || bin >= RANDOM_SOURCES) { 165 printf("SYSTEM: GET_RANDOMNESS_BIN: %d out of range\n", bin); 166 return EINVAL; 167 } 168 169 if(krandom.bin[bin].r_size < RANDOM_ELEMENTS) 170 return ENOENT; 171 172 length = sizeof(krandom.bin[bin]); 173 src_vir = (vir_bytes) &krandom.bin[bin]; 174 175 wipe_rnd_bin = bin; 176 177 break; 178 } 179 case GET_IRQACTIDS: { 180 length = sizeof(irq_actids); 181 src_vir = (vir_bytes) irq_actids; 182 break; 183 } 184 case GET_IDLETSC: { 185 struct proc * idl; 186 update_idle_time(); 187 idl = proc_addr(IDLE); 188 length = sizeof(idl->p_cycles); 189 src_vir = (vir_bytes) &idl->p_cycles; 190 break; 191 } 192 default: 193 printf("do_getinfo: invalid request %d\n", 194 m_ptr->m_lsys_krn_sys_getinfo.request); 195 return(EINVAL); 196 } 197 198 /* Try to make the actual copy for the requested data. */ 199 if (m_ptr->m_lsys_krn_sys_getinfo.val_len > 0 && 200 length > m_ptr->m_lsys_krn_sys_getinfo.val_len) 201 return (E2BIG); 202 203 r = data_copy_vmcheck(caller, KERNEL, src_vir, caller->p_endpoint, 204 m_ptr->m_lsys_krn_sys_getinfo.val_ptr, length); 205 206 if(r != OK) return r; 207 208 if(wipe_rnd_bin >= 0 && wipe_rnd_bin < RANDOM_SOURCES) { 209 krandom.bin[wipe_rnd_bin].r_size = 0; 210 krandom.bin[wipe_rnd_bin].r_next = 0; 211 } 212 213 return(OK); 214 } 215 216 #endif /* USE_GETINFO */ 217 218