Re: [PATCH kvmtool] x86: Fixed Unable to execute init process since glibc version 2.33

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 8 Mar 2022 17:31:25 +0000
Andre Przywara <andre.przywara@xxxxxxx> wrote:

Hi,

I did some digging on this issue, see below:

> On Sat, 26 Feb 2022 14:00:48 +0800
> Dongli Si <sidongli1997@xxxxxxxxx> wrote:
> 
> Hi,
> 
> > From: Dongli Si <sidongli1997@xxxxxxxxx>
> > 
> > glibc detected invalid CPU Vendor name will cause an error:
> > 
> > [    0.450127] Run /sbin/init as init process
> > /lib64/libc.so.6: CPU ISA level is lower than required
> > [    0.451931] Kernel panic - not syncing: Attempted to kill init!
> > exitcode=0x00007f00 [    0.452117] CPU: 0 PID: 1 Comm: init Not
> > tainted 5.17.0-rc1 #72
> > 
> > Signed-off-by: Dongli Si <sidongli1997@xxxxxxxxx>
> > ---
> >  x86/cpuid.c | 14 +++++++++-----
> >  1 file changed, 9 insertions(+), 5 deletions(-)
> > 
> > diff --git a/x86/cpuid.c b/x86/cpuid.c
> > index c3b67d9..d58a027 100644
> > --- a/x86/cpuid.c
> > +++ b/x86/cpuid.c
> > @@ -2,6 +2,7 @@
> >  
> >  #include "kvm/kvm.h"
> >  #include "kvm/util.h"
> > +#include "kvm/cpufeature.h"
> >  
> >  #include <sys/ioctl.h>
> >  #include <stdlib.h>
> > @@ -10,7 +11,7 @@
> >  
> >  static void filter_cpuid(struct kvm_cpuid2 *kvm_cpuid)
> >  {
> > -	unsigned int signature[3];
> > +	struct cpuid_regs regs;
> >  	unsigned int i;
> >  
> >  	/*
> > @@ -22,10 +23,13 @@ static void filter_cpuid(struct kvm_cpuid2
> > *kvm_cpuid) switch (entry->function) {
> >  		case 0:
> >  			/* Vendor name */
> > -			memcpy(signature, "LKVMLKVMLKVM", 12);
> > -			entry->ebx = signature[0];
> > -			entry->ecx = signature[1];
> > -			entry->edx = signature[2];
> > +			regs = (struct cpuid_regs) {
> > +				.eax		= 0x00,
> > +			};
> > +			host_cpuid(&regs);
> > +			entry->ebx = regs.ebx;
> > +			entry->ecx = regs.ecx;
> > +			entry->edx = regs.edx;  
> 
> But that's redundant, isn't it? We already get the host vendor ID in the
> three registers in entry, and the current code is just there to overwrite
> this. So just removing the whole "case 0:" part should do the trick.
> 
> Also please be aware that there was a reason for this fixup, as explained
> in commit bc0b99a2a740 ("kvm tools: Filter out CPU vendor string").
> 
So I had a closer look, this is some background:

1) x86 is in the process of stepping up the minimum requirements for the
ISA level, so older x86-64 CPUs might not be supported anymore by some
distros. As a part of this, glibc allows to set a minimum required CPU,
and has a runtime check to verify compatibility:
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/cpu-features.c;h=514226b37889;hb=HEAD#l398
This routine first checks the vendor string, and only does very basic
capability checks if an unknown vendor (not AMD/Centaur/Intel) is detected.
The AMD manual (APM Vol. 3, 24594 Rev 3.3), CPUID instruction, states:
===============
For AMD processors, the string is AuthenticAMD. This string informs
software that it should follow the AMD CPUID definition for subsequent
CPUID function calls. If the function returns another vendor’s string,
software must use that vendor’s CPUID definition when interpreting
the results of subsequent CPUID function calls.
===============

So kvmtool using "LKVMLKVMLKVM" as the vendor string will probably end up
as detecting only the minimum CPU ISA level, which means glibc's built to
a higher standard will fail, as reported.
On top of that glibc problem the kernel also does various CPU checks, and
will deny features if an unknown vendor is detected. There are already
warnings in the kernel boot log today because of this.

2) The above mentioned kvmtool commit bc0b99a2a740 switched away from
keeping the host's vendor ID, because certain errata workarounds triggered
when the guest saw the host CPU vendor/family/model/stepping values. This
led to random MSR accesses, which KVM could not deal well with at the
time. KVM has improved since, and has code to deal with #GP injections due
to not-emulated MSR accesses. The particular first issue mentioned in the
above commit for instance is addressed by Linux commit d47cc0db8fd6:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d47cc0db8fd6

In general I remember that using random vendor strings was dismissed as a
good idea years ago, and other VMMs and hypervisors tend to inject either
the host's vendor string or at least a well-known value. So any Linux
guest issues due to certain vendor strings would apply to other VMMs or
HVs as well, and are probably fixed already.


So the problem with glibc is out there, and is there to stay. The
algorithm of checking for the vendor string first is correct by the books,
although arguably technically not strictly needed. But we cannot fix this,
so have to deal with it.

> Alex, did you boot this on an AMD box, to spot if this is still an issue?

I gave it a try on an old AMD box similar to the one in mentioned in the
commit message, and it worked fine with the native vendor string.

So I would suggest to just revert kvmtool commit bc0b99a2a740. I will send
a patch to that effect, unless someone objects now.


Cheers,
Andre



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux