Skip to content
Snippets Groups Projects
Commit 25483050 authored by Yu Ning's avatar Yu Ning Committed by Tao Wu
Browse files

x86: Fix boot failure for GCC 4.9-built kernels

The current default cross toolchain for building x86 and x86_64 emulator
kernels is GCC 4.8, i.e.

 $AOSP/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8

on Linux hosts. It is also possible to build these kernels with GCC 4.9
($AOSP/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9), but
unfortunately, the generated kernel images are not bootable. This issue
affects both 3.4 and 3.10 kernels, and in the case of 3.10, both classic
(goldfish) and ranchu configurations.

The immediate cause of the boot failure is an invalid opcode exception
(escalating into a triple fault). The offending instruction is MOVDQA,
which belongs to the SSE2 instruction set. A postmortem on the vCPU
shows that the kernel is in an early boot stage, because paging (CR0.PG)
is not yet enabled. Nor is CR4.OSFXSR, which is in fact a prerequisite
for any SSE instructions, hence the exception.

The solution is to instruct GCC not to use SSE when compiling code for
x86 boot. This is done by back-porting the following patches from
upstream:

 5c630089 x86/kbuild: Eliminate duplicate command line options
 8b3b005d x86, build: Pass in additional -mno-mmx, -mno-sse options
 5551a34e x86-64, build: Always pass in -mno-sse

As to why GCC 4.9 behaves differently from GCC 4.8, this line from the
GCC 4.9 changelog (https://gcc.gnu.org/gcc-4.9/changes.html) offers a
possible explanation:

 * -mfpmath=sse is now implied by -ffast-math on all targets where SSE2
   is supported.

See https://android-review.googlesource.com/161639

 for the related
change in the 3.10 kernel.

Change-Id: I4bdf6cda44e3c576dce6510409daa8f3835a0e4f
Signed-off-by: default avatarYu Ning <yu.ning@intel.com>
(cherry picked from commit 6e093637)
parent 2d58ef98
Branches
No related tags found
No related merge requests found
......@@ -128,7 +128,7 @@ KBUILD_CFLAGS += -Wno-sign-compare
#
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
# prevent gcc from generating any FP code by mistake
KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow
KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
###
......
......@@ -52,18 +52,18 @@ $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
# How to compile the 16-bit code. Note we always compile for -march=i386,
# that way we can complain to the user if the CPU is insufficient.
KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
KBUILD_CFLAGS := $(LINUXINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ \
-DDISABLE_BRANCH_PROFILING \
-Wall -Wstrict-prototypes \
-march=i386 -mregparm=3 \
-include $(srctree)/$(src)/code16gcc.h \
-fno-strict-aliasing -fomit-frame-pointer \
-mno-mmx -mno-sse \
$(call cc-option, -ffreestanding) \
$(call cc-option, -fno-toplevel-reorder,\
$(call cc-option, -fno-unit-at-a-time)) \
$(call cc-option, -fno-stack-protector) \
$(call cc-option, -mpreferred-stack-boundary=2)
KBUILD_CFLAGS += $(call cc-option, -m32)
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
GCOV_PROFILE := n
......
......@@ -12,6 +12,7 @@ KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
cflags-$(CONFIG_X86_32) := -march=i386
cflags-$(CONFIG_X86_64) := -mcmodel=small
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += -mno-mmx -mno-sse
KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment