All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Doru Blânzeanu" <dblanzeanu@linux.microsoft.com>
To: qemu-devel@nongnu.org
Cc: "Wei Liu" <wei.liu@kernel.org>,
	"Magnus Kulke" <magnuskulke@microsoft.com>,
	"Wei Liu" <liuwe@microsoft.com>,
	"Magnus Kulke" <magnuskulke@linux.microsoft.com>,
	"Doru Blânzeanu" <dblanzeanu@microsoft.com>,
	"Doru Blânzeanu" <dblanzeanu@linux.microsoft.com>
Subject: [PATCH 1/2] accel/mshv: size XSAVE buffers from the hypervisor
Date: Mon,  7 Sep 2026 17:23:54 +0300	[thread overview]
Message-ID: <20260907142355.141033-2-dblanzeanu@linux.microsoft.com> (raw)
In-Reply-To: <20260907142355.141033-1-dblanzeanu@linux.microsoft.com>

Query MAX_XSAVE_DATA_SIZE at vcpu creation and cache it in MshvState.
Introduce a new trace event for the xsave area size reported by the
hypervisor.

Also fixes a leak of xsavec_buf on the get error path and switches
qemu_memalign() buffers to qemu_vfree().
No functional change on hosts reporting under 4 KiB.

Signed-off-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com>
---
 accel/mshv/mshv-all.c       | 21 +++++++++++++++++++++
 accel/mshv/trace-events     |  2 ++
 include/system/mshv_int.h   |  3 +++
 target/i386/mshv/mshv-cpu.c | 34 +++++++++++++++++++++++++---------
 4 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
index 5921ce693e..725ccd0511 100644
--- a/accel/mshv/mshv-all.c
+++ b/accel/mshv/mshv-all.c
@@ -162,6 +162,27 @@ static int get_proc_features(int vm_fd,
     return 0;
 }
 
