diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 54de1dc94f..3575a3cb3e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -121,6 +121,7 @@ else()
 
     if (ARCHITECTURE_x86_64)
         add_compile_options("-mcx16")
+        add_compile_options("-fwrapv")
     endif()
 
     if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index abde2a6d35..0e22d92730 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -52,6 +52,8 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
             return IocCtrlEventRegister(input, output);
         case 0x20:
             return IocCtrlEventUnregister(input, output);
+        case 0x21:
+            return IocCtrlEventUnregisterBatch(input, output);
         }
         break;
     default:
@@ -249,6 +251,25 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input,
     return FreeEvent(event_id);
 }
 
+NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(const std::vector<u8>& input,
+                                                  std::vector<u8>& output) {
+    IocCtrlEventUnregisterBatchParams params{};
+    std::memcpy(&params, input.data(), sizeof(params));
+    u64 event_mask = params.user_events;
+    LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask);
+
+    auto lock = NvEventsLock();
+    while (event_mask != 0) {
+        const u64 event_id = std::countr_zero(event_mask);
+        event_mask &= ~(1ULL << event_id);
+        const auto result = FreeEvent(static_cast<u32>(event_id));
+        if (result != NvResult::Success) {
+            return result;
+        }
+    }
+    return NvResult::Success;
+}
+
 NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output) {
     IocCtrlEventClearParams params{};
     std::memcpy(&params, input.data(), sizeof(params));
@@ -362,10 +383,11 @@ u32 nvhost_ctrl::FindFreeNvEvent(u32 syncpoint_id) {
 }
 
 void nvhost_ctrl::SignalNvEvent(u32 syncpoint_id, u32 value) {
-    const u32 max = MaxNvEvents - std::countl_zero(events_mask);
-    const u32 min = std::countr_zero(events_mask);
-    for (u32 i = min; i < max; i++) {
-        auto& event = events[i];
+    u64 signal_mask = events_mask;
+    while (signal_mask != 0) {
+        const u64 event_id = std::countr_zero(signal_mask);
+        signal_mask &= ~(1ULL << event_id);
+        auto& event = events[event_id];
         if (event.assigned_syncpt != syncpoint_id || event.assigned_value != value) {
             continue;
         }
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index f2fc5d0472..9bd10257bb 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -177,16 +177,17 @@ private:
     static_assert(sizeof(IocCtrlEventUnregisterParams) == 4,
                   "IocCtrlEventUnregisterParams is incorrect size");
 
-    struct IocCtrlEventKill {
+    struct IocCtrlEventUnregisterBatchParams {
         u64_le user_events{};
     };
-    static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size");
+    static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, "IocCtrlEventKill is incorrect size");
 
     NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output);
     NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output,
                               bool is_allocation);
     NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output);
     NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output);
+    NvResult IocCtrlEventUnregisterBatch(const std::vector<u8>& input, std::vector<u8>& output);
     NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output);
 
     NvResult FreeEvent(u32 slot);
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 80a1c69e00..8c0ff00941 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -249,6 +249,11 @@ struct GPU::Impl {
 
     void RegisterSyncptInterrupt(u32 syncpoint_id, u32 value) {
         std::scoped_lock lock{sync_mutex};
+        u32 current_value = syncpoints.at(syncpoint_id).load();
+        if ((static_cast<s32>(current_value) - static_cast<s32>(value)) >= 0) {
+            TriggerCpuInterrupt(syncpoint_id, value);
+            return;
+        }
         auto& interrupt = syncpt_interrupts.at(syncpoint_id);
         bool contains = std::any_of(interrupt.begin(), interrupt.end(),
                                     [value](u32 in_value) { return in_value == value; });