* [CFT PATCH 1/2] kvm: x86: mask out XSAVES
[not found] <1416594678-13011-1-git-send-email-pbonzini@redhat.com>
@ 2014-11-21 18:31 ` Paolo Bonzini
2014-11-21 18:31 ` [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host Paolo Bonzini
1 sibling, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2014-11-21 18:31 UTC (permalink / raw)
To: linux-kernel, kvm; +Cc: Wanpeng Li, stable, Nadav Amit
This feature is not supported inside KVM guests yet, because we do not emulate
MSR_IA32_XSS. Mask it out.
Cc: stable@vger.kernel.org
Cc: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/cpuid.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 20d83217fb1d..a4f5ac46226c 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -320,6 +320,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
F(ADX) | F(SMAP) | F(AVX512F) | F(AVX512PF) | F(AVX512ER) |
F(AVX512CD);
+ /* cpuid 0xD.1.eax */
+ const u32 kvm_supported_word10_x86_features =
+ F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1);
+
/* all calls to cpuid_count() should be made on the same cpu */
get_cpu();
@@ -456,13 +460,18 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
entry->eax &= supported;
entry->edx &= supported >> 32;
entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+ if (!supported)
+ break;
+
for (idx = 1, i = 1; idx < 64; ++idx) {
u64 mask = ((u64)1 << idx);
if (*nent >= maxnent)
goto out;
do_cpuid_1_ent(&entry[i], function, idx);
- if (entry[i].eax == 0 || !(supported & mask))
+ if (idx == 1)
+ entry[i].eax &= kvm_supported_word10_x86_features;
+ else if (entry[i].eax == 0 || !(supported & mask))
continue;
entry[i].flags |=
KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host
[not found] <1416594678-13011-1-git-send-email-pbonzini@redhat.com>
2014-11-21 18:31 ` [CFT PATCH 1/2] kvm: x86: mask out XSAVES Paolo Bonzini
@ 2014-11-21 18:31 ` Paolo Bonzini
2014-11-21 20:06 ` Andy Lutomirski
2014-11-24 2:10 ` Wanpeng Li
1 sibling, 2 replies; 6+ messages in thread
From: Paolo Bonzini @ 2014-11-21 18:31 UTC (permalink / raw)
To: linux-kernel, kvm; +Cc: Wanpeng Li, Fenghua Yu, stable, Nadav Amit
Userspace is expecting non-compacted format for KVM_GET_XSAVE, but
struct xsave_struct might be using the compacted format. Convert
in order to preserve userspace ABI.
Fixes: f31a9f7c71691569359fa7fb8b0acaa44bce0324
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: stable@vger.kernel.org
Cc: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/x86.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 43 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5337039427c8..7e8a20e5615a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3131,15 +3131,53 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
return 0;
}
+#define XSTATE_COMPACTION_ENABLED (1ULL << 63)
+
+static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
+{
+ struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state->xsave;
+ u64 xstate_bv = vcpu->arch.guest_supported_xcr0 | XSTATE_FPSSE;
+ u64 valid;
+
+ /*
+ * Copy legacy XSAVE area, to avoid complications with CPUID
+ * leaves 0 and 1 in the loop below.
+ */
+ memcpy(dest, xsave, XSAVE_HDR_OFFSET);
+
+ /* Set XSTATE_BV */
+ *(u64 *)(dest + XSAVE_HDR_OFFSET) = xstate_bv;
+
+ /*
+ * Copy each region from the possibly compacted offset to the
+ * non-compacted offset.
+ */
+ valid = xstate_bv & ~XSTATE_FPSSE;
+ if (xsave->xsave_hdr.xcomp_bv & XSTATE_COMPACTION_ENABLED)
+ valid &= xsave->xsave_hdr.xcomp_bv;
+
+ while (valid) {
+ u64 feature = valid & -valid;
+ int index = fls64(feature) - 1;
+ void *src = get_xsave_addr(xsave, feature);
+
+ if (src) {
+ u32 size, offset, ecx, edx;
+ cpuid_count(XSTATE_CPUID, index,
+ &size, &offset, &ecx, &edx);
+ memcpy(dest + offset, src, size);
+ }
+
+ valid -= feature;
+ }
+}
+
static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
struct kvm_xsave *guest_xsave)
{
if (cpu_has_xsave) {
- memcpy(guest_xsave->region,
- &vcpu->arch.guest_fpu.state->xsave,
- vcpu->arch.guest_xstate_size);
- *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] &=
- vcpu->arch.guest_supported_xcr0 | XSTATE_FPSSE;
+ memset(guest_xsave, 0, sizeof(struct kvm_xsave));
+ fill_xsave((u8 *) guest_xsave->region, vcpu);
} else {
memcpy(guest_xsave->region,
&vcpu->arch.guest_fpu.state->fxsave,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host
2014-11-21 18:31 ` [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host Paolo Bonzini
@ 2014-11-21 20:06 ` Andy Lutomirski
2014-11-21 21:58 ` Paolo Bonzini
2014-11-24 2:10 ` Wanpeng Li
1 sibling, 1 reply; 6+ messages in thread
From: Andy Lutomirski @ 2014-11-21 20:06 UTC (permalink / raw)
To: Paolo Bonzini, linux-kernel, kvm
Cc: Wanpeng Li, Fenghua Yu, stable, Nadav Amit
On 11/21/2014 10:31 AM, Paolo Bonzini wrote:
> Userspace is expecting non-compacted format for KVM_GET_XSAVE, but
> struct xsave_struct might be using the compacted format. Convert
> in order to preserve userspace ABI.
>
> Fixes: f31a9f7c71691569359fa7fb8b0acaa44bce0324
> Cc: Fenghua Yu <fenghua.yu@intel.com>
> Cc: stable@vger.kernel.org
> Cc: Nadav Amit <namit@cs.technion.ac.il>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> arch/x86/kvm/x86.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 43 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 5337039427c8..7e8a20e5615a 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3131,15 +3131,53 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
> return 0;
> }
>
> +#define XSTATE_COMPACTION_ENABLED (1ULL << 63)
> +
> +static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
> +{
> + struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state->xsave;
> + u64 xstate_bv = vcpu->arch.guest_supported_xcr0 | XSTATE_FPSSE;
> + u64 valid;
> +
> + /*
> + * Copy legacy XSAVE area, to avoid complications with CPUID
> + * leaves 0 and 1 in the loop below.
> + */
> + memcpy(dest, xsave, XSAVE_HDR_OFFSET);
> +
> + /* Set XSTATE_BV */
> + *(u64 *)(dest + XSAVE_HDR_OFFSET) = xstate_bv;
> +
> + /*
> + * Copy each region from the possibly compacted offset to the
> + * non-compacted offset.
> + */
> + valid = xstate_bv & ~XSTATE_FPSSE;
> + if (xsave->xsave_hdr.xcomp_bv & XSTATE_COMPACTION_ENABLED)
> + valid &= xsave->xsave_hdr.xcomp_bv;
> +
> + while (valid) {
> + u64 feature = valid & -valid;
> + int index = fls64(feature) - 1;
> + void *src = get_xsave_addr(xsave, feature);
> +
> + if (src) {
> + u32 size, offset, ecx, edx;
> + cpuid_count(XSTATE_CPUID, index,
> + &size, &offset, &ecx, &edx);
> + memcpy(dest + offset, src, size);
Is this really the best way to do this? cpuid is serializing, so this
is possibly *very* slow.
--Andy
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host
2014-11-21 20:06 ` Andy Lutomirski
@ 2014-11-21 21:58 ` Paolo Bonzini
0 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2014-11-21 21:58 UTC (permalink / raw)
To: Andy Lutomirski, linux-kernel, kvm
Cc: Wanpeng Li, Fenghua Yu, stable, Nadav Amit
On 21/11/2014 21:06, Andy Lutomirski wrote:
>> > + cpuid_count(XSTATE_CPUID, index,
>> > + &size, &offset, &ecx, &edx);
>> > + memcpy(dest + offset, src, size);
> Is this really the best way to do this? cpuid is serializing, so this
> is possibly *very* slow.
The data is in arch/x86/kernel/xsave.c, but it is not exported. But
this is absolutely not a hotspot.
Paolo
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host
2014-11-21 18:31 ` [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host Paolo Bonzini
2014-11-21 20:06 ` Andy Lutomirski
@ 2014-11-24 2:10 ` Wanpeng Li
2014-11-24 10:07 ` Paolo Bonzini
1 sibling, 1 reply; 6+ messages in thread
From: Wanpeng Li @ 2014-11-24 2:10 UTC (permalink / raw)
To: Paolo Bonzini
Cc: linux-kernel, kvm, Fenghua Yu, stable, Nadav Amit,
Andy Lutomirski
Hi Paolo,
On Fri, Nov 21, 2014 at 07:31:18PM +0100, Paolo Bonzini wrote:
[...]
>+ u64 feature = valid & -valid;
>+ int index = fls64(feature) - 1;
>+ void *src = get_xsave_addr(xsave, feature);
>+
>+ if (src) {
>+ u32 size, offset, ecx, edx;
>+ cpuid_count(XSTATE_CPUID, index,
>+ &size, &offset, &ecx, &edx);
>+ memcpy(dest + offset, src, size);
The offset you get is still for compact format, so you almost convert compat
format to compat format instead of convert compact format to standard format.
In addition, I think convert standard format to compact format should be
implemented in put path.
Regards,
Wanpeng Li
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host
2014-11-24 2:10 ` Wanpeng Li
@ 2014-11-24 10:07 ` Paolo Bonzini
0 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2014-11-24 10:07 UTC (permalink / raw)
To: Wanpeng Li
Cc: linux-kernel, kvm, Fenghua Yu, stable, Nadav Amit,
Andy Lutomirski
On 24/11/2014 03:10, Wanpeng Li wrote:
> Hi Paolo,
> On Fri, Nov 21, 2014 at 07:31:18PM +0100, Paolo Bonzini wrote:
> [...]
>> + u64 feature = valid & -valid;
>> + int index = fls64(feature) - 1;
>> + void *src = get_xsave_addr(xsave, feature);
>> +
>> + if (src) {
>> + u32 size, offset, ecx, edx;
>> + cpuid_count(XSTATE_CPUID, index,
>> + &size, &offset, &ecx, &edx);
>> + memcpy(dest + offset, src, size);
>
> The offset you get is still for compact format
No, it's not, or all old software using XSAVE/XRSTOR would be broken.
The code in arch/x86/kernel/xsave.c agrees with me; compacted offsets
(xsave_comp_offsets) are computed by summing sizes, while non-compacted
offsets (xsave_offsets) come for CPUID.
> , so you almost convert compat
> format to compat format instead of convert compact format to standard format.
> In addition, I think convert standard format to compact format should be
> implemented in put path.
If I do that, userspace is broken because it expects standard format.
Hence, passing XSAVE data to userspace in compact format can be done,
but has to be guarded by an explicitly enabled capability (using
KVM_ENABLE_CAP).
I do not think that's useful, since no supervisor-specific states are
defined yet, and anyway they can be passed using KVM_GET/SET_MSR because
this is not a fast path.
Paolo
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-11-24 10:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1416594678-13011-1-git-send-email-pbonzini@redhat.com>
2014-11-21 18:31 ` [CFT PATCH 1/2] kvm: x86: mask out XSAVES Paolo Bonzini
2014-11-21 18:31 ` [CFT PATCH 2/2] KVM: x86: support XSAVES usage in the host Paolo Bonzini
2014-11-21 20:06 ` Andy Lutomirski
2014-11-21 21:58 ` Paolo Bonzini
2014-11-24 2:10 ` Wanpeng Li
2014-11-24 10:07 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).