From: Yu'an Wang wangyuan46@huawei.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I830AI CVE: NA
--------------------------------
Before initializing the device, reset the device to clear the residual data to prevent unexpected problems, such as reboot scene, which may maintain device state before reboot.
Signed-off-by: Yu'an Wang wangyuan46@huawei.com --- drivers/crypto/hisilicon/hpre/hpre_main.c | 68 +++++++++++-------- drivers/crypto/hisilicon/qm.c | 83 ++++++++++++++++------- drivers/crypto/hisilicon/rde/rde_main.c | 64 ++++++++--------- drivers/crypto/hisilicon/sec2/sec_main.c | 39 ++++++----- drivers/crypto/hisilicon/zip/zip_main.c | 42 +++++++----- 5 files changed, 175 insertions(+), 121 deletions(-)
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index 1a980f255ad4..cbe8ea438fd2 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -780,28 +780,6 @@ static void hpre_debugfs_exit(struct hisi_qm *qm) debugfs_remove_recursive(qm->debug.debug_root); }
-static int hpre_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev) -{ - int ret; - - qm->algs = "rsa\ndh\n"; - qm->uacce_mode = uacce_mode; - qm->pdev = pdev; - ret = hisi_qm_pre_init(qm, pf_q_num, HPRE_PF_DEF_Q_BASE); - if (ret) - return ret; - if (qm->ver == QM_HW_V1) { - pci_warn(pdev, "HPRE version 1 is not supported!\n"); - return -EINVAL; - } - - qm->qm_list = &hpre_devices; - qm->sqe_size = HPRE_SQE_SIZE; - qm->dev_name = hpre_name; - - return 0; -} - static void hpre_log_hw_error(struct hisi_qm *qm, u32 err_sts) { const struct hpre_hw_error *err = hpre_hw_errors; @@ -836,30 +814,36 @@ static void hpre_open_axi_master_ooo(struct hisi_qm *qm) HPRE_ADDR(qm, HPRE_AM_OOO_SHUTDOWN_ENB)); }
-static int hpre_pf_probe_init(struct hisi_qm *qm) +static void hpre_err_ini_set(struct hisi_qm *qm) { - int ret; - - if (qm->ver != QM_HW_V2) - return -EINVAL; + if (qm->fun_type == QM_HW_VF) + return;
- qm->ctrl_q_num = HPRE_QUEUE_NUM_V2; qm->err_ini.get_dev_hw_err_status = hpre_get_hw_err_status; qm->err_ini.clear_dev_hw_err_status = hpre_clear_hw_err_status; qm->err_ini.err_info.ecc_2bits_mask = HPRE_CORE_ECC_2BIT_ERR | - HPRE_OOO_ECC_2BIT_ERR; + HPRE_OOO_ECC_2BIT_ERR; qm->err_ini.err_info.ce = QM_BASE_CE; qm->err_ini.err_info.nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT; qm->err_ini.err_info.fe = 0; qm->err_ini.err_info.msi = QM_DB_RANDOM_INVALID; qm->err_ini.err_info.acpi_rst = "HRST"; - qm->err_ini.hw_err_disable = hpre_hw_error_disable; qm->err_ini.hw_err_enable = hpre_hw_error_enable; qm->err_ini.set_usr_domain_cache = hpre_set_user_domain_and_cache; qm->err_ini.log_dev_hw_err = hpre_log_hw_error; qm->err_ini.open_axi_master_ooo = hpre_open_axi_master_ooo; qm->err_ini.err_info.msi_wr_port = HPRE_WR_MSI_PORT; +} + +static int hpre_pf_probe_init(struct hisi_qm *qm) +{ + int ret; + + if (qm->ver != QM_HW_V2) + return -EINVAL; + + qm->ctrl_q_num = HPRE_QUEUE_NUM_V2;
ret = qm->err_ini.set_usr_domain_cache(qm); if (ret) @@ -870,6 +854,30 @@ static int hpre_pf_probe_init(struct hisi_qm *qm) return 0; }
+static int hpre_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev) +{ + int ret; + + qm->algs = "rsa\ndh\n"; + qm->uacce_mode = uacce_mode; + qm->pdev = pdev; + ret = hisi_qm_pre_init(qm, pf_q_num, HPRE_PF_DEF_Q_BASE); + if (ret) + return ret; + + if (qm->ver == QM_HW_V1) { + pci_warn(pdev, "HPRE version 1 is not supported!\n"); + return -EINVAL; + } + + qm->qm_list = &hpre_devices; + qm->sqe_size = HPRE_SQE_SIZE; + qm->dev_name = hpre_name; + hpre_err_ini_set(qm); + + return 0; +} + static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct hisi_qm *qm; diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 739b1a6565fd..f2706dc0d55e 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -230,6 +230,7 @@ #define QMC_ALIGN(sz) ALIGN(sz, 32)
static int __hisi_qm_start(struct hisi_qm *qm); +static int qm_reset_device(struct hisi_qm *qm);
enum vft_type { SQC_VFT = 0, @@ -2584,6 +2585,30 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) return ret; }
+static int qm_clear_device(struct hisi_qm *qm) +{ + u32 val; + int ret; + + if (qm->fun_type == QM_HW_VF) + return 0; + + /* OOO register set and check */ + writel(MASTER_GLOBAL_CTRL_SHUTDOWN, qm->io_base + MASTER_GLOBAL_CTRL); + + ret = readl_relaxed_poll_timeout(qm->io_base + MASTER_TRANS_RETURN, + val, (val == MASTER_TRANS_RETURN_RW), + QM_REG_RD_INTVRL_US, + QM_REG_RD_TMOUT_US); + if (ret) { + pci_warn(qm->pdev, "Device is busy, can not clear device.\n"); + writel(0x0, qm->io_base + MASTER_GLOBAL_CTRL); + return ret; + } + + return qm_reset_device(qm); +} + static int hisi_qm_pci_init(struct hisi_qm *qm) { struct pci_dev *pdev = qm->pdev; @@ -2626,8 +2651,14 @@ static int hisi_qm_pci_init(struct hisi_qm *qm) goto err_set_mask_and_coherent; }
+ ret = qm_clear_device(qm); + if (ret) + goto err_free_vectors; + return 0;
+err_free_vectors: + pci_free_irq_vectors(pdev); err_set_mask_and_coherent: devm_iounmap(dev, qm->io_base); err_ioremap: @@ -3808,6 +3839,34 @@ static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm) } }
+static int qm_reset_device(struct hisi_qm *qm) +{ + struct pci_dev *pdev = qm->pdev; + unsigned long long value = 0; + acpi_status s; + + /* The reset related sub-control registers are not in PCI BAR */ + if (ACPI_HANDLE(&pdev->dev)) { + s = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev), + qm->err_ini.err_info.acpi_rst, + NULL, &value); + if (ACPI_FAILURE(s)) { + pci_err(pdev, "NO controller reset method!\n"); + return -EIO; + } + + if (value) { + pci_err(pdev, "Reset step %llu failed!\n", value); + return -EIO; + } + + return 0; + } + + pci_err(pdev, "No reset method!\n"); + return -EINVAL; +} + static int qm_soft_reset(struct hisi_qm *qm) { struct pci_dev *pdev = qm->pdev; @@ -3853,29 +3912,7 @@ static int qm_soft_reset(struct hisi_qm *qm) return ret; }
- /* The reset related sub-control registers are not in PCI BAR */ - if (ACPI_HANDLE(&pdev->dev)) { - unsigned long long value = 0; - acpi_status s; - - s = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev), - qm->err_ini.err_info.acpi_rst, - NULL, &value); - if (ACPI_FAILURE(s)) { - pci_err(pdev, "NO controller reset method!\n"); - return -EIO; - } - - if (value) { - pci_err(pdev, "Reset step %llu failed!\n", value); - return -EIO; - } - } else { - pci_err(pdev, "No reset method!\n"); - return -EINVAL; - } - - return 0; + return qm_reset_device(qm); }
static int qm_vf_reset_done(struct pci_dev *pdev, diff --git a/drivers/crypto/hisilicon/rde/rde_main.c b/drivers/crypto/hisilicon/rde/rde_main.c index f3f70079aa77..f2e00ff891db 100644 --- a/drivers/crypto/hisilicon/rde/rde_main.c +++ b/drivers/crypto/hisilicon/rde/rde_main.c @@ -28,15 +28,8 @@ #define HRDE_QUEUE_NUM_V2 1024 #define HRDE_PCI_DEVICE_ID 0xa25a #define HRDE_SQE_SIZE 64 -#define HRDE_SQ_SIZE (HRDE_SQE_SIZE * QM_Q_DEPTH) #define HRDE_PF_DEF_Q_NUM 64 #define HRDE_PF_DEF_Q_BASE 0 -#define HRDE_RD_INTVRL_US 10 -#define HRDE_RD_TMOUT_US 1000 -#define HRDE_RST_TMOUT_MS 400 -#define HRDE_ENABLE 1 -#define HRDE_DISABLE 0 -#define HRDE_PCI_COMMAND_INVALID 0xFFFFFFFF
#define HRDE_RAS_INT_MSK 0x310290 #define HRDE_RAS_CE_MSK BIT(2) @@ -101,7 +94,7 @@ static struct hisi_qm_list rde_devices; static void hisi_rde_ras_proc(struct work_struct *work);
static const struct hisi_rde_hw_error rde_hw_error[] = { - {.int_msk = BIT(0), .msg = "Rde_ecc_1bitt_err"}, + {.int_msk = BIT(0), .msg = "Rde_ecc_1bit_err"}, {.int_msk = BIT(1), .msg = "Rde_ecc_2bit_err"}, {.int_msk = BIT(2), .msg = "Rde_stat_mgmt_state_timeout_err"}, {.int_msk = BIT(3), .msg = "Rde_data_wr_state_timeout_err"}, @@ -269,7 +262,7 @@ static int hisi_rde_set_user_domain_and_cache(struct hisi_qm *qm) writel(AXI_M_CFG, qm->io_base + QM_AXI_M_CFG); writel(AXI_M_CFG_ENABLE, qm->io_base + QM_AXI_M_CFG_ENABLE);
- /* disable BME/PM/SRIOV FLR*/ + /* disable BME/PM/SRIOV FLR */ writel(PEH_AXUSER_CFG, qm->io_base + QM_PEH_AXUSER_CFG); writel(PEH_AXUSER_CFG_ENABLE, qm->io_base + QM_PEH_AXUSER_CFG_ENABLE);
@@ -351,7 +344,7 @@ static int current_qm_write(struct ctrl_debug_file *file, u32 val) u32 tmp;
if (val > 0) { - pr_err("Function id should be smaller than 0.\n"); + pr_err("Function id should be equal to 0.\n"); return -EINVAL; }
@@ -423,7 +416,7 @@ static ssize_t ctrl_debug_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos) { struct ctrl_debug_file *file = filp->private_data; - char tbuf[20]; + char tbuf[HRDE_DBGFS_VAL_MAX_LEN]; unsigned long val; int len, ret;
@@ -623,6 +616,24 @@ static void hisi_rde_open_master_ooo(struct hisi_qm *qm) writel(val | HRDE_AXI_SHUTDOWN_EN, qm->io_base + HRDE_CFG); }
+static void hisi_rde_err_ini_set(struct hisi_qm *qm) +{ + qm->err_ini.get_dev_hw_err_status = hisi_rde_get_hw_err_status; + qm->err_ini.clear_dev_hw_err_status = hisi_rde_clear_hw_err_status; + qm->err_ini.err_info.ecc_2bits_mask = HRDE_ECC_2BIT_ERR; + qm->err_ini.err_info.ce = QM_BASE_CE; + qm->err_ini.err_info.nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT; + qm->err_ini.err_info.fe = 0; + qm->err_ini.err_info.msi = 0; + qm->err_ini.err_info.acpi_rst = "RRST"; + qm->err_ini.hw_err_disable = hisi_rde_hw_error_disable; + qm->err_ini.hw_err_enable = hisi_rde_hw_error_enable; + qm->err_ini.set_usr_domain_cache = hisi_rde_set_user_domain_and_cache; + qm->err_ini.log_dev_hw_err = hisi_rde_hw_error_log; + qm->err_ini.open_axi_master_ooo = hisi_rde_open_master_ooo; + qm->err_ini.err_info.msi_wr_port = HRDE_WR_MSI_PORT; +} + static int hisi_rde_pf_probe_init(struct hisi_qm *qm) { struct hisi_rde *hisi_rde = container_of(qm, struct hisi_rde, qm); @@ -649,21 +660,6 @@ static int hisi_rde_pf_probe_init(struct hisi_qm *qm) return -EINVAL; }
- qm->err_ini.get_dev_hw_err_status = hisi_rde_get_hw_err_status; - qm->err_ini.clear_dev_hw_err_status = hisi_rde_clear_hw_err_status; - qm->err_ini.err_info.ecc_2bits_mask = HRDE_ECC_2BIT_ERR; - qm->err_ini.err_info.ce = QM_BASE_CE; - qm->err_ini.err_info.nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT; - qm->err_ini.err_info.fe = 0; - qm->err_ini.err_info.msi = 0; - qm->err_ini.err_info.acpi_rst = "RRST"; - qm->err_ini.hw_err_disable = hisi_rde_hw_error_disable; - qm->err_ini.hw_err_enable = hisi_rde_hw_error_enable; - qm->err_ini.set_usr_domain_cache = hisi_rde_set_user_domain_and_cache; - qm->err_ini.log_dev_hw_err = hisi_rde_hw_error_log; - qm->err_ini.open_axi_master_ooo = hisi_rde_open_master_ooo; - qm->err_ini.err_info.msi_wr_port = HRDE_WR_MSI_PORT; - ret = qm->err_ini.set_usr_domain_cache(qm); if (ret) return ret; @@ -690,6 +686,7 @@ static int hisi_rde_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev) qm->sqe_size = HRDE_SQE_SIZE; qm->dev_name = hisi_rde_name; qm->abnormal_fix = hisi_rde_abnormal_fix; + hisi_rde_err_ini_set(qm);
return 0; } @@ -727,31 +724,31 @@ static int hisi_rde_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ret = hisi_rde_qm_pre_init(qm, pdev); if (ret) { - pci_err(pdev, "Pre init qm failed!\n"); + pci_err(pdev, "Failed to pre init qm!\n"); return ret; }
ret = hisi_qm_init(qm); if (ret) { - pci_err(pdev, "Init qm failed!\n"); + pci_err(pdev, "Failed to init qm!\n"); return ret; }
ret = hisi_rde_pf_probe_init(qm); if (ret) { - pci_err(pdev, "Init pf failed!\n"); + pci_err(pdev, "Failed to init pf!\n"); goto err_qm_uninit; }
ret = hisi_qm_start(qm); if (ret) { - pci_err(pdev, "Start qm failed!\n"); + pci_err(pdev, "Failed to start qm!\n"); goto err_qm_uninit; }
ret = hisi_rde_debugfs_init(qm); if (ret) - pci_warn(pdev, "Init debugfs failed!\n"); + pci_warn(pdev, "Failed to init debugfs!\n");
hisi_qm_add_to_list(qm, &rde_devices);
@@ -793,8 +790,7 @@ static void hisi_rde_ras_proc(struct work_struct *work) ret = hisi_qm_process_dev_error(pdev); if (ret == PCI_ERS_RESULT_NEED_RESET) if (hisi_qm_controller_reset(&hisi_rde->qm)) - dev_err(&pdev->dev, "Hisi_rde reset fail.\n"); - + dev_err(&pdev->dev, "Failed to reset device!\n"); }
int hisi_rde_abnormal_fix(struct hisi_qm *qm) @@ -850,7 +846,7 @@ static int __init hisi_rde_init(void) ret = pci_register_driver(&hisi_rde_pci_driver); if (ret < 0) { hisi_rde_unregister_debugfs(); - pr_err("Register pci driver failed.\n"); + pr_err("Failed to register pci driver!\n"); }
return ret; diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index a568d5363c1e..0f32dcb69e12 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -712,29 +712,17 @@ static void sec_open_axi_master_ooo(struct hisi_qm *qm) writel(val | SEC_AXI_SHUTDOWN_ENABLE, SEC_ADDR(qm, SEC_CONTROL_REG)); }
-static int sec_pf_probe_init(struct hisi_qm *qm) +static void sec_err_ini_set(struct hisi_qm *qm) { - int ret; - - switch (qm->ver) { - case QM_HW_V1: - qm->ctrl_q_num = SEC_QUEUE_NUM_V1; - break; - - case QM_HW_V2: - qm->ctrl_q_num = SEC_QUEUE_NUM_V2; - break; - - default: - return -EINVAL; - } + if (qm->fun_type == QM_HW_VF) + return;
qm->err_ini.get_dev_hw_err_status = sec_get_hw_err_status; qm->err_ini.clear_dev_hw_err_status = sec_clear_hw_err_status; qm->err_ini.err_info.ecc_2bits_mask = SEC_CORE_INT_STATUS_M_ECC; qm->err_ini.err_info.ce = QM_BASE_CE; qm->err_ini.err_info.nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT | - QM_ACC_WB_NOT_READY_TIMEOUT; + QM_ACC_WB_NOT_READY_TIMEOUT; qm->err_ini.err_info.fe = 0; qm->err_ini.err_info.msi = QM_DB_RANDOM_INVALID; qm->err_ini.err_info.acpi_rst = "SRST"; @@ -744,6 +732,24 @@ static int sec_pf_probe_init(struct hisi_qm *qm) qm->err_ini.log_dev_hw_err = sec_log_hw_error; qm->err_ini.open_axi_master_ooo = sec_open_axi_master_ooo; qm->err_ini.err_info.msi_wr_port = SEC_WR_MSI_PORT; +} + +static int sec_pf_probe_init(struct hisi_qm *qm) +{ + int ret; + + switch (qm->ver) { + case QM_HW_V1: + qm->ctrl_q_num = SEC_QUEUE_NUM_V1; + break; + + case QM_HW_V2: + qm->ctrl_q_num = SEC_QUEUE_NUM_V2; + break; + + default: + return -EINVAL; + }
ret = qm->err_ini.set_usr_domain_cache(qm); if (ret) @@ -807,6 +813,7 @@ static int sec_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev) qm->qm_list = &sec_devices; qm->sqe_size = SEC_SQE_SIZE; qm->dev_name = sec_name; + sec_err_ini_set(qm);
return 0; } diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 17bbab667553..1ca51793e26a 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c @@ -204,7 +204,7 @@ static struct debugfs_reg32 hzip_dfx_regs[] = { {"HZIP_AVG_DELAY ", 0x28ull}, {"HZIP_MEM_VISIBLE_DATA ", 0x30ull}, {"HZIP_MEM_VISIBLE_ADDR ", 0x34ull}, - {"HZIP_COMSUMED_BYTE ", 0x38ull}, + {"HZIP_CONSUMED_BYTE ", 0x38ull}, {"HZIP_PRODUCED_BYTE ", 0x40ull}, {"HZIP_COMP_INF ", 0x70ull}, {"HZIP_PRE_OUT ", 0x78ull}, @@ -755,6 +755,28 @@ static void hisi_zip_close_axi_master_ooo(struct hisi_qm *qm) qm->io_base + HZIP_CORE_INT_SET); }
+static void hisi_zip_err_ini_set(struct hisi_qm *qm) +{ + if (qm->fun_type == QM_HW_VF) + return; + + qm->err_ini.get_dev_hw_err_status = hisi_zip_get_hw_err_status; + qm->err_ini.clear_dev_hw_err_status = hisi_zip_clear_hw_err_status; + qm->err_ini.err_info.ecc_2bits_mask = HZIP_CORE_INT_STATUS_M_ECC; + qm->err_ini.err_info.ce = QM_BASE_CE; + qm->err_ini.err_info.nfe = QM_BASE_NFE | QM_ACC_WB_NOT_READY_TIMEOUT; + qm->err_ini.err_info.fe = 0; + qm->err_ini.err_info.msi = QM_DB_RANDOM_INVALID; + qm->err_ini.err_info.acpi_rst = "ZRST"; + qm->err_ini.hw_err_disable = hisi_zip_hw_error_disable; + qm->err_ini.hw_err_enable = hisi_zip_hw_error_enable; + qm->err_ini.set_usr_domain_cache = hisi_zip_set_user_domain_and_cache; + qm->err_ini.log_dev_hw_err = hisi_zip_log_hw_error; + qm->err_ini.open_axi_master_ooo = hisi_zip_open_axi_master_ooo; + qm->err_ini.close_axi_master_ooo = hisi_zip_close_axi_master_ooo; + qm->err_ini.err_info.msi_wr_port = HZIP_WR_PORT; +} + static int hisi_zip_pf_probe_init(struct hisi_qm *qm) { struct hisi_zip *zip = container_of(qm, struct hisi_zip, qm); @@ -781,23 +803,6 @@ static int hisi_zip_pf_probe_init(struct hisi_qm *qm) return -EINVAL; }
- qm->err_ini.get_dev_hw_err_status = hisi_zip_get_hw_err_status; - qm->err_ini.clear_dev_hw_err_status = hisi_zip_clear_hw_err_status; - qm->err_ini.err_info.ecc_2bits_mask = HZIP_CORE_INT_STATUS_M_ECC; - qm->err_ini.err_info.ce = QM_BASE_CE; - qm->err_ini.err_info.nfe = QM_BASE_NFE | QM_ACC_WB_NOT_READY_TIMEOUT; - qm->err_ini.err_info.fe = 0; - qm->err_ini.err_info.msi = QM_DB_RANDOM_INVALID; - qm->err_ini.err_info.acpi_rst = "ZRST"; - qm->err_ini.hw_err_disable = hisi_zip_hw_error_disable; - qm->err_ini.hw_err_enable = hisi_zip_hw_error_enable; - qm->err_ini.set_usr_domain_cache = hisi_zip_set_user_domain_and_cache; - qm->err_ini.log_dev_hw_err = hisi_zip_log_hw_error; - qm->err_ini.open_axi_master_ooo = hisi_zip_open_axi_master_ooo; - qm->err_ini.close_axi_master_ooo = hisi_zip_close_axi_master_ooo; - - qm->err_ini.err_info.msi_wr_port = HZIP_WR_PORT; - ret = qm->err_ini.set_usr_domain_cache(qm); if (ret) return ret; @@ -822,6 +827,7 @@ static int hisi_zip_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev) qm->sqe_size = HZIP_SQE_SIZE; qm->dev_name = hisi_zip_name; qm->qm_list = &zip_devices; + hisi_zip_err_ini_set(qm);
return 0; }
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/2259 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/B...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/2259 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/B...