Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Mike Galbraith
On Tue, 2017-01-31 at 18:49 +0100, Borislav Petkov wrote:
> On Tue, Jan 31, 2017 at 01:31:00PM +0100, Borislav Petkov wrote:
> > On Tue, Jan 31, 2017 at 12:31:17PM +0100, Mike Galbraith wrote:
> > > (bisect fingered irqdomain: Avoid activating interrupts more than once)
> > 
> > Yeah, that one is not kosher on x86. It broke IO-APIC timer on a box
> > here.
> 
> Mike,
> 
> does the below hunk fix the issue for ya? (Ontop of tip/master, without
> the revert).
> 
> It does fix my APIC timer detection failure.

Yup, need a new doorstop.

-Mike


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Mike Galbraith
On Tue, 2017-01-31 at 18:49 +0100, Borislav Petkov wrote:
> On Tue, Jan 31, 2017 at 01:31:00PM +0100, Borislav Petkov wrote:
> > On Tue, Jan 31, 2017 at 12:31:17PM +0100, Mike Galbraith wrote:
> > > (bisect fingered irqdomain: Avoid activating interrupts more than once)
> > 
> > Yeah, that one is not kosher on x86. It broke IO-APIC timer on a box
> > here.
> 
> Mike,
> 
> does the below hunk fix the issue for ya? (Ontop of tip/master, without
> the revert).
> 
> It does fix my APIC timer detection failure.

Yup, need a new doorstop.

-Mike


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Thomas Gleixner
On Tue, 31 Jan 2017, Mike Galbraith wrote:

> On Tue, 2017-01-31 at 11:01 +0100, Borislav Petkov wrote:
> > On Tue, Jan 31, 2017 at 08:43:55AM +0100, Ingo Molnar wrote:
> > > (Cc:-ed Mike as this could explain his early boot crash/hang?
> > > Mike: please try -tip f18a8a0143b1 that I just pushed out. )
> > 
> > One other thing to try, Mike, is boot with "dis_ucode_ldr". See whether
> > that makes it go away.
> 
> (bisect fingered irqdomain: Avoid activating interrupts more than once)

That commit exposed interesting code in x86 land. Can you please try the
patch below?

Thanks,

tglx
8<--

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1e35dd06b090..52f352b063fd 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2117,6 +2117,7 @@ static inline void __init check_timer(void)
if (idx != -1 && irq_trigger(idx))
unmask_ioapic_irq(irq_get_chip_data(0));
}
+   irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
if (timer_irq_works()) {
if (disable_timer_pin_1 > 0)
@@ -2138,6 +2139,7 @@ static inline void __init check_timer(void)
 * legacy devices should be connected to IO APIC #0
 */
replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2);
+   irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
legacy_pic->unmask(0);
if (timer_irq_works()) {
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 85e87b46c318..dc6ba5bda9fc 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -352,6 +352,7 @@ static int hpet_resume(struct clock_event_device *evt, int 
timer)
} else {
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
 
+   irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq));
irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
disable_irq(hdev->irq);
irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));



Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Thomas Gleixner
On Tue, 31 Jan 2017, Mike Galbraith wrote:

> On Tue, 2017-01-31 at 11:01 +0100, Borislav Petkov wrote:
> > On Tue, Jan 31, 2017 at 08:43:55AM +0100, Ingo Molnar wrote:
> > > (Cc:-ed Mike as this could explain his early boot crash/hang?
> > > Mike: please try -tip f18a8a0143b1 that I just pushed out. )
> > 
> > One other thing to try, Mike, is boot with "dis_ucode_ldr". See whether
> > that makes it go away.
> 
> (bisect fingered irqdomain: Avoid activating interrupts more than once)

That commit exposed interesting code in x86 land. Can you please try the
patch below?

Thanks,

tglx
8<--

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1e35dd06b090..52f352b063fd 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2117,6 +2117,7 @@ static inline void __init check_timer(void)
if (idx != -1 && irq_trigger(idx))
unmask_ioapic_irq(irq_get_chip_data(0));
}
+   irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
if (timer_irq_works()) {
if (disable_timer_pin_1 > 0)
@@ -2138,6 +2139,7 @@ static inline void __init check_timer(void)
 * legacy devices should be connected to IO APIC #0
 */
replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2);
+   irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
legacy_pic->unmask(0);
if (timer_irq_works()) {
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 85e87b46c318..dc6ba5bda9fc 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -352,6 +352,7 @@ static int hpet_resume(struct clock_event_device *evt, int 
timer)
} else {
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
 
+   irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq));
irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
disable_irq(hdev->irq);
irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));



Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Borislav Petkov
On Tue, Jan 31, 2017 at 01:31:00PM +0100, Borislav Petkov wrote:
> On Tue, Jan 31, 2017 at 12:31:17PM +0100, Mike Galbraith wrote:
> > (bisect fingered irqdomain: Avoid activating interrupts more than once)
> 
> Yeah, that one is not kosher on x86. It broke IO-APIC timer on a box
> here.

Mike,

does the below hunk fix the issue for ya? (Ontop of tip/master, without
the revert).

It does fix my APIC timer detection failure.

---
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1e35dd06b090..52f352b063fd 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2117,6 +2117,7 @@ static inline void __init check_timer(void)
if (idx != -1 && irq_trigger(idx))
unmask_ioapic_irq(irq_get_chip_data(0));
}
+   irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
if (timer_irq_works()) {
if (disable_timer_pin_1 > 0)
@@ -2138,6 +2139,7 @@ static inline void __init check_timer(void)
 * legacy devices should be connected to IO APIC #0
 */
replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2);
+   irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
legacy_pic->unmask(0);
if (timer_irq_works()) {
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 85e87b46c318..dc6ba5bda9fc 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -352,6 +352,7 @@ static int hpet_resume(struct clock_event_device *evt, int 
timer)
} else {
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
 
+   irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq));
irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
disable_irq(hdev->irq);
irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Borislav Petkov
On Tue, Jan 31, 2017 at 01:31:00PM +0100, Borislav Petkov wrote:
> On Tue, Jan 31, 2017 at 12:31:17PM +0100, Mike Galbraith wrote:
> > (bisect fingered irqdomain: Avoid activating interrupts more than once)
> 
> Yeah, that one is not kosher on x86. It broke IO-APIC timer on a box
> here.

Mike,

does the below hunk fix the issue for ya? (Ontop of tip/master, without
the revert).

It does fix my APIC timer detection failure.

---
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1e35dd06b090..52f352b063fd 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2117,6 +2117,7 @@ static inline void __init check_timer(void)
if (idx != -1 && irq_trigger(idx))
unmask_ioapic_irq(irq_get_chip_data(0));
}
+   irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
if (timer_irq_works()) {
if (disable_timer_pin_1 > 0)
@@ -2138,6 +2139,7 @@ static inline void __init check_timer(void)
 * legacy devices should be connected to IO APIC #0
 */
replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2);
+   irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
legacy_pic->unmask(0);
if (timer_irq_works()) {
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 85e87b46c318..dc6ba5bda9fc 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -352,6 +352,7 @@ static int hpet_resume(struct clock_event_device *evt, int 
timer)
} else {
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
 
+   irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq));
irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
disable_irq(hdev->irq);
irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Ingo Molnar

* Borislav Petkov  wrote:

> On Tue, Jan 31, 2017 at 08:43:55AM +0100, Ingo Molnar wrote:
> > (Cc:-ed Mike as this could explain his early boot crash/hang?
> > Mike: please try -tip f18a8a0143b1 that I just pushed out. )
> 
> One other thing to try, Mike, is boot with "dis_ucode_ldr". See whether
> that makes it go away.
> 
> > Nice - I've updated the branch with your resolution. Could you please 
> > double-check the double checked resolution?
> 
> That's like quadruple-checked :-)

Yeah, so when I wrote that I was pondering whether that counts as triple or 
quadruple checked. I couldn't make up my mind ;-)

Thanks,

Ingo


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Ingo Molnar

* Borislav Petkov  wrote:

> On Tue, Jan 31, 2017 at 08:43:55AM +0100, Ingo Molnar wrote:
> > (Cc:-ed Mike as this could explain his early boot crash/hang?
> > Mike: please try -tip f18a8a0143b1 that I just pushed out. )
> 
> One other thing to try, Mike, is boot with "dis_ucode_ldr". See whether
> that makes it go away.
> 
> > Nice - I've updated the branch with your resolution. Could you please 
> > double-check the double checked resolution?
> 
> That's like quadruple-checked :-)

Yeah, so when I wrote that I was pondering whether that counts as triple or 
quadruple checked. I couldn't make up my mind ;-)

Thanks,

Ingo


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Borislav Petkov
On Tue, Jan 31, 2017 at 12:31:17PM +0100, Mike Galbraith wrote:
> (bisect fingered irqdomain: Avoid activating interrupts more than once)

Yeah, that one is not kosher on x86. It broke IO-APIC timer on a box
here.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Borislav Petkov
On Tue, Jan 31, 2017 at 12:31:17PM +0100, Mike Galbraith wrote:
> (bisect fingered irqdomain: Avoid activating interrupts more than once)

Yeah, that one is not kosher on x86. It broke IO-APIC timer on a box
here.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Mike Galbraith
On Tue, 2017-01-31 at 11:01 +0100, Borislav Petkov wrote:
> On Tue, Jan 31, 2017 at 08:43:55AM +0100, Ingo Molnar wrote:
> > (Cc:-ed Mike as this could explain his early boot crash/hang?
> > Mike: please try -tip f18a8a0143b1 that I just pushed out. )
> 
> One other thing to try, Mike, is boot with "dis_ucode_ldr". See whether
> that makes it go away.

(bisect fingered irqdomain: Avoid activating interrupts more than once)


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Mike Galbraith
On Tue, 2017-01-31 at 11:01 +0100, Borislav Petkov wrote:
> On Tue, Jan 31, 2017 at 08:43:55AM +0100, Ingo Molnar wrote:
> > (Cc:-ed Mike as this could explain his early boot crash/hang?
> > Mike: please try -tip f18a8a0143b1 that I just pushed out. )
> 
> One other thing to try, Mike, is boot with "dis_ucode_ldr". See whether
> that makes it go away.

(bisect fingered irqdomain: Avoid activating interrupts more than once)


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Borislav Petkov
On Tue, Jan 31, 2017 at 08:43:55AM +0100, Ingo Molnar wrote:
> (Cc:-ed Mike as this could explain his early boot crash/hang?
> Mike: please try -tip f18a8a0143b1 that I just pushed out. )

