[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6ae7e64c53727f9f00537d787e9612c292c4e244.camel@redhat.com>
Date: Thu, 13 Jan 2022 16:41:54 +0200
From: Maxim Levitsky <mlevitsk@...hat.com>
To: Vitaly Kuznetsov <vkuznets@...hat.com>,
Paolo Bonzini <pbonzini@...hat.com>,
Igor Mammedov <imammedo@...hat.com>
Cc: kvm@...r.kernel.org, Sean Christopherson <seanjc@...gle.com>,
Wanpeng Li <wanpengli@...cent.com>,
Jim Mattson <jmattson@...gle.com>, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/2] KVM: x86: Forbid KVM_SET_CPUID{,2} after KVM_RUN
On Thu, 2022-01-13 at 15:36 +0100, Vitaly Kuznetsov wrote:
> Maxim Levitsky <mlevitsk@...hat.com> writes:
>
> > On Thu, 2022-01-13 at 10:27 +0100, Vitaly Kuznetsov wrote:
> > > Paolo Bonzini <pbonzini@...hat.com> writes:
> > >
> > > > On 1/12/22 14:58, Vitaly Kuznetsov wrote:
> > > > > - best = kvm_find_cpuid_entry(vcpu, 0xD, 1);
> > > > > + best = cpuid_entry2_find(entries, nent, 0xD, 1);
> > > > > if (best && (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
> > > > > cpuid_entry_has(best, X86_FEATURE_XSAVEC)))
> > > > > best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
> > > > >
> > > > > - best = kvm_find_kvm_cpuid_features(vcpu);
> > > > > + best = __kvm_find_kvm_cpuid_features(vcpu, vcpu->arch.cpuid_entries,
> > > > > + vcpu->arch.cpuid_nent);
> > > > > if (kvm_hlt_in_guest(vcpu->kvm) && best &&
> > > >
> > > > I think this should be __kvm_find_kvm_cpuid_features(vcpu, entries, nent).
> > > >
> > >
> > > Of course.
> > >
> > > > > + case 0x1:
> > > > > + /* Only initial LAPIC id is allowed to change */
> > > > > + if (e->eax ^ best->eax || ((e->ebx ^ best->ebx) >> 24) ||
> > > > > + e->ecx ^ best->ecx || e->edx ^ best->edx)
> > > > > + return -EINVAL;
> > > > > + break;
> > > >
> > > > This XOR is a bit weird. In addition the EBX test is checking the wrong
> > > > bits (it checks whether 31:24 change and ignores changes to 23:0).
> > >
> > > Indeed, however, I've tested CPU hotplug with QEMU trying different
> > > CPUs in random order and surprisingly othing blew up, feels like QEMU
> > > was smart enough to re-use the right fd)
> > >
> > > > You can write just "(e->ebx & ~0xff000000u) != (best->ebx ~0xff000000u)".
> > > >
> > > > > + default:
> > > > > + if (e->eax ^ best->eax || e->ebx ^ best->ebx ||
> > > > > + e->ecx ^ best->ecx || e->edx ^ best->edx)
> > > > > + return -EINVAL;
> > > >
> > > > This one even more so.
> > >
> > > Thanks for the early review, I'm going to prepare a selftest and send
> > > this out.
> > >
> > I also looked at this recently (due to other reasons) and I found out that
> > qemu picks a parked vcpu by its vcpu_id which is its initial apic id,
> > thus apic id related features should not change.
> >
> > Take a look at 'kvm_get_vcpu' in qemu source.
> > Maybe old qemu versions didn't do this?
>
> I took Igor's word on this, I didn't check QEMU code :-)
>
> In the v1 I've just sent [L,x2]APIC ids are allowed to change. This
> shouldn't screw the MMU (which was the main motivation for forbidding
> KVM_SET_CPUID{,2} after KVM_RUN in the first place) but maybe we don't
> really need to be so permissive.
>
For my nested AVIC work I would really want the APIC ID of a VCPU to be read-only
and be equal to vcpu_id.
That simplifies lot of things, and in practice it is hightly likely that no guests
change their APIC id, and likely that qemu doesn't as well.
Best regards,
Maxim Levitsky
Powered by blists - more mailing lists