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

Commit d3432896 authored by Andi Kleen's avatar Andi Kleen Committed by Ingo Molnar
Browse files

x86: don't disable the APIC if it hasn't been mapped yet



When the kernel panics early for some unrelated reason
there would be eventually an early exception inside panic because
clear_local_APIC tried to disable the not yet mapped APIC.
Check for that explicitely.

Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent ca74a6f8
Loading
Loading
Loading
Loading
+8 −3
Original line number Original line Diff line number Diff line
@@ -99,6 +99,8 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
/* Local APIC was disabled by the BIOS and enabled by the kernel */
/* Local APIC was disabled by the BIOS and enabled by the kernel */
static int enabled_via_apicbase;
static int enabled_via_apicbase;


static unsigned long apic_phys;

/*
/*
 * Get the LAPIC version
 * Get the LAPIC version
 */
 */
@@ -631,9 +633,14 @@ int setup_profiling_timer(unsigned int multiplier)
 */
 */
void clear_local_APIC(void)
void clear_local_APIC(void)
{
{
	int maxlvt = lapic_get_maxlvt();
	int maxlvt;
	u32 v;
	u32 v;


	/* APIC hasn't been mapped yet */
	if (!apic_phys)
		return;

	maxlvt = lapic_get_maxlvt();
	/*
	/*
	 * Masking an LVT entry can trigger a local APIC error
	 * Masking an LVT entry can trigger a local APIC error
	 * if the vector is zero. Mask LVTERR first to prevent this.
	 * if the vector is zero. Mask LVTERR first to prevent this.
@@ -1120,8 +1127,6 @@ static int __init detect_init_APIC(void)
 */
 */
void __init init_apic_mappings(void)
void __init init_apic_mappings(void)
{
{
	unsigned long apic_phys;

	/*
	/*
	 * If no local APIC can be found then set up a fake all
	 * If no local APIC can be found then set up a fake all
	 * zeroes page to simulate the local APIC and another
	 * zeroes page to simulate the local APIC and another
+7 −2
Original line number Original line Diff line number Diff line
@@ -81,6 +81,8 @@ static struct clock_event_device lapic_clockevent = {
};
};
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);


static unsigned long apic_phys;

/*
/*
 * Get the LAPIC version
 * Get the LAPIC version
 */
 */
@@ -525,6 +527,11 @@ void clear_local_APIC(void)
	int maxlvt = lapic_get_maxlvt();
	int maxlvt = lapic_get_maxlvt();
	u32 v;
	u32 v;


	/* APIC hasn't been mapped yet */
	if (!apic_phys)
		return;

	maxlvt = lapic_get_maxlvt();
	/*
	/*
	 * Masking an LVT entry can trigger a local APIC error
	 * Masking an LVT entry can trigger a local APIC error
	 * if the vector is zero. Mask LVTERR first to prevent this.
	 * if the vector is zero. Mask LVTERR first to prevent this.
@@ -859,8 +866,6 @@ static int __init detect_init_APIC(void)
 */
 */
void __init init_apic_mappings(void)
void __init init_apic_mappings(void)
{
{
	unsigned long apic_phys;

	/*
	/*
	 * If no local APIC can be found then set up a fake all
	 * If no local APIC can be found then set up a fake all
	 * zeroes page to simulate the local APIC and another
	 * zeroes page to simulate the local APIC and another