{"id":2223931,"url":"http://patchwork.ozlabs.org/api/patches/2223931/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260416121116.527927-9-magnuskulke@linux.microsoft.com/","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/projects/14/?format=json","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":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260416121116.527927-9-magnuskulke@linux.microsoft.com>","list_archive_url":null,"date":"2026-04-16T12:11:15","name":"[v6,8/9] target/i386/mshv: use hv-provided [0xD,1+2].EBX","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"b2666e7c60d0370930e93308a13b04cd211e345a","submitter":{"id":90753,"url":"http://patchwork.ozlabs.org/api/people/90753/?format=json","name":"Magnus Kulke","email":"magnuskulke@linux.microsoft.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260416121116.527927-9-magnuskulke@linux.microsoft.com/mbox/","series":[{"id":500142,"url":"http://patchwork.ozlabs.org/api/series/500142/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/list/?series=500142","date":"2026-04-16T12:11:08","name":"Support QEMU cpu models in MSHV accelerator","version":6,"mbox":"http://patchwork.ozlabs.org/series/500142/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2223931/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2223931/checks/","tags":{},"related":[],"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 (1024-bit key;\n unprotected) header.d=linux.microsoft.com header.i=@linux.microsoft.com\n header.a=rsa-sha256 header.s=default header.b=b1grMpiw;\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 4fxH1v6f44z1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 16 Apr 2026 22:12:03 +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 1wDLZQ-0008Sn-6C; Thu, 16 Apr 2026 08:11:44 -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 <magnuskulke@linux.microsoft.com>)\n id 1wDLZO-0008QP-Mq\n for qemu-devel@nongnu.org; Thu, 16 Apr 2026 08:11:42 -0400","from linux.microsoft.com ([13.77.154.182])\n by eggs.gnu.org with esmtp (Exim 4.90_1)\n (envelope-from <magnuskulke@linux.microsoft.com>) id 1wDLZM-0002Oj-Og\n for qemu-devel@nongnu.org; Thu, 16 Apr 2026 08:11:42 -0400","from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.32])\n by linux.microsoft.com (Postfix) with ESMTPSA id 9D59920B7129;\n Thu, 16 Apr 2026 05:11:38 -0700 (PDT)"],"DKIM-Filter":"OpenDKIM Filter v2.11.0 linux.microsoft.com 9D59920B7129","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com;\n s=default; t=1776341500;\n bh=zdYRIkg+oa2YRSRRDin+ckBgXO9q8zPFkYu1dCSFXfQ=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=b1grMpiw8on1/7hA1D6Fx8F20wcgzNVUsyexkgCnNzx6nVZ3pRhzSfaNvNKNWaJP0\n Otzs5X0Mve4GMCpUMpUrvuAV9vpBNJhAfLKsqwUdqrE03TsGJa0sKYcnsAUOEpH+1K\n 5vATUK3KAAEi5bLgjwdyWbnqlvJb9iR/VNPOEEk4=","From":"Magnus Kulke <magnuskulke@linux.microsoft.com>","To":"qemu-devel@nongnu.org","Cc":"Wei Liu <wei.liu@kernel.org>,\n Magnus Kulke <magnuskulke@linux.microsoft.com>,\n Zhao Liu <zhao1.liu@intel.com>, Paolo Bonzini <pbonzini@redhat.com>,\n Wei Liu <liuwe@microsoft.com>, Magnus Kulke <magnuskulke@microsoft.com>","Subject":"[PATCH v6 8/9] target/i386/mshv: use hv-provided [0xD,1+2].EBX","Date":"Thu, 16 Apr 2026 14:11:15 +0200","Message-Id":"<20260416121116.527927-9-magnuskulke@linux.microsoft.com>","X-Mailer":"git-send-email 2.34.1","In-Reply-To":"<20260416121116.527927-1-magnuskulke@linux.microsoft.com>","References":"<20260416121116.527927-1-magnuskulke@linux.microsoft.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Received-SPF":"pass client-ip=13.77.154.182;\n envelope-from=magnuskulke@linux.microsoft.com; helo=linux.microsoft.com","X-Spam_score_int":"-42","X-Spam_score":"-4.3","X-Spam_bar":"----","X-Spam_report":"(-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","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":"We cannot statically set the responses for CPUID[0xD,{1,2}].EBX, b/c\nthose are dynamic, dependent on which features the guest enables.\n\nHence we mask EBX when registering answers for those subleaves at the\nhypervisor, which will result in the hypervisor providing us answers,\nconsidering XCR0 and XSS.\n\nThe reported size now reflects the field masks properly (without the\nmask they were 576 and 10728, which is wrong):\n\n$ cpuid -l 0xd -s 0\nCPU 0:\n   XSAVE features (0xd/0):\n      XCR0 valid bit field mask               = 0x00000000000600e7\n      ...\n      bytes required by fields in XCR0        = 0x00002b00 (11008)\n      bytes required by XSAVE/XRSTOR area     = 0x00002b00 (11008)\n\n$ cpuid -l 0xd -s 1\nCPU 0:\n   XSAVE features (0xd/1):\n      ...\n      SAVE area size in bytes                     = 0x000029c0 (10688)\n      IA32_XSS lower 32 bits valid bit field mask = 0x00001800\n      IA32_XSS upper 32 bits valid bit field mask = 0x00000000\n\nSigned-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>\n---\n target/i386/mshv/mshv-cpu.c | 23 +++++++++++++++++++++--\n 1 file changed, 21 insertions(+), 2 deletions(-)","diff":"diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c\nindex ee25eb5f6f..b90e2983c8 100644\n--- a/target/i386/mshv/mshv-cpu.c\n+++ b/target/i386/mshv/mshv-cpu.c\n@@ -528,6 +528,7 @@ static void collect_cpuid_entries(const CPUState *cpu, GList **cpuid_entries)\n static int register_intercept_result_cpuid_entry(const CPUState *cpu,\n                                                  uint8_t subleaf_specific,\n                                                  uint8_t always_override,\n+                                                 uint32_t ebx_mask,\n                                                  struct hv_cpuid_entry *entry)\n {\n     int ret;\n@@ -543,11 +544,12 @@ static int register_intercept_result_cpuid_entry(const CPUState *cpu,\n         /*\n          * Masks specify which bits to override. Set to 0xFFFFFFFF to\n          * override all bits with the values from the QEMU CPU model.\n+         * A mask of 0 lets the hypervisor supply its own value.\n          */\n         .result.eax = entry->eax,\n         .result.eax_mask = 0xFFFFFFFF,\n         .result.ebx = entry->ebx,\n-        .result.ebx_mask = 0xFFFFFFFF,\n+        .result.ebx_mask = ebx_mask,\n         .result.ecx = entry->ecx,\n         .result.ecx_mask = 0xFFFFFFFF,\n         .result.edx = entry->edx,\n@@ -582,6 +584,7 @@ static int register_intercept_result_cpuid(const CPUState *cpu,\n     int ret = 0, entry_ret;\n     struct hv_cpuid_entry *entry;\n     uint8_t subleaf_specific, always_override;\n+    uint32_t ebx_mask;\n \n     for (size_t i = 0; i < cpuid->nent; i++) {\n         entry = &cpuid->entries[i];\n@@ -589,6 +592,7 @@ static int register_intercept_result_cpuid(const CPUState *cpu,\n         /* set defaults */\n         subleaf_specific = 0;\n         always_override = 1;\n+        ebx_mask = 0xFFFFFFFF;\n \n         /*\n          * Intel\n@@ -628,8 +632,22 @@ static int register_intercept_result_cpuid(const CPUState *cpu,\n             always_override = 1;\n         }\n \n-        entry_ret = register_intercept_result_cpuid_entry(cpu, subleaf_specific,\n+        /*\n+         * CPUID[0xD,0].EBX and CPUID[0xD,1].EBX report the XSAVE area\n+         * size based on features currently enabled in XCR0/XSS. These\n+         * values are dynamic and must not be overridden with static\n+         * results from the QEMU CPU model. Setting ebx_mask to 0 lets\n+         * the hypervisor supply EBX based on the guest's actual state.\n+         */\n+        if (entry->function == 0x0d &&\n+           (entry->index == 0 || entry->index == 1)) {\n+            ebx_mask = 0;\n+        }\n+\n+        entry_ret = register_intercept_result_cpuid_entry(cpu,\n+                                                          subleaf_specific,\n                                                           always_override,\n+                                                          ebx_mask,\n                                                           entry);\n         if ((entry_ret < 0) && (ret == 0)) {\n             ret = entry_ret;\n@@ -1663,6 +1681,7 @@ uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg)\n     if (func == 0x01       && reg == R_ECX) {\n         ret &= ~CPUID_EXT_VMX;\n     }\n+\n     return ret;\n }\n \n","prefixes":["v6","8/9"]}