One other thing to try, Mike, is boot with "dis_ucode_ldr". See whether
that makes it go away.

> Nice - I've updated the branch with your resolution. Could you please 
> double-check the double checked resolution?

That's like quadruple-checked :-)

> So the diff between your resolution and mine is attached below - now 
> fpu/core.c 
> changes, so I'm not sure why fpu/core.c is in your diff?

Hmm, maybe I did the diff wrong?

So this is how I generated it:

$ git diff tip/x86/microcode~1..tip/x86/microcode

meaning that I want to see what the merge commit changed. That's why
this pulled in the fpu/core.c hunk which is new in urgent.

In any case, the merge looks ok to me, I'll be testing it anyway in the
coming days so I'll let you know if anything goes nuts.

Thanks!

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-31 Thread Borislav Petkov
On Tue, Jan 31, 2017 at 08:43:55AM +0100, Ingo Molnar wrote:
> (Cc:-ed Mike as this could explain his early boot crash/hang?
> Mike: please try -tip f18a8a0143b1 that I just pushed out. )

One other thing to try, Mike, is boot with "dis_ucode_ldr". See whether
that makes it go away.

> Nice - I've updated the branch with your resolution. Could you please 
> double-check the double checked resolution?

That's like quadruple-checked :-)

> So the diff between your resolution and mine is attached below - now 
> fpu/core.c 
> changes, so I'm not sure why fpu/core.c is in your diff?

Hmm, maybe I did the diff wrong?

So this is how I generated it:

$ git diff tip/x86/microcode~1..tip/x86/microcode

meaning that I want to see what the merge commit changed. That's why
this pulled in the fpu/core.c hunk which is new in urgent.

In any case, the merge looks ok to me, I'll be testing it anyway in the
coming days so I'll let you know if anything goes nuts.

Thanks!

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-30 Thread Ingo Molnar

(Cc:-ed Mike as this could explain his early boot crash/hang?
Mike: please try -tip f18a8a0143b1 that I just pushed out. )

* Borislav Petkov  wrote:

> On Mon, Jan 30, 2017 at 09:46:32AM +0100, Ingo Molnar wrote:
> > Ok, I have applied this to tip:x86/urgent.
> > 
> > Note that there are new conflicts with your pending work in 
> > tip:x86/microcode, and 
> > I fixed them up in:
> > 
> >   7c5b4112040e Merge branch 'x86/urgent' into x86/microcode, to resolve 
> > conflicts
> > 
> > Could you please double-check my conflict resolution?
> 
> Almost, this part is wrong:
> 
> - arch/x86/kernel/cpu/microcode/amd.c 
> -
> index 7889ae492af0,079e81733a58..73082365ed1c
> @@@ -268,20 -316,43 +268,20 @@@ void __load_ucode_amd(unsigned int cpui
>   use_pa  = false;
>   }
>   
> - if (!get_builtin_microcode(, x86_family(cpuid_1_eax)))
>  -if (!get_builtin_microcode(, family))
> ++if (!get_builtin_microcode(, x86_family(cpuid_1_eax)) && 
> !initrd_gone)
>   cp = find_microcode_in_initrd(path, use_pa);
> 
> --
> 
> Btw, I did experiment with the merging because I knew it'll cause
> trouble due to the urgent fix and here's what I did:
> 
> You're merging tip/x86/urgent into tip/x86/microcode so I checked out
> the microcode branch and did:
> 
> $ git checkout -b tip-microcode tip/x86/microcode
> $ git merge -s recursive -X ours tip/x86/urgent
> 
> This way I'm favouring our changes in the conflicting files. It merges
> cleanly and the resulting diff is below.

Nice - I've updated the branch with your resolution. Could you please 
double-check the double checked resolution?

> The logic behind it is is that tip/x86/microcode does away with a bunch
> of code and the urgent change touches some of that code but that's only
> for 4.10.
> 
> It goes away in 4.11 and that's why we should prefer "ours" as the merge
> option.
> 
>[ Btw, I'll send a patch for 4.11 later to make initrd_gone static as
>  it is going to be used only in microcode/core.c after the cleanup. ]
> 
> However, I still haven't figured out how to say "prefer ours but only
> for specific files or subtree" because the diff has that hunk in
> arch/x86/kernel/fpu/core.c too which should definitely not be "ours" as
> it is a fix and there the urgent version should be the one going in.
> 
> Hmmm.

So the diff between your resolution and mine is attached below - now fpu/core.c 
changes, so I'm not sure why fpu/core.c is in your diff?

Thanks,

Ingo

diff --git a/arch/x86/kernel/cpu/microcode/amd.c 
b/arch/x86/kernel/cpu/microcode/amd.c
index 73082365ed1c..7889ae492af0 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -268,7 +268,7 @@ void __load_ucode_amd(unsigned int cpuid_1_eax, struct 
cpio_data *ret)
use_pa  = false;
}
 
-   if (!get_builtin_microcode(, x86_family(cpuid_1_eax)) && 
!initrd_gone)
+   if (!get_builtin_microcode(, x86_family(cpuid_1_eax)))
cp = find_microcode_in_initrd(path, use_pa);
 
