)]}'
{
  "commit": "7a1e025a7fa589ddb1c72f1f8e54cb0bb7ce8391",
  "tree": "a1f0a10458cc58d9a981e5a6cad55b3538ec815b",
  "parents": [
    "2aa94575a5a7b809c593f73487f25ec4e2e90098"
  ],
  "author": {
    "name": "Barret Rhoden",
    "email": "brho@cs.berkeley.edu",
    "time": "Wed Oct 23 18:56:05 2019 -0400"
  },
  "committer": {
    "name": "Barret Rhoden",
    "email": "brho@cs.berkeley.edu",
    "time": "Wed Oct 23 19:06:29 2019 -0400"
  },
  "message": "vmm: reimplement the x86 instruction decoder\n\nOur old decoder had a bunch of issues.  Whenever we get a new version of\nLinux, we tend to have new instructions that need decoding.  The old\ndecoder was hard to extend, and it was also hiding a bunch of bugs.\n\nHere are some of the problems the old decoder had:\n- It assumed every operation was a load or store.  Including cmp (which\ndoes not change registers/memory) and add (which does change them, but\nonly after adding).\n- It did not set rflags\n- It did not zero-extend 32-bit wide register results\n- *word was busted.  At one point, we did word++ when we meant to\nadvance by a byte.\n- etc.\n\nThe code was pretty \u0027swirly\u0027 too, where you\u0027d have similar processing\nrepeated all over the place, like the REX checks.\n\nTo fix that, I added a \u0027decode\u0027 struct, to pass along values that we\ndetermined, such as address size, operand size, rex bits, etc.\n\nBest of all, we weren\u0027t computing the size correctly, since we didn\u0027t\nreally do the modrm handling right.  Here\u0027s the case:\n\n\t81 7d 00 5f 4d 50 5f    cmp    DWORD PTR [rbp+0x0],0x5f504d5f\n\nThat was being treated like it is only 4 bytes long, instead of 7.\nWhoops!\n\nHowever, it didn\u0027t crash, even though we set RIP to be part way (4\nbytes) into the instruction!  Why?  well, those extra three bytes that\nare just arbitrary numbers in the immediate32 part of the instruction\n(which we end up running) decodes too!\n\n\t0:  4d 50                   rex.WRB push r8\n\t2:  5f                      pop    rdi\n\nIt pushes and pops, essentially clobbering rdi.  The Linux guest ends up\nresetting rdi later, so no one noticed.\n\nHad it been another value for the immed, we\u0027d execute that too.  It\nmight blow up, and we\u0027d notice.  But this one silently executed and\nsilently trashed a register.\n\nTo fix that, I needed better mod/rm+sib handling.  We still get away\nwith using GPA instead of decoding modrm+sib and translating through the\nguest\u0027s page tables.  Ron\u0027s comment still applies.  \u003d)\n\nTo handle the emulation of instructions, I had our callers pass us the\n\u0027access()\u0027 function.  So we can handle read-modify-write instructions,\nlike add.  Those didn\u0027t need to change too much, though I yanked out\ndestreg, which was just debug clutter.\n\nI could have broken the commit up a little bit, but there wasn\u0027t a lot\nof value in it, since the whole thing needed to be overhauled.\n\nNote that the APIC_ACCESS and WRITE exits never happen.  That might have\nbeen the case ever since we started using the x2APIC for the guest.\n\nSigned-off-by: Barret Rhoden \u003cbrho@cs.berkeley.edu\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "78a9930f50c58149667ca4a5f70083cca197c765",
      "old_mode": 33188,
      "old_path": "user/vmm/apic.c",
      "new_id": "bc164c2f71899ecaade64df9cdd88fda4a4a46e9",
      "new_mode": 33188,
      "new_path": "user/vmm/apic.c"
    },
    {
      "type": "modify",
      "old_id": "d0a0dffa98cba53f728a2c89ac3a30386b936bf7",
      "old_mode": 33188,
      "old_path": "user/vmm/decode.c",
      "new_id": "f61de3774b141522f3f7e52e225b011e9c9b3257",
      "new_mode": 33188,
      "new_path": "user/vmm/decode.c"
    },
    {
      "type": "modify",
      "old_id": "5a8d91f9138aa93ff222efc4501ca88db9a7c783",
      "old_mode": 33188,
      "old_path": "user/vmm/include/vmm/vmm.h",
      "new_id": "447a8f3efd2371ffbed6845f96ca3dc2608baf53",
      "new_mode": 33188,
      "new_path": "user/vmm/include/vmm/vmm.h"
    },
    {
      "type": "modify",
      "old_id": "9111d0c7b871e67d761fb162be737a890622178d",
      "old_mode": 33188,
      "old_path": "user/vmm/ioapic.c",
      "new_id": "0b35f63aa1b9fab148a23f38edded4f34c9826d5",
      "new_mode": 33188,
      "new_path": "user/vmm/ioapic.c"
    },
    {
      "type": "modify",
      "old_id": "11538959bb10c82bb9e0d22945b111da8f7cf6e8",
      "old_mode": 33188,
      "old_path": "user/vmm/vmexit.c",
      "new_id": "ca83fc9ee39a11caa10abf70ba1cbef9da23064e",
      "new_mode": 33188,
      "new_path": "user/vmm/vmexit.c"
    },
    {
      "type": "modify",
      "old_id": "1d450f835751e6a978fc64714de33a09a58edf14",
      "old_mode": 33188,
      "old_path": "user/vmm/vmx.c",
      "new_id": "eb3ae1c5cde1ed91108eedd214e8e84f12d7f68c",
      "new_mode": 33188,
      "new_path": "user/vmm/vmx.c"
    }
  ]
}
