From patchwork Sat Jan 27 23:14:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gaurav Kashyap (QUIC)" X-Patchwork-Id: 13534288 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6AA7120330; Sat, 27 Jan 2024 23:26:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706398013; cv=none; b=ZQjGLebQvzTwMqQNM8rfvl0WAMFW3X7jJDPp7/Mib8UGsuDGvMaWfW0WemTbVjGtrUGONajDorr4/gip/G6wzKmE8FVdrwsEge4TkjXCrORVLbNFcHYSrY/6FzQA9SdzPKnYI+t2SiPxs34eT538gPsZG2lFu+Tu0CtQEvVukn0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706398013; c=relaxed/simple; bh=TdflGAFlnKkP908ZgClwGfXG3SEGQ1slqme3fBG1gLY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ICe7btPRzTBc3NMN+YrpPpvEPBWwr/SodcdQQadbezqoCjRl3DQiwSSk8qu0eqnJ3AJ3MInyRmaZeMebnOMKKOv3t2UiIOPnakau8gem8K3at4F52uu8vksK8RpeKs+cGEwMcBANmurle3I9AeSojxTzWuX3Yb4Teq346uP43fg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=T3j4i7+c; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="T3j4i7+c" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40RNQN6T003781; Sat, 27 Jan 2024 23:26:23 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= qcppdkim1; bh=wBaK0o1GnMNc+odUjrhenzXzmX4XzAfSWMyOi7YuBWc=; b=T3 j4i7+c6GvqorJzodCjArKs2g/g57ANXx79sCb3ATeSbRAC1BmxX9sBHAjH2knFzh 10k9QITyaa4Ca11UyuHPUN7WhfkoF8ATGrn0jH++vvxTF/N878mUbxfK23RWf2DL udCQj0kEGUh7uxuZXrh9891+44BCztbvZpz9/yFJ30YtOZdPd3SsbdhSGZPDl/uG xqPFOjwMoyXvFEuboXBjQCTuKg8pCavPmAfXO42oDadPveVtZbMYP9aeVWMQuqGa ihUsMAG9+cROqlIy72M6XXPWgkKqJjrgvoeCqzfQ2rPmxTYGR5vUmjH7kICKEZco FKIAgR+Xdgciax8SKK9A== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3vvrsuh6mp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sat, 27 Jan 2024 23:26:22 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 40RNQLkT030314 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sat, 27 Jan 2024 23:26:21 GMT Received: from hu-gaurkash-lv.qualcomm.com (10.49.16.6) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Sat, 27 Jan 2024 15:26:17 -0800 From: Gaurav Kashyap To: , , , , , , , , CC: , , , , , , , , , , , , , , , Gaurav Kashyap Subject: [PATCH v4 04/15] soc: qcom: ice: add hwkm support in ice Date: Sat, 27 Jan 2024 15:14:02 -0800 Message-ID: <20240127232436.2632187-5-quic_gaurkash@quicinc.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240127232436.2632187-1-quic_gaurkash@quicinc.com> References: <20240127232436.2632187-1-quic_gaurkash@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: 4CtFsJwD6lzr-M2nvAHjnH17tomqppCs X-Proofpoint-GUID: 4CtFsJwD6lzr-M2nvAHjnH17tomqppCs X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-01-25_14,2024-01-25_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 adultscore=0 impostorscore=0 suspectscore=0 phishscore=0 lowpriorityscore=0 mlxscore=0 clxscore=1015 malwarescore=0 bulkscore=0 spamscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401190000 definitions=main-2401270178 Qualcomm's ICE (Inline Crypto Engine) contains a proprietary key management hardware called Hardware Key Manager (HWKM). This patch integrates HWKM support in ICE when it is available. HWKM primarily provides hardware wrapped key support where the ICE (storage) keys are not available in software and protected in hardware. When HWKM software support is not fully available (from Trustzone), there can be a scenario where the ICE hardware supports HWKM, but it cannot be used for wrapped keys. In this case, standard keys have to be used without using HWKM. Hence, providing a toggle controlled by a devicetree entry to use HWKM or not. Signed-off-by: Gaurav Kashyap Tested-by: Neil Armstrong --- drivers/soc/qcom/ice.c | 126 ++++++++++++++++++++++++++++++++++++++++- include/soc/qcom/ice.h | 1 + 2 files changed, 124 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index 6f941d32fffb..c718e8153b23 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -26,6 +26,20 @@ #define QCOM_ICE_REG_FUSE_SETTING 0x0010 #define QCOM_ICE_REG_BIST_STATUS 0x0070 #define QCOM_ICE_REG_ADVANCED_CONTROL 0x1000 +#define QCOM_ICE_REG_CONTROL 0x0 +/* QCOM ICE HWKM registers */ +#define QCOM_ICE_REG_HWKM_TZ_KM_CTL 0x1000 +#define QCOM_ICE_REG_HWKM_TZ_KM_STATUS 0x1004 +#define QCOM_ICE_REG_HWKM_BANK0_BANKN_IRQ_STATUS 0x2008 +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_0 0x5000 +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_1 0x5004 +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_2 0x5008 +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_3 0x500C +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_4 0x5010 + +/* QCOM ICE HWKM BIST vals */ +#define QCOM_ICE_HWKM_BIST_DONE_V1_VAL 0x14007 +#define QCOM_ICE_HWKM_BIST_DONE_V2_VAL 0x287 /* BIST ("built-in self-test") status flags */ #define QCOM_ICE_BIST_STATUS_MASK GENMASK(31, 28) @@ -34,6 +48,9 @@ #define QCOM_ICE_FORCE_HW_KEY0_SETTING_MASK 0x2 #define QCOM_ICE_FORCE_HW_KEY1_SETTING_MASK 0x4 +#define QCOM_ICE_HWKM_REG_OFFSET 0x8000 +#define HWKM_OFFSET(reg) ((reg) + QCOM_ICE_HWKM_REG_OFFSET) + #define qcom_ice_writel(engine, val, reg) \ writel((val), (engine)->base + (reg)) @@ -46,6 +63,9 @@ struct qcom_ice { struct device_link *link; struct clk *core_clk; + u8 hwkm_version; + bool use_hwkm; + bool hwkm_init_complete; }; static bool qcom_ice_check_supported(struct qcom_ice *ice) @@ -63,8 +83,21 @@ static bool qcom_ice_check_supported(struct qcom_ice *ice) return false; } - dev_info(dev, "Found QC Inline Crypto Engine (ICE) v%d.%d.%d\n", - major, minor, step); + if (major >= 4 || (major == 3 && minor == 2 && step >= 1)) + ice->hwkm_version = 2; + else if (major == 3 && minor == 2) + ice->hwkm_version = 1; + else + ice->hwkm_version = 0; + + if (ice->hwkm_version == 0) + ice->use_hwkm = false; + + dev_info(dev, "Found QC Inline Crypto Engine (ICE) v%d.%d.%d, HWKM v%d\n", + major, minor, step, ice->hwkm_version); + + if (!ice->use_hwkm) + dev_info(dev, "QC ICE HWKM (Hardware Key Manager) not used/supported"); /* If fuses are blown, ICE might not work in the standard way. */ regval = qcom_ice_readl(ice, QCOM_ICE_REG_FUSE_SETTING); @@ -113,10 +146,14 @@ static void qcom_ice_optimization_enable(struct qcom_ice *ice) * fails, so we needn't do it in software too, and (c) properly testing * storage encryption requires testing the full storage stack anyway, * and not relying on hardware-level self-tests. + * + * However, we still care about if HWKM BIST failed (when supported) as + * important functionality would fail later, so disable hwkm on failure. */ static int qcom_ice_wait_bist_status(struct qcom_ice *ice) { u32 regval; + u32 bist_done_reg; int err; err = readl_poll_timeout(ice->base + QCOM_ICE_REG_BIST_STATUS, @@ -125,15 +162,85 @@ static int qcom_ice_wait_bist_status(struct qcom_ice *ice) if (err) dev_err(ice->dev, "Timed out waiting for ICE self-test to complete\n"); + if (ice->use_hwkm) { + bist_done_reg = (ice->hwkm_version == 1) ? + QCOM_ICE_HWKM_BIST_DONE_V1_VAL : + QCOM_ICE_HWKM_BIST_DONE_V2_VAL; + if (qcom_ice_readl(ice, + HWKM_OFFSET(QCOM_ICE_REG_HWKM_TZ_KM_STATUS)) != + bist_done_reg) { + dev_err(ice->dev, "HWKM BIST error\n"); + ice->use_hwkm = false; + } + } return err; } +static void qcom_ice_enable_standard_mode(struct qcom_ice *ice) +{ + u32 val = 0; + + /* + * When ICE is in standard (hwkm) mode, it supports HW wrapped + * keys, and when it is in legacy mode, it only supports standard + * (non HW wrapped) keys. + * + * Put ICE in standard mode, ICE defaults to legacy mode. + * Legacy mode - ICE HWKM slave not supported. + * Standard mode - ICE HWKM slave supported. + * + * Depending on the version of HWKM, it is controlled by different + * registers in ICE. + */ + if (ice->hwkm_version >= 2) { + val = qcom_ice_readl(ice, QCOM_ICE_REG_CONTROL); + val = val & 0xFFFFFFFE; + qcom_ice_writel(ice, val, QCOM_ICE_REG_CONTROL); + } else { + qcom_ice_writel(ice, 0x7, HWKM_OFFSET(QCOM_ICE_REG_HWKM_TZ_KM_CTL)); + } +} + +static void qcom_ice_hwkm_init(struct qcom_ice *ice) +{ + /* Disable CRC checks. This HWKM feature is not used. */ + qcom_ice_writel(ice, 0x6, + HWKM_OFFSET(QCOM_ICE_REG_HWKM_TZ_KM_CTL)); + + /* + * Give register bank of the HWKM slave access to read and modify + * the keyslots in ICE HWKM slave. Without this, trustzone will not + * be able to program keys into ICE. + */ + qcom_ice_writel(ice, 0xFFFFFFFF, HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_0)); + qcom_ice_writel(ice, 0xFFFFFFFF, HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_1)); + qcom_ice_writel(ice, 0xFFFFFFFF, HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_2)); + qcom_ice_writel(ice, 0xFFFFFFFF, HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_3)); + qcom_ice_writel(ice, 0xFFFFFFFF, HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_4)); + + /* Clear HWKM response FIFO before doing anything */ + qcom_ice_writel(ice, 0x8, HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BANKN_IRQ_STATUS)); + ice->hwkm_init_complete = true; +} + int qcom_ice_enable(struct qcom_ice *ice) { + int err; + qcom_ice_low_power_mode_enable(ice); qcom_ice_optimization_enable(ice); - return qcom_ice_wait_bist_status(ice); + if (ice->use_hwkm) + qcom_ice_enable_standard_mode(ice); + + err = qcom_ice_wait_bist_status(ice); + if (err) + return err; + + if (ice->use_hwkm) + qcom_ice_hwkm_init(ice); + + return err; } EXPORT_SYMBOL_GPL(qcom_ice_enable); @@ -149,6 +256,10 @@ int qcom_ice_resume(struct qcom_ice *ice) return err; } + if (ice->use_hwkm) { + qcom_ice_enable_standard_mode(ice); + qcom_ice_hwkm_init(ice); + } return qcom_ice_wait_bist_status(ice); } EXPORT_SYMBOL_GPL(qcom_ice_resume); @@ -156,6 +267,7 @@ EXPORT_SYMBOL_GPL(qcom_ice_resume); int qcom_ice_suspend(struct qcom_ice *ice) { clk_disable_unprepare(ice->core_clk); + ice->hwkm_init_complete = false; return 0; } @@ -205,6 +317,12 @@ int qcom_ice_evict_key(struct qcom_ice *ice, int slot) } EXPORT_SYMBOL_GPL(qcom_ice_evict_key); +bool qcom_ice_hwkm_supported(struct qcom_ice *ice) +{ + return ice->use_hwkm; +} +EXPORT_SYMBOL_GPL(qcom_ice_hwkm_supported); + static struct qcom_ice *qcom_ice_create(struct device *dev, void __iomem *base) { @@ -239,6 +357,8 @@ static struct qcom_ice *qcom_ice_create(struct device *dev, engine->core_clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(engine->core_clk)) return ERR_CAST(engine->core_clk); + engine->use_hwkm = of_property_read_bool(dev->of_node, + "qcom,ice-use-hwkm"); if (!qcom_ice_check_supported(engine)) return ERR_PTR(-EOPNOTSUPP); diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h index 9dd835dba2a7..1f52e82e3e1c 100644 --- a/include/soc/qcom/ice.h +++ b/include/soc/qcom/ice.h @@ -34,5 +34,6 @@ int qcom_ice_program_key(struct qcom_ice *ice, const struct blk_crypto_key *bkey, u8 data_unit_size, int slot); int qcom_ice_evict_key(struct qcom_ice *ice, int slot); +bool qcom_ice_hwkm_supported(struct qcom_ice *ice); struct qcom_ice *of_qcom_ice_get(struct device *dev); #endif /* __QCOM_ICE_H__ */