/* Needed in load_microcode_amd() */
diff --git a/arch/x86/kernel/cpu/microcode/core.c 
b/arch/x86/kernel/cpu/microcode/core.c
index e51eeaed8016..b4a4cd39b358 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -230,7 +230,7 @@ static int __init save_microcode_in_initrd(void)
break;
case X86_VENDOR_AMD:
if (c->x86 >= 0x10)
-   ret = save_microcode_in_initrd_amd(cpuid_eax(1));
+   return save_microcode_in_initrd_amd(cpuid_eax(1));
break;
default:
break;



Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-30 Thread Ingo Molnar

(Cc:-ed Mike as this could explain his early boot crash/hang?
Mike: please try -tip f18a8a0143b1 that I just pushed out. )

* Borislav Petkov  wrote:

> On Mon, Jan 30, 2017 at 09:46:32AM +0100, Ingo Molnar wrote:
> > Ok, I have applied this to tip:x86/urgent.
> > 
> > Note that there are new conflicts with your pending work in 
> > tip:x86/microcode, and 
> > I fixed them up in:
> > 
> >   7c5b4112040e Merge branch 'x86/urgent' into x86/microcode, to resolve 
> > conflicts
> > 
> > Could you please double-check my conflict resolution?
> 
> Almost, this part is wrong:
> 
> - arch/x86/kernel/cpu/microcode/amd.c 
> -
> index 7889ae492af0,079e81733a58..73082365ed1c
> @@@ -268,20 -316,43 +268,20 @@@ void __load_ucode_amd(unsigned int cpui
>   use_pa  = false;
>   }
>   
> - if (!get_builtin_microcode(, x86_family(cpuid_1_eax)))
>  -if (!get_builtin_microcode(, family))
> ++if (!get_builtin_microcode(, x86_family(cpuid_1_eax)) && 
> !initrd_gone)
>   cp = find_microcode_in_initrd(path, use_pa);
> 
> --
> 
> Btw, I did experiment with the merging because I knew it'll cause
> trouble due to the urgent fix and here's what I did:
> 
> You're merging tip/x86/urgent into tip/x86/microcode so I checked out
> the microcode branch and did:
> 
> $ git checkout -b tip-microcode tip/x86/microcode
> $ git merge -s recursive -X ours tip/x86/urgent
> 
> This way I'm favouring our changes in the conflicting files. It merges
> cleanly and the resulting diff is below.

Nice - I've updated the branch with your resolution. Could you please 
double-check the double checked resolution?

> The logic behind it is is that tip/x86/microcode does away with a bunch
> of code and the urgent change touches some of that code but that's only
> for 4.10.
> 
> It goes away in 4.11 and that's why we should prefer "ours" as the merge
> option.
> 
>[ Btw, I'll send a patch for 4.11 later to make initrd_gone static as
>  it is going to be used only in microcode/core.c after the cleanup. ]
> 
> However, I still haven't figured out how to say "prefer ours but only
> for specific files or subtree" because the diff has that hunk in
> arch/x86/kernel/fpu/core.c too which should definitely not be "ours" as
> it is a fix and there the urgent version should be the one going in.
> 
> Hmmm.

So the diff between your resolution and mine is attached below - now fpu/core.c 
changes, so I'm not sure why fpu/core.c is in your diff?

Thanks,

Ingo

diff --git a/arch/x86/kernel/cpu/microcode/amd.c 
b/arch/x86/kernel/cpu/microcode/amd.c
index 73082365ed1c..7889ae492af0 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -268,7 +268,7 @@ void __load_ucode_amd(unsigned int cpuid_1_eax, struct 
cpio_data *ret)
use_pa  = false;
}
 
-   if (!get_builtin_microcode(, x86_family(cpuid_1_eax)) && 
!initrd_gone)
+   if (!get_builtin_microcode(, x86_family(cpuid_1_eax)))
cp = find_microcode_in_initrd(path, use_pa);
 
/* Needed in load_microcode_amd() */
diff --git a/arch/x86/kernel/cpu/microcode/core.c 
b/arch/x86/kernel/cpu/microcode/core.c
index e51eeaed8016..b4a4cd39b358 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -230,7 +230,7 @@ static int __init save_microcode_in_initrd(void)
break;
case X86_VENDOR_AMD:
if (c->x86 >= 0x10)
-   ret = save_microcode_in_initrd_amd(cpuid_eax(1));
+   return save_microcode_in_initrd_amd(cpuid_eax(1));
break;
default:
break;



Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-30 Thread Borislav Petkov
On Mon, Jan 30, 2017 at 09:46:32AM +0100, Ingo Molnar wrote:
> Ok, I have applied this to tip:x86/urgent.
> 
> Note that there are new conflicts with your pending work in 
> tip:x86/microcode, and 
> I fixed them up in:
> 
>   7c5b4112040e Merge branch 'x86/urgent' into x86/microcode, to resolve 
> conflicts
> 
> Could you please double-check my conflict resolution?

Almost, this part is wrong:

- arch/x86/kernel/cpu/microcode/amd.c -
index 7889ae492af0,079e81733a58..73082365ed1c
@@@ -268,20 -316,43 +268,20 @@@ void __load_ucode_amd(unsigned int cpui
use_pa  = false;
}
  
