On Thu, 08 Feb 2018 15:20:16 +0000
Eric Anholt <eric(a)anholt.net> wrote:
> Boris Brezillon <boris.brezillon(a)bootlin.com> writes:
>
> > All bcm2835 PLLs should be gated before their rate can be changed.
> > Setting CLK_SET_RATE_GATE will let the core enforce that, but this is
> > not enough to make the code work in all situations. Indeed, the
> > CLK_SET_RATE_GATE flag prevents a user from changing the rate while
> > the clock is enabled, but this check only guarantees there's no Linux
> > users. In our case, the clock might have been enabled by the
> > bootloader/FW, and, because we have CLK_IGNORE_UNUSED set, Linux never
> > disables the PLL. So we have to make sure the PLL is actually disabled
> > before changing the rate.
> >
> > Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks")
> > Cc: <stable(a)vger.kernel.org>
> > Signed-off-by: Boris Brezillon <boris.brezillon(a)bootlin.com>
> > ---
> > drivers/clk/bcm/clk-bcm2835.c | 14 +++++++++++++-
> > 1 file changed, 13 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
> > index 6c5d4a8e426c..051ce769c109 100644
> > --- a/drivers/clk/bcm/clk-bcm2835.c
> > +++ b/drivers/clk/bcm/clk-bcm2835.c
> > @@ -678,6 +678,18 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
> > u32 ana[4];
> > int i;
> >
> > + /*
> > + * Normally, the CLK_SET_RATE_GATE flag prevents a user from changing
> > + * the rate while the clock is enabled, but this check only makes sure
> > + * there's no Linux users.
> > + * In our case, the clock might have been enabled by the bootloader/FW,
> > + * and, since CLK_IGNORE_UNUSED flag is set, Linux never disables it.
> > + * So we have to make sure the clk is actually disabled before changing
> > + * the rate.
> > + */
> > + if (bcm2835_pll_is_on(hw))
> > + bcm2835_pll_off(hw);
> > +
>
> I'm not sure this improves the situation. If the PLL was on, then
> presumably there's a divider using it and a CM clock using that, so
> we'll probably end up driving some glitches on them.
Hm, yes, but if someone is trying to change the rate of the PLL, and the
core doesn't know other clks depend on this PLL (which is the case if
we reach this point), we're already in big trouble.
>
> Does the common clk framework have a way to disable unused clocks from
> the leaf clocks up to this root, before the general
> disable-unused-clocks path happens late in the boot process?
Not that I know of. What do you have in mind?
--
Boris Brezillon, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com
On Thu, 08 Feb 2018 15:15:42 +0000
Eric Anholt <eric(a)anholt.net> wrote:
> Boris Brezillon <boris.brezillon(a)bootlin.com> writes:
>
> > In order to enable a PLL, not only the PLL has to be powered up and
> > locked, but you also have to de-assert the reset signal. The last part
> > was missing. Add it so PLLs that were not enabled by the FW/bootloader
> > can be enabled from Linux.
> >
> > Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks")
> > Cc: <stable(a)vger.kernel.org>
> > Signed-off-by: Boris Brezillon <boris.brezillon(a)bootlin.com>
> > ---
> > drivers/clk/bcm/clk-bcm2835.c | 7 +++++++
> > 1 file changed, 7 insertions(+)
> >
> > diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
> > index a07f6451694a..6c5d4a8e426c 100644
> > --- a/drivers/clk/bcm/clk-bcm2835.c
> > +++ b/drivers/clk/bcm/clk-bcm2835.c
> > @@ -602,6 +602,9 @@ static void bcm2835_pll_off(struct clk_hw *hw)
> > const struct bcm2835_pll_data *data = pll->data;
> >
> > spin_lock(&cprman->regs_lock);
> > + cprman_write(cprman, data->a2w_ctrl_reg,
> > + cprman_read(cprman, data->a2w_ctrl_reg) &
> > + ~A2W_PLL_CTRL_PRST_DISABLE);
> > cprman_write(cprman, data->cm_ctrl_reg,
> > cprman_read(cprman, data->cm_ctrl_reg) |
> > CM_PLL_ANARST);
>
> For turning off, the FW just does the equivalent of:
>
> cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
> cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
>
> How about we do that, instead?
Agreed.
>
> > @@ -640,6 +643,10 @@ static int bcm2835_pll_on(struct clk_hw *hw)
> > cpu_relax();
> > }
> >
> > + cprman_write(cprman, data->a2w_ctrl_reg,
> > + cprman_read(cprman, data->a2w_ctrl_reg) |
> > + A2W_PLL_CTRL_PRST_DISABLE);
> > +
> > return 0;
> > }
>
> I agree with this hunk -- they drop PRST at the very end, after lock.
--
Boris Brezillon, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com
From: Borislav Petkov <bp(a)suse.de>
commit a15a753539eca8ba243d576f02e7ca9c4b7d7042 upstream with minor
adjustments.
Doing so is completely void of sense for multiple reasons so prevent
it. Set dis_ucode_ldr to true and thus disable the microcode loader by
default to address xen pv guests which execute the AP path but not the
BSP path.
By having it turned off by default, the APs won't run into the loader
either.
Also, check CPUID(1).ECX[31] which hypervisors set. Well almost, not the
xen pv one. That one gets the aforementioned "fix".
Also, improve the detection method by caching the final decision whether
to continue loading in dis_ucode_ldr and do it once on the BSP. The APs
then simply test that value.
Signed-off-by: Borislav Petkov <bp(a)suse.de>
Tested-by: Juergen Gross <jgross(a)suse.com>
Tested-by: Boris Ostrovsky <boris.ostrovsky(a)oracle.com>
Acked-by: Juergen Gross <jgross(a)suse.com>
Link: http://lkml.kernel.org/r/20161218164414.9649-4-bp@alien8.de
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Cc: <stable(a)vger.kernel.org> # 4.4.x
Signed-off-by: Rolf Neugebauer <rolf.neugebauer(a)docker.com>
---
arch/x86/kernel/cpu/microcode/core.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index b3e94ef461fd..1b3e0aa4c511 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -44,7 +44,7 @@
static struct microcode_ops *microcode_ops;
-static bool dis_ucode_ldr;
+static bool dis_ucode_ldr = true;
static int __init disable_loader(char *str)
{
@@ -81,6 +81,7 @@ struct cpu_info_ctx {
static bool __init check_loader_disabled_bsp(void)
{
+ u32 a, b, c, d;
#ifdef CONFIG_X86_32
const char *cmdline = (const char *)__pa_nodebug(boot_command_line);
const char *opt = "dis_ucode_ldr";
@@ -93,8 +94,23 @@ static bool __init check_loader_disabled_bsp(void)
bool *res = &dis_ucode_ldr;
#endif
- if (cmdline_find_option_bool(cmdline, option))
- *res = true;
+ if (!have_cpuid_p())
+ return *res;
+
+ a = 1;
+ c = 0;
+ native_cpuid(&a, &b, &c, &d);
+
+ /*
+ * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not
+ * completely accurate as xen pv guests don't see that CPUID bit set but
+ * that's good enough as they don't land on the BSP path anyway.
+ */
+ if (c & BIT(31))
+ return *res;
+
+ if (cmdline_find_option_bool(cmdline, option) <= 0)
+ *res = false;
return *res;
}
@@ -126,9 +142,6 @@ void __init load_ucode_bsp(void)
if (check_loader_disabled_bsp())
return;
- if (!have_cpuid_p())
- return;
-
vendor = x86_vendor();
family = x86_family();
@@ -162,9 +175,6 @@ void load_ucode_ap(void)
if (check_loader_disabled_ap())
return;
- if (!have_cpuid_p())
- return;
-
vendor = x86_vendor();
family = x86_family();
--
2.16.0
This is a note to let you know that I've just added the patch titled
x86/microcode: Do the family check first
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
x86-microcode-do-the-family-check-first.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 1f161f67a272cc4f29f27934dd3f74cb657eb5c4 Mon Sep 17 00:00:00 2001
From: Borislav Petkov <bp(a)suse.de>
Date: Thu, 12 Oct 2017 13:23:16 +0200
Subject: x86/microcode: Do the family check first
From: Borislav Petkov <bp(a)suse.de>
commit 1f161f67a272cc4f29f27934dd3f74cb657eb5c4 upstream with adjustments.
On CPUs like AMD's Geode, for example, we shouldn't even try to load
microcode because they do not support the modern microcode loading
interface.
However, we do the family check *after* the other checks whether the
loader has been disabled on the command line or whether we're running in
a guest.
So move the family checks first in order to exit early if we're being
loaded on an unsupported family.
Reported-and-tested-by: Sven Glodowski <glodi1(a)arcor.de>
Signed-off-by: Borislav Petkov <bp(a)suse.de>
Cc: <stable(a)vger.kernel.org> # 4.11..
Cc: Linus Torvalds <torvalds(a)linux-foundation.org>
Cc: Peter Zijlstra <peterz(a)infradead.org>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Link: http://bugzilla.suse.com/show_bug.cgi?id=1061396
Link: http://lkml.kernel.org/r/20171012112316.977-1-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo(a)kernel.org>
Signed-off-by: Rolf Neugebauer <rolf.neugebauer(a)docker.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
arch/x86/kernel/cpu/microcode/core.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -86,9 +86,6 @@ static bool __init check_loader_disabled
bool *res = &dis_ucode_ldr;
#endif
- if (!have_cpuid_p())
- return *res;
-
a = 1;
c = 0;
native_cpuid(&a, &b, &c, &d);
@@ -130,8 +127,9 @@ void __init load_ucode_bsp(void)
{
int vendor;
unsigned int family;
+ bool intel = true;
- if (check_loader_disabled_bsp())
+ if (!have_cpuid_p())
return;
vendor = x86_cpuid_vendor();
@@ -139,16 +137,27 @@ void __init load_ucode_bsp(void)
switch (vendor) {
case X86_VENDOR_INTEL:
- if (family >= 6)
- load_ucode_intel_bsp();
+ if (family < 6)
+ return;
break;
+
case X86_VENDOR_AMD:
- if (family >= 0x10)
- load_ucode_amd_bsp(family);
+ if (family < 0x10)
+ return;
+ intel = false;
break;
+
default:
- break;
+ return;
}
+
+ if (check_loader_disabled_bsp())
+ return;
+
+ if (intel)
+ load_ucode_intel_bsp();
+ else
+ load_ucode_amd_bsp(family);
}
static bool check_loader_disabled_ap(void)
Patches currently in stable-queue which might be from bp(a)suse.de are
queue-4.9/x86-cpufeatures-add-intel-feature-bits-for-speculation-control.patch
queue-4.9/x86-retpoline-simplify-vmexit_fill_rsb.patch
queue-4.9/x86-cpufeatures-clean-up-spectre-v2-related-cpuid-flags.patch
queue-4.9/x86-cpufeatures-add-cpuid_7_edx-cpuid-leaf.patch
queue-4.9/x86-microcode-amd-do-not-load-when-running-on-a-hypervisor.patch
queue-4.9/x86-nospec-fix-header-guards-names.patch
queue-4.9/x86-alternative-print-unadorned-pointers.patch
queue-4.9/x86-microcode-do-the-family-check-first.patch
queue-4.9/x86-spectre-fix-spelling-mistake-vunerable-vulnerable.patch
queue-4.9/x86-pti-mark-constant-arrays-as-__initconst.patch
queue-4.9/x86-bugs-drop-one-mitigation-from-dmesg.patch
queue-4.9/x86-pti-do-not-enable-pti-on-cpus-which-are-not-vulnerable-to-meltdown.patch
This is a note to let you know that I've just added the patch titled
x86/microcode: Do the family check first
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
x86-microcode-do-the-family-check-first.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 1f161f67a272cc4f29f27934dd3f74cb657eb5c4 Mon Sep 17 00:00:00 2001
From: Borislav Petkov <bp(a)suse.de>
Date: Thu, 12 Oct 2017 13:23:16 +0200
Subject: x86/microcode: Do the family check first
From: Borislav Petkov <bp(a)suse.de>
commit 1f161f67a272cc4f29f27934dd3f74cb657eb5c4 upstream with adjustments.
On CPUs like AMD's Geode, for example, we shouldn't even try to load
microcode because they do not support the modern microcode loading
interface.
However, we do the family check *after* the other checks whether the
loader has been disabled on the command line or whether we're running in
a guest.
So move the family checks first in order to exit early if we're being
loaded on an unsupported family.
Reported-and-tested-by: Sven Glodowski <glodi1(a)arcor.de>
Signed-off-by: Borislav Petkov <bp(a)suse.de>
Cc: <stable(a)vger.kernel.org> # 4.11..
Cc: Linus Torvalds <torvalds(a)linux-foundation.org>
Cc: Peter Zijlstra <peterz(a)infradead.org>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Link: http://bugzilla.suse.com/show_bug.cgi?id=1061396
Link: http://lkml.kernel.org/r/20171012112316.977-1-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo(a)kernel.org>
Signed-off-by: Rolf Neugebauer <rolf.neugebauer(a)docker.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
arch/x86/kernel/cpu/microcode/core.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -94,9 +94,6 @@ static bool __init check_loader_disabled
bool *res = &dis_ucode_ldr;
#endif
- if (!have_cpuid_p())
- return *res;
-
a = 1;
c = 0;
native_cpuid(&a, &b, &c, &d);
@@ -138,8 +135,9 @@ void __init load_ucode_bsp(void)
{
int vendor;
unsigned int family;
+ bool intel = true;
- if (check_loader_disabled_bsp())
+ if (!have_cpuid_p())
return;
vendor = x86_vendor();
@@ -147,16 +145,27 @@ void __init load_ucode_bsp(void)
switch (vendor) {
case X86_VENDOR_INTEL:
- if (family >= 6)
- load_ucode_intel_bsp();
+ if (family < 6)
+ return;
break;
+
case X86_VENDOR_AMD:
- if (family >= 0x10)
- load_ucode_amd_bsp(family);
+ if (family < 0x10)
+ return;
+ intel = false;
break;
+
default:
- break;
+ return;
}
+
+ if (check_loader_disabled_bsp())
+ return;
+
+ if (intel)
+ load_ucode_intel_bsp();
+ else
+ load_ucode_amd_bsp(family);
}
static bool check_loader_disabled_ap(void)
Patches currently in stable-queue which might be from bp(a)suse.de are
queue-4.4/x86-microcode-amd-do-not-load-when-running-on-a-hypervisor.patch
queue-4.4/x86-microcode-do-the-family-check-first.patch
This is a note to let you know that I've just added the patch titled
x86/microcode/AMD: Do not load when running on a hypervisor
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
x86-microcode-amd-do-not-load-when-running-on-a-hypervisor.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From a15a753539eca8ba243d576f02e7ca9c4b7d7042 Mon Sep 17 00:00:00 2001
From: Borislav Petkov <bp(a)suse.de>
Date: Sun, 18 Dec 2016 17:44:13 +0100
Subject: x86/microcode/AMD: Do not load when running on a hypervisor
From: Borislav Petkov <bp(a)suse.de>
commit a15a753539eca8ba243d576f02e7ca9c4b7d7042 upstream with minor
adjustments.
Doing so is completely void of sense for multiple reasons so prevent
it. Set dis_ucode_ldr to true and thus disable the microcode loader by
default to address xen pv guests which execute the AP path but not the
BSP path.
By having it turned off by default, the APs won't run into the loader
either.
Also, check CPUID(1).ECX[31] which hypervisors set. Well almost, not the
xen pv one. That one gets the aforementioned "fix".
Also, improve the detection method by caching the final decision whether
to continue loading in dis_ucode_ldr and do it once on the BSP. The APs
then simply test that value.
Signed-off-by: Borislav Petkov <bp(a)suse.de>
Tested-by: Juergen Gross <jgross(a)suse.com>
Tested-by: Boris Ostrovsky <boris.ostrovsky(a)oracle.com>
Acked-by: Juergen Gross <jgross(a)suse.com>
Link: http://lkml.kernel.org/r/20161218164414.9649-4-bp@alien8.de
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Signed-off-by: Rolf Neugebauer <rolf.neugebauer(a)docker.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
arch/x86/kernel/cpu/microcode/core.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -44,7 +44,7 @@
static struct microcode_ops *microcode_ops;
-static bool dis_ucode_ldr;
+static bool dis_ucode_ldr = true;
static int __init disable_loader(char *str)
{
@@ -81,6 +81,7 @@ struct cpu_info_ctx {
static bool __init check_loader_disabled_bsp(void)
{
+ u32 a, b, c, d;
#ifdef CONFIG_X86_32
const char *cmdline = (const char *)__pa_nodebug(boot_command_line);
const char *opt = "dis_ucode_ldr";
@@ -93,8 +94,23 @@ static bool __init check_loader_disabled
bool *res = &dis_ucode_ldr;
#endif
- if (cmdline_find_option_bool(cmdline, option))
- *res = true;
+ if (!have_cpuid_p())
+ return *res;
+
+ a = 1;
+ c = 0;
+ native_cpuid(&a, &b, &c, &d);
+
+ /*
+ * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not
+ * completely accurate as xen pv guests don't see that CPUID bit set but
+ * that's good enough as they don't land on the BSP path anyway.
+ */
+ if (c & BIT(31))
+ return *res;
+
+ if (cmdline_find_option_bool(cmdline, option) <= 0)
+ *res = false;
return *res;
}
@@ -126,9 +142,6 @@ void __init load_ucode_bsp(void)
if (check_loader_disabled_bsp())
return;
- if (!have_cpuid_p())
- return;
-
vendor = x86_vendor();
family = x86_family();
@@ -162,9 +175,6 @@ void load_ucode_ap(void)
if (check_loader_disabled_ap())
return;
- if (!have_cpuid_p())
- return;
-
vendor = x86_vendor();
family = x86_family();
Patches currently in stable-queue which might be from bp(a)suse.de are
queue-4.4/x86-microcode-amd-do-not-load-when-running-on-a-hypervisor.patch
queue-4.4/x86-microcode-do-the-family-check-first.patch
This is a note to let you know that I've just added the patch titled
drm: rcar-du: Use the VBK interrupt for vblank events
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
drm-rcar-du-use-the-vbk-interrupt-for-vblank-events.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From cbbb90b0c084d7dfb2ed8e3fecf8df200fbdd2a0 Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart+renesas(a)ideasonboard.com>
Date: Mon, 10 Jul 2017 23:46:39 +0300
Subject: drm: rcar-du: Use the VBK interrupt for vblank events
From: Laurent Pinchart <laurent.pinchart+renesas(a)ideasonboard.com>
commit cbbb90b0c084d7dfb2ed8e3fecf8df200fbdd2a0 upstream.
When implementing support for interlaced modes, the driver switched from
reporting vblank events on the vertical blanking (VBK) interrupt to the
frame end interrupt (FRM). This incorrectly divided the reported refresh
rate by two. Fix it by moving back to the VBK interrupt.
Fixes: 906eff7fcada ("drm: rcar-du: Implement support for interlaced modes")
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas(a)ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas(a)ideasonboard.com>
Signed-off-by: thongsyho <thong.ho.px(a)rvc.renesas.com>
Signed-off-by: Nhan Nguyen <nhan.nguyen.yb(a)renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -551,7 +551,7 @@ static irqreturn_t rcar_du_crtc_irq(int
status = rcar_du_crtc_read(rcrtc, DSSR);
rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
- if (status & DSSR_FRM) {
+ if (status & DSSR_VBK) {
drm_crtc_handle_vblank(&rcrtc->crtc);
rcar_du_crtc_finish_page_flip(rcrtc);
ret = IRQ_HANDLED;
Patches currently in stable-queue which might be from laurent.pinchart+renesas(a)ideasonboard.com are
queue-4.9/drm-rcar-du-use-the-vbk-interrupt-for-vblank-events.patch
queue-4.9/drm-rcar-du-fix-race-condition-when-disabling-planes-at-crtc-stop.patch
This is a note to let you know that I've just added the patch titled
drm: rcar-du: Fix race condition when disabling planes at CRTC stop
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
drm-rcar-du-fix-race-condition-when-disabling-planes-at-crtc-stop.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 641307df71fe77d7b38a477067495ede05d47295 Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart+renesas(a)ideasonboard.com>
Date: Sat, 29 Jul 2017 02:31:33 +0300
Subject: drm: rcar-du: Fix race condition when disabling planes at CRTC stop
From: Laurent Pinchart <laurent.pinchart+renesas(a)ideasonboard.com>
commit 641307df71fe77d7b38a477067495ede05d47295 upstream.
When stopping the CRTC the driver must disable all planes and wait for
the change to take effect at the next vblank. Merely calling
drm_crtc_wait_one_vblank() is not enough, as the function doesn't
include any mechanism to handle the race with vblank interrupts.
Replace the drm_crtc_wait_one_vblank() call with a manual mechanism that
handles the vblank interrupt race.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas(a)ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas(a)ideasonboard.com>
Signed-off-by: thongsyho <thong.ho.px(a)rvc.renesas.com>
Signed-off-by: Nhan Nguyen <nhan.nguyen.yb(a)renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 53 +++++++++++++++++++++++++++++----
drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 8 ++++
2 files changed, 55 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -392,6 +392,31 @@ static void rcar_du_crtc_start(struct rc
rcrtc->started = true;
}
+static void rcar_du_crtc_disable_planes(struct rcar_du_crtc *rcrtc)
+{
+ struct rcar_du_device *rcdu = rcrtc->group->dev;
+ struct drm_crtc *crtc = &rcrtc->crtc;
+ u32 status;
+ /* Make sure vblank interrupts are enabled. */
+ drm_crtc_vblank_get(crtc);
+ /*
+ * Disable planes and calculate how many vertical blanking interrupts we
+ * have to wait for. If a vertical blanking interrupt has been triggered
+ * but not processed yet, we don't know whether it occurred before or
+ * after the planes got disabled. We thus have to wait for two vblank
+ * interrupts in that case.
+ */
+ spin_lock_irq(&rcrtc->vblank_lock);
+ rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
+ status = rcar_du_crtc_read(rcrtc, DSSR);
+ rcrtc->vblank_count = status & DSSR_VBK ? 2 : 1;
+ spin_unlock_irq(&rcrtc->vblank_lock);
+ if (!wait_event_timeout(rcrtc->vblank_wait, rcrtc->vblank_count == 0,
+ msecs_to_jiffies(100)))
+ dev_warn(rcdu->dev, "vertical blanking timeout\n");
+ drm_crtc_vblank_put(crtc);
+}
+
static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
{
struct drm_crtc *crtc = &rcrtc->crtc;
@@ -400,17 +425,16 @@ static void rcar_du_crtc_stop(struct rca
return;
/* Disable all planes and wait for the change to take effect. This is
- * required as the DSnPR registers are updated on vblank, and no vblank
- * will occur once the CRTC is stopped. Disabling planes when starting
- * the CRTC thus wouldn't be enough as it would start scanning out
- * immediately from old frame buffers until the next vblank.
+ * required as the plane enable registers are updated on vblank, and no
+ * vblank will occur once the CRTC is stopped. Disabling planes when
+ * starting the CRTC thus wouldn't be enough as it would start scanning
+ * out immediately from old frame buffers until the next vblank.
*
* This increases the CRTC stop delay, especially when multiple CRTCs
* are stopped in one operation as we now wait for one vblank per CRTC.
* Whether this can be improved needs to be researched.
*/
- rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
- drm_crtc_wait_one_vblank(crtc);
+ rcar_du_crtc_disable_planes(rcrtc);
/* Disable vertical blanking interrupt reporting. We first need to wait
* for page flip completion before stopping the CRTC as userspace
@@ -548,10 +572,25 @@ static irqreturn_t rcar_du_crtc_irq(int
irqreturn_t ret = IRQ_NONE;
u32 status;
+ spin_lock(&rcrtc->vblank_lock);
+
status = rcar_du_crtc_read(rcrtc, DSSR);
rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
if (status & DSSR_VBK) {
+ /*
+ * Wake up the vblank wait if the counter reaches 0. This must
+ * be protected by the vblank_lock to avoid races in
+ * rcar_du_crtc_disable_planes().
+ */
+ if (rcrtc->vblank_count) {
+ if (--rcrtc->vblank_count == 0)
+ wake_up(&rcrtc->vblank_wait);
+ }
+ }
+ spin_unlock(&rcrtc->vblank_lock);
+
+ if (status & DSSR_VBK) {
drm_crtc_handle_vblank(&rcrtc->crtc);
rcar_du_crtc_finish_page_flip(rcrtc);
ret = IRQ_HANDLED;
@@ -606,6 +645,8 @@ int rcar_du_crtc_create(struct rcar_du_g
}
init_waitqueue_head(&rcrtc->flip_wait);
+ init_waitqueue_head(&rcrtc->vblank_wait);
+ spin_lock_init(&rcrtc->vblank_lock);
rcrtc->group = rgrp;
rcrtc->mmio_offset = mmio_offsets[index];
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -15,6 +15,7 @@
#define __RCAR_DU_CRTC_H__
#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/wait.h>
#include <drm/drmP.h>
@@ -33,6 +34,9 @@ struct rcar_du_vsp;
* @started: whether the CRTC has been started and is running
* @event: event to post when the pending page flip completes
* @flip_wait: wait queue used to signal page flip completion
+ * @vblank_lock: protects vblank_wait and vblank_count
+ * @vblank_wait: wait queue used to signal vertical blanking
+ * @vblank_count: number of vertical blanking interrupts to wait for
* @outputs: bitmask of the outputs (enum rcar_du_output) driven by this CRTC
* @group: CRTC group this CRTC belongs to
*/
@@ -48,6 +52,10 @@ struct rcar_du_crtc {
struct drm_pending_vblank_event *event;
wait_queue_head_t flip_wait;
+ spinlock_t vblank_lock;
+ wait_queue_head_t vblank_wait;
+ unsigned int vblank_count;
+
unsigned int outputs;
struct rcar_du_group *group;
Patches currently in stable-queue which might be from laurent.pinchart+renesas(a)ideasonboard.com are
queue-4.9/drm-rcar-du-use-the-vbk-interrupt-for-vblank-events.patch
queue-4.9/drm-rcar-du-fix-race-condition-when-disabling-planes-at-crtc-stop.patch
This is a note to let you know that I've just added the patch titled
crypto: tcrypt - fix S/G table for test_aead_speed()
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
crypto-tcrypt-fix-s-g-table-for-test_aead_speed.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 5c6ac1d4f8fbdbed65dbeb8cf149d736409d16a1 Mon Sep 17 00:00:00 2001
From: Robert Baronescu <robert.baronescu(a)nxp.com>
Date: Tue, 10 Oct 2017 13:21:59 +0300
Subject: crypto: tcrypt - fix S/G table for test_aead_speed()
From: Robert Baronescu <robert.baronescu(a)nxp.com>
commit 5c6ac1d4f8fbdbed65dbeb8cf149d736409d16a1 upstream.
In case buffer length is a multiple of PAGE_SIZE,
the S/G table is incorrectly generated.
Fix this by handling buflen = k * PAGE_SIZE separately.
Signed-off-by: Robert Baronescu <robert.baronescu(a)nxp.com>
Signed-off-by: Herbert Xu <herbert(a)gondor.apana.org.au>
Signed-off-by: Horia Geantă <horia.geanta(a)nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
crypto/tcrypt.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -223,11 +223,13 @@ static void sg_init_aead(struct scatterl
}
sg_init_table(sg, np + 1);
- np--;
+ if (rem)
+ np--;
for (k = 0; k < np; k++)
sg_set_buf(&sg[k + 1], xbuf[k], PAGE_SIZE);
- sg_set_buf(&sg[k + 1], xbuf[k], rem);
+ if (rem)
+ sg_set_buf(&sg[k + 1], xbuf[k], rem);
}
static void test_aead_speed(const char *algo, int enc, unsigned int secs,
Patches currently in stable-queue which might be from robert.baronescu(a)nxp.com are
queue-4.9/crypto-tcrypt-fix-s-g-table-for-test_aead_speed.patch
This is a note to let you know that I've just added the patch titled
ASoC: rsnd: don't call free_irq() on Parent SSI
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
asoc-rsnd-don-t-call-free_irq-on-parent-ssi.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 1f8754d4daea5f257370a52a30fcb22798c54516 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx(a)renesas.com>
Date: Tue, 16 May 2017 01:48:24 +0000
Subject: ASoC: rsnd: don't call free_irq() on Parent SSI
From: Kuninori Morimoto <kuninori.morimoto.gx(a)renesas.com>
commit 1f8754d4daea5f257370a52a30fcb22798c54516 upstream.
If SSI uses shared pin, some SSI will be used as parent SSI.
Then, normal SSI's remove and Parent SSI's remove
(these are same SSI) will be called when unbind or remove timing.
In this case, free_irq() will be called twice.
This patch solve this issue.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx(a)renesas.com>
Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx(a)renesas.com>
Reported-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx(a)renesas.com>
Signed-off-by: Mark Brown <broonie(a)kernel.org>
Signed-off-by: thongsyho <thong.ho.px(a)rvc.renesas.com>
Signed-off-by: Nhan Nguyen <nhan.nguyen.yb(a)renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/soc/sh/rcar/ssi.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -699,9 +699,14 @@ static int rsnd_ssi_dma_remove(struct rs
struct rsnd_priv *priv)
{
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
+ struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
struct device *dev = rsnd_priv_to_dev(priv);
int irq = ssi->irq;
+ /* Do nothing for SSI parent mod */
+ if (ssi_parent_mod == mod)
+ return 0;
+
/* PIO will request IRQ again */
devm_free_irq(dev, irq, mod);
Patches currently in stable-queue which might be from kuninori.morimoto.gx(a)renesas.com are
queue-4.9/asoc-rsnd-don-t-call-free_irq-on-parent-ssi.patch
queue-4.9/asoc-rsnd-avoid-duplicate-free_irq.patch