get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.1/patches/2229757/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2229757,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229757/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260428153946.1802-1-yanjiewtw@gmail.com/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20260428153946.1802-1-yanjiewtw@gmail.com>",
    "date": "2026-04-28T15:39:46",
    "name": "hw/i386/vapic: revalidate TPR instruction before patching",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "e63d622aca401a6f8df9b047156c664a2792c0ff",
    "submitter": {
        "id": 93275,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/93275/?format=api",
        "name": "Yan-Jie Wang",
        "email": "yanjiewtw@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260428153946.1802-1-yanjiewtw@gmail.com/mbox/",
    "series": [
        {
            "id": 501909,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/501909/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=501909",
            "date": "2026-04-28T15:39:46",
            "name": "hw/i386/vapic: revalidate TPR instruction before patching",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501909/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2229757/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2229757/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=oUAz1uyA;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4nJY2cl0z1xrS\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 03:20:43 +1000 (AEST)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wHm6d-0003LO-70; Tue, 28 Apr 2026 13:20:19 -0400",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <yanjiewtw@gmail.com>)\n id 1wHkXw-0005Zz-PR\n for qemu-devel@nongnu.org; Tue, 28 Apr 2026 11:40:24 -0400",
            "from mail-pg1-x52f.google.com ([2607:f8b0:4864:20::52f])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <yanjiewtw@gmail.com>)\n id 1wHkXs-0007no-RU\n for qemu-devel@nongnu.org; Tue, 28 Apr 2026 11:40:24 -0400",
            "by mail-pg1-x52f.google.com with SMTP id\n 41be03b00d2f7-c70c112cb61so7575391a12.0\n for <qemu-devel@nongnu.org>; Tue, 28 Apr 2026 08:40:17 -0700 (PDT)",
            "from YanJie-Laptop\n (2001-b011-3817-7976-54ea-e6f1-3f33-d05a.dynamic-ip6.hinet.net.\n [2001:b011:3817:7976:54ea:e6f1:3f33:d05a])\n by smtp.gmail.com with ESMTPSA id\n d2e1a72fcca58-834daf624d9sm3056952b3a.43.2026.04.28.08.40.13\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 28 Apr 2026 08:40:14 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1777390816; x=1777995616; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=DhlNy2l7cJVTYuDoPsfamzM3U+g7x1THoUSGf0UMe5o=;\n b=oUAz1uyALKWGEyJBYSs86RkFvyRFdwTpXBMWpLG1hCy4a942xZa2JbFZcI9F1LwCSI\n SRxgkdn0tkARcd6uswu68cwvAszy9byj3cXykcwWgq7ovbxTq3f9pMCAwPrG5hfqXhFa\n Pv0OHUrhZ4ucJ5EX4IcSosxuaS9JuDb36s3Xu+yLa6IjEos+dL4ZO1M5UAGSmTgpv5KZ\n XyzGKk1G+ek0imp6X3kq/c0Q9P9zRgkbq0ALnfTXJ8QReAVb1ZZT5JyY0Xonaulcqh3j\n r3SJ4ZIthADjw+YhdSrpBThDjLyaTkNyyLTXwfB8Dy/x3K4vqXgYd2OO+6/JsjELzOfH\n KPFw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777390816; x=1777995616;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=DhlNy2l7cJVTYuDoPsfamzM3U+g7x1THoUSGf0UMe5o=;\n b=YUZW1A7bYMPx2IXn17DOgzzWuJvBjIDEvK+m5I6P2T1JLbL8fBJr4YrlUhv/XYLEd8\n HWuGc8it39upeYf3mAUG3RH9EDSNcUn/rGVBxMRypjQ4odxeNFMB7maAc6oMqIw5e1nL\n 1W1eTuRPK8PEw7ChisacIdWuJ25syOe9a3LsD4jl2r9JI4/RzPSky9lVjmYAndtYPIcl\n IqRbIPpLUCOrAsKTZKEEz+qyCq/0OxrCh1K4LATbLbF73UAKnhp523ivUbZb5bcgurcC\n Qne5/LWRArlV2OXM8Ek/fhxBCZD2HeOFgO+GPKTx3cWYfH2yHclwtG2nx5JL/2m11n+E\n 7tGQ==",
        "X-Gm-Message-State": "AOJu0YwPUscYybpubNoA0H/y1zaDM65raoFFVBJu2xKTCzfbZh6jUuoH\n R8t1mIWSJ8Wu7U8Tx4gDeLDQpC2C1jYWGeapiwmZNANCwp7gW7ZplOU2oKaC3PdQ6+8=",
        "X-Gm-Gg": "AeBDieuQ1esVq3RkouWJ1j9UjthPkRm6iKww8mIflM4Jw0qieKBNxuS1V8t2xAMCtOk\n cmBsAxP8hPx3pJMdqkxE1wZz1jvDk0/pR+v4RLfbbSvx72HWbcuyDY42GXxmCAa+6xlStNbvW6r\n iyJi62gnMyT6x4Ck6eTvoN6yf65tYDdyB5G8VI0flQbm+wZNkSeYXo7Fwmu+nTAl8cgb8OOHMeD\n us3uDy90gN7h485WdeEf3mnAtPa1B9Q11K3/E5pqq5Ry6S48EdYSjGHDDxK5KGj1yYYecfya90k\n SIVs5Q8dIjaBeBxzKOPBDnR+7SlSEMjQPzg6FMA3mLlxZp+tkm9M7xSJZnnxIk40y5ZNhF04pnL\n +KaqHPQIblcYGudVCbtHr22vvansFAgQ4xacYquc4/UfwZPTKuqgryXc570jUwE91u3ehZx/6rT\n 1QuyW9SJ6+0owH6pLnJ9hCwJnvIjZk9xntkhI0utkpb5WB9xy8DDyXs54/JTszZOYBBc3Kv+r5p\n 2Gzi4uvBVT+Mleglg4tNveEIsvYbFKYLqd95aKq3LKdRw==",
        "X-Received": "by 2002:a05:6a00:1d8e:b0:82f:250b:9f1b with SMTP id\n d2e1a72fcca58-834ddbbffdfmr3863710b3a.23.1777390815401;\n Tue, 28 Apr 2026 08:40:15 -0700 (PDT)",
        "From": "Yan-Jie Wang <yanjiewtw@gmail.com>",
        "To": "qemu-devel@nongnu.org",
        "Cc": "\"Michael S . Tsirkin\" <mst@redhat.com>,\n Paolo Bonzini <pbonzini@redhat.com>,\n Richard Henderson <richard.henderson@linaro.org>,\n Yan-Jie Wang <yanjiewtw@gmail.com>",
        "Subject": "[PATCH] hw/i386/vapic: revalidate TPR instruction before patching",
        "Date": "Tue, 28 Apr 2026 23:39:46 +0800",
        "Message-ID": "<20260428153946.1802-1-yanjiewtw@gmail.com>",
        "X-Mailer": "git-send-email 2.54.0.windows.1",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Received-SPF": "pass client-ip=2607:f8b0:4864:20::52f;\n envelope-from=yanjiewtw@gmail.com; helo=mail-pg1-x52f.google.com",
        "X-Spam_score_int": "-20",
        "X-Spam_score": "-2.1",
        "X-Spam_bar": "--",
        "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no",
        "X-Spam_action": "no action",
        "X-Mailman-Approved-At": "Tue, 28 Apr 2026 13:20:17 -0400",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "qemu development <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "The kvmvapic TPR optimization identifies a guest TPR access\ninstruction and queues do_patch_instruction() via async_safe_run_on_cpu()\nto patch the instruction later.\n\nIn a 32-bit Windows XP guest with multiple vCPUs, I observed that when the\nguest is about to reboot, several vCPUs may execute the same TPR access\ninstruction at nearly the same time. This can queue multiple patch\noperations for the same guest IP before any queued patch operation has\ncompleted.\n\nThe first queued work item may successfully patch the instruction. Later\nqueued work items then re-read the same guest IP and observe the already\npatched instruction bytes instead of the original TPR instruction. For\nexample, opcode 0x8b may already have been replaced with 0x90. The old\ncode treats this as an unexpected opcode and aborts QEMU.\n\nRecord the matched instruction bytes before queuing the patch operation,\nand re-read and compare the instruction before patching it. If the\ninstruction has already changed, leave it unchanged instead of aborting.\n\nUse warn_report_once() only for unexpected internal consistency failures,\nso the normal multi-vCPU already-patched case remains silent.\n\nResolves: https://gitlab.com/qemu-project/qemu/-/work_items/3296\nResolves: https://gitlab.com/qemu-project/qemu/-/work_items/3451\n\nSigned-off-by: Yan-Jie Wang <yanjiewtw@gmail.com>\n---\n hw/i386/vapic.c | 112 +++++++++++++++++++++++++++++++++++++-----------\n 1 file changed, 87 insertions(+), 25 deletions(-)",
    "diff": "diff --git a/hw/i386/vapic.c b/hw/i386/vapic.c\nindex 1acb9f91b2..1e16780008 100644\n--- a/hw/i386/vapic.c\n+++ b/hw/i386/vapic.c\n@@ -25,6 +25,7 @@\n #include \"exec/cpu-common.h\"\n #include \"migration/vmstate.h\"\n #include \"qom/object.h\"\n+#include \"qemu/error-report.h\"\n \n #define VAPIC_IO_PORT           0x7e\n \n@@ -80,6 +81,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VAPICROMState, VAPIC)\n \n #define TPR_INSTR_ABS_MODRM             0x1\n #define TPR_INSTR_MATCH_MODRM_REG       0x2\n+#define TPR_INSTR_MAX_LENGTH            10\n \n typedef struct TPRInstruction {\n     uint8_t opcode;\n@@ -194,7 +196,7 @@ static bool is_abs_modrm(uint8_t modrm)\n     return (modrm & 0xc7) == 0x05;\n }\n \n-static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr)\n+static bool opcode_matches(const uint8_t *opcode, const TPRInstruction *instr)\n {\n     return opcode[0] == instr->opcode &&\n         (!(instr->flags & TPR_INSTR_ABS_MODRM) || is_abs_modrm(opcode[1])) &&\n@@ -203,12 +205,13 @@ static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr)\n }\n \n static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,\n-                                    target_ulong *pip, TPRAccess access)\n+                                    target_ulong *pip, uint8_t *instr_bytes,\n+                                    size_t *pinstr_len, TPRAccess access)\n {\n     CPUState *cs = CPU(cpu);\n     const TPRInstruction *instr;\n     target_ulong ip = *pip;\n-    uint8_t opcode[2];\n+    size_t instr_len = 0;\n     uint32_t real_tpr_addr;\n     int i;\n \n@@ -239,26 +242,44 @@ static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,\n          */\n         for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {\n             instr = &tpr_instr[i];\n+            instr_len = instr->length;\n+            if (instr_len > TPR_INSTR_MAX_LENGTH) {\n+                warn_report_once(\"kvmvapic: TPR instruction length %zu \"\n+                                 \"exceeds maximum %d\",\n+                                 instr_len, TPR_INSTR_MAX_LENGTH);\n+                return -1;\n+            }\n             if (instr->access != access) {\n                 continue;\n             }\n-            if (cpu_memory_rw_debug(cs, ip - instr->length, opcode,\n-                                    sizeof(opcode), 0) < 0) {\n+            if (cpu_memory_rw_debug(cs, ip - instr_len, instr_bytes,\n+                                    instr_len, 0) < 0) {\n                 return -1;\n             }\n-            if (opcode_matches(opcode, instr)) {\n+            if (opcode_matches(instr_bytes, instr)) {\n                 ip -= instr->length;\n                 goto instruction_ok;\n             }\n         }\n         return -1;\n     } else {\n-        if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0) < 0) {\n-            return -1;\n-        }\n         for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {\n             instr = &tpr_instr[i];\n-            if (opcode_matches(opcode, instr)) {\n+            if (instr->length > TPR_INSTR_MAX_LENGTH) {\n+                warn_report_once(\"kvmvapic: TPR instruction length %zu \"\n+                                 \"exceeds maximum %d\",\n+                                 instr->length, TPR_INSTR_MAX_LENGTH);\n+                return -1;\n+            }\n+            /* tpr_instr must be sorted by length with shortest first */\n+            if (instr->length > instr_len) {\n+                instr_len = instr->length;\n+                if (cpu_memory_rw_debug(cs, ip, instr_bytes,\n+                                        instr_len, 0) < 0) {\n+                    return -1;\n+                }\n+            }\n+            if (opcode_matches(instr_bytes, instr)) {\n                 goto instruction_ok;\n             }\n         }\n@@ -270,11 +291,14 @@ instruction_ok:\n      * Grab the virtual TPR address from the instruction\n      * and update the cached values.\n      */\n-    if (cpu_memory_rw_debug(cs, ip + instr->addr_offset,\n-                            (void *)&real_tpr_addr,\n-                            sizeof(real_tpr_addr), 0) < 0) {\n+    if (instr->addr_offset + sizeof(real_tpr_addr) > instr->length) {\n+        warn_report_once(\n+            \"kvmvapic: TPR address offset %zu exceeds instruction length %zu\",\n+            (size_t)instr->addr_offset, instr->length);\n         return -1;\n     }\n+    memcpy(&real_tpr_addr, instr_bytes + instr->addr_offset,\n+           sizeof(real_tpr_addr));\n     real_tpr_addr = le32_to_cpu(real_tpr_addr);\n     if ((real_tpr_addr & 0xfff) != 0x80) {\n         return -1;\n@@ -283,6 +307,7 @@ instruction_ok:\n     update_guest_rom_state(s);\n \n     *pip = ip;\n+    *pinstr_len = instr->length;\n     return 0;\n }\n \n@@ -403,6 +428,8 @@ static void patch_call(X86CPU *cpu, target_ulong ip, uint32_t target)\n typedef struct PatchInfo {\n     VAPICHandlers *handler;\n     target_ulong ip;\n+    size_t instr_len;\n+    uint8_t instr[TPR_INSTR_MAX_LENGTH];\n } PatchInfo;\n \n static void do_patch_instruction(CPUState *cs, run_on_cpu_data data)\n@@ -411,19 +438,33 @@ static void do_patch_instruction(CPUState *cs, run_on_cpu_data data)\n     PatchInfo *info = (PatchInfo *) data.host_ptr;\n     VAPICHandlers *handlers = info->handler;\n     target_ulong ip = info->ip;\n-    uint8_t opcode[2];\n+    size_t instr_len = info->instr_len;\n+    uint8_t instr[TPR_INSTR_MAX_LENGTH];\n     uint32_t imm32 = 0;\n \n-    cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);\n+    /*\n+     * The instruction may have changed before this queued work item runs.\n+     * Leave it unchanged if it no longer matches the saved bytes.\n+     */\n+    if (instr_len == 0 || instr_len > TPR_INSTR_MAX_LENGTH) {\n+        warn_report_once(\n+            \"kvmvapic: saved TPR instruction length %zu is invalid\",\n+            instr_len);\n+        goto out;\n+    }\n+    if (cpu_memory_rw_debug(cs, ip, instr, instr_len, 0) < 0\n+        || memcmp(instr, info->instr, instr_len) != 0) {\n+        goto out;\n+    }\n \n-    switch (opcode[0]) {\n+    switch (instr[0]) {\n     case 0x89: /* mov r32 to r/m32 */\n-        patch_byte(x86_cpu, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */\n+        patch_byte(x86_cpu, ip, 0x50 + modrm_reg(instr[1]));  /* push reg */\n         patch_call(x86_cpu, ip + 1, handlers->set_tpr);\n         break;\n     case 0x8b: /* mov r/m32 to r32 */\n         patch_byte(x86_cpu, ip, 0x90);\n-        patch_call(x86_cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);\n+        patch_call(x86_cpu, ip + 1, handlers->get_tpr[modrm_reg(instr[1])]);\n         break;\n     case 0xa1: /* mov abs to eax */\n         patch_call(x86_cpu, ip, handlers->get_tpr[0]);\n@@ -432,8 +473,14 @@ static void do_patch_instruction(CPUState *cs, run_on_cpu_data data)\n         patch_call(x86_cpu, ip, handlers->set_tpr_eax);\n         break;\n     case 0xc7: /* mov imm32, r/m32 (c7/0) */\n+        if (sizeof(imm32) + 6 > instr_len) {\n+            warn_report_once(\n+                \"kvmvapic: TPR mov-imm instruction length %zu is too short\",\n+                instr_len);\n+            goto out;\n+        }\n         patch_byte(x86_cpu, ip, 0x68);  /* push imm32 */\n-        cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);\n+        memcpy(&imm32, instr + 6, sizeof(imm32));\n         cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);\n         patch_call(x86_cpu, ip + 5, handlers->set_tpr);\n         break;\n@@ -442,13 +489,18 @@ static void do_patch_instruction(CPUState *cs, run_on_cpu_data data)\n         patch_call(x86_cpu, ip + 1, handlers->get_tpr_stack);\n         break;\n     default:\n-        abort();\n+        warn_report_once(\"kvmvapic: unexpected TPR instruction opcode 0x%02x \"\n+                         \"while patching; leaving instruction unchanged\",\n+                         instr[0]);\n+        break;\n     }\n \n+out:\n     g_free(info);\n }\n \n-static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)\n+static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip,\n+                              const uint8_t *instr_bytes, size_t instr_len)\n {\n     MachineState *ms = MACHINE(qdev_get_machine());\n     CPUState *cs = CPU(cpu);\n@@ -461,10 +513,18 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)\n         handlers = &s->rom_state.mp;\n     }\n \n-    info  = g_new(PatchInfo, 1);\n+    if (instr_len == 0 || instr_len > TPR_INSTR_MAX_LENGTH) {\n+        warn_report_once(\n+            \"kvmvapic: not patching invalid TPR instruction length %zu\",\n+            instr_len);\n+        return;\n+    }\n+\n+    info = g_new(PatchInfo, 1);\n     info->handler = handlers;\n     info->ip = ip;\n-\n+    info->instr_len = instr_len;\n+    memcpy(info->instr, instr_bytes, instr_len);\n     async_safe_run_on_cpu(cs, do_patch_instruction, RUN_ON_CPU_HOST_PTR(info));\n }\n \n@@ -474,10 +534,12 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,\n     VAPICROMState *s = VAPIC(dev);\n     X86CPU *cpu = X86_CPU(cs);\n     CPUX86State *env = &cpu->env;\n+    size_t instr_len;\n+    uint8_t instr[TPR_INSTR_MAX_LENGTH];\n \n     cpu_synchronize_state(cs);\n \n-    if (evaluate_tpr_instruction(s, cpu, &ip, access) < 0) {\n+    if (evaluate_tpr_instruction(s, cpu, &ip, instr, &instr_len, access) < 0) {\n         if (s->state == VAPIC_ACTIVE) {\n             vapic_enable(s, cpu);\n         }\n@@ -489,7 +551,7 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,\n     if (vapic_enable(s, cpu) < 0) {\n         return;\n     }\n-    patch_instruction(s, cpu, ip);\n+    patch_instruction(s, cpu, ip, instr, instr_len);\n }\n \n typedef struct VAPICEnableTPRReporting {\n",
    "prefixes": []
}