Use CPUID to see if the current CPU supports long mode when attemping to
boot an amd64 kernel. If not, then fail the boot request with an error message. Otherwise, the boot attempt will fail with a BTX fault when trying to read the EFER MSR. MFC after: 3 days
This commit is contained in:
parent
8c3bc1af40
commit
f252d86740
@ -32,6 +32,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/linker.h>
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include "bootstrap.h"
|
||||
#include "libi386.h"
|
||||
#include "btxv86.h"
|
||||
@ -124,7 +127,45 @@ bi_copymodules64(vm_offset_t addr)
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the information expected by an i386 kernel.
|
||||
* Check to see if this CPU supports long mode.
|
||||
*/
|
||||
static int
|
||||
bi_checkcpu(void)
|
||||
{
|
||||
char *cpu_vendor;
|
||||
int vendor[3];
|
||||
int eflags, regs[4];
|
||||
|
||||
/* Check for presence of "cpuid". */
|
||||
eflags = read_eflags();
|
||||
write_eflags(eflags ^ PSL_ID);
|
||||
if (!((eflags ^ read_eflags()) & PSL_ID))
|
||||
return (0);
|
||||
|
||||
/* Fetch the vendor string. */
|
||||
do_cpuid(0, regs);
|
||||
vendor[0] = regs[1];
|
||||
vendor[1] = regs[3];
|
||||
vendor[2] = regs[2];
|
||||
cpu_vendor = (char *)vendor;
|
||||
|
||||
/* Check for vendors that support AMD features. */
|
||||
if (strncmp(cpu_vendor, "GenuineIntel", 12) != 0 &&
|
||||
strncmp(cpu_vendor, "AuthenticAMD", 12) != 0)
|
||||
return (0);
|
||||
|
||||
/* Has to support AMD features. */
|
||||
do_cpuid(0x80000000, regs);
|
||||
if (!(regs[0] >= 0x80000001))
|
||||
return (0);
|
||||
|
||||
/* Check for long mode. */
|
||||
do_cpuid(0x80000001, regs);
|
||||
return (regs[3] & AMDID_LM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the information expected by an amd64 kernel.
|
||||
*
|
||||
* - The 'boothowto' argument is constructed
|
||||
* - The 'bootdev' argument is constructed
|
||||
@ -145,6 +186,11 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
|
||||
char *rootdevname;
|
||||
int howto;
|
||||
|
||||
if (!bi_checkcpu()) {
|
||||
printf("CPU doesn't support long mode\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
howto = bi_getboothowto(args);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user