-   if (!get_builtin_microcode(, x86_family(cpuid_1_eax)))
 -  if (!get_builtin_microcode(, family))
++  if (!get_builtin_microcode(, x86_family(cpuid_1_eax)) && 
!initrd_gone)
cp = find_microcode_in_initrd(path, use_pa);

--

Btw, I did experiment with the merging because I knew it'll cause
trouble due to the urgent fix and here's what I did:

You're merging tip/x86/urgent into tip/x86/microcode so I checked out
the microcode branch and did:

$ git checkout -b tip-microcode tip/x86/microcode
$ git merge -s recursive -X ours tip/x86/urgent

This way I'm favouring our changes in the conflicting files. It merges
cleanly and the resulting diff is below.

The logic behind it is is that tip/x86/microcode does away with a bunch
of code and the urgent change touches some of that code but that's only
for 4.10.

It goes away in 4.11 and that's why we should prefer "ours" as the merge
option.

 [ Btw, I'll send a patch for 4.11 later to make initrd_gone static as
   it is going to be used only in microcode/core.c after the cleanup. ]

However, I still haven't figured out how to say "prefer ours but only
for specific files or subtree" because the diff has that hunk in
arch/x86/kernel/fpu/core.c too which should definitely not be "ours" as
it is a fix and there the urgent version should be the one going in.

Hmmm.

---

$ git diff HEAD~1..
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 90b22bbdfce9..daadeeea00b1 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -139,6 +139,7 @@ extern void __init load_ucode_bsp(void);
 extern void load_ucode_ap(void);
 void reload_early_microcode(void);
 extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
+extern bool initrd_gone;
 #else
 static inline int __init microcode_init(void)  { return 0; };
 static inline void __init load_ucode_bsp(void) { }
diff --git a/arch/x86/kernel/cpu/microcode/core.c 
b/arch/x86/kernel/cpu/microcode/core.c
index 3b74d2f315d3..b4a4cd39b358 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -46,6 +46,8 @@
 static struct microcode_ops*microcode_ops;
 static bool dis_ucode_ldr = true;
 
+bool initrd_gone;
+
 LIST_HEAD(microcode_cache);
 
 /*
@@ -219,11 +221,12 @@ void load_ucode_ap(void)
 static int __init save_microcode_in_initrd(void)
 {
struct cpuinfo_x86 *c = _cpu_data;
+   int ret = -EINVAL;
 
switch (c->x86_vendor) {
case X86_VENDOR_INTEL:
if (c->x86 >= 6)
-   return save_microcode_in_initrd_intel();
+   ret = save_microcode_in_initrd_intel();
break;
case X86_VENDOR_AMD:
if (c->x86 >= 0x10)
@@ -233,7 +236,9 @@ static int __init save_microcode_in_initrd(void)
break;
}
 
-   return -EINVAL;
+   initrd_gone = true;
+
+   return ret;
 }
 
 struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa)
@@ -276,9 +281,16 @@ struct cpio_data find_microcode_in_initrd(const char 
*path, bool use_pa)
 * has the virtual address of the beginning of the initrd. It also
 * possibly relocates the ramdisk. In either case, initrd_start contains
 * the updated address so use that instead.
+*
+* initrd_gone is for the hotplug case where we've thrown out initrd
+* already.
 */
-   if (!use_pa && initrd_start)
-   start = initrd_start;
+   if (!use_pa) {
+   if (initrd_gone)
+   return (struct cpio_data){ NULL, 0, "" };
+   if (initrd_start)
+   start = initrd_start;
+   }
 
return find_cpio_data(path, (void *)start, size, NULL);
 #else /* !CONFIG_BLK_DEV_INITRD */
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index e4e97a5355ce..de7234401275 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -183,7 +184,8 @@ void fpstate_init(union fpregs_state *state)
 * it will #GP. Make sure it is replaced after the memset().
 */
if 

Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-30 Thread Borislav Petkov
On Mon, Jan 30, 2017 at 09:46:32AM +0100, Ingo Molnar wrote:
> Ok, I have applied this to tip:x86/urgent.
> 
> Note that there are new conflicts with your pending work in 
> tip:x86/microcode, and 
> I fixed them up in:
> 
>   7c5b4112040e Merge branch 'x86/urgent' into x86/microcode, to resolve 
> conflicts
> 
> Could you please double-check my conflict resolution?

Almost, this part is wrong:

- arch/x86/kernel/cpu/microcode/amd.c -
index 7889ae492af0,079e81733a58..73082365ed1c
@@@ -268,20 -316,43 +268,20 @@@ void __load_ucode_amd(unsigned int cpui
use_pa  = false;
}
  
-   if (!get_builtin_microcode(, x86_family(cpuid_1_eax)))
 -  if (!get_builtin_microcode(, family))
++  if (!get_builtin_microcode(, x86_family(cpuid_1_eax)) && 
!initrd_gone)
cp = find_microcode_in_initrd(path, use_pa);

--

Btw, I did experiment with the merging because I knew it'll cause
trouble due to the urgent fix and here's what I did:

You're merging tip/x86/urgent into tip/x86/microcode so I checked out
the microcode branch and did:

$ git checkout -b tip-microcode tip/x86/microcode
$ git merge -s recursive -X ours tip/x86/urgent

This way I'm favouring our changes in the conflicting files. It merges
cleanly and the resulting diff is below.

