Process.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  1. #include "types.h"
  2. #include "Process.h"
  3. #include "kmalloc.h"
  4. #include "VGA.h"
  5. #include "StdLib.h"
  6. #include "i386.h"
  7. #include "system.h"
  8. #include <VirtualFileSystem/FileHandle.h>
  9. #include <VirtualFileSystem/VirtualFileSystem.h>
  10. #include <ELFLoader/ExecSpace.h>
  11. #include "MemoryManager.h"
  12. #include "errno.h"
  13. #include "i8253.h"
  14. #include "RTC.h"
  15. #include "ProcFileSystem.h"
  16. #include <AK/StdLib.h>
  17. //#define DEBUG_IO
  18. //#define TASK_DEBUG
  19. //#define SCHEDULER_DEBUG
  20. // FIXME: Only do a single validation for accesses that don't span multiple pages.
  21. // FIXME: Some places pass strlen(arg1) as arg2. This doesn't seem entirely perfect..
  22. #define VALIDATE_USER_READ(b, s) \
  23. do { \
  24. LinearAddress laddr((dword)(b)); \
  25. if (!validate_user_read(laddr) || !validate_user_read(laddr.offset((s) - 1))) \
  26. return -EFAULT; \
  27. } while(0)
  28. #define VALIDATE_USER_WRITE(b, s) \
  29. do { \
  30. LinearAddress laddr((dword)(b)); \
  31. if (!validate_user_write(laddr) || !validate_user_write(laddr.offset((s) - 1))) \
  32. return -EFAULT; \
  33. } while(0)
  34. static const DWORD defaultStackSize = 16384;
  35. Process* current;
  36. Process* s_kernelProcess;
  37. static pid_t next_pid;
  38. static InlineLinkedList<Process>* s_processes;
  39. static InlineLinkedList<Process>* s_deadProcesses;
  40. static String* s_hostname;
  41. static String& hostnameStorage(InterruptDisabler&)
  42. {
  43. ASSERT(s_hostname);
  44. return *s_hostname;
  45. }
  46. static String getHostname()
  47. {
  48. InterruptDisabler disabler;
  49. return hostnameStorage(disabler).isolatedCopy();
  50. }
  51. static bool contextSwitch(Process*);
  52. static void redoKernelProcessTSS()
  53. {
  54. if (!s_kernelProcess->selector())
  55. s_kernelProcess->setSelector(gdt_alloc_entry());
  56. auto& tssDescriptor = getGDTEntry(s_kernelProcess->selector());
  57. tssDescriptor.setBase(&s_kernelProcess->tss());
  58. tssDescriptor.setLimit(0xffff);
  59. tssDescriptor.dpl = 0;
  60. tssDescriptor.segment_present = 1;
  61. tssDescriptor.granularity = 1;
  62. tssDescriptor.zero = 0;
  63. tssDescriptor.operation_size = 1;
  64. tssDescriptor.descriptor_type = 0;
  65. tssDescriptor.type = 9;
  66. flushGDT();
  67. }
  68. void Process::prepForIRETToNewProcess()
  69. {
  70. redoKernelProcessTSS();
  71. s_kernelProcess->tss().backlink = current->selector();
  72. loadTaskRegister(s_kernelProcess->selector());
  73. }
  74. static void hlt_loop()
  75. {
  76. for (;;) {
  77. asm volatile("hlt");
  78. }
  79. }
  80. void Process::initialize()
  81. {
  82. current = nullptr;
  83. next_pid = 0;
  84. s_processes = new InlineLinkedList<Process>;
  85. s_deadProcesses = new InlineLinkedList<Process>;
  86. s_kernelProcess = Process::createKernelProcess(hlt_loop, "colonel");
  87. s_hostname = new String("birx");
  88. redoKernelProcessTSS();
  89. loadTaskRegister(s_kernelProcess->selector());
  90. }
  91. void Process::allocateLDT()
  92. {
  93. ASSERT(!m_tss.ldt);
  94. static const WORD numLDTEntries = 4;
  95. m_ldt_selector = gdt_alloc_entry();
  96. m_ldtEntries = new Descriptor[numLDTEntries];
  97. #if 0
  98. kprintf("new ldt selector = %x\n", m_ldt_selector);
  99. kprintf("new ldt table at = %p\n", m_ldtEntries);
  100. kprintf("new ldt table size = %u\n", (numLDTEntries * 8) - 1);
  101. #endif
  102. Descriptor& ldt = getGDTEntry(m_ldt_selector);
  103. ldt.setBase(m_ldtEntries);
  104. ldt.setLimit(numLDTEntries * 8 - 1);
  105. ldt.dpl = 0;
  106. ldt.segment_present = 1;
  107. ldt.granularity = 0;
  108. ldt.zero = 0;
  109. ldt.operation_size = 1;
  110. ldt.descriptor_type = 0;
  111. ldt.type = Descriptor::LDT;
  112. m_tss.ldt = m_ldt_selector;
  113. }
  114. template<typename Callback>
  115. static void forEachProcess(Callback callback)
  116. {
  117. ASSERT_INTERRUPTS_DISABLED();
  118. for (auto* process = s_processes->head(); process; process = process->next()) {
  119. if (!callback(*process))
  120. break;
  121. }
  122. }
  123. Vector<Process*> Process::allProcesses()
  124. {
  125. InterruptDisabler disabler;
  126. Vector<Process*> processes;
  127. processes.ensureCapacity(s_processes->sizeSlow());
  128. for (auto* process = s_processes->head(); process; process = process->next())
  129. processes.append(process);
  130. return processes;
  131. }
  132. Region* Process::allocateRegion(size_t size, String&& name)
  133. {
  134. // FIXME: This needs sanity checks. What if this overlaps existing regions?
  135. auto zone = MM.createZone(size);
  136. ASSERT(zone);
  137. m_regions.append(adopt(*new Region(m_nextRegion, size, move(zone), move(name))));
  138. m_nextRegion = m_nextRegion.offset(size).offset(16384);
  139. MM.mapRegion(*this, *m_regions.last());
  140. return m_regions.last().ptr();
  141. }
  142. bool Process::deallocateRegion(Region& region)
  143. {
  144. InterruptDisabler disabler;
  145. for (size_t i = 0; i < m_regions.size(); ++i) {
  146. if (m_regions[i].ptr() == &region) {
  147. MM.unmapRegion(*this, region);
  148. m_regions.remove(i);
  149. return true;
  150. }
  151. }
  152. return false;
  153. }
  154. Region* Process::regionFromRange(LinearAddress laddr, size_t size)
  155. {
  156. for (auto& region : m_regions) {
  157. if (region->linearAddress == laddr && region->size == size)
  158. return region.ptr();
  159. }
  160. return nullptr;
  161. }
  162. int Process::sys$set_mmap_name(void* addr, size_t size, const char* name)
  163. {
  164. VALIDATE_USER_READ(name, strlen(name));
  165. auto* region = regionFromRange(LinearAddress((dword)addr), size);
  166. if (!region)
  167. return -EINVAL;
  168. region->name = name;
  169. return 0;
  170. }
  171. void* Process::sys$mmap(void* addr, size_t size)
  172. {
  173. InterruptDisabler disabler;
  174. // FIXME: Implement mapping at a client-preferred address.
  175. ASSERT(addr == nullptr);
  176. auto* region = allocateRegion(size, "mmap");
  177. if (!region)
  178. return (void*)-1;
  179. MM.mapRegion(*this, *region);
  180. return (void*)region->linearAddress.get();
  181. }
  182. int Process::sys$munmap(void* addr, size_t size)
  183. {
  184. InterruptDisabler disabler;
  185. auto* region = regionFromRange(LinearAddress((dword)addr), size);
  186. if (!region)
  187. return -1;
  188. if (!deallocateRegion(*region))
  189. return -1;
  190. return 0;
  191. }
  192. int Process::sys$gethostname(char* buffer, size_t size)
  193. {
  194. VALIDATE_USER_WRITE(buffer, size);
  195. auto hostname = getHostname();
  196. if (size < (hostname.length() + 1))
  197. return -ENAMETOOLONG;
  198. memcpy(buffer, hostname.characters(), size);
  199. return 0;
  200. }
  201. int Process::sys$spawn(const char* path, const char** args)
  202. {
  203. if (args) {
  204. for (size_t i = 0; args[i]; ++i) {
  205. VALIDATE_USER_READ(args[i], strlen(args[i]));
  206. }
  207. }
  208. int error = 0;
  209. auto* child = Process::createUserProcess(path, m_uid, m_gid, m_pid, error, args, m_tty);
  210. if (child)
  211. return child->pid();
  212. return error;
  213. }
  214. Process* Process::createUserProcess(const String& path, uid_t uid, gid_t gid, pid_t parentPID, int& error, const char** args, TTY* tty)
  215. {
  216. auto parts = path.split('/');
  217. if (parts.isEmpty()) {
  218. error = -ENOENT;
  219. return nullptr;
  220. }
  221. RetainPtr<VirtualFileSystem::Node> cwd;
  222. {
  223. InterruptDisabler disabler;
  224. if (auto* parentProcess = Process::fromPID(parentPID))
  225. cwd = parentProcess->m_cwd.copyRef();
  226. if (!cwd)
  227. cwd = VirtualFileSystem::the().root();
  228. }
  229. auto handle = VirtualFileSystem::the().open(path, error, 0, cwd ? cwd->inode : InodeIdentifier());
  230. if (!handle)
  231. return nullptr;
  232. if (!handle->metadata().mayExecute(uid, gid)) {
  233. error = -EACCES;
  234. return nullptr;
  235. }
  236. auto elfData = handle->readEntireFile();
  237. if (!elfData) {
  238. error = -EIO; // FIXME: Get a more detailed error from VFS.
  239. return nullptr;
  240. }
  241. Vector<String> processArguments;
  242. if (args) {
  243. for (size_t i = 0; args[i]; ++i) {
  244. processArguments.append(args[i]);
  245. }
  246. } else {
  247. processArguments.append(parts.last());
  248. }
  249. Vector<String> processEnvironment;
  250. processEnvironment.append("PATH=/bin");
  251. processEnvironment.append("SHELL=/bin/sh");
  252. processEnvironment.append("TERM=console");
  253. processEnvironment.append("HOME=/");
  254. auto* t = new Process(parts.takeLast(), uid, gid, parentPID, Ring3, move(cwd), handle->vnode(), tty);
  255. t->m_arguments = move(processArguments);
  256. t->m_initialEnvironment = move(processEnvironment);
  257. ExecSpace space;
  258. Region* region = nullptr;
  259. ProcessPagingScope pagingScope(*t);
  260. space.hookableAlloc = [&] (const String& name, size_t size) {
  261. if (!size)
  262. return (void*)nullptr;
  263. size = ((size / 4096) + 1) * 4096; // FIXME: Use ceil_div?
  264. region = t->allocateRegion(size, String(name));
  265. return (void*)region->linearAddress.get();
  266. };
  267. bool success = space.loadELF(move(elfData));
  268. if (!success) {
  269. delete t;
  270. kprintf("Failure loading ELF %s\n", path.characters());
  271. error = -ENOEXEC;
  272. return nullptr;
  273. }
  274. space.forEachArea([&] (const String& name, dword offset, size_t size, LinearAddress laddr) {
  275. if (laddr.isNull())
  276. return;
  277. dword roundedOffset = offset & 0xfffff000;
  278. size_t roundedSize = 4096 * ceilDiv((offset - roundedOffset) + size, 4096u);
  279. LinearAddress roundedLaddr = laddr;
  280. roundedLaddr.mask(0xfffff000);
  281. t->m_subregions.append(make<Subregion>(*region, roundedOffset, roundedSize, roundedLaddr, String(name)));
  282. #ifdef SUBREGION_DEBUG
  283. kprintf(" req subregion %s (offset: %u, size: %u) @ %p\n", name.characters(), offset, size, laddr.get());
  284. kprintf("actual subregion %s (offset: %u, size: %u) @ %p\n", name.characters(), roundedOffset, roundedSize, roundedLaddr.get());
  285. #endif
  286. MM.mapSubregion(*t, *t->m_subregions.last());
  287. });
  288. t->m_tss.eip = (dword)space.symbolPtr("_start");
  289. if (!t->m_tss.eip) {
  290. // FIXME: This is ugly. If we need to do this, it should be at a different level.
  291. delete t;
  292. error = -ENOEXEC;
  293. return nullptr;
  294. }
  295. ASSERT(region);
  296. ProcFileSystem::the().addProcess(*t);
  297. s_processes->prepend(t);
  298. system.nprocess++;
  299. #ifdef TASK_DEBUG
  300. kprintf("Process %u (%s) spawned @ %p\n", t->pid(), t->name().characters(), t->m_tss.eip);
  301. #endif
  302. error = 0;
  303. return t;
  304. }
  305. int Process::sys$get_environment(char*** environ)
  306. {
  307. auto* region = allocateRegion(4096, "environ");
  308. if (!region)
  309. return -ENOMEM;
  310. MM.mapRegion(*this, *region);
  311. char* envpage = (char*)region->linearAddress.get();
  312. *environ = (char**)envpage;
  313. char* bufptr = envpage + (sizeof(char*) * (m_initialEnvironment.size() + 1));
  314. for (size_t i = 0; i < m_initialEnvironment.size(); ++i) {
  315. (*environ)[i] = bufptr;
  316. memcpy(bufptr, m_initialEnvironment[i].characters(), m_initialEnvironment[i].length());
  317. bufptr += m_initialEnvironment[i].length();
  318. *(bufptr++) = '\0';
  319. }
  320. (*environ)[m_initialEnvironment.size()] = nullptr;
  321. return 0;
  322. }
  323. int Process::sys$get_arguments(int* argc, char*** argv)
  324. {
  325. auto* region = allocateRegion(4096, "argv");
  326. if (!region)
  327. return -ENOMEM;
  328. MM.mapRegion(*this, *region);
  329. char* argpage = (char*)region->linearAddress.get();
  330. *argc = m_arguments.size();
  331. *argv = (char**)argpage;
  332. char* bufptr = argpage + (sizeof(char*) * m_arguments.size());
  333. for (size_t i = 0; i < m_arguments.size(); ++i) {
  334. (*argv)[i] = bufptr;
  335. memcpy(bufptr, m_arguments[i].characters(), m_arguments[i].length());
  336. bufptr += m_arguments[i].length();
  337. *(bufptr++) = '\0';
  338. }
  339. return 0;
  340. }
  341. Process* Process::createKernelProcess(void (*e)(), String&& name)
  342. {
  343. auto* process = new Process(move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0);
  344. process->m_tss.eip = (dword)e;
  345. if (process->pid() != 0) {
  346. InterruptDisabler disabler;
  347. s_processes->prepend(process);
  348. system.nprocess++;
  349. ProcFileSystem::the().addProcess(*process);
  350. #ifdef TASK_DEBUG
  351. kprintf("Kernel process %u (%s) spawned @ %p\n", process->pid(), process->name().characters(), process->m_tss.eip);
  352. #endif
  353. }
  354. return process;
  355. }
  356. Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel ring, RetainPtr<VirtualFileSystem::Node>&& cwd, RetainPtr<VirtualFileSystem::Node>&& executable, TTY* tty)
  357. : m_name(move(name))
  358. , m_pid(next_pid++)
  359. , m_uid(uid)
  360. , m_gid(gid)
  361. , m_state(Runnable)
  362. , m_ring(ring)
  363. , m_cwd(move(cwd))
  364. , m_executable(move(executable))
  365. , m_tty(tty)
  366. , m_parentPID(parentPID)
  367. {
  368. {
  369. // FIXME: Use a ProcessHandle? Presumably we're executing *IN* the parent right now though..
  370. InterruptDisabler disabler;
  371. if (auto* parent = Process::fromPID(m_parentPID)) {
  372. m_sid = parent->m_sid;
  373. m_pgid = parent->m_pgid;
  374. }
  375. }
  376. m_page_directory = (PageDirectory*)kmalloc_page_aligned(sizeof(PageDirectory));
  377. MM.populate_page_directory(*this);
  378. m_file_descriptors.resize(m_max_open_file_descriptors);
  379. if (tty) {
  380. m_file_descriptors[0] = tty->open(O_RDONLY);
  381. m_file_descriptors[1] = tty->open(O_WRONLY);
  382. m_file_descriptors[2] = tty->open(O_WRONLY);
  383. }
  384. m_nextRegion = LinearAddress(0x10000000);
  385. memset(&m_tss, 0, sizeof(m_tss));
  386. if (isRing3()) {
  387. memset(&m_ldtEntries, 0, sizeof(m_ldtEntries));
  388. allocateLDT();
  389. }
  390. // Only IF is set when a process boots.
  391. m_tss.eflags = 0x0202;
  392. word cs, ds, ss;
  393. if (isRing0()) {
  394. cs = 0x08;
  395. ds = 0x10;
  396. ss = 0x10;
  397. } else {
  398. cs = 0x1b;
  399. ds = 0x23;
  400. ss = 0x23;
  401. }
  402. m_tss.ds = ds;
  403. m_tss.es = ds;
  404. m_tss.fs = ds;
  405. m_tss.gs = ds;
  406. m_tss.ss = ss;
  407. m_tss.cs = cs;
  408. m_tss.cr3 = (dword)m_page_directory;
  409. if (isRing0()) {
  410. // FIXME: This memory is leaked.
  411. // But uh, there's also no kernel process termination, so I guess it's not technically leaked...
  412. dword stackBottom = (dword)kmalloc_eternal(defaultStackSize);
  413. m_stackTop0 = (stackBottom + defaultStackSize) & 0xffffff8;
  414. m_tss.esp = m_stackTop0;
  415. } else {
  416. auto* region = allocateRegion(defaultStackSize, "stack");
  417. ASSERT(region);
  418. m_stackTop3 = region->linearAddress.offset(defaultStackSize).get() & 0xfffffff8;
  419. m_tss.esp = m_stackTop3;
  420. }
  421. if (isRing3()) {
  422. // Ring3 processes need a separate stack for Ring0.
  423. m_kernelStack = kmalloc(defaultStackSize);
  424. m_stackTop0 = ((DWORD)m_kernelStack + defaultStackSize) & 0xffffff8;
  425. m_tss.ss0 = 0x10;
  426. m_tss.esp0 = m_stackTop0;
  427. }
  428. // HACK: Ring2 SS in the TSS is the current PID.
  429. m_tss.ss2 = m_pid;
  430. m_farPtr.offset = 0x98765432;
  431. }
  432. Process::~Process()
  433. {
  434. InterruptDisabler disabler;
  435. ProcFileSystem::the().removeProcess(*this);
  436. system.nprocess--;
  437. if (isRing3()) {
  438. delete [] m_ldtEntries;
  439. m_ldtEntries = nullptr;
  440. gdt_free_entry(m_ldt_selector);
  441. }
  442. gdt_free_entry(selector());
  443. if (m_kernelStack) {
  444. kfree(m_kernelStack);
  445. m_kernelStack = nullptr;
  446. }
  447. MM.release_page_directory(*this);
  448. }
  449. void Process::dumpRegions()
  450. {
  451. kprintf("Process %s(%u) regions:\n", name().characters(), pid());
  452. kprintf("BEGIN END SIZE NAME\n");
  453. for (auto& region : m_regions) {
  454. kprintf("%x -- %x %x %s\n",
  455. region->linearAddress.get(),
  456. region->linearAddress.offset(region->size - 1).get(),
  457. region->size,
  458. region->name.characters());
  459. }
  460. kprintf("Process %s(%u) subregions:\n", name().characters(), pid());
  461. kprintf("REGION OFFSET BEGIN END SIZE NAME\n");
  462. for (auto& subregion : m_subregions) {
  463. kprintf("%x %x %x -- %x %x %s\n",
  464. subregion->region->linearAddress.get(),
  465. subregion->offset,
  466. subregion->linearAddress.get(),
  467. subregion->linearAddress.offset(subregion->size - 1).get(),
  468. subregion->size,
  469. subregion->name.characters());
  470. }
  471. }
  472. void Process::notify_waiters(pid_t waitee, int exit_status, int signal)
  473. {
  474. ASSERT_INTERRUPTS_DISABLED();
  475. for (auto* process = s_processes->head(); process; process = process->next()) {
  476. if (process->waitee() == waitee)
  477. process->m_waiteeStatus = (exit_status << 8) | (signal);
  478. }
  479. }
  480. void Process::sys$exit(int status)
  481. {
  482. cli();
  483. #ifdef TASK_DEBUG
  484. kprintf("sys$exit: %s(%u) exit with status %d\n", name().characters(), pid(), status);
  485. #endif
  486. set_state(Exiting);
  487. s_processes->remove(this);
  488. notify_waiters(m_pid, status, 0);
  489. if (!scheduleNewProcess()) {
  490. kprintf("Process::sys$exit: Failed to schedule a new process :(\n");
  491. HANG;
  492. }
  493. s_deadProcesses->append(this);
  494. switchNow();
  495. }
  496. void Process::murder(int signal)
  497. {
  498. ASSERT_INTERRUPTS_DISABLED();
  499. bool wasCurrent = current == this;
  500. set_state(Exiting);
  501. s_processes->remove(this);
  502. notify_waiters(m_pid, 0, signal);
  503. if (wasCurrent) {
  504. kprintf("Current process committing suicide!\n");
  505. if (!scheduleNewProcess()) {
  506. kprintf("Process::murder: Failed to schedule a new process :(\n");
  507. HANG;
  508. }
  509. }
  510. s_deadProcesses->append(this);
  511. if (wasCurrent)
  512. switchNow();
  513. }
  514. void Process::processDidCrash(Process* crashedProcess)
  515. {
  516. ASSERT_INTERRUPTS_DISABLED();
  517. if (crashedProcess->state() == Crashing) {
  518. kprintf("Double crash :(\n");
  519. HANG;
  520. }
  521. crashedProcess->set_state(Crashing);
  522. crashedProcess->dumpRegions();
  523. s_processes->remove(crashedProcess);
  524. notify_waiters(crashedProcess->m_pid, 0, SIGSEGV);
  525. if (!scheduleNewProcess()) {
  526. kprintf("Process::processDidCrash: Failed to schedule a new process :(\n");
  527. HANG;
  528. }
  529. s_deadProcesses->append(crashedProcess);
  530. switchNow();
  531. }
  532. void Process::doHouseKeeping()
  533. {
  534. if (s_deadProcesses->isEmpty())
  535. return;
  536. InterruptDisabler disabler;
  537. Process* next = nullptr;
  538. for (auto* deadProcess = s_deadProcesses->head(); deadProcess; deadProcess = next) {
  539. next = deadProcess->next();
  540. delete deadProcess;
  541. }
  542. s_deadProcesses->clear();
  543. }
  544. void yield()
  545. {
  546. if (!current) {
  547. kprintf( "PANIC: yield() with !current" );
  548. HANG;
  549. }
  550. //kprintf("%s<%u> yield()\n", current->name().characters(), current->pid());
  551. InterruptDisabler disabler;
  552. if (!scheduleNewProcess())
  553. return;
  554. //kprintf("yield() jumping to new process: %x (%s)\n", current->farPtr().selector, current->name().characters());
  555. switchNow();
  556. }
  557. void switchNow()
  558. {
  559. Descriptor& descriptor = getGDTEntry(current->selector());
  560. descriptor.type = 9;
  561. flushGDT();
  562. asm("sti\n"
  563. "ljmp *(%%eax)\n"
  564. ::"a"(&current->farPtr())
  565. );
  566. }
  567. bool scheduleNewProcess()
  568. {
  569. ASSERT_INTERRUPTS_DISABLED();
  570. if (!current) {
  571. // XXX: The first ever context_switch() goes to the idle process.
  572. // This to setup a reliable place we can return to.
  573. return contextSwitch(Process::kernelProcess());
  574. }
  575. // Check and unblock processes whose wait conditions have been met.
  576. for (auto* process = s_processes->head(); process; process = process->next()) {
  577. if (process->state() == Process::BlockedSleep) {
  578. if (process->wakeupTime() <= system.uptime) {
  579. process->unblock();
  580. continue;
  581. }
  582. }
  583. if (process->state() == Process::BlockedWait) {
  584. if (!Process::fromPID(process->waitee())) {
  585. process->unblock();
  586. continue;
  587. }
  588. }
  589. if (process->state() == Process::BlockedRead) {
  590. ASSERT(process->m_fdBlockedOnRead != -1);
  591. if (process->m_file_descriptors[process->m_fdBlockedOnRead]->hasDataAvailableForRead()) {
  592. process->unblock();
  593. continue;
  594. }
  595. }
  596. }
  597. #ifdef SCHEDULER_DEBUG
  598. dbgprintf("Scheduler choices:\n");
  599. for (auto* process = s_processes->head(); process; process = process->next()) {
  600. //if (process->state() == Process::BlockedWait || process->state() == Process::BlockedSleep)
  601. // continue;
  602. dbgprintf("%w %s(%u)\n", process->state(), process->name().characters(), process->pid());
  603. }
  604. #endif
  605. auto* prevHead = s_processes->head();
  606. for (;;) {
  607. // Move head to tail.
  608. s_processes->append(s_processes->removeHead());
  609. auto* process = s_processes->head();
  610. if (process->state() == Process::Runnable || process->state() == Process::Running) {
  611. #ifdef SCHEDULER_DEBUG
  612. dbgprintf("switch to %s(%u) (%p vs %p)\n", process->name().characters(), process->pid(), process, current);
  613. #endif
  614. return contextSwitch(process);
  615. }
  616. if (process == prevHead) {
  617. // Back at process_head, nothing wants to run.
  618. kprintf("Nothing wants to run!\n");
  619. kprintf("PID OWNER STATE NSCHED NAME\n");
  620. for (auto* process = s_processes->head(); process; process = process->next()) {
  621. kprintf("%w %w:%w %b %w %s\n",
  622. process->pid(),
  623. process->uid(),
  624. process->gid(),
  625. process->state(),
  626. process->timesScheduled(),
  627. process->name().characters());
  628. }
  629. kprintf("Switch to kernel process @ %w:%x\n", s_kernelProcess->tss().cs, s_kernelProcess->tss().eip);
  630. return contextSwitch(Process::kernelProcess());
  631. }
  632. }
  633. }
  634. static bool contextSwitch(Process* t)
  635. {
  636. t->setTicksLeft(5);
  637. t->didSchedule();
  638. if (current == t)
  639. return false;
  640. #ifdef SCHEDULER_DEBUG
  641. // Some sanity checking to force a crash earlier.
  642. auto csRPL = t->tss().cs & 3;
  643. auto ssRPL = t->tss().ss & 3;
  644. if (csRPL != ssRPL) {
  645. kprintf("Fuckup! Switching from %s(%u) to %s(%u) has RPL mismatch\n",
  646. current->name().characters(), current->pid(),
  647. t->name().characters(), t->pid()
  648. );
  649. kprintf("code: %w:%x\n", t->tss().cs, t->tss().eip);
  650. kprintf(" stk: %w:%x\n", t->tss().ss, t->tss().esp);
  651. ASSERT(csRPL == ssRPL);
  652. }
  653. #endif
  654. if (current) {
  655. // If the last process hasn't blocked (still marked as running),
  656. // mark it as runnable for the next round.
  657. if (current->state() == Process::Running)
  658. current->set_state(Process::Runnable);
  659. }
  660. current = t;
  661. t->set_state(Process::Running);
  662. if (!t->selector()) {
  663. t->setSelector(gdt_alloc_entry());
  664. auto& descriptor = getGDTEntry(t->selector());
  665. descriptor.setBase(&t->tss());
  666. descriptor.setLimit(0xffff);
  667. descriptor.dpl = 0;
  668. descriptor.segment_present = 1;
  669. descriptor.granularity = 1;
  670. descriptor.zero = 0;
  671. descriptor.operation_size = 1;
  672. descriptor.descriptor_type = 0;
  673. }
  674. auto& descriptor = getGDTEntry(t->selector());
  675. descriptor.type = 11; // Busy TSS
  676. flushGDT();
  677. return true;
  678. }
  679. Process* Process::fromPID(pid_t pid)
  680. {
  681. ASSERT_INTERRUPTS_DISABLED();
  682. for (auto* process = s_processes->head(); process; process = process->next()) {
  683. if (process->pid() == pid)
  684. return process;
  685. }
  686. return nullptr;
  687. }
  688. FileHandle* Process::fileHandleIfExists(int fd)
  689. {
  690. if (fd < 0)
  691. return nullptr;
  692. if ((unsigned)fd < m_file_descriptors.size())
  693. return m_file_descriptors[fd].ptr();
  694. return nullptr;
  695. }
  696. ssize_t Process::sys$get_dir_entries(int fd, void* buffer, size_t size)
  697. {
  698. VALIDATE_USER_WRITE(buffer, size);
  699. auto* handle = fileHandleIfExists(fd);
  700. if (!handle)
  701. return -EBADF;
  702. return handle->get_dir_entries((byte*)buffer, size);
  703. }
  704. int Process::sys$lseek(int fd, off_t offset, int whence)
  705. {
  706. auto* handle = fileHandleIfExists(fd);
  707. if (!handle)
  708. return -EBADF;
  709. return handle->seek(offset, whence);
  710. }
  711. int Process::sys$ttyname_r(int fd, char* buffer, size_t size)
  712. {
  713. VALIDATE_USER_WRITE(buffer, size);
  714. auto* handle = fileHandleIfExists(fd);
  715. if (!handle)
  716. return -EBADF;
  717. if (!handle->isTTY())
  718. return -ENOTTY;
  719. auto ttyName = handle->tty()->ttyName();
  720. if (size < ttyName.length() + 1)
  721. return -ERANGE;
  722. strcpy(buffer, ttyName.characters());
  723. return 0;
  724. }
  725. ssize_t Process::sys$write(int fd, const void* data, size_t size)
  726. {
  727. VALIDATE_USER_READ(data, size);
  728. #ifdef DEBUG_IO
  729. kprintf("Process::sys$write: called(%d, %p, %u)\n", fd, data, size);
  730. #endif
  731. auto* handle = fileHandleIfExists(fd);
  732. #ifdef DEBUG_IO
  733. kprintf("Process::sys$write: handle=%p\n", handle);
  734. #endif
  735. if (!handle)
  736. return -EBADF;
  737. auto nwritten = handle->write((const byte*)data, size);
  738. #ifdef DEBUG_IO
  739. kprintf("Process::sys$write: nwritten=%u\n", nwritten);
  740. #endif
  741. return nwritten;
  742. }
  743. ssize_t Process::sys$read(int fd, void* outbuf, size_t nread)
  744. {
  745. VALIDATE_USER_WRITE(outbuf, nread);
  746. #ifdef DEBUG_IO
  747. kprintf("Process::sys$read: called(%d, %p, %u)\n", fd, outbuf, nread);
  748. #endif
  749. auto* handle = fileHandleIfExists(fd);
  750. #ifdef DEBUG_IO
  751. kprintf("Process::sys$read: handle=%p\n", handle);
  752. #endif
  753. if (!handle)
  754. return -EBADF;
  755. if (handle->isBlocking()) {
  756. if (!handle->hasDataAvailableForRead()) {
  757. m_fdBlockedOnRead = fd;
  758. block(BlockedRead);
  759. yield();
  760. }
  761. }
  762. nread = handle->read((byte*)outbuf, nread);
  763. #ifdef DEBUG_IO
  764. kprintf("Process::sys$read: nread=%u\n", nread);
  765. #endif
  766. return nread;
  767. }
  768. int Process::sys$close(int fd)
  769. {
  770. auto* handle = fileHandleIfExists(fd);
  771. if (!handle)
  772. return -EBADF;
  773. int rc = handle->close();
  774. m_file_descriptors[fd] = nullptr;
  775. return rc;
  776. }
  777. int Process::sys$lstat(const char* path, Unix::stat* statbuf)
  778. {
  779. VALIDATE_USER_WRITE(statbuf, sizeof(Unix::stat));
  780. int error;
  781. auto handle = VirtualFileSystem::the().open(move(path), error, O_NOFOLLOW_NOERROR, cwdInode());
  782. if (!handle)
  783. return error;
  784. handle->stat(statbuf);
  785. return 0;
  786. }
  787. int Process::sys$stat(const char* path, Unix::stat* statbuf)
  788. {
  789. VALIDATE_USER_WRITE(statbuf, sizeof(Unix::stat));
  790. int error;
  791. auto handle = VirtualFileSystem::the().open(move(path), error, 0, cwdInode());
  792. if (!handle)
  793. return error;
  794. handle->stat(statbuf);
  795. return 0;
  796. }
  797. int Process::sys$readlink(const char* path, char* buffer, size_t size)
  798. {
  799. VALIDATE_USER_READ(path, strlen(path));
  800. VALIDATE_USER_WRITE(buffer, size);
  801. int error;
  802. auto handle = VirtualFileSystem::the().open(path, error, O_RDONLY | O_NOFOLLOW_NOERROR, cwdInode());
  803. if (!handle)
  804. return error;
  805. if (!handle->metadata().isSymbolicLink())
  806. return -EINVAL;
  807. auto contents = handle->readEntireFile();
  808. if (!contents)
  809. return -EIO; // FIXME: Get a more detailed error from VFS.
  810. memcpy(buffer, contents.pointer(), min(size, contents.size()));
  811. if (contents.size() + 1 < size)
  812. buffer[contents.size()] = '\0';
  813. return 0;
  814. }
  815. int Process::sys$chdir(const char* path)
  816. {
  817. VALIDATE_USER_READ(path, strlen(path));
  818. int error;
  819. auto handle = VirtualFileSystem::the().open(path, error, 0, cwdInode());
  820. if (!handle)
  821. return error;
  822. if (!handle->isDirectory())
  823. return -ENOTDIR;
  824. m_cwd = handle->vnode();
  825. return 0;
  826. }
  827. int Process::sys$getcwd(char* buffer, size_t size)
  828. {
  829. VALIDATE_USER_WRITE(buffer, size);
  830. auto path = VirtualFileSystem::the().absolutePath(cwdInode());
  831. if (path.isNull())
  832. return -EINVAL;
  833. if (size < path.length() + 1)
  834. return -ERANGE;
  835. strcpy(buffer, path.characters());
  836. return -ENOTIMPL;
  837. }
  838. size_t Process::number_of_open_file_descriptors() const
  839. {
  840. size_t count = 0;
  841. for (auto& handle : m_file_descriptors) {
  842. if (handle)
  843. ++count;
  844. }
  845. return count;
  846. }
  847. int Process::sys$open(const char* path, int options)
  848. {
  849. #ifdef DEBUG_IO
  850. kprintf("Process::sys$open(): PID=%u, path=%s {%u}\n", m_pid, path, pathLength);
  851. #endif
  852. VALIDATE_USER_READ(path, strlen(path));
  853. if (number_of_open_file_descriptors() >= m_max_open_file_descriptors)
  854. return -EMFILE;
  855. int error;
  856. auto handle = VirtualFileSystem::the().open(path, error, options, cwdInode());
  857. if (!handle)
  858. return error;
  859. if (options & O_DIRECTORY && !handle->isDirectory())
  860. return -ENOTDIR; // FIXME: This should be handled by VFS::open.
  861. int fd = 0;
  862. for (; fd < m_max_open_file_descriptors; ++fd) {
  863. if (!m_file_descriptors[fd])
  864. break;
  865. }
  866. handle->setFD(fd);
  867. m_file_descriptors[fd] = move(handle);
  868. return fd;
  869. }
  870. int Process::sys$uname(utsname* buf)
  871. {
  872. VALIDATE_USER_WRITE(buf, sizeof(utsname));
  873. strcpy(buf->sysname, "Serenity");
  874. strcpy(buf->release, "1.0-dev");
  875. strcpy(buf->version, "FIXME");
  876. strcpy(buf->machine, "i386");
  877. strcpy(buf->nodename, getHostname().characters());
  878. return 0;
  879. }
  880. int Process::sys$kill(pid_t pid, int sig)
  881. {
  882. (void) sig;
  883. if (pid == 0) {
  884. // FIXME: Send to same-group processes.
  885. ASSERT(pid != 0);
  886. }
  887. if (pid == -1) {
  888. // FIXME: Send to all processes.
  889. ASSERT(pid != -1);
  890. }
  891. ASSERT(pid != current->pid()); // FIXME: Support this scenario.
  892. InterruptDisabler disabler;
  893. auto* peer = Process::fromPID(pid);
  894. if (!peer)
  895. return -ESRCH;
  896. if (sig == SIGKILL) {
  897. peer->murder(SIGKILL);
  898. return 0;
  899. } else {
  900. ASSERT_NOT_REACHED();
  901. }
  902. return -1;
  903. }
  904. int Process::sys$sleep(unsigned seconds)
  905. {
  906. if (!seconds)
  907. return 0;
  908. sleep(seconds * TICKS_PER_SECOND);
  909. return 0;
  910. }
  911. int Process::sys$gettimeofday(timeval* tv)
  912. {
  913. VALIDATE_USER_WRITE(tv, sizeof(tv));
  914. InterruptDisabler disabler;
  915. auto now = RTC::now();
  916. tv->tv_sec = now;
  917. tv->tv_usec = 0;
  918. return 0;
  919. }
  920. uid_t Process::sys$getuid()
  921. {
  922. return m_uid;
  923. }
  924. gid_t Process::sys$getgid()
  925. {
  926. return m_gid;
  927. }
  928. pid_t Process::sys$getpid()
  929. {
  930. return m_pid;
  931. }
  932. pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
  933. {
  934. if (wstatus)
  935. VALIDATE_USER_WRITE(wstatus, sizeof(int));
  936. InterruptDisabler disabler;
  937. if (!Process::fromPID(waitee))
  938. return -1;
  939. m_waitee = waitee;
  940. m_waiteeStatus = 0;
  941. block(BlockedWait);
  942. yield();
  943. if (wstatus)
  944. *wstatus = m_waiteeStatus;
  945. return m_waitee;
  946. }
  947. void Process::unblock()
  948. {
  949. ASSERT(m_state != Process::Runnable && m_state != Process::Running);
  950. system.nblocked--;
  951. m_state = Process::Runnable;
  952. }
  953. void Process::block(Process::State state)
  954. {
  955. ASSERT(current->state() == Process::Running);
  956. system.nblocked++;
  957. current->set_state(state);
  958. }
  959. void block(Process::State state)
  960. {
  961. current->block(state);
  962. yield();
  963. }
  964. void sleep(DWORD ticks)
  965. {
  966. ASSERT(current->state() == Process::Running);
  967. current->setWakeupTime(system.uptime + ticks);
  968. current->block(Process::BlockedSleep);
  969. yield();
  970. }
  971. Process* Process::kernelProcess()
  972. {
  973. ASSERT(s_kernelProcess);
  974. return s_kernelProcess;
  975. }
  976. Region::Region(LinearAddress a, size_t s, RetainPtr<Zone>&& z, String&& n)
  977. : linearAddress(a)
  978. , size(s)
  979. , zone(move(z))
  980. , name(move(n))
  981. {
  982. }
  983. Region::~Region()
  984. {
  985. }
  986. Subregion::Subregion(Region& r, dword o, size_t s, LinearAddress l, String&& n)\
  987. : region(r)
  988. , offset(o)
  989. , size(s)
  990. , linearAddress(l)
  991. , name(move(n))
  992. {
  993. }
  994. Subregion::~Subregion()
  995. {
  996. }
  997. bool Process::isValidAddressForKernel(LinearAddress laddr) const
  998. {
  999. // We check extra carefully here since the first 4MB of the address space is identity-mapped.
  1000. // This code allows access outside of the known used address ranges to get caught.
  1001. InterruptDisabler disabler;
  1002. if (laddr.get() >= ksyms().first().address && laddr.get() <= ksyms().last().address)
  1003. return true;
  1004. if (is_kmalloc_address((void*)laddr.get()))
  1005. return true;
  1006. return validate_user_read(laddr);
  1007. }
  1008. bool Process::validate_user_read(LinearAddress laddr) const
  1009. {
  1010. InterruptDisabler disabler;
  1011. return MM.validate_user_read(*this, laddr);
  1012. }
  1013. bool Process::validate_user_write(LinearAddress laddr) const
  1014. {
  1015. InterruptDisabler disabler;
  1016. return MM.validate_user_write(*this, laddr);
  1017. }
  1018. pid_t Process::sys$getsid(pid_t pid)
  1019. {
  1020. if (pid == 0)
  1021. return m_sid;
  1022. InterruptDisabler disabler;
  1023. auto* process = Process::fromPID(pid);
  1024. if (!process)
  1025. return -ESRCH;
  1026. if (m_sid != process->m_sid)
  1027. return -EPERM;
  1028. return process->m_sid;
  1029. }
  1030. pid_t Process::sys$setsid()
  1031. {
  1032. InterruptDisabler disabler;
  1033. bool found_process_with_same_pgid_as_my_pid = false;
  1034. forEachProcess([&] (auto& process) {
  1035. if (process.pgid() == pid()) {
  1036. found_process_with_same_pgid_as_my_pid = true;
  1037. return false;
  1038. }
  1039. return true;
  1040. });
  1041. if (found_process_with_same_pgid_as_my_pid)
  1042. return -EPERM;
  1043. m_sid = m_pid;
  1044. m_pgid = m_pid;
  1045. return m_sid;
  1046. }
  1047. pid_t Process::sys$getpgid(pid_t pid)
  1048. {
  1049. if (pid == 0)
  1050. return m_pgid;
  1051. InterruptDisabler disabler; // FIXME: Use a ProcessHandle
  1052. auto* process = Process::fromPID(pid);
  1053. if (!process)
  1054. return -ESRCH;
  1055. return process->m_pgid;
  1056. }
  1057. pid_t Process::sys$getpgrp()
  1058. {
  1059. return m_pgid;
  1060. }
  1061. static pid_t get_sid_from_pgid(pid_t pgid)
  1062. {
  1063. InterruptDisabler disabler;
  1064. auto* group_leader = Process::fromPID(pgid);
  1065. if (!group_leader)
  1066. return -1;
  1067. return group_leader->sid();
  1068. }
  1069. int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
  1070. {
  1071. InterruptDisabler disabler; // FIXME: Use a ProcessHandle
  1072. pid_t pid = specified_pid ? specified_pid : m_pid;
  1073. if (specified_pgid < 0)
  1074. return -EINVAL;
  1075. auto* process = Process::fromPID(pid);
  1076. if (!process)
  1077. return -ESRCH;
  1078. pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid;
  1079. pid_t current_sid = get_sid_from_pgid(process->m_pgid);
  1080. pid_t new_sid = get_sid_from_pgid(new_pgid);
  1081. if (current_sid != new_sid) {
  1082. // Can't move a process between sessions.
  1083. return -EPERM;
  1084. }
  1085. // FIXME: There are more EPERM conditions to check for here..
  1086. process->m_pgid = new_pgid;
  1087. return 0;
  1088. }