svn commit: r183823 - in stable/7/sys: . boot/i386/libi386
John Baldwin
jhb at FreeBSD.org
Mon Oct 13 16:14:21 UTC 2008
Author: jhb
Date: Mon Oct 13 16:14:21 2008
New Revision: 183823
URL: http://svn.freebsd.org/changeset/base/183823
Log:
MFC: Fail requests to boot an amd64 kernel on an i386-only CPU.
Approved by: re (kib)
Modified:
stable/7/sys/ (props changed)
stable/7/sys/boot/i386/libi386/bootinfo64.c
Modified: stable/7/sys/boot/i386/libi386/bootinfo64.c
==============================================================================
--- stable/7/sys/boot/i386/libi386/bootinfo64.c Mon Oct 13 14:05:01 2008 (r183822)
+++ stable/7/sys/boot/i386/libi386/bootinfo64.c Mon Oct 13 16:14:21 2008 (r183823)
@@ -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 *modul
char *rootdevname;
int howto;
+ if (!bi_checkcpu()) {
+ printf("CPU doesn't support long mode\n");
+ return (EINVAL);
+ }
+
howto = bi_getboothowto(args);
/*
More information about the svn-src-all
mailing list