The logic behind it is is that tip/x86/microcode does away with a bunch
of code and the urgent change touches some of that code but that's only
for 4.10.

It goes away in 4.11 and that's why we should prefer "ours" as the merge
option.

 [ Btw, I'll send a patch for 4.11 later to make initrd_gone static as
   it is going to be used only in microcode/core.c after the cleanup. ]

However, I still haven't figured out how to say "prefer ours but only
for specific files or subtree" because the diff has that hunk in
arch/x86/kernel/fpu/core.c too which should definitely not be "ours" as
it is a fix and there the urgent version should be the one going in.

Hmmm.

---

$ git diff HEAD~1..
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 90b22bbdfce9..daadeeea00b1 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -139,6 +139,7 @@ extern void __init load_ucode_bsp(void);
 extern void load_ucode_ap(void);
 void reload_early_microcode(void);
 extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
+extern bool initrd_gone;
 #else
 static inline int __init microcode_init(void)  { return 0; };
 static inline void __init load_ucode_bsp(void) { }
diff --git a/arch/x86/kernel/cpu/microcode/core.c 
b/arch/x86/kernel/cpu/microcode/core.c
index 3b74d2f315d3..b4a4cd39b358 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -46,6 +46,8 @@
 static struct microcode_ops*microcode_ops;
 static bool dis_ucode_ldr = true;
 
+bool initrd_gone;
+
 LIST_HEAD(microcode_cache);
 
 /*
@@ -219,11 +221,12 @@ void load_ucode_ap(void)
 static int __init save_microcode_in_initrd(void)
 {
struct cpuinfo_x86 *c = _cpu_data;
+   int ret = -EINVAL;
 
switch (c->x86_vendor) {
case X86_VENDOR_INTEL:
if (c->x86 >= 6)
-   return save_microcode_in_initrd_intel();
+   ret = save_microcode_in_initrd_intel();
break;
case X86_VENDOR_AMD:
if (c->x86 >= 0x10)
@@ -233,7 +236,9 @@ static int __init save_microcode_in_initrd(void)
break;
}
 
-   return -EINVAL;
+   initrd_gone = true;
+
+   return ret;
 }
 
 struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa)
@@ -276,9 +281,16 @@ struct cpio_data find_microcode_in_initrd(const char 
*path, bool use_pa)
 * has the virtual address of the beginning of the initrd. It also
 * possibly relocates the ramdisk. In either case, initrd_start contains
 * the updated address so use that instead.
+*
+* initrd_gone is for the hotplug case where we've thrown out initrd
+* already.
 */
-   if (!use_pa && initrd_start)
-   start = initrd_start;
+   if (!use_pa) {
+   if (initrd_gone)
+   return (struct cpio_data){ NULL, 0, "" };
+   if (initrd_start)
+   start = initrd_start;
+   }
 
return find_cpio_data(path, (void *)start, size, NULL);
 #else /* !CONFIG_BLK_DEV_INITRD */
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index e4e97a5355ce..de7234401275 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -183,7 +184,8 @@ void fpstate_init(union fpregs_state *state)
 * it will #GP. Make sure it is replaced after the memset().
 */
if 

Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-30 Thread Ingo Molnar

* Borislav Petkov  wrote:

> On Fri, Jan 27, 2017 at 11:14:06AM +0300, Andrey Ryabinin wrote:
> > Works for me as well.
> > Tested-by: Andrey Ryabinin 
> 
> Thanks!

Ok, I have applied this to tip:x86/urgent.

Note that there are new conflicts with your pending work in tip:x86/microcode, 
and 
I fixed them up in:

  7c5b4112040e Merge branch 'x86/urgent' into x86/microcode, to resolve 
conflicts

Could you please double-check my conflict resolution?

Thanks,

Ingo


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-30 Thread Ingo Molnar

* Borislav Petkov  wrote:

> On Fri, Jan 27, 2017 at 11:14:06AM +0300, Andrey Ryabinin wrote:
> > Works for me as well.
> > Tested-by: Andrey Ryabinin 
> 
> Thanks!

Ok, I have applied this to tip:x86/urgent.

Note that there are new conflicts with your pending work in tip:x86/microcode, 
and 
I fixed them up in:

  7c5b4112040e Merge branch 'x86/urgent' into x86/microcode, to resolve 
conflicts

Could you please double-check my conflict resolution?

Thanks,

Ingo


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-27 Thread Borislav Petkov
On Fri, Jan 27, 2017 at 11:14:06AM +0300, Andrey Ryabinin wrote:
> Works for me as well.
> Tested-by: Andrey Ryabinin 

Thanks!

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-27 Thread Borislav Petkov
On Fri, Jan 27, 2017 at 11:14:06AM +0300, Andrey Ryabinin wrote:
> Works for me as well.
> Tested-by: Andrey Ryabinin 

Thanks!

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-27 Thread Andrey Ryabinin


On 01/26/2017 07:58 PM, Borislav Petkov wrote:
> On Wed, Jan 25, 2017 at 08:23:36PM +0100, Borislav Petkov wrote:
>> On Wed, Jan 25, 2017 at 10:14:50PM +0300, Andrey Ryabinin wrote:
 Does that help?
