ice: fix issue with losing ICE key configuration during reset
TZ is called to restore key configuration in case of UFS reset Change-Id: Id434e7f9ec6befdce97f52fd350957b66adcb15f Signed-off-by: Andrey Markovytch <andreym@codeaurora.org>
This commit is contained in:
parent
2aa89ab3ff
commit
a1cd6239e4
5 changed files with 86 additions and 3 deletions
|
@ -24,6 +24,7 @@
|
|||
#include <linux/pfk.h>
|
||||
#include <crypto/ice.h>
|
||||
#include <soc/qcom/scm.h>
|
||||
#include <soc/qcom/qseecomi.h>
|
||||
#include "iceregs.h"
|
||||
|
||||
#define TZ_SYSCALL_CREATE_SMC_ID(o, s, f) \
|
||||
|
@ -40,6 +41,13 @@
|
|||
#define TZ_OS_KS_RESTORE_KEY_ID_PARAM_ID \
|
||||
TZ_SYSCALL_CREATE_PARAM_ID_0
|
||||
|
||||
#define TZ_OS_KS_RESTORE_KEY_CONFIG_ID \
|
||||
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x06)
|
||||
|
||||
#define TZ_OS_KS_RESTORE_KEY_CONFIG_ID_PARAM_ID \
|
||||
TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
|
||||
|
||||
|
||||
#define ICE_REV(x, y) (((x) & ICE_CORE_##y##_REV_MASK) >> ICE_CORE_##y##_REV)
|
||||
#define QCOM_UFS_ICE_DEV "iceufs"
|
||||
#define QCOM_SDCC_ICE_DEV "icesdcc"
|
||||
|
@ -830,6 +838,24 @@ static int qcom_ice_restore_config(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int qcom_ice_restore_key_config(void)
|
||||
{
|
||||
struct scm_desc desc = {0};
|
||||
int ret = -1;
|
||||
|
||||
/* For ice 3, key configuration needs to be restored in case of reset */
|
||||
|
||||
desc.arginfo = TZ_OS_KS_RESTORE_KEY_CONFIG_ID_PARAM_ID;
|
||||
desc.args[0] = 10; /* UFS_ICE */
|
||||
|
||||
ret = scm_call2(TZ_OS_KS_RESTORE_KEY_CONFIG_ID, &desc);
|
||||
|
||||
if (ret)
|
||||
pr_err("%s: Error: 0x%x\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcom_ice_init_clocks(struct ice_device *ice)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
@ -1103,6 +1129,22 @@ static int qcom_ice_finish_power_collapse(struct ice_device *ice_dev)
|
|||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* ICE looses its key configuration when UFS is reset,
|
||||
* restore it
|
||||
*/
|
||||
} else if (ICE_REV(ice_dev->ice_hw_version, MAJOR) > 2) {
|
||||
err = qcom_ice_restore_key_config();
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* for PFE case, clear the cached ICE key table,
|
||||
* this will force keys to be reconfigured
|
||||
* per each next transaction
|
||||
*/
|
||||
pfk_clear_on_reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -24,6 +24,7 @@ int pfk_load_key_start(const struct bio *bio,
|
|||
int pfk_load_key_end(const struct bio *bio, bool *is_pfe);
|
||||
int pfk_remove_key(const unsigned char *key, size_t key_size);
|
||||
bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2);
|
||||
void pfk_clear_on_reset(void);
|
||||
|
||||
#else
|
||||
static inline int pfk_load_key_start(const struct bio *bio,
|
||||
|
@ -48,6 +49,9 @@ static inline bool pfk_allow_merge_bio(const struct bio *bio1,
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline void pfk_clear_on_reset(void)
|
||||
{}
|
||||
|
||||
#endif /* CONFIG_PFK */
|
||||
|
||||
#endif /* PFK_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -476,6 +476,18 @@ bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2)
|
|||
return (*(pfk_allow_merge_bio_ftable[which_pfe1]))(bio1, bio2,
|
||||
inode1, inode2);
|
||||
}
|
||||
/**
|
||||
* Flush key table on storage core reset. During core reset key configuration
|
||||
* is lost in ICE. We need to flash the cache, so that the keys will be
|
||||
* reconfigured again for every subsequent transaction
|
||||
*/
|
||||
void pfk_clear_on_reset(void)
|
||||
{
|
||||
if (!pfk_is_ready())
|
||||
return;
|
||||
|
||||
pfk_kc_clear_on_reset();
|
||||
}
|
||||
|
||||
module_init(pfk_init);
|
||||
module_exit(pfk_exit);
|
||||
|
|
|
@ -826,3 +826,27 @@ out:
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* pfk_kc_clear_on_reset() - clear the table and remove all keys from ICE
|
||||
* The assumption is that at this point we don't have any pending transactions
|
||||
* Also, there is no need to clear keys from ICE
|
||||
*
|
||||
* Return 0 on success, error otherwise
|
||||
*
|
||||
*/
|
||||
void pfk_kc_clear_on_reset(void)
|
||||
{
|
||||
struct kc_entry *entry = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (!kc_is_ready())
|
||||
return;
|
||||
|
||||
kc_spin_lock();
|
||||
for (i = 0; i < PFK_KC_TABLE_SIZE; i++) {
|
||||
entry = kc_entry_at_index(i);
|
||||
kc_clear_entry(entry);
|
||||
}
|
||||
kc_spin_unlock();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -26,6 +26,7 @@ int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size,
|
|||
const unsigned char *salt, size_t salt_size);
|
||||
int pfk_kc_remove_key(const unsigned char *key, size_t key_size);
|
||||
int pfk_kc_clear(void);
|
||||
void pfk_kc_clear_on_reset(void);
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue