summaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-gembird.c
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2026-09-23 09:37:21 -0700
committerPaolo Bonzini <pbonzini@redhat.com>2026-09-26 00:39:55 -0400
commit93de2a6a4b91b72607136dd656edf03fb399d27f (patch)
tree9220c76eb23cb39a146fac9692ee69afa4aa3135 /drivers/hid/hid-gembird.c
downloadlinux-stable-93de2a6a4b91b72607136dd656edf03fb399d27f.tar.gz
linux-stable-93de2a6a4b91b72607136dd656edf03fb399d27f.zip
KVM: SEV: Do cache maintenance on the source VM during intra-host migrationgrafted
Manually perform cache maintenance on the source VM during intra-host migration to ensure no stale data is left in CPU caches after the VM is destroyed. Because the source VM is "converted" to a non-SEV VM, KVM's memory reclaim flows won't trigger cache maintenance, e.g. when all guest memory is reclaimed in response to detaching from the mmu_notifier. Note, relying on the destination VM to do cache maintenance isn't an option as KVM doesn't require identical guest memory configurations, i.e. the source VM may have access to memory that the destination VM does not. Enforcing equivalent memory configurations is infeasible, as it would require a *deep* comparison of memslots, e.g. to verify that not only are the memslot identical, but what the memslots point at is also identical. Fixes: b56639318bb2 ("KVM: SEV: Add support for SEV intra host migration") Cc: stable@vger.kernel.org Reported-by: Stefan Teodorescu <fane@google.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20260923163721.1584779-3-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'drivers/hid/hid-gembird.c')
-rw-r--r--drivers/hid/hid-gembird.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/drivers/hid/hid-gembird.c b/drivers/hid/hid-gembird.c
new file mode 100644
index 000000000..20a8de766
--- /dev/null
+++ b/drivers/hid/hid-gembird.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * HID driver for Gembird Joypad, "PC Game Controller"
+ *
+ * Copyright (c) 2015 Red Hat, Inc
+ * Copyright (c) 2015 Benjamin Tissoires
+ */
+
+/*
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define GEMBIRD_START_FAULTY_RDESC 8
+
+static const __u8 gembird_jpd_faulty_rdesc[] = {
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x05, /* Report Count (5) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xff, 0x00, /* Logical Maximum (255) */
+ 0x35, 0x00, /* Physical Minimum (0) */
+ 0x46, 0xff, 0x00, /* Physical Maximum (255) */
+ 0x09, 0x30, /* Usage (X) */
+ 0x09, 0x31, /* Usage (Y) */
+ 0x09, 0x32, /* Usage (Z) */
+ 0x09, 0x32, /* Usage (Z) */
+ 0x09, 0x35, /* Usage (Rz) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+};
+
+/*
+ * we fix the report descriptor by:
+ * - marking the first Z axis as constant (so it is ignored by HID)
+ * - assign the original second Z to Rx
+ * - assign the original Rz to Ry
+ */
+static const __u8 gembird_jpd_fixed_rdesc[] = {
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x02, /* Report Count (2) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xff, 0x00, /* Logical Maximum (255) */
+ 0x35, 0x00, /* Physical Minimum (0) */
+ 0x46, 0xff, 0x00, /* Physical Maximum (255) */
+ 0x09, 0x30, /* Usage (X) */
+ 0x09, 0x31, /* Usage (Y) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x09, 0x32, /* Usage (Z) */
+ 0x81, 0x01, /* Input (Cnst,Arr,Abs) */
+ 0x95, 0x02, /* Report Count (2) */
+ 0x09, 0x33, /* Usage (Rx) */
+ 0x09, 0x34, /* Usage (Ry) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+};
+
+static const __u8 *gembird_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+{
+ __u8 *new_rdesc;
+ /* delta_size is > 0 */
+ size_t delta_size = sizeof(gembird_jpd_fixed_rdesc) -
+ sizeof(gembird_jpd_faulty_rdesc);
+ size_t new_size = *rsize + delta_size;
+
+ if (*rsize >= 31 && !memcmp(&rdesc[GEMBIRD_START_FAULTY_RDESC],
+ gembird_jpd_faulty_rdesc,
+ sizeof(gembird_jpd_faulty_rdesc))) {
+ new_rdesc = devm_kzalloc(&hdev->dev, new_size, GFP_KERNEL);
+ if (new_rdesc == NULL)
+ return rdesc;
+
+ dev_info(&hdev->dev,
+ "fixing Gembird JPD-DualForce 2 report descriptor.\n");
+
+ /* start by copying the end of the rdesc */
+ memcpy(new_rdesc + delta_size, rdesc, *rsize);
+
+ /* add the correct beginning */
+ memcpy(new_rdesc, rdesc, GEMBIRD_START_FAULTY_RDESC);
+
+ /* replace the faulty part with the fixed one */
+ memcpy(new_rdesc + GEMBIRD_START_FAULTY_RDESC,
+ gembird_jpd_fixed_rdesc,
+ sizeof(gembird_jpd_fixed_rdesc));
+
+ *rsize = new_size;
+ rdesc = new_rdesc;
+ }
+
+ return rdesc;
+}
+
+static const struct hid_device_id gembird_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD,
+ USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, gembird_devices);
+
+static struct hid_driver gembird_driver = {
+ .name = "gembird",
+ .id_table = gembird_devices,
+ .report_fixup = gembird_report_fixup,
+};
+module_hid_driver(gembird_driver);
+
+MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
+MODULE_DESCRIPTION("HID Gembird joypad driver");
+MODULE_LICENSE("GPL");