This issue was found in 4.14 and is present in earlier kernels.
Please backport
f5bbbbe4d635 blk-mq: sync the update nr_hw_queues with
blk_mq_queue_tag_busy_iter
530ca2c9bd69 blk-mq: Allow blocking queue tag iter callbacks
onto the stable branches that don't have these. The second is a fix
for the first. Thank you.
4.19.y and later - commits already present
4.14.y - f5bbbbe4d635 doesn't patch cleanly but it's still
straightforward, just drop the comment and code mentioning switching
to 'none' in the trailing context
4.9.y - ditto
4.4.y - there was a refactoring of the code in commit
0bf6cd5b9531bcc29c0a5e504b6ce2984c6fd8d8 making this non-trivial
3.16.y - ditto
I am happy to try to produce clean patches, but it may be a day or so.
Regards,
Giuliano.
Root Complex Integrated devices (RCiEP) do not have a Root Port before the
device. pci_configure_mps() should simply stick the max value for MaxPayload
size in Device Control, and for MaxReadReq. Unless pcie=pcie_bus-peer2peer
is used in kernel commandline PCIE_BUS_PEER2PEER.
When MPS is configured lower, it could result in reduced performance.
Fixes: 9dae3a97297f ("PCI: Move MPS configuration check to pci_configure_device()")
Signed-off-by: Ashok Raj <ashok.raj(a)intel.com>
Tested-by: Dave Jiang <dave.jiang(a)intel.com>
To: Bjorn Helgaas <bhelgaas(a)google.com>
To: linux-pci(a)vger.kernel.org
Cc: linux-kernel(a)vger.kernel.org
Cc: stable(a)vger.kernel.org
Cc: Ashok Raj <ashok.raj(a)intel.com>
---
drivers/pci/probe.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index eeff8a07..a738b1c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1895,13 +1895,34 @@ static void pci_configure_mps(struct pci_dev *dev)
struct pci_dev *bridge = pci_upstream_bridge(dev);
int mps, mpss, p_mps, rc;
- if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge))
+ if (!pci_is_pcie(dev))
return;
/* MPS and MRRS fields are of type 'RsvdP' for VFs, short-circuit out */
if (dev->is_virtfn)
return;
+ /*
+ * If this is a Root Complex Integrated Endpoint
+ * Simply program the max value from DEVCAP. No additional
+ * Lookup is necessary
+ */
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) {
+ if (pcie_bus_config == PCIE_BUS_PEER2PEER)
+ mps = 128;
+ else
+ mps = 128 << dev->pcie_mpss;
+ rc = pcie_set_mps(dev, mps);
+ if (rc) {
+ pci_warn(dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+ mps);
+ return;
+ }
+ }
+
+ if (!bridge || !pci_is_pcie(bridge))
+ return;
+
mps = pcie_get_mps(dev);
p_mps = pcie_get_mps(bridge);
--
2.7.4
When doing an atomic modeset with ALLOW_MODESET drivers are allowed to
pull in arbitrary other resources, including CRTCs (e.g. when
reconfiguring global resources).
But in nonblocking mode userspace has then no idea this happened,
which can lead to spurious EBUSY calls, both:
- when that other CRTC is currently busy doing a page_flip the
ALLOW_MODESET commit can fail with an EBUSY
- on the other CRTC a normal atomic flip can fail with EBUSY because
of the additional commit inserted by the kernel without userspace's
knowledge
For blocking commits this isn't a problem, because everyone else will
just block until all the CRTC are reconfigured. Only thing userspace
can notice is the dropped frames without any reason for why frames got
dropped.
Consensus is that we need new uapi to handle this properly, but no one
has any idea what exactly the new uapi should look like. As a stop-gap
plug this problem by demoting nonblocking commits which might cause
issues by including CRTCs not in the original request to blocking
commits.
v2: Add comments and a WARN_ON to enforce this only when allowed - we
don't want to silently convert page flips into blocking plane updates
just because the driver is buggy.
v3: Fix inverted WARN_ON (Pekka).
References: https://lists.freedesktop.org/archives/dri-devel/2018-July/182281.html
Bugzilla: https://gitlab.freedesktop.org/wayland/weston/issues/24#note_9568
Cc: Daniel Stone <daniel(a)fooishbar.org>
Cc: Pekka Paalanen <pekka.paalanen(a)collabora.co.uk>
Cc: stable(a)vger.kernel.org
Reviewed-by: Daniel Stone <daniels(a)collabora.com>
Cc: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter(a)intel.com>
--
Resending because last attempt failed CI and meanwhile the results are
lost :-/
-Daniel
---
drivers/gpu/drm/drm_atomic.c | 34 +++++++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 965173fd0ac2..4f140ff6fb98 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1362,15 +1362,43 @@ EXPORT_SYMBOL(drm_atomic_commit);
int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
{
struct drm_mode_config *config = &state->dev->mode_config;
- int ret;
+ unsigned requested_crtc = 0;
+ unsigned affected_crtc = 0;
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *crtc_state;
+ bool nonblocking = true;
+ int ret, i;
+
+ /*
+ * For commits that allow modesets drivers can add other CRTCs to the
+ * atomic commit, e.g. when they need to reallocate global resources.
+ *
+ * But when userspace also requests a nonblocking commit then userspace
+ * cannot know that the commit affects other CRTCs, which can result in
+ * spurious EBUSY failures. Until we have better uapi plug this by
+ * demoting such commits to blocking mode.
+ */
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i)
+ requested_crtc |= drm_crtc_mask(crtc);
ret = drm_atomic_check_only(state);
if (ret)
return ret;
- DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i)
+ affected_crtc |= drm_crtc_mask(crtc);
+
+ if (affected_crtc != requested_crtc) {
+ /* adding other CRTC is only allowed for modeset commits */
+ WARN_ON(!state->allow_modeset);
+
+ DRM_DEBUG_ATOMIC("demoting %p to blocking mode to avoid EBUSY\n", state);
+ nonblocking = false;
+ } else {
+ DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
+ }
- return config->funcs->atomic_commit(state->dev, state, true);
+ return config->funcs->atomic_commit(state->dev, state, nonblocking);
}
EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
--
2.25.1
A recent review of the Sony Xperia Development kernel tree [0] resulted
in the discovery of various patches which have been backported from
Mainline in order to fix an array of issues. These patches should be
applied to Stable such that everyone can benefit from them.
Note: The review is still on-going (~50%) - more to follow.
[0] https://github.com/sonyxperiadev/kernel
Alexey Brodkin (1):
devres: Align data[] to ARCH_KMALLOC_MINALIGN
Arun KS (1):
arm64: Fix size of __early_cpu_boot_status
Austin Kim (1):
mm/vmalloc.c: move 'area->pages' after if statement
Chris Lew (1):
soc: qcom: smem: Use le32_to_cpu for comparison
Dedy Lansky (2):
wil6210: fix temperature debugfs
wil6210: rate limit wil_rx_refill error
Geert Uytterhoeven (1):
clk: Fix debugfs_create_*() usage
Hamad Kadmany (1):
wil6210: increase firmware ready timeout
Hans Verkuil (1):
drm_dp_mst_topology: fix broken
drm_dp_sideband_parse_remote_dpcd_read()
Joe Moriarty (1):
drm: NULL pointer dereference [null-pointer-deref] (CWE 476) problem
Lior David (1):
wil6210: fix length check in __wmi_send
Mohit Aggarwal (1):
rtc: pm8xxx: Fix issue in RTC write path
Rob Clark (1):
drm/msm: stop abusing dma_map/unmap for cache
Rob Herring (1):
of: fix missing kobject init for !SYSFS && OF_DYNAMIC config
Roger Quadros (1):
usb: dwc3: don't set gadget->is_otg flag
Subhash Jadavani (2):
scsi: ufs: Fix error handing during hibern8 enter
scsi: ufs: ufs-qcom: remove broken hci version quirk
Taniya Das (1):
clk: qcom: rcg: Return failure for RCG update
Timur Tabi (1):
Revert "gpio: set up initial state from .get_direction()"
Venkat Gopalakrishnan (1):
scsi: ufs: make sure all interrupts are processed
Will Deacon (1):
arm64: traps: Don't print stack or raw PC/LR values in backtraces
arch/arm64/kernel/head.S | 2 +-
arch/arm64/kernel/process.c | 8 +--
arch/arm64/kernel/traps.c | 74 +-------------------
drivers/base/devres.c | 10 ++-
drivers/clk/clk.c | 30 ++++----
drivers/clk/qcom/clk-rcg2.c | 2 +-
drivers/gpio/gpiolib.c | 31 ++------
drivers/gpu/drm/drm_dp_mst_topology.c | 9 ++-
drivers/gpu/drm/msm/msm_gem.c | 4 +-
drivers/net/wireless/ath/wil6210/debugfs.c | 7 +-
drivers/net/wireless/ath/wil6210/interrupt.c | 22 +++++-
drivers/net/wireless/ath/wil6210/main.c | 2 +-
drivers/net/wireless/ath/wil6210/txrx.c | 4 +-
drivers/net/wireless/ath/wil6210/wmi.c | 2 +-
drivers/of/base.c | 3 -
drivers/rtc/rtc-pm8xxx.c | 49 ++++++++++---
drivers/scsi/ufs/ufs-qcom.c | 2 +-
drivers/scsi/ufs/ufshcd.c | 46 ++++++++----
drivers/soc/qcom/smem.c | 2 +-
drivers/usb/dwc3/gadget.c | 1 -
mm/vmalloc.c | 8 ++-
21 files changed, 152 insertions(+), 166 deletions(-)
--
2.25.1
When driver is set to enable bb credit recovery, the switch displayed
the setting as inactive. If the link bounces, it switches to Active.
During link up processing, the driver currently does a MBX_READ_SPARAM
followed by a MBX_CONFIG_LINK. These mbox commands are queued to be
executed, one at a time and the completion is processed by the worker
thread. Since the MBX_READ_SPARAM is done BEFORE the MBX_CONFIG_LINK,
the BB_SC_N bit is never set the the returned values. BB Credit recovery
status only gets set after the driver requests the feature in
CONFIG_LINK, which is done after the link up. Thus the ordering of
READ_SPARAM needs to follow the CONFIG_LINK.
Fix by reordering so that READ_SPARAM is done after CONFIG_LINK.
Added a HBA_DEFER_FLOGI flag so that any FLOGI handling waits until
after the READ_SPARAM is done so that the proper BB credit value is
set in the FLOGI payload.
Fixes: 6bfb16208298 ("scsi: lpfc: Fix configuration of BB credit recovery in service parameters")
Cc: <stable(a)vger.kernel.org> # v5.4+
Signed-off-by: Dick Kennedy <dick.kennedy(a)broadcom.com>
Signed-off-by: James Smart <jsmart2021(a)gmail.com>
---
drivers/scsi/lpfc/lpfc.h | 1 +
drivers/scsi/lpfc/lpfc_hbadisc.c | 59 ++++++++++++++++++++++++++--------------
2 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 04d73e2be373..3f2cb17c4574 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -749,6 +749,7 @@ struct lpfc_hba {
* capability
*/
#define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */
+#define HBA_DEFER_FLOGI 0x800000 /* Defer FLOGI till read_sparm cmpl */
uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
struct lpfc_dmabuf slim2p;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index dcc8999c6a68..6a2bdae0e52a 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1163,13 +1163,16 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
}
/* Start discovery by sending a FLOGI. port_state is identically
- * LPFC_FLOGI while waiting for FLOGI cmpl
+ * LPFC_FLOGI while waiting for FLOGI cmpl. Check if sending
+ * the FLOGI is being deferred till after MBX_READ_SPARAM completes.
*/
- if (vport->port_state != LPFC_FLOGI)
- lpfc_initial_flogi(vport);
- else if (vport->fc_flag & FC_PT2PT)
- lpfc_disc_start(vport);
-
+ if (vport->port_state != LPFC_FLOGI) {
+ if (!(phba->hba_flag & HBA_DEFER_FLOGI))
+ lpfc_initial_flogi(vport);
+ } else {
+ if (vport->fc_flag & FC_PT2PT)
+ lpfc_disc_start(vport);
+ }
return;
out:
@@ -3094,6 +3097,14 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
mempool_free(pmb, phba->mbox_mem_pool);
+
+ /* Check if sending the FLOGI is being deferred to after we get
+ * up to date CSPs from MBX_READ_SPARAM.
+ */
+ if (phba->hba_flag & HBA_DEFER_FLOGI) {
+ lpfc_initial_flogi(vport);
+ phba->hba_flag &= ~HBA_DEFER_FLOGI;
+ }
return;
out:
@@ -3224,6 +3235,23 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
}
lpfc_linkup(phba);
+ sparam_mbox = NULL;
+
+ if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+ cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!cfglink_mbox)
+ goto out;
+ vport->port_state = LPFC_LOCAL_CFG_LINK;
+ lpfc_config_link(phba, cfglink_mbox);
+ cfglink_mbox->vport = vport;
+ cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
+ rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED) {
+ mempool_free(cfglink_mbox, phba->mbox_mem_pool);
+ goto out;
+ }
+ }
+
sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!sparam_mbox)
goto out;
@@ -3244,20 +3272,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
goto out;
}
- if (!(phba->hba_flag & HBA_FCOE_MODE)) {
- cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!cfglink_mbox)
- goto out;
- vport->port_state = LPFC_LOCAL_CFG_LINK;
- lpfc_config_link(phba, cfglink_mbox);
- cfglink_mbox->vport = vport;
- cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
- rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT);
- if (rc == MBX_NOT_FINISHED) {
- mempool_free(cfglink_mbox, phba->mbox_mem_pool);
- goto out;
- }
- } else {
+ if (phba->hba_flag & HBA_FCOE_MODE) {
vport->port_state = LPFC_VPORT_UNKNOWN;
/*
* Add the driver's default FCF record at FCF index 0 now. This
@@ -3314,6 +3329,10 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
}
/* Reset FCF roundrobin bmask for new discovery */
lpfc_sli4_clear_fcf_rr_bmask(phba);
+ } else {
+ if (phba->bbcredit_support && phba->cfg_enable_bbcr &&
+ !(phba->link_flag & LS_LOOPBACK_MODE))
+ phba->hba_flag |= HBA_DEFER_FLOGI;
}
/* Prepare for LINK up registrations */
--
2.13.7
This series is to backport the upstream patches that fixes busy detection
for long operation mmc commands by implementing Tegra specific timeout
callback to switch between finite and infinite HW busy detection wait
modes.
Sowjanya Komatineni (2):
sdhci: tegra: Implement Tegra specific set_timeout callback
sdhci: tegra: Enable MMC_CAP_WAIT_WHILE_BUSY host capability
drivers/mmc/host/sdhci-tegra.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
--
2.7.4
Changes since v1:
- Rename memcpy_mcsafe() to copy_safe() since the x86-machine-check
specifics have already been de-emphasized in a previous commit and are
further de-emphasized by these changes. (Linus)
- Move copy_safe() out-of-line since it no longer reverts to plain
memcpy (Linus)
- Move copy_safe() to its own stand-alone compilation unit where it no
longer entangles with arch/x86/lib/memcpy_64.S. This also allows perf
to stop tracking ongoing updates to that file due to copy_safe()
updates. (Linus)
- Move the PowerPC implementation over to the new name.
[1]: http://lore.kernel.org/r/158654083112.1572482.8944305411228188871.stgit@dwi…
---
The primary motivation to go touch memcpy_mcsafe() is that the existing
benefit of doing slow and careful copies is obviated on newer CPUs. That
fact solves the problem of needing to detect machine-check recovery
capability. Now the old "mcsafe_key" opt-in to careful copying can be made
an opt-out from the default fast copy implementation.
The discussion with Linus further made clear that this facility had
already lost its x86-machine-check specificity starting with commit
2c89130a56a ("x86/asm/memcpy_mcsafe: Add write-protection-fault
handling"). The new changes to not require a "careful copy" further
de-emphasizes the role that x86-MCA plays in the implementation to just
one more source of recoverable trap during the operation.
With the above realizations the name "mcsafe" is no longer accurate and
copy_safe() is proposed as its replacement. x86 grows a copy_safe_fast()
implementation as a default implementation that is independent of
detecting the presence of x86-MCA.
---
Dan Williams (2):
copy_safe: Rename memcpy_mcsafe() to copy_safe()
x86/copy_safe: Introduce copy_safe_fast()
arch/powerpc/Kconfig | 2
arch/powerpc/include/asm/string.h | 2
arch/powerpc/include/asm/uaccess.h | 4
arch/powerpc/lib/Makefile | 2
arch/powerpc/lib/copy_safe.S | 4
arch/x86/Kconfig | 2
arch/x86/Kconfig.debug | 2
arch/x86/include/asm/copy_safe.h | 18 ++
arch/x86/include/asm/copy_safe_test.h | 75 +++++++++
arch/x86/include/asm/mcsafe_test.h | 75 ---------
arch/x86/include/asm/string_64.h | 32 ----
arch/x86/include/asm/uaccess_64.h | 21 ---
arch/x86/kernel/cpu/mce/core.c | 9 -
arch/x86/kernel/quirks.c | 10 -
arch/x86/lib/Makefile | 1
arch/x86/lib/copy_safe.c | 66 ++++++++
arch/x86/lib/copy_safe_64.S | 163 ++++++++++++++++++++
arch/x86/lib/memcpy_64.S | 115 --------------
arch/x86/lib/usercopy_64.c | 21 ---
drivers/md/dm-writecache.c | 12 +
drivers/nvdimm/claim.c | 2
drivers/nvdimm/pmem.c | 6 -
include/linux/string.h | 17 +-
include/linux/uio.h | 10 +
lib/Kconfig | 2
lib/iov_iter.c | 36 ++--
tools/arch/x86/include/asm/copy_safe_test.h | 13 ++
tools/arch/x86/include/asm/mcsafe_test.h | 13 --
tools/arch/x86/lib/memcpy_64.S | 115 --------------
tools/objtool/check.c | 5 -
tools/perf/bench/Build | 1
tools/perf/bench/mem-memcpy-x86-64-lib.c | 24 ---
tools/testing/nvdimm/test/nfit.c | 49 +++---
.../testing/selftests/powerpc/copyloops/.gitignore | 2
tools/testing/selftests/powerpc/copyloops/Makefile | 6 -
.../selftests/powerpc/copyloops/copy_safe.S | 0
36 files changed, 429 insertions(+), 508 deletions(-)
rename arch/powerpc/lib/{memcpy_mcsafe_64.S => copy_safe.S} (98%)
create mode 100644 arch/x86/include/asm/copy_safe.h
create mode 100644 arch/x86/include/asm/copy_safe_test.h
delete mode 100644 arch/x86/include/asm/mcsafe_test.h
create mode 100644 arch/x86/lib/copy_safe.c
create mode 100644 arch/x86/lib/copy_safe_64.S
create mode 100644 tools/arch/x86/include/asm/copy_safe_test.h
delete mode 100644 tools/arch/x86/include/asm/mcsafe_test.h
delete mode 100644 tools/perf/bench/mem-memcpy-x86-64-lib.c
rename tools/testing/selftests/powerpc/copyloops/{memcpy_mcsafe_64.S => copy_safe.S} (100%)
base-commit: b8dcd632c06b8706d22934f9bf9bf16a42b1ecc7
From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Revert back to comparing fb->format->format instead fb->format for the
page flip ioctl. This check was originally only here to disallow pixel
format changes, but when we changed it to do the pointer comparison
we potentially started to reject some (but definitely not all) modifier
changes as well. In fact the current behaviour depends on whether the
driver overrides the format info for a specific format+modifier combo.
Eg. on i915 this now rejects compression vs. no compression changes but
does not reject any other tiling changes. That's just inconsistent
nonsense.
The main reason we have to go back to the old behaviour is to fix page
flipping with Xorg. At some point Xorg got its atomic rights taken away
and since then we can't page flip between compressed and non-compressed
fbs on i915. Currently we get no page flipping for any games pretty much
since Mesa likes to use compressed buffers. Not sure how compositors are
working around this (don't use one myself). I guess they must be doing
something to get non-compressed buffers instead. Either that or
somehow no one noticed the tearing from the blit fallback.
Looking back at the original discussion on this change we pretty much
just did it in the name of skipping a few extra pointer dereferences.
However, I've decided not to revert the whole thing in case someone
has since started to depend on these changes. None of the other checks
are relevant for i915 anyways.
Cc: stable(a)vger.kernel.org
Cc: Laurent Pinchart <laurent.pinchart(a)ideasonboard.com>
Fixes: dbd4d5761e1f ("drm: Replace 'format->format' comparisons to just 'format' comparisons")
Signed-off-by: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
---
drivers/gpu/drm/drm_plane.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index d6ad60ab0d38..f2ca5315f23b 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -1153,7 +1153,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if (ret)
goto out;
- if (old_fb->format != fb->format) {
+ if (old_fb->format->format != fb->format->format) {
DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
ret = -EINVAL;
goto out;
--
2.24.1
During ONFI detection, the CRC derived from the parameter page and the
CRC supposed to be at the end of the parameter page are compared. If
they do not match, the second then the third copies of the page are
tried.
The current implementation compares the newly derived CRC with the CRC
contained in the first page only. So if this particular CRC area has
been corrupted, then the detection will fail for a wrong reason.
Fix this issue by checking the derived CRC against the right one.
Fixes: 39138c1f4a31 ("mtd: rawnand: use bit-wise majority to recover the ONFI param page")
Cc: stable(a)vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal(a)bootlin.com>
Reviewed-by: Boris Brezillon <boris.brezillon(a)collabora.com>
---
drivers/mtd/nand/raw/nand_onfi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
index 0b879bd0a68c..8fe8d7bdd203 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -173,7 +173,7 @@ int nand_onfi_detect(struct nand_chip *chip)
}
if (onfi_crc16(ONFI_CRC_BASE, (u8 *)&p[i], 254) ==
- le16_to_cpu(p->crc)) {
+ le16_to_cpu(p[i].crc)) {
if (i)
memcpy(p, &p[i], sizeof(*p));
break;
--
2.20.1
boot_aggregate is the first entry of IMA measurement list. Its purpose is
to link pre-boot measurements to IMA measurements. As IMA was designed to
work with a TPM 1.2, the SHA1 PCR bank was always selected even if a
TPM 2.0 with support for stronger hash algorithms is available.
This patch first tries to find a PCR bank with the IMA default hash
algorithm. If it does not find it, it selects the SHA256 PCR bank for
TPM 2.0 and SHA1 for TPM 1.2. Ultimately, it selects SHA1 also for TPM 2.0
if the SHA256 PCR bank is not found.
If none of the PCR banks above can be found, boot_aggregate file digest is
filled with zeros, as for TPM bypass, making it impossible to perform a
remote attestation of the system.
Changelog
v3:
- Remove option to select the first PCR bank and select SHA1 as fallback
choice also for TPM 2.0 (suggested by Mimi)
v1:
- add Mimi's comments
- if there is no PCR bank for the IMA default hash algorithm use SHA256
(suggested by James Bottomley)
Cc: stable(a)vger.kernel.org # 5.1.x
Fixes: 879b589210a9 ("tpm: retrieve digest size of unknown algorithms with PCR read")
Reported-by: Jerry Snitselaar <jsnitsel(a)redhat.com>
Suggested-by: James Bottomley <James.Bottomley(a)HansenPartnership.com>
Signed-off-by: Roberto Sassu <roberto.sassu(a)huawei.com>
---
security/integrity/ima/ima_crypto.c | 47 +++++++++++++++++++++++++----
security/integrity/ima/ima_init.c | 22 +++++++++++---
2 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 423c84f95a14..8e445a671225 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -655,18 +655,29 @@ static void __init ima_pcrread(u32 idx, struct tpm_digest *d)
}
/*
- * Calculate the boot aggregate hash
+ * The boot_aggregate is a cumulative hash over TPM registers 0 - 7. With
+ * TPM 1.2 the boot_aggregate was based on reading the SHA1 PCRs, but with
+ * TPM 2.0 hash agility, TPM chips could support multiple TPM PCR banks,
+ * allowing firmware to configure and enable different banks.
+ *
+ * Knowing which TPM bank is read to calculate the boot_aggregate digest
+ * needs to be conveyed to a verifier. For this reason, use the same
+ * hash algorithm for reading the TPM PCRs as for calculating the boot
+ * aggregate digest as stored in the measurement list.
*/
-static int __init ima_calc_boot_aggregate_tfm(char *digest,
+static int __init ima_calc_boot_aggregate_tfm(char *digest, u16 alg_id,
struct crypto_shash *tfm)
{
- struct tpm_digest d = { .alg_id = TPM_ALG_SHA1, .digest = {0} };
+ struct tpm_digest d = { .alg_id = alg_id, .digest = {0} };
int rc;
u32 i;
SHASH_DESC_ON_STACK(shash, tfm);
shash->tfm = tfm;
+ pr_devel("calculating the boot-aggregate based on TPM bank: %04x\n",
+ d.alg_id);
+
rc = crypto_shash_init(shash);
if (rc != 0)
return rc;
@@ -675,7 +686,8 @@ static int __init ima_calc_boot_aggregate_tfm(char *digest,
for (i = TPM_PCR0; i < TPM_PCR8; i++) {
ima_pcrread(i, &d);
/* now accumulate with current aggregate */
- rc = crypto_shash_update(shash, d.digest, TPM_DIGEST_SIZE);
+ rc = crypto_shash_update(shash, d.digest,
+ crypto_shash_digestsize(tfm));
}
if (!rc)
crypto_shash_final(shash, digest);
@@ -685,14 +697,37 @@ static int __init ima_calc_boot_aggregate_tfm(char *digest,
int __init ima_calc_boot_aggregate(struct ima_digest_data *hash)
{
struct crypto_shash *tfm;
- int rc;
+ u16 crypto_id, alg_id;
+ int rc, i, bank_idx = -1;
+
+ for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) {
+ crypto_id = ima_tpm_chip->allocated_banks[i].crypto_id;
+ if (crypto_id == hash->algo) {
+ bank_idx = i;
+ break;
+ }
+
+ if (crypto_id == HASH_ALGO_SHA256)
+ bank_idx = i;
+
+ if (bank_idx == -1 && crypto_id == HASH_ALGO_SHA1)
+ bank_idx = i;
+ }
+
+ if (bank_idx == -1) {
+ pr_err("No suitable TPM algorithm for boot aggregate\n");
+ return 0;
+ }
+
+ hash->algo = ima_tpm_chip->allocated_banks[bank_idx].crypto_id;
tfm = ima_alloc_tfm(hash->algo);
if (IS_ERR(tfm))
return PTR_ERR(tfm);
hash->length = crypto_shash_digestsize(tfm);
- rc = ima_calc_boot_aggregate_tfm(hash->digest, tfm);
+ alg_id = ima_tpm_chip->allocated_banks[bank_idx].alg_id;
+ rc = ima_calc_boot_aggregate_tfm(hash->digest, alg_id, tfm);
ima_free_tfm(tfm);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 567468188a61..fc1e1002b48d 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -25,7 +25,7 @@ struct tpm_chip *ima_tpm_chip;
/* Add the boot aggregate to the IMA measurement list and extend
* the PCR register.
*
- * Calculate the boot aggregate, a SHA1 over tpm registers 0-7,
+ * Calculate the boot aggregate, a hash over tpm registers 0-7,
* assuming a TPM chip exists, and zeroes if the TPM chip does not
* exist. Add the boot aggregate measurement to the measurement
* list and extend the PCR register.
@@ -49,15 +49,27 @@ static int __init ima_add_boot_aggregate(void)
int violation = 0;
struct {
struct ima_digest_data hdr;
- char digest[TPM_DIGEST_SIZE];
+ char digest[TPM_MAX_DIGEST_SIZE];
} hash;
memset(iint, 0, sizeof(*iint));
memset(&hash, 0, sizeof(hash));
iint->ima_hash = &hash.hdr;
- iint->ima_hash->algo = HASH_ALGO_SHA1;
- iint->ima_hash->length = SHA1_DIGEST_SIZE;
-
+ iint->ima_hash->algo = ima_hash_algo;
+ iint->ima_hash->length = hash_digest_size[ima_hash_algo];
+
+ /*
+ * With TPM 2.0 hash agility, TPM chips could support multiple TPM
+ * PCR banks, allowing firmware to configure and enable different
+ * banks. The SHA1 bank is not necessarily enabled.
+ *
+ * Use the same hash algorithm for reading the TPM PCRs as for
+ * calculating the boot aggregate digest. Preference is given to
+ * the configured IMA default hash algorithm. Otherwise, use the
+ * TCG required banks - SHA256 for TPM 2.0, SHA1 for TPM 1.2.
+ * Ultimately select SHA1 also for TPM 2.0 if the SHA256 PCR bank
+ * is not found.
+ */
if (ima_tpm_chip) {
result = ima_calc_boot_aggregate(&hash.hdr);
if (result < 0) {
--
2.17.1