>>>
>>> Yup.
>>> Tested-by: Andrey Ryabinin 
>>
>> Thanks, I'll run it through the test boxes here too.
> 
> Yeah, the fix isn't that simple, I had to do a bit more. Please test
> that one instead.
> 

Works for me as well.
Tested-by: Andrey Ryabinin 


Re: [PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-27 Thread Andrey Ryabinin


On 01/26/2017 07:58 PM, Borislav Petkov wrote:
> On Wed, Jan 25, 2017 at 08:23:36PM +0100, Borislav Petkov wrote:
>> On Wed, Jan 25, 2017 at 10:14:50PM +0300, Andrey Ryabinin wrote:
 Does that help?
>>>
>>> Yup.
>>> Tested-by: Andrey Ryabinin 
>>
>> Thanks, I'll run it through the test boxes here too.
> 
> Yeah, the fix isn't that simple, I had to do a bit more. Please test
> that one instead.
> 

Works for me as well.
Tested-by: Andrey Ryabinin 


[PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-26 Thread Borislav Petkov
On Wed, Jan 25, 2017 at 08:23:36PM +0100, Borislav Petkov wrote:
> On Wed, Jan 25, 2017 at 10:14:50PM +0300, Andrey Ryabinin wrote:
> > > Does that help?
> > 
> > Yup.
> > Tested-by: Andrey Ryabinin 
> 
> Thanks, I'll run it through the test boxes here too.

Yeah, the fix isn't that simple, I had to do a bit more. Please test
that one instead.

Thanks.

---
From: Borislav Petkov 
Date: Wed, 25 Jan 2017 21:00:48 +0100
Subject: [PATCH] x86/microcode: Do not access the initrd after it has been freed

When we look for microcode blobs, we first try builtin and if that
doesn't succeed, we fallback to the initrd supplied to the kernel.

However, at some point doing boot, that initrd gets jettisoned and we
shouldn't access it anymore. But we do, as the below KASAN report shows.
That's because find_microcode_in_initrd() doesn't check whether the
initrd is still valid or not.

So do that.

  ==
  BUG: KASAN: use-after-free in find_cpio_data
  Read of size 1 by task swapper/1/0
  page:eadb9d40 count:0 mapcount:0 mapping:  (null) index:0x1
  flags: 0x100()
  raw: 0100  0001 
  raw: dead0100 dead0200  
  page dumped because: kasan: bad access detected
  CPU: 1 PID: 0 Comm: swapper/1 Tainted: GW   
4.10.0-rc5-debug-00075-g2dbde22 #3
  Hardware name: Dell Inc. XPS 13 9360/0839Y6, BIOS 1.2.3 12/01/2016
  Call Trace:
   dump_stack
   ? _atomic_dec_and_lock
   ? __dump_page
   kasan_report_error
   ? pointer
   ? find_cpio_data
   __asan_report_load1_noabort
   ? find_cpio_data
   find_cpio_data
   ? vsprintf
   ? dump_stack
   ? get_ucode_user
   ? print_usage_bug
   find_microcode_in_initrd
   __load_ucode_intel
   ? collect_cpu_info_early
   ? debug_check_no_locks_freed
   load_ucode_intel_ap
   ? collect_cpu_info
   ? trace_hardirqs_on
   ? flat_send_IPI_mask_allbutself
   load_ucode_ap
   ? get_builtin_firmware
   ? flush_tlb_func
   ? do_raw_spin_trylock
   ? cpumask_weight
   cpu_init
   ? trace_hardirqs_off
   ? play_dead_common
   ? native_play_dead
   ? hlt_play_dead
   ? syscall_init
   ? arch_cpu_idle_dead
   ? do_idle
   start_secondary
   start_cpu
  Memory state around the buggy address:
   880036e74f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
   880036e74f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
  >880036e75000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ^
   880036e75080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
   880036e75100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
  ==

Reported-by: Andrey Ryabinin 
Signed-off-by: Borislav Petkov 
---
 arch/x86/include/asm/microcode.h |  1 +
 arch/x86/kernel/cpu/microcode/amd.c  |  5 +++--
 arch/x86/kernel/cpu/microcode/core.c | 22 +-
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 38711df3bcb5..2266f864b747 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -140,6 +140,7 @@ extern void __init load_ucode_bsp(void);
 extern void load_ucode_ap(void);
 void reload_early_microcode(void);
 extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
+extern bool initrd_gone;
 #else
 static inline int __init microcode_init(void)  { return 0; };
 static inline void __init load_ucode_bsp(void) { }
diff --git a/arch/x86/kernel/cpu/microcode/amd.c 
b/arch/x86/kernel/cpu/microcode/amd.c
index 6a31e2691f3a..079e81733a58 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -384,8 +384,9 @@ void load_ucode_amd_ap(unsigned int family)
 reget:
if (!get_builtin_microcode(, family)) {
 #ifdef CONFIG_BLK_DEV_INITRD
-   cp = find_cpio_data(ucode_path, (void *)initrd_start,
-   initrd_end - initrd_start, NULL);
+   if (!initrd_gone)
+   cp = find_cpio_data(ucode_path, (void 
*)initrd_start,
+   initrd_end - initrd_start, 
NULL);
 #endif
if (!(cp.data && cp.size)) {
/*
diff --git a/arch/x86/kernel/cpu/microcode/core.c 
b/arch/x86/kernel/cpu/microcode/core.c
index 2af69d27da62..73102d932760 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -46,6 +46,8 @@
 static struct microcode_ops*microcode_ops;
 static bool dis_ucode_ldr = true;
 
+bool initrd_gone;
+
 LIST_HEAD(microcode_cache);
 
 /*
@@ -190,21 +192,24 @@ void load_ucode_ap(void)
 static int __init 

[PATCH] x86/microcode: Do not access the initrd after it has been freed

2017-01-26 Thread Borislav Petkov
On Wed, Jan 25, 2017 at 08:23:36PM +0100, Borislav Petkov wrote:
> On Wed, Jan 25, 2017 at 10:14:50PM +0300, Andrey Ryabinin wrote:
> > > Does that help?
> > 
> > Yup.
> > Tested-by: Andrey Ryabinin 
> 
> Thanks, I'll run it through the test boxes here too.

Yeah, the fix isn't that simple, I had to do a bit more. Please test
that one instead.

Thanks.

---
From: Borislav Petkov 
Date: Wed, 25 Jan 2017 21:00:48 +0100
Subject: [PATCH] x86/microcode: Do not access the initrd after it has been freed

When we look for microcode blobs, we first try builtin and if that
doesn't succeed, we fallback to the initrd supplied to the kernel.

However, at some point doing boot, that initrd gets jettisoned and we
shouldn't access it anymore. But we do, as the below KASAN report shows.
That's because find_microcode_in_initrd() doesn't check whether the
initrd is still valid or not.

So do that.

  ==
  BUG: KASAN: use-after-free in find_cpio_data
  Read of size 1 by task swapper/1/0
  page:eadb9d40 count:0 mapcount:0 mapping:  (null) index:0x1
  flags: 0x100()
  raw: 0100  0001 
  raw: dead0100 dead0200  
  page dumped because: kasan: bad access detected
  CPU: 1 PID: 0 Comm: swapper/1 Tainted: GW   
4.10.0-rc5-debug-00075-g2dbde22 #3
  Hardware name: Dell Inc. XPS 13 9360/0839Y6, BIOS 1.2.3 12/01/2016
  Call Trace:
   dump_stack
   ? _atomic_dec_and_lock
   ? __dump_page
   kasan_report_error
   ? pointer
   ? find_cpio_data
   __asan_report_load1_noabort
   ? find_cpio_data
   find_cpio_data
   ? vsprintf
   ? dump_stack
   ? get_ucode_user
   ? print_usage_bug
   find_microcode_in_initrd
   __load_ucode_intel
   ? collect_cpu_info_early
   ? debug_check_no_locks_freed
   load_ucode_intel_ap
   ? collect_cpu_info
   ? trace_hardirqs_on
   ? flat_send_IPI_mask_allbutself
   load_ucode_ap
   ? get_builtin_firmware
   ? flush_tlb_func
   ? do_raw_spin_trylock
   ? cpumask_weight
   cpu_init
   ? trace_hardirqs_off
   ? play_dead_common
   ? native_play_dead
   ? hlt_play_dead
   ? syscall_init
   ? arch_cpu_idle_dead
   ? do_idle
   start_secondary
   start_cpu
  Memory state around the buggy address:
   880036e74f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
   880036e74f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
  >880036e75000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ^
   880036e75080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
   880036e75100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
  ==

Reported-by: Andrey Ryabinin 
Signed-off-by: Borislav Petkov 
---
 arch/x86/include/asm/microcode.h |  1 +
 arch/x86/kernel/cpu/microcode/amd.c  |  5 +++--
 arch/x86/kernel/cpu/microcode/core.c | 22 +-
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 38711df3bcb5..2266f864b747 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -140,6 +140,7 @@ extern void __init load_ucode_bsp(void);
 extern void load_ucode_ap(void);
 void reload_early_microcode(void);
 extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
+extern bool initrd_gone;
 #else
 static inline int __init microcode_init(void)  { return 0; };
 static inline void __init load_ucode_bsp(void) { }
diff --git a/arch/x86/kernel/cpu/microcode/amd.c 
b/arch/x86/kernel/cpu/microcode/amd.c
index 6a31e2691f3a..079e81733a58 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -384,8 +384,9 @@ void load_ucode_amd_ap(unsigned int family)
 reget:
if (!get_builtin_microcode(, family)) {
 #ifdef CONFIG_BLK_DEV_INITRD
-   cp = find_cpio_data(ucode_path, (void *)initrd_start,
-   initrd_end - initrd_start, NULL);
+   if (!initrd_gone)
+   cp = find_cpio_data(ucode_path, (void 
*)initrd_start,
+   initrd_end - initrd_start, 
NULL);
 #endif
if (!(cp.data && cp.size)) {
/*
diff --git a/arch/x86/kernel/cpu/microcode/core.c 
b/arch/x86/kernel/cpu/microcode/core.c
index 2af69d27da62..73102d932760 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -46,6 +46,8 @@
 static struct microcode_ops*microcode_ops;
 static bool dis_ucode_ldr = true;
 
+bool initrd_gone;
+
 LIST_HEAD(microcode_cache);
 
 /*
@@ -190,21 +192,24 @@ void load_ucode_ap(void)
 static int __init save_microcode_in_initrd(void)
 {
struct cpuinfo_x86 *c = _cpu_data;
+   int