)]}'
{
  "commit": "7e9ef4d35c9aa707f274b019acaf06b682639f50",
  "tree": "054e7fa2a4c62a955c4a23298f5aa7847c2ac6f8",
  "parents": [
    "d7abf316488c4540764f6682632b053b308654fc"
  ],
  "author": {
    "name": "Barret Rhoden",
    "email": "brho@cs.berkeley.edu",
    "time": "Tue Jul 12 14:30:39 2016 -0400"
  },
  "committer": {
    "name": "Barret Rhoden",
    "email": "brho@cs.berkeley.edu",
    "time": "Tue Jul 19 11:43:10 2016 -0400"
  },
  "message": "x86: Ensure boot_pgdir\u0027s user entries are unmapped\n\nFor sanity reasons, we should never have anything in boot_pgdir below ULIM.\nTechnically, we could make it work, but not without some thought.  The\nissues is that PML4 entries are pointers, pointing to common PML3s.  Any\nentry in boot_pgdir is shared with every process, from the PML3 on down.\nThe kernel expects to manage and synchronize global access to the kernel\nmappings (above ULIM).  But memory below ULIM is managed per-process.\n\nBackstory: I was trying to debug a null function pointer by mapping\nsomething at page 0.  The kernel panicked after decreffing a page too many\ntimes.\n\nWhat happened was that inserting one page at virtual addr 0 created a PML3,\nPML2, and PML1 that was shared between every process - not just the page\nmapped at 0.  This PTE reach was 512 GB, including the program binary\n(which was in the page cache).\n\nThe first process was fine.  However, when we forked, the pages for e.g.\nbusybox\u0027s text segment already had PTEs in the new process\u0027s address space.\nTechnically, they were the same PTEs (and PML3, 2, and 1) as the parent\nprocess, since they were shared data structures.\n\nAnyway, map_page_at_addr() saw that the PTE had a mapping, so it decreffed\nthe page before inserting a new page.  It just so happened that the new\npage was the same as the old one, since it was a fork (duplicate_vmrs,\netc).  That page had a single refcnt, since it was managed by the page\ncache, causing it to be freed.\n\nNow the page is freed, but it is in the page tables still, since\nmap_page_at_addr() wrote the PTE with the value of the page.  Basically, it\nwas a \"replace the PTE with its own value\", but it triggered a decref.\n\nNext up was the VMR for busybox\u0027s MAP_PRIVATE vmr.  Since it\u0027s a private\nmapping, it gets its own page.  upage_alloc() gives us the most recently\nfreed page, which was the one that was still in the address space, right at\nthe top of the text segment.\n\nEventually the process page faults, probably because of the madness of its\naddress space.  When it does, the kernel puts every page in the VMRs.  At\nleast one page (the one we discussed) was in there twice.  The second\ndecref triggers the kref assert, since we decreffed something that was\nalready 0.\n\nGood times.\n\nSigned-off-by: Barret Rhoden \u003cbrho@cs.berkeley.edu\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "1c2ac2dcd187f0b1f15776963e13426c91eec335",
      "old_mode": 33188,
      "old_path": "kern/arch/x86/pmap64.c",
      "new_id": "09469a957218e1f9fa125335cfab5257c400280d",
      "new_mode": 33188,
      "new_path": "kern/arch/x86/pmap64.c"
    },
    {
      "type": "modify",
      "old_id": "c43f01e17012d3ab5fcf32076d172cf8653f2d52",
      "old_mode": 33188,
      "old_path": "kern/src/env.c",
      "new_id": "2abc57c3bb171fb7834c54439130b5c26e46a4bc",
      "new_mode": 33188,
      "new_path": "kern/src/env.c"
    }
  ]
}
