From 5c936493d314daa5721c150b67c1e1e01c9297a7 Mon Sep 17 00:00:00 2001 From: robertmh Date: Fri, 9 Oct 2009 17:57:02 +0000 Subject: [PATCH 1/2] 2009-10-09 Robert Millan Fail gracefuly when attempting to load 64-bit kFreeBSD on IA32 CPU. * include/grub/i386/cpuid.h: New file. * commands/i386/cpuid.c: Include `'. (has_longmode): Rename to ... (grub_cpuid_has_longmode): ... this. Update all users. Remove `static' attribute. * loader/i386/bsd.c: Include `'. (grub_bsd_load_elf): Fail if load of 64-bit kernel was requested on a CPU that doesn't implement AMD64 instruction set. --- ChangeLog | 13 +++++++++++++ commands/i386/cpuid.c | 11 ++++++----- include/grub/i386/cpuid.h | 19 +++++++++++++++++++ loader/i386/bsd.c | 4 ++++ 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 include/grub/i386/cpuid.h diff --git a/ChangeLog b/ChangeLog index c02e3a6e2..6c89eaad6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2009-10-09 Robert Millan + + Fail gracefuly when attempting to load 64-bit kFreeBSD on IA32 CPU. + + * include/grub/i386/cpuid.h: New file. + * commands/i386/cpuid.c: Include `'. + (has_longmode): Rename to ... + (grub_cpuid_has_longmode): ... this. Update all users. Remove + `static' attribute. + * loader/i386/bsd.c: Include `'. + (grub_bsd_load_elf): Fail if load of 64-bit kernel was requested + on a CPU that doesn't implement AMD64 instruction set. + 2009-10-06 Colin Watson * Makefile.in (docs/stamp-vti): Depend on configure.ac as well, so diff --git a/commands/i386/cpuid.c b/commands/i386/cpuid.c index 71f33efb3..a8bbfe69b 100644 --- a/commands/i386/cpuid.c +++ b/commands/i386/cpuid.c @@ -1,7 +1,7 @@ /* cpuid.c - test for CPU features */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006, 2007 Free Software Foundation, Inc. + * Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. * Based on gcc/gcc/config/i386/driver-i386.c * * GRUB is free software: you can redistribute it and/or modify @@ -24,6 +24,7 @@ #include #include #include +#include #define cpuid(num,a,b,c,d) \ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \ @@ -38,14 +39,14 @@ static const struct grub_arg_option options[] = #define bit_LM (1 << 29) -static unsigned char has_longmode = 0; +unsigned char grub_cpuid_has_longmode = 0; static grub_err_t grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - return has_longmode ? GRUB_ERR_NONE + return grub_cpuid_has_longmode ? GRUB_ERR_NONE : grub_error (GRUB_ERR_TEST_FAILURE, "false"); } @@ -55,7 +56,7 @@ GRUB_MOD_INIT(cpuid) { #ifdef __x86_64__ /* grub-emu */ - has_longmode = 1; + grub_cpuid_has_longmode = 1; #else unsigned int eax, ebx, ecx, edx; unsigned int max_level; @@ -82,7 +83,7 @@ GRUB_MOD_INIT(cpuid) goto done; cpuid (0x80000001, eax, ebx, ecx, edx); - has_longmode = !!(edx & bit_LM); + grub_cpuid_has_longmode = !!(edx & bit_LM); done: #endif diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h new file mode 100644 index 000000000..f6ae20f38 --- /dev/null +++ b/include/grub/i386/cpuid.h @@ -0,0 +1,19 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +extern unsigned char grub_cpuid_has_longmode; diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 1accfb660..afe1825a5 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -871,6 +872,9 @@ grub_bsd_load_elf (grub_elf_t elf) { is_64bit = 1; + if (! grub_cpuid_has_longmode) + return grub_error (GRUB_ERR_BAD_OS, "Your CPU does not implement AMD64 architecture."); + /* FreeBSD has 64-bit entry point. */ if (kernel_type == KERNEL_TYPE_FREEBSD) { From 86564c267a823d7dd84e3eb070913e648984f05c Mon Sep 17 00:00:00 2001 From: robertmh Date: Fri, 9 Oct 2009 18:23:48 +0000 Subject: [PATCH 2/2] 2009-10-09 Robert Millan * include/grub/i386/cpuid.h: Add header protection. --- ChangeLog | 4 ++++ include/grub/i386/cpuid.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6c89eaad6..8640249ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-10-09 Robert Millan + + * include/grub/i386/cpuid.h: Add header protection. + 2009-10-09 Robert Millan Fail gracefuly when attempting to load 64-bit kFreeBSD on IA32 CPU. diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h index f6ae20f38..09b313bb8 100644 --- a/include/grub/i386/cpuid.h +++ b/include/grub/i386/cpuid.h @@ -16,4 +16,9 @@ * along with GRUB. If not, see . */ +#ifndef GRUB_CPU_CPUID_HEADER +#define GRUB_CPU_CPUID_HEADER 1 + extern unsigned char grub_cpuid_has_longmode; + +#endif