Files
kernel_xiaomi_mt6785/include/linux/keyslot-manager.h
mtk81325 53ad86156f [ALPS05283935] keyslot-manager: set rw semaphore subclass
We found a recursive locking as below:

[   87.848606] -(1)[282:init] down_write+0x3c/0xd0
[   87.849229] -(1)[282:init] keyslot_manager_evict_key+0x398/0x600
[   87.850035] -(1)[282:init] blk_crypto_evict_key+0xb0/0x18c
[   87.850779] -(1)[282:init] dm_keyslot_evict_callback+0x74/0xf0
[   87.851566] -(1)[282:init] default_key_iterate_devices+0xa0/0xb4
[   87.852373] -(1)[282:init] dm_keyslot_evict+0x15c/0x240
[   87.853082] -(1)[282:init] keyslot_manager_evict_key+0x3bc/0x600
[   87.853888] -(1)[282:init] blk_crypto_evict_key+0xb0/0x18c
[   87.854631] -(1)[282:init] fscrypt_destroy_inline_crypt_key+0x84/0x114

Although dm ksm semaphore is totally different with lower device drivers,
it will result in lockdep detection disabled, then stability test CANNOT
detect lock potential issue anymore.

Try to set a sub-class lock level in DM layer.

MTK-Commit-Id: aeade56a7b177d3d350ba74fdabf72de8587a103

Change-Id: I22645daf78583910545f83e91cfb87b622db629c
Tests: MTK HIE U.T (fscrypt v2) 2~5 cases 100 times in UFS/eMMC platforms
Signed-off-by: mtk81325 <peng.zhou@mediatek.com>
CR-Id: ALPS05283935
Feature: SIM
2021-01-29 02:20:03 +08:00

106 lines
3.5 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2019 Google LLC
*/
#ifndef __LINUX_KEYSLOT_MANAGER_H
#define __LINUX_KEYSLOT_MANAGER_H
#include <linux/bio.h>
/* Inline crypto feature bits. Must set at least one. */
enum {
/* Support for standard software-specified keys */
BLK_CRYPTO_FEATURE_STANDARD_KEYS = BIT(0),
/* Support for hardware-wrapped keys */
BLK_CRYPTO_FEATURE_WRAPPED_KEYS = BIT(1),
};
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
struct keyslot_manager;
/**
* struct keyslot_mgmt_ll_ops - functions to manage keyslots in hardware
* @keyslot_program: Program the specified key into the specified slot in the
* inline encryption hardware.
* @keyslot_evict: Evict key from the specified keyslot in the hardware.
* The key is provided so that e.g. dm layers can evict
* keys from the devices that they map over.
* Returns 0 on success, -errno otherwise.
* @derive_raw_secret: (Optional) Derive a software secret from a
* hardware-wrapped key. Returns 0 on success, -EOPNOTSUPP
* if unsupported on the hardware, or another -errno code.
*
* This structure should be provided by storage device drivers when they set up
* a keyslot manager - this structure holds the function ptrs that the keyslot
* manager will use to manipulate keyslots in the hardware.
*/
struct keyslot_mgmt_ll_ops {
int (*keyslot_program)(struct keyslot_manager *ksm,
const struct blk_crypto_key *key,
unsigned int slot);
int (*keyslot_evict)(struct keyslot_manager *ksm,
const struct blk_crypto_key *key,
unsigned int slot);
int (*derive_raw_secret)(struct keyslot_manager *ksm,
const u8 *wrapped_key,
unsigned int wrapped_key_size,
u8 *secret, unsigned int secret_size);
};
struct keyslot_manager *keyslot_manager_create(
struct device *dev,
unsigned int num_slots,
const struct keyslot_mgmt_ll_ops *ksm_ops,
unsigned int features,
const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],
void *ll_priv_data);
void keyslot_manager_set_max_dun_bytes(struct keyslot_manager *ksm,
unsigned int max_dun_bytes);
int keyslot_manager_get_slot_for_key(struct keyslot_manager *ksm,
const struct blk_crypto_key *key);
void keyslot_manager_get_slot(struct keyslot_manager *ksm, unsigned int slot);
void keyslot_manager_put_slot(struct keyslot_manager *ksm, unsigned int slot);
bool keyslot_manager_crypto_mode_supported(struct keyslot_manager *ksm,
enum blk_crypto_mode_num crypto_mode,
unsigned int dun_bytes,
unsigned int data_unit_size,
bool is_hw_wrapped_key);
int keyslot_manager_evict_key(struct keyslot_manager *ksm,
const struct blk_crypto_key *key);
void keyslot_manager_reprogram_all_keys(struct keyslot_manager *ksm);
void *keyslot_manager_private(struct keyslot_manager *ksm);
void keyslot_manager_destroy(struct keyslot_manager *ksm);
struct keyslot_manager *keyslot_manager_create_passthrough(
struct device *dev,
const struct keyslot_mgmt_ll_ops *ksm_ops,
unsigned int features,
const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],
void *ll_priv_data);
void keyslot_manager_intersect_modes(struct keyslot_manager *parent,
const struct keyslot_manager *child);
int keyslot_manager_derive_raw_secret(struct keyslot_manager *ksm,
const u8 *wrapped_key,
unsigned int wrapped_key_size,
u8 *secret, unsigned int secret_size);
inline void ksm_flock(struct keyslot_manager *ksm, unsigned int flags);
#endif /* CONFIG_BLK_INLINE_ENCRYPTION */
#endif /* __LINUX_KEYSLOT_MANAGER_H */