From 6f915cf27d24a96c882a17b161517a5200ac62a1 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 8 Nov 2019 04:44:49 +0000 Subject: [PATCH] ANDROID: scsi: ufs-hisi: Enable BROKEN_CRYPTO quirk flag HiKey960 doesn't play well with the inline crypto logic, and seems to deviate from the UFS standard. Eric Biggers noted: "It declares that it has 32 crypto configurations (a.k.a. keyslots), starting at offset 1280 from the start of the UFS registers. Per the UFS standard, each crypto configuration is 128 bytes, so that means they go until offset 5376. However, the device tree node for the UFS host controller (in hi3660.dtsi) only declares 4096 bytes for the UFS standard registers, and then the next 4096 physical bytes are declared to be vendor-specific UFS registers. The ufs-hisi driver already uses these vendor-specific registers to do things like reset the UFS controller and configure the clocks. But if we follow the UFS standard, the very same memory addresses have a different meaning. Also, even if I hardcode the number of keyslots to 22 so they fit in the first 4096 bytes, then there is either an SError interrupt while programming keyslot 0, or CRYPTO_GENERAL_ERROR is reported from the UFS request." So until we can understand the hardware better disable inline crypto using the quirks flag in the driver. Bug: 137270441 Change-Id: I69b1c10018bae9ac8ed2a32b02d253afbff64c34 Signed-off-by: John Stultz Signed-off-by: Satya Tangirala --- drivers/scsi/ufs/ufs-hisi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c index c2cee73a8560..71655be7bda2 100644 --- a/drivers/scsi/ufs/ufs-hisi.c +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -540,6 +540,14 @@ static int ufs_hisi_init_common(struct ufs_hba *hba) if (!host) return -ENOMEM; + /* + * Inline crypto is currently broken with ufs-hisi because the keyslots + * overlap with the vendor-specific SYS CTRL registers -- and even if + * software uses only non-overlapping keyslots, the kernel crashes when + * programming a key or a UFS error occurs on the first encrypted I/O. + */ + hba->quirks |= UFSHCD_QUIRK_BROKEN_CRYPTO; + host->hba = hba; ufshcd_set_variant(hba, host);