Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cda846f1 authored by Jarkko Sakkinen's avatar Jarkko Sakkinen Committed by H. Peter Anvin
Browse files

x86, realmode: read cr4 and EFER from kernel for 64-bit trampoline



This patch changes 64-bit trampoline so that CR4 and
EFER are provided by the kernel instead of using fixed
values.

Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@intel.com>
Link: http://lkml.kernel.org/r/1336501366-28617-24-git-send-email-jarkko.sakkinen@intel.com


Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent bf8b88e9
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -545,12 +545,15 @@ static inline void load_sp0(struct tss_struct *tss,
 * after us can get the correct flags.
 */
extern unsigned long mmu_cr4_features;
extern u32 *trampoline_cr4_features;

static inline void set_in_cr4(unsigned long mask)
{
	unsigned long cr4;

	mmu_cr4_features |= mask;
	if (trampoline_cr4_features)
		*trampoline_cr4_features = mmu_cr4_features;
	cr4 = read_cr4();
	cr4 |= mask;
	write_cr4(cr4);
@@ -561,6 +564,8 @@ static inline void clear_in_cr4(unsigned long mask)
	unsigned long cr4;

	mmu_cr4_features &= ~mask;
	if (trampoline_cr4_features)
		*trampoline_cr4_features = mmu_cr4_features;
	cr4 = read_cr4();
	cr4 &= ~mask;
	write_cr4(cr4);
+6 −2
Original line number Diff line number Diff line
@@ -24,18 +24,22 @@ struct real_mode_header {
#ifdef CONFIG_X86_32
	u32	machine_real_restart_asm;
#endif
} __attribute__((__packed__));
};

/* This must match data at trampoline_32/64.S */
struct trampoline_header {
#ifdef CONFIG_X86_32
	u32 start;
	u16 gdt_pad;
	u16 gdt_limit;
	u32 gdt_base;
#else
	u64 start;
	u32 cr4;
	u32 efer_low;
	u32 efer_high;
#endif
} __attribute__((__packed__));
};

extern struct real_mode_header *real_mode_header;
extern unsigned char real_mode_blob_end[];
+8 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <asm/realmode.h>

struct real_mode_header *real_mode_header;
u32 *trampoline_cr4_features;

void __init setup_real_mode(void)
{
@@ -64,7 +65,14 @@ void __init setup_real_mode(void)
	trampoline_header->gdt_limit = __BOOT_DS + 7;
	trampoline_header->gdt_base = __pa(boot_gdt);
#else
	if (rdmsr_safe(MSR_EFER, &trampoline_header->efer_low,
		       &trampoline_header->efer_high))
		BUG();

	trampoline_header->start = (u64) secondary_startup_64;
	trampoline_cr4_features = &trampoline_header->cr4;
	*trampoline_cr4_features = read_cr4();

	trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
	trampoline_pgd[0] = __pa(level3_ident_pgt) + _KERNPG_TABLE;
	trampoline_pgd[511] = __pa(level3_kernel_pgt) + _KERNPG_TABLE;
+2 −0
Original line number Diff line number Diff line
@@ -975,6 +975,8 @@ void __init setup_arch(char **cmdline_p)
	if (boot_cpu_data.cpuid_level >= 0) {
		/* A CPU has %cr4 if and only if it has CPUID */
		mmu_cr4_features = read_cr4();
		if (trampoline_cr4_features)
			*trampoline_cr4_features = mmu_cr4_features;
	}

#ifdef CONFIG_X86_32
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

	.section ".header", "a"

	.balign	16
GLOBAL(real_mode_header)
	.long	pa_text_start
	.long	pa_ro_end
Loading