+int mshv_get_max_xsave_size(int vm_fd, uint32_t *size)
+{
+    uint64_t value = 0;
+    int ret;
+
+    ret = get_partition_property(vm_fd,
+                                 HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE,
+                                 &value);
+    if (ret < 0) {
+        error_report("Failed to get partition property MAX_XSAVE_DATA_SIZE");
+        return -1;
+    }
+
+    /* round up to page size */
+    *size = ROUND_UP(value, HV_HYP_PAGE_SIZE);
+
+    trace_mshv_xsave_data_size(value, *size);
+
+    return 0;
+}
+
 static int create_partition(int mshv_fd, int *vm_fd)
 {
     int ret;
diff --git a/accel/mshv/trace-events b/accel/mshv/trace-events
index 859e8bfb0f..9473530140 100644
--- a/accel/mshv/trace-events
+++ b/accel/mshv/trace-events
@@ -12,6 +12,8 @@ mshv_mem_ioeventfd_del(uint64_t addr, uint32_t size, uint32_t data) "addr=0x%" P
 
 mshv_hvcall_args(const char* hvcall, uint16_t code, uint16_t in_sz) "built args for '%s' code: %d in_sz: %d"
 
+mshv_xsave_data_size(uint64_t required, uint32_t allocated) "required=%" PRIu64 " allocated=%u"
+
 mshv_handle_interrupt(uint32_t cpu, int mask) "cpu_index=%d mask=0x%x"
 mshv_set_msi_routing(uint32_t gsi, uint64_t addr, uint32_t data) "gsi=%d addr=0x%" PRIx64 " data=0x%x"
 mshv_remove_msi_routing(uint32_t gsi) "gsi=%d"
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
index 3dffe3c5fb..9d0957a65b 100644
--- a/include/system/mshv_int.h
+++ b/include/system/mshv_int.h
@@ -70,6 +70,8 @@ struct MshvState {
     unsigned long *used_gsi_bitmap;
     unsigned int gsi_count;
     union hv_partition_processor_features processor_features;
+    /* compacted xsave area size rounded up to the page size */
+    uint32_t xsave_data_size;
 };
 
 typedef struct MshvMsiControl {
@@ -107,6 +109,7 @@ void mshv_arch_amend_proc_features(
 void mshv_arch_disable_partition_proc_features(
      union hv_partition_processor_features *disabled_features);
 int mshv_arch_post_init_vm(int vm_fd);
+int mshv_get_max_xsave_size(int vm_fd, uint32_t *size);
 int mshv_get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state);
 int mshv_set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state);
 typedef struct mshv_root_hvcall mshv_root_hvcall;
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index f528dd2b9a..7ce05bfb17 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -157,9 +157,8 @@ static int get_xsave_state(CPUState *cpu)
     int ret;
     void *xsavec_buf;
     const size_t page = HV_HYP_PAGE_SIZE;
-    size_t xsavec_buf_len = page;
+    size_t xsavec_buf_len = mshv_state->xsave_data_size;
 
-    /* TODO: should properly determine xsavec size based on CPUID */
     xsavec_buf = qemu_memalign(page, xsavec_buf_len);
     memset(xsavec_buf, 0, xsavec_buf_len);
 
@@ -172,11 +171,12 @@ static int get_xsave_state(CPUState *cpu)
     ret = ioctl(cpu_fd, MSHV_GET_VP_STATE, &args);
     if (ret < 0) {
         error_report("failed to get xsave state: %s", strerror(errno));
+        qemu_vfree(xsavec_buf);
         return -errno;
     }
 
     ret = decompact_xsave_area(xsavec_buf, xsavec_buf_len, env);
-    g_free(xsavec_buf);
+    qemu_vfree(xsavec_buf);
     if (ret < 0) {
         error_report("failed to decompact xsave area");
         return ret;
@@ -196,8 +196,8 @@ static int set_xsave_state(const CPUState *cpu)
     size_t page = HV_HYP_PAGE_SIZE, xsavec_buf_len;
 
     /* allocate and populate compacted buffer */
-    xsavec_buf = qemu_memalign(page, page);
-    xsavec_buf_len = page;
+    xsavec_buf_len = mshv_state->xsave_data_size;
+    xsavec_buf = qemu_memalign(page, xsavec_buf_len);
 
     /* save registers to standard format buffer */
     x86_cpu_xsave_all_areas(x86cpu, env->xsave_buf, env->xsave_buf_len);
@@ -212,7 +212,7 @@ static int set_xsave_state(const CPUState *cpu)
     };
 
     ret = ioctl(cpu_fd, MSHV_SET_VP_STATE, &args);
-    g_free(xsavec_buf);
+    qemu_vfree(xsavec_buf);
     if (ret < 0) {
         error_report("failed to set xsave state: %s", strerror(errno));
         return -errno;
@@ -2125,6 +2125,24 @@ void mshv_arch_init_vcpu(CPUState *cpu)
     int ret;
     X86XSaveHeader *header;
 
+    /* get the xsave data size */
+    if (!mshv_state->xsave_data_size) {
+        ret = mshv_get_max_xsave_size(mshv_state->vm,
+                                      &mshv_state->xsave_data_size);
+        if (ret < 0) {
+            warn_report("failed to get the max xsave area size: %s",
+                        strerror(errno));
+            /*
+             * Use the maximum size for xsave because the partition is
+             * provisioned with every XSAVE component supported
+             */
+            mshv_state->xsave_data_size =
+                ROUND_UP(mshv_get_supported_cpuid(0xD, 0, R_ECX), page);
+        }
+        /* never allow a zero-sized xsave area */
+        mshv_state->xsave_data_size = MAX(mshv_state->xsave_data_size, page);
+    }
+
     /* sanity check, to make sure we don't overflow the page */
     QEMU_BUILD_BUG_ON((MAX_REGISTER_COUNT
                       * sizeof(hv_register_assoc)
@@ -2149,9 +2167,7 @@ void mshv_arch_init_vcpu(CPUState *cpu)
 
     env->emu_mmio_buf = g_new(char, 4096);
 
-    /* Initialize XSAVE buffer page-aligned */
-    /* TODO: pick proper size based on CPUID */
-    xsave_len = page;
+    xsave_len = mshv_state->xsave_data_size;
     env->xsave_buf = qemu_memalign(page, xsave_len);
     env->xsave_buf_len = xsave_len;
     memset(env->xsave_buf, 0, env->xsave_buf_len);
-- 
2.53.0



  reply	other threads:[~2026-09-07 14:24 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-07 14:23 [PATCH 0/2] acce/mshv: size XSAVE buffers from the hypervisor Doru Blânzeanu
2026-09-07 14:23 ` Doru Blânzeanu [this message]
2026-09-08 11:26   ` [PATCH 1/2] accel/mshv: " Magnus Kulke
2026-09-07 14:23 ` [PATCH 2/2] accel/mshv: enable amx tiles support for guests Doru Blânzeanu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260907142355.141033-2-dblanzeanu@linux.microsoft.com \
    --to=dblanzeanu@linux.microsoft.com \
    --cc=dblanzeanu@microsoft.com \
    --cc=liuwe@microsoft.com \
    --cc=magnuskulke@linux.microsoft.com \
    --cc=magnuskulke@microsoft.com \
    --cc=qemu-devel@nongnu.org \
    --cc=wei.liu@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.