summaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-gaff.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-gaff.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-gaff.c')
-rw-r--r--drivers/hid/hid-gaff.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
new file mode 100644
index 000000000..ec793a179
--- /dev/null
+++ b/drivers/hid/hid-gaff.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Force feedback support for GreenAsia (Product ID 0x12) based devices
+ *
+ * The devices are distributed under various names and the same USB device ID
+ * can be used in many game controllers.
+ *
+ * 0e8f:0012 "GreenAsia Inc. USB Joystick "
+ * - tested with MANTA Warior MM816 and SpeedLink Strike2 SL-6635.
+ *
+ * Copyright (c) 2008 Lukasz Lubojanski <lukasz@lubojanski.info>
+ */
+
+/*
+ */
+
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include "hid-ids.h"
+
+#ifdef CONFIG_GREENASIA_FF
+
+struct gaff_device {
+ struct hid_report *report;
+};
+
+static int hid_gaff_play(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ struct hid_device *hid = input_get_drvdata(dev);
+ struct gaff_device *gaff = data;
+ int left, right;
+
+ left = effect->u.rumble.strong_magnitude;
+ right = effect->u.rumble.weak_magnitude;
+
+ dbg_hid("called with 0x%04x 0x%04x", left, right);
+
+ left = left * 0xfe / 0xffff;
+ right = right * 0xfe / 0xffff;
+
+ gaff->report->field[0]->value[0] = 0x51;
+ gaff->report->field[0]->value[1] = 0x0;
+ gaff->report->field[0]->value[2] = right;
+ gaff->report->field[0]->value[3] = 0;
+ gaff->report->field[0]->value[4] = left;
+ gaff->report->field[0]->value[5] = 0;
+ dbg_hid("running with 0x%02x 0x%02x", left, right);
+ hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT);
+
+ gaff->report->field[0]->value[0] = 0xfa;
+ gaff->report->field[0]->value[1] = 0xfe;
+ gaff->report->field[0]->value[2] = 0x0;
+ gaff->report->field[0]->value[4] = 0x0;
+
+ hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT);
+
+ return 0;
+}
+
+static int gaff_input_configured(struct hid_device *hid, struct hid_input *hidinput)
+{
+ struct gaff_device *gaff;
+ struct hid_report *report;
+ struct list_head *report_list =
+ &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+ if (!list_is_first(&hidinput->list, &hid->inputs))
+ return 0;
+
+ report = list_first_entry_or_null(report_list, struct hid_report, list);
+ if (!report) {
+ hid_err(hid, "no output reports found\n");
+ return -ENODEV;
+ }
+ if (report->maxfield < 1) {
+ hid_err(hid, "no fields in the report\n");
+ return -ENODEV;
+ }
+
+ if (report->field[0]->report_count < 6) {
+ hid_err(hid, "not enough values in the field\n");
+ return -ENODEV;
+ }
+
+ gaff = kzalloc_obj(struct gaff_device);
+ if (!gaff)
+ return -ENOMEM;
+
+ gaff->report = report;
+ set_bit(FF_RUMBLE, dev->ffbit);
+
+ error = input_ff_create_memless(dev, gaff, hid_gaff_play);
+ if (error) {
+ kfree(gaff);
+ return error;
+ }
+
+ gaff->report->field[0]->value[0] = 0x51;
+ gaff->report->field[0]->value[1] = 0x00;
+ gaff->report->field[0]->value[2] = 0x00;
+ gaff->report->field[0]->value[3] = 0x00;
+ hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT);
+
+ gaff->report->field[0]->value[0] = 0xfa;
+ gaff->report->field[0]->value[1] = 0xfe;
+
+ hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT);
+
+ hid_info(hid, "Force Feedback for GreenAsia 0x12 devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n");
+
+ return 0;
+}
+#else
+static inline int gaff_input_configured(struct hid_device *hdev,
+ struct hid_input *hidinput)
+{
+ return 0;
+}
+#endif
+
+static const struct hid_device_id ga_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012), },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, ga_devices);
+
+static struct hid_driver ga_driver = {
+ .name = "greenasia",
+ .id_table = ga_devices,
+ .input_configured = gaff_input_configured,
+};
+module_hid_driver(ga_driver);
+
+MODULE_DESCRIPTION("Force feedback support for GreenAsia (Product ID 0x12) based devices");
+MODULE_LICENSE("GPL");