Message ID | 20160815175059.GA12532@potion (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Aug 15, 2016 at 07:50:59PM +0200, Radim Krčmář wrote: [...] > +static void kvm_clear_invalid_cpuid(struct kvm_vcpu *vcpu) > +{ > + struct kvm *kvm = vcpu->kvm; > + struct kvm_cpuid_entry2 *best; > + > + if (!kvm->clear_invalid_cpuid) > + return; > + > + best = kvm_find_cpuid_entry(vcpu, 1, 0); > + if (best && !lapic_in_kernel(vcpu)) > + best->ecx &= ~F(X2APIC); Isn't it possible to implement x2apic support in userspace APIC using the current KVM interfaces?
2016-08-15 15:00-0300, Eduardo Habkost: > On Mon, Aug 15, 2016 at 07:50:59PM +0200, Radim Krčmář wrote: > [...] >> +static void kvm_clear_invalid_cpuid(struct kvm_vcpu *vcpu) >> +{ >> + struct kvm *kvm = vcpu->kvm; >> + struct kvm_cpuid_entry2 *best; >> + >> + if (!kvm->clear_invalid_cpuid) >> + return; >> + >> + best = kvm_find_cpuid_entry(vcpu, 1, 0); >> + if (best && !lapic_in_kernel(vcpu)) >> + best->ecx &= ~F(X2APIC); > > Isn't it possible to implement x2apic support in userspace APIC > using the current KVM interfaces? No, MSR accesses never get to userspace. We'll probably implement it in the future as there already has been a proposal for unhandled MSRs. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 739db9ab16b2..8d085823c4af 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -545,6 +545,9 @@ struct kvm_cpuid { struct kvm_cpuid_entry entries[0]; }; +If KVM_CAP_CLEAR_INVALID_CPUID is enabled, then the ioctls can modify CPUID +bits to prevent invalid configurations. + 4.21 KVM_SET_SIGNAL_MASK @@ -3900,6 +3903,18 @@ to take care of that. This capability can be enabled dynamically even if VCPUs were already created and are running. +7.9 KVM_CAP_CLEAR_INVALID_CPUID + +Architectures: x86 +Parameters: none + +After setting this capability, KVM_SET_CPUID2 can modify CPUID bits that are +invalid in the given configuration, e.g. disable KVM_FEATURE_PV_UNHALT when the +LAPIC is in the userspace. + +The userspace is expected to use KVM_GET_CPUID2 to retrieve the final CPUID. + + 8. Other capabilities. ---------------------- diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index afa7bbb596cd..afa05bb31cc3 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -160,6 +160,21 @@ static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu) } } +static void kvm_clear_invalid_cpuid(struct kvm_vcpu *vcpu) +{ + struct kvm *kvm = vcpu->kvm; + struct kvm_cpuid_entry2 *best; + + if (!kvm->clear_invalid_cpuid) + return; + + best = kvm_find_cpuid_entry(vcpu, 1, 0); + if (best && !lapic_in_kernel(vcpu)) + best->ecx &= ~F(X2APIC); + + /* TODO: to disable KVM_FEATURE_PV_UNHALT */ +} + int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; @@ -234,6 +249,8 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, cpuid->nent * sizeof(struct kvm_cpuid_entry2))) goto out; vcpu->arch.cpuid_nent = cpuid->nent; + + kvm_clear_invalid_cpuid(vcpu); kvm_apic_set_version(vcpu); kvm_x86_ops->cpuid_update(vcpu); r = kvm_update_cpuid(vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 19f9f9e05c2a..99028df615e7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3812,6 +3812,13 @@ split_irqchip_unlock: r = 0; break; + case KVM_CAP_CLEAR_INVALID_CPUID: + r = -EEXIST; + if (kvm->created_vcpus) + break; + kvm->clear_invalid_cpuid = true; + r = 0; + break; default: r = -EINVAL; break;