)]}'
{
  "commit": "f39b7d2b96e3e73c01bb678cd096f7baf0b9ab39",
  "tree": "5d75aca0bb322e055f9cf7096ab6279603191c58",
  "parents": [
    "a27dd2de68f37ba96fe164a42121daa5f0750afc"
  ],
  "author": {
    "name": "David Hildenbrand",
    "email": "david@redhat.com",
    "time": "Fri Nov 11 10:47:58 2022 -0500"
  },
  "committer": {
    "name": "Paolo Bonzini",
    "email": "pbonzini@redhat.com",
    "time": "Wed Jan 11 09:59:39 2023 +0100"
  },
  "message": "kvm: Atomic memslot updates\n\nIf we update an existing memslot (e.g., resize, split), we temporarily\nremove the memslot to re-add it immediately afterwards. These updates\nare not atomic, especially not for KVM VCPU threads, such that we can\nget spurious faults.\n\nLet\u0027s inhibit most KVM ioctls while performing relevant updates, such\nthat we can perform the update just as if it would happen atomically\nwithout additional kernel support.\n\nWe capture the add/del changes and apply them in the notifier commit\nstage instead. There, we can check for overlaps and perform the ioctl\ninhibiting only if really required (-\u003e overlap).\n\nTo keep things simple we don\u0027t perform additional checks that wouldn\u0027t\nactually result in an overlap -- such as !RAM memory regions in some\ncases (see kvm_set_phys_mem()).\n\nTo minimize cache-line bouncing, use a separate indicator\n(in_ioctl_lock) per CPU.  Also, make sure to hold the kvm_slots_lock\nwhile performing both actions (removing+re-adding).\n\nWe have to wait until all IOCTLs were exited and block new ones from\ngetting executed.\n\nThis approach cannot result in a deadlock as long as the inhibitor does\nnot hold any locks that might hinder an IOCTL from getting finished and\nexited - something fairly unusual. The inhibitor will always hold the BQL.\n\nAFAIKs, one possible candidate would be userfaultfd. If a page cannot be\nplaced (e.g., during postcopy), because we\u0027re waiting for a lock, or if the\nuserfaultfd thread cannot process a fault, because it is waiting for a\nlock, there could be a deadlock. However, the BQL is not applicable here,\nbecause any other guest memory access while holding the BQL would already\nresult in a deadlock.\n\nNothing else in the kernel should block forever and wait for userspace\nintervention.\n\nNote: pause_all_vcpus()/resume_all_vcpus() or\nstart_exclusive()/end_exclusive() cannot be used, as they either drop\nthe BQL or require to be called without the BQL - something inhibitors\ncannot handle. We need a low-level locking mechanism that is\ndeadlock-free even when not releasing the BQL.\n\nSigned-off-by: David Hildenbrand \u003cdavid@redhat.com\u003e\nSigned-off-by: Emanuele Giuseppe Esposito \u003ceesposit@redhat.com\u003e\nTested-by: Emanuele Giuseppe Esposito \u003ceesposit@redhat.com\u003e\nMessage-Id: \u003c20221111154758.1372674-4-eesposit@redhat.com\u003e\nSigned-off-by: Paolo Bonzini \u003cpbonzini@redhat.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "8760d55002cc59c6838806ebf3eaaa3e867df79b",
      "old_mode": 33188,
      "old_path": "accel/kvm/kvm-all.c",
      "new_id": "7e6a6076b16c8d293b4f274fd5722c6f5978f382",
      "new_mode": 33188,
      "new_path": "accel/kvm/kvm-all.c"
    },
    {
      "type": "modify",
      "old_id": "3b4adcdc101d2a009b0b870617dd025c66478ed0",
      "old_mode": 33188,
      "old_path": "include/sysemu/kvm_int.h",
      "new_id": "60b520a13e84e0e710e5575c850ddad5e5ab26fa",
      "new_mode": 33188,
      "new_path": "include/sysemu/kvm_int.h"
    }
  ]
}
