Import of kernel-5.14.0-611.16.1.el9_7
This commit is contained in:
parent
e239c331eb
commit
e562c02649
@ -12,7 +12,7 @@ RHEL_MINOR = 7
|
||||
#
|
||||
# Use this spot to avoid future merge conflicts.
|
||||
# Do not trim this comment.
|
||||
RHEL_RELEASE = 611.13.1
|
||||
RHEL_RELEASE = 611.16.1
|
||||
|
||||
#
|
||||
# ZSTREAM
|
||||
|
||||
@ -2903,6 +2903,7 @@ void __init sev_set_cpu_caps(void)
|
||||
void __init sev_hardware_setup(void)
|
||||
{
|
||||
unsigned int eax, ebx, ecx, edx, sev_asid_count, sev_es_asid_count;
|
||||
struct sev_platform_init_args init_args = {0};
|
||||
bool sev_snp_supported = false;
|
||||
bool sev_es_supported = false;
|
||||
bool sev_supported = false;
|
||||
@ -3019,6 +3020,15 @@ out:
|
||||
sev_supported_vmsa_features = 0;
|
||||
if (sev_es_debug_swap_enabled)
|
||||
sev_supported_vmsa_features |= SVM_SEV_FEAT_DEBUG_SWAP;
|
||||
|
||||
if (!sev_enabled)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Do both SNP and SEV initialization at KVM module load.
|
||||
*/
|
||||
init_args.probe = true;
|
||||
sev_platform_init(&init_args);
|
||||
}
|
||||
|
||||
void sev_hardware_unsetup(void)
|
||||
@ -3034,6 +3044,8 @@ void sev_hardware_unsetup(void)
|
||||
|
||||
misc_cg_set_capacity(MISC_CG_RES_SEV, 0);
|
||||
misc_cg_set_capacity(MISC_CG_RES_SEV_ES, 0);
|
||||
|
||||
sev_platform_shutdown();
|
||||
}
|
||||
|
||||
int sev_cpu_init(struct svm_cpu_data *sd)
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
static DEFINE_IDR(nbd_index_idr);
|
||||
static DEFINE_MUTEX(nbd_index_mutex);
|
||||
static struct workqueue_struct *nbd_del_wq;
|
||||
static struct cred *nbd_cred;
|
||||
static int nbd_total_devices = 0;
|
||||
|
||||
struct nbd_sock {
|
||||
@ -556,6 +557,7 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
|
||||
int result;
|
||||
struct msghdr msg = {} ;
|
||||
unsigned int noreclaim_flag;
|
||||
const struct cred *old_cred;
|
||||
|
||||
if (unlikely(!sock)) {
|
||||
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
||||
@ -564,6 +566,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
old_cred = override_creds(nbd_cred);
|
||||
|
||||
msg.msg_iter = *iter;
|
||||
|
||||
noreclaim_flag = memalloc_noreclaim_save();
|
||||
@ -588,6 +592,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
|
||||
|
||||
memalloc_noreclaim_restore(noreclaim_flag);
|
||||
|
||||
revert_creds(old_cred);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2661,7 +2667,15 @@ static int __init nbd_init(void)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
nbd_cred = prepare_kernel_cred(&init_task);
|
||||
if (!nbd_cred) {
|
||||
destroy_workqueue(nbd_del_wq);
|
||||
unregister_blkdev(NBD_MAJOR, "nbd");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (genl_register_family(&nbd_genl_family)) {
|
||||
put_cred(nbd_cred);
|
||||
destroy_workqueue(nbd_del_wq);
|
||||
unregister_blkdev(NBD_MAJOR, "nbd");
|
||||
return -EINVAL;
|
||||
@ -2716,6 +2730,7 @@ static void __exit nbd_cleanup(void)
|
||||
/* Also wait for nbd_dev_remove_work() completes */
|
||||
destroy_workqueue(nbd_del_wq);
|
||||
|
||||
put_cred(nbd_cred);
|
||||
idr_destroy(&nbd_index_idr);
|
||||
unregister_blkdev(NBD_MAJOR, "nbd");
|
||||
}
|
||||
|
||||
@ -109,6 +109,15 @@ static void *sev_init_ex_buffer;
|
||||
*/
|
||||
static struct sev_data_range_list *snp_range_list;
|
||||
|
||||
static void __sev_firmware_shutdown(struct sev_device *sev, bool panic);
|
||||
|
||||
static int snp_shutdown_on_panic(struct notifier_block *nb,
|
||||
unsigned long reason, void *arg);
|
||||
|
||||
static struct notifier_block snp_panic_notifier = {
|
||||
.notifier_call = snp_shutdown_on_panic,
|
||||
};
|
||||
|
||||
static inline bool sev_version_greater_or_equal(u8 maj, u8 min)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
@ -1112,7 +1121,7 @@ static int __sev_snp_init_locked(int *error)
|
||||
if (!sev_version_greater_or_equal(SNP_MIN_API_MAJOR, SNP_MIN_API_MINOR)) {
|
||||
dev_dbg(sev->dev, "SEV-SNP support requires firmware version >= %d:%d\n",
|
||||
SNP_MIN_API_MAJOR, SNP_MIN_API_MINOR);
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* SNP_INIT requires MSR_VM_HSAVE_PA to be cleared on all CPUs. */
|
||||
@ -1176,21 +1185,34 @@ static int __sev_snp_init_locked(int *error)
|
||||
wbinvd_on_all_cpus();
|
||||
|
||||
rc = __sev_do_cmd_locked(cmd, arg, error);
|
||||
if (rc)
|
||||
if (rc) {
|
||||
dev_err(sev->dev, "SEV-SNP: %s failed rc %d, error %#x\n",
|
||||
cmd == SEV_CMD_SNP_INIT_EX ? "SNP_INIT_EX" : "SNP_INIT",
|
||||
rc, *error);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Prepare for first SNP guest launch after INIT. */
|
||||
wbinvd_on_all_cpus();
|
||||
rc = __sev_do_cmd_locked(SEV_CMD_SNP_DF_FLUSH, NULL, error);
|
||||
if (rc)
|
||||
if (rc) {
|
||||
dev_err(sev->dev, "SEV-SNP: SNP_DF_FLUSH failed rc %d, error %#x\n",
|
||||
rc, *error);
|
||||
return rc;
|
||||
}
|
||||
|
||||
sev->snp_initialized = true;
|
||||
dev_dbg(sev->dev, "SEV-SNP firmware initialized\n");
|
||||
|
||||
dev_info(sev->dev, "SEV-SNP API:%d.%d build:%d\n", sev->api_major,
|
||||
sev->api_minor, sev->build);
|
||||
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&snp_panic_notifier);
|
||||
|
||||
sev_es_tmr_size = SNP_TMR_SIZE;
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __sev_platform_init_handle_tmr(struct sev_device *sev)
|
||||
@ -1253,9 +1275,11 @@ static int __sev_platform_init_handle_init_ex_path(struct sev_device *sev)
|
||||
|
||||
static int __sev_platform_init_locked(int *error)
|
||||
{
|
||||
int rc, psp_ret = SEV_RET_NO_FW_CALL;
|
||||
int rc, psp_ret, dfflush_error;
|
||||
struct sev_device *sev;
|
||||
|
||||
psp_ret = dfflush_error = SEV_RET_NO_FW_CALL;
|
||||
|
||||
if (!psp_master || !psp_master->sev_data)
|
||||
return -ENODEV;
|
||||
|
||||
@ -1287,16 +1311,22 @@ static int __sev_platform_init_locked(int *error)
|
||||
if (error)
|
||||
*error = psp_ret;
|
||||
|
||||
if (rc)
|
||||
if (rc) {
|
||||
dev_err(sev->dev, "SEV: %s failed %#x, rc %d\n",
|
||||
sev_init_ex_buffer ? "INIT_EX" : "INIT", psp_ret, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
sev->state = SEV_STATE_INIT;
|
||||
|
||||
/* Prepare for first SEV guest launch after INIT */
|
||||
wbinvd_on_all_cpus();
|
||||
rc = __sev_do_cmd_locked(SEV_CMD_DF_FLUSH, NULL, error);
|
||||
if (rc)
|
||||
rc = __sev_do_cmd_locked(SEV_CMD_DF_FLUSH, NULL, &dfflush_error);
|
||||
if (rc) {
|
||||
dev_err(sev->dev, "SEV: DF_FLUSH failed %#x, rc %d\n",
|
||||
dfflush_error, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dev_dbg(sev->dev, "SEV firmware initialized\n");
|
||||
|
||||
@ -1319,19 +1349,9 @@ static int _sev_platform_init_locked(struct sev_platform_init_args *args)
|
||||
if (sev->state == SEV_STATE_INIT)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Legacy guests cannot be running while SNP_INIT(_EX) is executing,
|
||||
* so perform SEV-SNP initialization at probe time.
|
||||
*/
|
||||
rc = __sev_snp_init_locked(&args->error);
|
||||
if (rc && rc != -ENODEV) {
|
||||
/*
|
||||
* Don't abort the probe if SNP INIT failed,
|
||||
* continue to initialize the legacy SEV firmware.
|
||||
*/
|
||||
dev_err(sev->dev, "SEV-SNP: failed to INIT rc %d, error %#x\n",
|
||||
rc, args->error);
|
||||
}
|
||||
if (rc && rc != -ENODEV)
|
||||
return rc;
|
||||
|
||||
/* Defer legacy SEV/SEV-ES support if allowed by caller/module. */
|
||||
if (args->probe && !psp_init_on_probe)
|
||||
@ -1367,8 +1387,11 @@ static int __sev_platform_shutdown_locked(int *error)
|
||||
return 0;
|
||||
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(sev->dev, "SEV: failed to SHUTDOWN error %#x, rc %d\n",
|
||||
*error, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sev->state = SEV_STATE_UNINIT;
|
||||
dev_dbg(sev->dev, "SEV firmware shutdown\n");
|
||||
@ -1389,6 +1412,37 @@ static int sev_get_platform_state(int *state, int *error)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sev_move_to_init_state(struct sev_issue_cmd *argp, bool *shutdown_required)
|
||||
{
|
||||
struct sev_platform_init_args init_args = {0};
|
||||
int rc;
|
||||
|
||||
rc = _sev_platform_init_locked(&init_args);
|
||||
if (rc) {
|
||||
argp->error = SEV_RET_INVALID_PLATFORM_STATE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
*shutdown_required = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snp_move_to_init_state(struct sev_issue_cmd *argp, bool *shutdown_required)
|
||||
{
|
||||
int error, rc;
|
||||
|
||||
rc = __sev_snp_init_locked(&error);
|
||||
if (rc) {
|
||||
argp->error = SEV_RET_INVALID_PLATFORM_STATE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
*shutdown_required = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sev_ioctl_do_reset(struct sev_issue_cmd *argp, bool writable)
|
||||
{
|
||||
int state, rc;
|
||||
@ -1441,24 +1495,31 @@ static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)
|
||||
static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp, bool writable)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
bool shutdown_required = false;
|
||||
int rc;
|
||||
|
||||
if (!writable)
|
||||
return -EPERM;
|
||||
|
||||
if (sev->state == SEV_STATE_UNINIT) {
|
||||
rc = __sev_platform_init_locked(&argp->error);
|
||||
rc = sev_move_to_init_state(argp, &shutdown_required);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return __sev_do_cmd_locked(cmd, NULL, &argp->error);
|
||||
rc = __sev_do_cmd_locked(cmd, NULL, &argp->error);
|
||||
|
||||
if (shutdown_required)
|
||||
__sev_firmware_shutdown(sev, false);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
struct sev_user_data_pek_csr input;
|
||||
bool shutdown_required = false;
|
||||
struct sev_data_pek_csr data;
|
||||
void __user *input_address;
|
||||
void *blob = NULL;
|
||||
@ -1490,7 +1551,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
|
||||
|
||||
cmd:
|
||||
if (sev->state == SEV_STATE_UNINIT) {
|
||||
ret = __sev_platform_init_locked(&argp->error);
|
||||
ret = sev_move_to_init_state(argp, &shutdown_required);
|
||||
if (ret)
|
||||
goto e_free_blob;
|
||||
}
|
||||
@ -1511,6 +1572,9 @@ cmd:
|
||||
}
|
||||
|
||||
e_free_blob:
|
||||
if (shutdown_required)
|
||||
__sev_firmware_shutdown(sev, false);
|
||||
|
||||
kfree(blob);
|
||||
return ret;
|
||||
}
|
||||
@ -1682,9 +1746,12 @@ static int __sev_snp_shutdown_locked(int *error, bool panic)
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_SNP_SHUTDOWN_EX, &data, error);
|
||||
/* SHUTDOWN may require DF_FLUSH */
|
||||
if (*error == SEV_RET_DFFLUSH_REQUIRED) {
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_SNP_DF_FLUSH, NULL, NULL);
|
||||
int dfflush_error = SEV_RET_NO_FW_CALL;
|
||||
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_SNP_DF_FLUSH, NULL, &dfflush_error);
|
||||
if (ret) {
|
||||
dev_err(sev->dev, "SEV-SNP DF_FLUSH failed\n");
|
||||
dev_err(sev->dev, "SEV-SNP DF_FLUSH failed, ret = %d, error = %#x\n",
|
||||
ret, dfflush_error);
|
||||
return ret;
|
||||
}
|
||||
/* reissue the shutdown command */
|
||||
@ -1692,7 +1759,8 @@ static int __sev_snp_shutdown_locked(int *error, bool panic)
|
||||
error);
|
||||
}
|
||||
if (ret) {
|
||||
dev_err(sev->dev, "SEV-SNP firmware shutdown failed\n");
|
||||
dev_err(sev->dev, "SEV-SNP firmware shutdown failed, rc %d, error %#x\n",
|
||||
ret, *error);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1718,6 +1786,18 @@ static int __sev_snp_shutdown_locked(int *error, bool panic)
|
||||
sev->snp_initialized = false;
|
||||
dev_dbg(sev->dev, "SEV-SNP firmware shutdown\n");
|
||||
|
||||
/*
|
||||
* __sev_snp_shutdown_locked() deadlocks when it tries to unregister
|
||||
* itself during panic as the panic notifier is called with RCU read
|
||||
* lock held and notifier unregistration does RCU synchronization.
|
||||
*/
|
||||
if (!panic)
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&snp_panic_notifier);
|
||||
|
||||
/* Reset TMR size back to default */
|
||||
sev_es_tmr_size = SEV_TMR_SIZE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1726,6 +1806,7 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
struct sev_user_data_pek_cert_import input;
|
||||
struct sev_data_pek_cert_import data;
|
||||
bool shutdown_required = false;
|
||||
void *pek_blob, *oca_blob;
|
||||
int ret;
|
||||
|
||||
@ -1756,7 +1837,7 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
|
||||
|
||||
/* If platform is not in INIT state then transition it to INIT */
|
||||
if (sev->state != SEV_STATE_INIT) {
|
||||
ret = __sev_platform_init_locked(&argp->error);
|
||||
ret = sev_move_to_init_state(argp, &shutdown_required);
|
||||
if (ret)
|
||||
goto e_free_oca;
|
||||
}
|
||||
@ -1764,6 +1845,9 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, &data, &argp->error);
|
||||
|
||||
e_free_oca:
|
||||
if (shutdown_required)
|
||||
__sev_firmware_shutdown(sev, false);
|
||||
|
||||
kfree(oca_blob);
|
||||
e_free_pek:
|
||||
kfree(pek_blob);
|
||||
@ -1880,18 +1964,9 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
|
||||
struct sev_data_pdh_cert_export data;
|
||||
void __user *input_cert_chain_address;
|
||||
void __user *input_pdh_cert_address;
|
||||
bool shutdown_required = false;
|
||||
int ret;
|
||||
|
||||
/* If platform is not in INIT state then transition it to INIT. */
|
||||
if (sev->state != SEV_STATE_INIT) {
|
||||
if (!writable)
|
||||
return -EPERM;
|
||||
|
||||
ret = __sev_platform_init_locked(&argp->error);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
|
||||
return -EFAULT;
|
||||
|
||||
@ -1931,6 +2006,17 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
|
||||
data.cert_chain_len = input.cert_chain_len;
|
||||
|
||||
cmd:
|
||||
/* If platform is not in INIT state then transition it to INIT. */
|
||||
if (sev->state != SEV_STATE_INIT) {
|
||||
if (!writable) {
|
||||
ret = -EPERM;
|
||||
goto e_free_cert;
|
||||
}
|
||||
ret = sev_move_to_init_state(argp, &shutdown_required);
|
||||
if (ret)
|
||||
goto e_free_cert;
|
||||
}
|
||||
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, &data, &argp->error);
|
||||
|
||||
/* If we query the length, FW responded with expected data. */
|
||||
@ -1957,6 +2043,9 @@ cmd:
|
||||
}
|
||||
|
||||
e_free_cert:
|
||||
if (shutdown_required)
|
||||
__sev_firmware_shutdown(sev, false);
|
||||
|
||||
kfree(cert_blob);
|
||||
e_free_pdh:
|
||||
kfree(pdh_blob);
|
||||
@ -1966,12 +2055,13 @@ e_free_pdh:
|
||||
static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
bool shutdown_required = false;
|
||||
struct sev_data_snp_addr buf;
|
||||
struct page *status_page;
|
||||
int ret, error;
|
||||
void *data;
|
||||
int ret;
|
||||
|
||||
if (!sev->snp_initialized || !argp->data)
|
||||
if (!argp->data)
|
||||
return -EINVAL;
|
||||
|
||||
status_page = alloc_page(GFP_KERNEL_ACCOUNT);
|
||||
@ -1980,6 +2070,12 @@ static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp)
|
||||
|
||||
data = page_address(status_page);
|
||||
|
||||
if (!sev->snp_initialized) {
|
||||
ret = snp_move_to_init_state(argp, &shutdown_required);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Firmware expects status page to be in firmware-owned state, otherwise
|
||||
* it will report firmware error code INVALID_PAGE_STATE (0x1A).
|
||||
@ -2008,6 +2104,9 @@ static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp)
|
||||
ret = -EFAULT;
|
||||
|
||||
cleanup:
|
||||
if (shutdown_required)
|
||||
__sev_snp_shutdown_locked(&error, false);
|
||||
|
||||
__free_pages(status_page, 0);
|
||||
return ret;
|
||||
}
|
||||
@ -2016,21 +2115,33 @@ static int sev_ioctl_do_snp_commit(struct sev_issue_cmd *argp)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
struct sev_data_snp_commit buf;
|
||||
bool shutdown_required = false;
|
||||
int ret, error;
|
||||
|
||||
if (!sev->snp_initialized)
|
||||
return -EINVAL;
|
||||
if (!sev->snp_initialized) {
|
||||
ret = snp_move_to_init_state(argp, &shutdown_required);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
buf.len = sizeof(buf);
|
||||
|
||||
return __sev_do_cmd_locked(SEV_CMD_SNP_COMMIT, &buf, &argp->error);
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_SNP_COMMIT, &buf, &argp->error);
|
||||
|
||||
if (shutdown_required)
|
||||
__sev_snp_shutdown_locked(&error, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sev_ioctl_do_snp_set_config(struct sev_issue_cmd *argp, bool writable)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
struct sev_user_data_snp_config config;
|
||||
bool shutdown_required = false;
|
||||
int ret, error;
|
||||
|
||||
if (!sev->snp_initialized || !argp->data)
|
||||
if (!argp->data)
|
||||
return -EINVAL;
|
||||
|
||||
if (!writable)
|
||||
@ -2039,17 +2150,29 @@ static int sev_ioctl_do_snp_set_config(struct sev_issue_cmd *argp, bool writable
|
||||
if (copy_from_user(&config, (void __user *)argp->data, sizeof(config)))
|
||||
return -EFAULT;
|
||||
|
||||
return __sev_do_cmd_locked(SEV_CMD_SNP_CONFIG, &config, &argp->error);
|
||||
if (!sev->snp_initialized) {
|
||||
ret = snp_move_to_init_state(argp, &shutdown_required);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_SNP_CONFIG, &config, &argp->error);
|
||||
|
||||
if (shutdown_required)
|
||||
__sev_snp_shutdown_locked(&error, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sev_ioctl_do_snp_vlek_load(struct sev_issue_cmd *argp, bool writable)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
struct sev_user_data_snp_vlek_load input;
|
||||
bool shutdown_required = false;
|
||||
int ret, error;
|
||||
void *blob;
|
||||
int ret;
|
||||
|
||||
if (!sev->snp_initialized || !argp->data)
|
||||
if (!argp->data)
|
||||
return -EINVAL;
|
||||
|
||||
if (!writable)
|
||||
@ -2068,8 +2191,18 @@ static int sev_ioctl_do_snp_vlek_load(struct sev_issue_cmd *argp, bool writable)
|
||||
|
||||
input.vlek_wrapped_address = __psp_pa(blob);
|
||||
|
||||
if (!sev->snp_initialized) {
|
||||
ret = snp_move_to_init_state(argp, &shutdown_required);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = __sev_do_cmd_locked(SEV_CMD_SNP_VLEK_LOAD, &input, &argp->error);
|
||||
|
||||
if (shutdown_required)
|
||||
__sev_snp_shutdown_locked(&error, false);
|
||||
|
||||
cleanup:
|
||||
kfree(blob);
|
||||
|
||||
return ret;
|
||||
@ -2296,7 +2429,7 @@ static void __sev_firmware_shutdown(struct sev_device *sev, bool panic)
|
||||
{
|
||||
int error;
|
||||
|
||||
__sev_platform_shutdown_locked(NULL);
|
||||
__sev_platform_shutdown_locked(&error);
|
||||
|
||||
if (sev_es_tmr) {
|
||||
/*
|
||||
@ -2339,6 +2472,15 @@ static void sev_firmware_shutdown(struct sev_device *sev)
|
||||
mutex_unlock(&sev_cmd_mutex);
|
||||
}
|
||||
|
||||
void sev_platform_shutdown(void)
|
||||
{
|
||||
if (!psp_master || !psp_master->sev_data)
|
||||
return;
|
||||
|
||||
sev_firmware_shutdown(psp_master->sev_data);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sev_platform_shutdown);
|
||||
|
||||
void sev_dev_destroy(struct psp_device *psp)
|
||||
{
|
||||
struct sev_device *sev = psp->sev_data;
|
||||
@ -2373,10 +2515,6 @@ static int snp_shutdown_on_panic(struct notifier_block *nb,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block snp_panic_notifier = {
|
||||
.notifier_call = snp_shutdown_on_panic,
|
||||
};
|
||||
|
||||
int sev_issue_cmd_external_user(struct file *filep, unsigned int cmd,
|
||||
void *data, int *error)
|
||||
{
|
||||
@ -2390,9 +2528,7 @@ EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user);
|
||||
void sev_pci_init(void)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
struct sev_platform_init_args args = {0};
|
||||
u8 api_major, api_minor, build;
|
||||
int rc;
|
||||
|
||||
if (!sev)
|
||||
return;
|
||||
@ -2415,18 +2551,6 @@ void sev_pci_init(void)
|
||||
api_major, api_minor, build,
|
||||
sev->api_major, sev->api_minor, sev->build);
|
||||
|
||||
/* Initialize the platform */
|
||||
args.probe = true;
|
||||
rc = sev_platform_init(&args);
|
||||
if (rc)
|
||||
dev_err(sev->dev, "SEV: failed to INIT error %#x, rc %d\n",
|
||||
args.error, rc);
|
||||
|
||||
dev_info(sev->dev, "SEV%s API:%d.%d build:%d\n", sev->snp_initialized ?
|
||||
"-SNP" : "", sev->api_major, sev->api_minor, sev->build);
|
||||
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&snp_panic_notifier);
|
||||
return;
|
||||
|
||||
err:
|
||||
@ -2443,7 +2567,4 @@ void sev_pci_exit(void)
|
||||
return;
|
||||
|
||||
sev_firmware_shutdown(sev);
|
||||
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&snp_panic_notifier);
|
||||
}
|
||||
|
||||
@ -421,7 +421,7 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
|
||||
fdno = get_unused_fd_flags(O_CLOEXEC);
|
||||
if (fdno < 0) {
|
||||
rc = fdno;
|
||||
goto out_fput;
|
||||
goto out_abort;
|
||||
}
|
||||
|
||||
cmd->out_fault_id = fault->obj.id;
|
||||
@ -437,8 +437,6 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
|
||||
return 0;
|
||||
out_put_fdno:
|
||||
put_unused_fd(fdno);
|
||||
out_fput:
|
||||
fput(filep);
|
||||
out_abort:
|
||||
iommufd_object_abort_and_destroy(ucmd->ictx, &fault->obj);
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "iommufd_test.h"
|
||||
|
||||
struct iommufd_object_ops {
|
||||
size_t file_offset;
|
||||
void (*destroy)(struct iommufd_object *obj);
|
||||
void (*abort)(struct iommufd_object *obj);
|
||||
};
|
||||
@ -71,10 +72,30 @@ void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj)
|
||||
void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx,
|
||||
struct iommufd_object *obj)
|
||||
{
|
||||
if (iommufd_object_ops[obj->type].abort)
|
||||
iommufd_object_ops[obj->type].abort(obj);
|
||||
const struct iommufd_object_ops *ops = &iommufd_object_ops[obj->type];
|
||||
|
||||
if (ops->file_offset) {
|
||||
struct file **filep = ((void *)obj) + ops->file_offset;
|
||||
|
||||
/*
|
||||
* A file should hold a users refcount while the file is open
|
||||
* and put it back in its release. The file should hold a
|
||||
* pointer to obj in their private data. Normal fput() is
|
||||
* deferred to a workqueue and can get out of order with the
|
||||
* following kfree(obj). Using the sync version ensures the
|
||||
* release happens immediately. During abort we require the file
|
||||
* refcount is one at this point - meaning the object alloc
|
||||
* function cannot do anything to allow another thread to take a
|
||||
* refcount prior to a guaranteed success.
|
||||
*/
|
||||
if (*filep)
|
||||
__fput_sync(*filep);
|
||||
}
|
||||
|
||||
if (ops->abort)
|
||||
ops->abort(obj);
|
||||
else
|
||||
iommufd_object_ops[obj->type].destroy(obj);
|
||||
ops->destroy(obj);
|
||||
iommufd_object_abort(ictx, obj);
|
||||
}
|
||||
|
||||
@ -481,6 +502,12 @@ void iommufd_ctx_put(struct iommufd_ctx *ictx)
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(iommufd_ctx_put, IOMMUFD);
|
||||
|
||||
#define IOMMUFD_FILE_OFFSET(_struct, _filep, _obj) \
|
||||
.file_offset = (offsetof(_struct, _filep) + \
|
||||
BUILD_BUG_ON_ZERO(!__same_type( \
|
||||
struct file *, ((_struct *)NULL)->_filep)) + \
|
||||
BUILD_BUG_ON_ZERO(offsetof(_struct, _obj)))
|
||||
|
||||
static const struct iommufd_object_ops iommufd_object_ops[] = {
|
||||
[IOMMUFD_OBJ_ACCESS] = {
|
||||
.destroy = iommufd_access_destroy_object,
|
||||
@ -490,6 +517,7 @@ static const struct iommufd_object_ops iommufd_object_ops[] = {
|
||||
},
|
||||
[IOMMUFD_OBJ_FAULT] = {
|
||||
.destroy = iommufd_fault_destroy,
|
||||
IOMMUFD_FILE_OFFSET(struct iommufd_fault, filep, obj),
|
||||
},
|
||||
[IOMMUFD_OBJ_HWPT_PAGING] = {
|
||||
.destroy = iommufd_hwpt_paging_destroy,
|
||||
|
||||
@ -934,10 +934,15 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
/* Check to see if link went down during discovery */
|
||||
if (lpfc_els_chk_latt(vport)) {
|
||||
/* One additional decrement on node reference count to
|
||||
* trigger the release of the node
|
||||
* trigger the release of the node. Make sure the ndlp
|
||||
* is marked NLP_DROPPED.
|
||||
*/
|
||||
if (!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD))
|
||||
if (!test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag) &&
|
||||
!test_bit(NLP_DROPPED, &ndlp->nlp_flag) &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) {
|
||||
set_bit(NLP_DROPPED, &ndlp->nlp_flag);
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -995,9 +1000,10 @@ stop_rr_fcf_flogi:
|
||||
IOERR_LOOP_OPEN_FAILURE)))
|
||||
lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,
|
||||
"2858 FLOGI Status:x%x/x%x TMO"
|
||||
":x%x Data x%lx x%x\n",
|
||||
":x%x Data x%lx x%x x%lx x%x\n",
|
||||
ulp_status, ulp_word4, tmo,
|
||||
phba->hba_flag, phba->fcf.fcf_flag);
|
||||
phba->hba_flag, phba->fcf.fcf_flag,
|
||||
ndlp->nlp_flag, ndlp->fc4_xpt_flags);
|
||||
|
||||
/* Check for retry */
|
||||
if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
|
||||
@ -1015,14 +1021,17 @@ stop_rr_fcf_flogi:
|
||||
* reference to trigger node release.
|
||||
*/
|
||||
if (!test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag) &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD))
|
||||
!test_bit(NLP_DROPPED, &ndlp->nlp_flag) &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) {
|
||||
set_bit(NLP_DROPPED, &ndlp->nlp_flag);
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
|
||||
"0150 FLOGI Status:x%x/x%x "
|
||||
"xri x%x TMO:x%x refcnt %d\n",
|
||||
"xri x%x iotag x%x TMO:x%x refcnt %d\n",
|
||||
ulp_status, ulp_word4, cmdiocb->sli4_xritag,
|
||||
tmo, kref_read(&ndlp->kref));
|
||||
cmdiocb->iotag, tmo, kref_read(&ndlp->kref));
|
||||
|
||||
/* If this is not a loop open failure, bail out */
|
||||
if (!(ulp_status == IOSTAT_LOCAL_REJECT &&
|
||||
@ -1279,6 +1288,19 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
uint32_t tmo, did;
|
||||
int rc;
|
||||
|
||||
/* It's possible for lpfc to reissue a FLOGI on an ndlp that is marked
|
||||
* NLP_DROPPED. This happens when the FLOGI completed with the XB bit
|
||||
* set causing lpfc to reference the ndlp until the XRI_ABORTED CQE is
|
||||
* issued. The time window for the XRI_ABORTED CQE can be as much as
|
||||
* 2*2*RA_TOV allowing for ndlp reuse of this type when the link is
|
||||
* cycling quickly. When true, restore the initial reference and remove
|
||||
* the NLP_DROPPED flag as lpfc is retrying.
|
||||
*/
|
||||
if (test_and_clear_bit(NLP_DROPPED, &ndlp->nlp_flag)) {
|
||||
if (!lpfc_nlp_get(ndlp))
|
||||
return 1;
|
||||
}
|
||||
|
||||
cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
||||
ndlp->nlp_DID, ELS_CMD_FLOGI);
|
||||
|
||||
@ -423,6 +423,7 @@ lpfc_check_nlp_post_devloss(struct lpfc_vport *vport,
|
||||
struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
if (test_and_clear_bit(NLP_IN_RECOV_POST_DEV_LOSS, &ndlp->save_flags)) {
|
||||
clear_bit(NLP_DROPPED, &ndlp->nlp_flag);
|
||||
lpfc_nlp_get(ndlp);
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY | LOG_NODE,
|
||||
"8438 Devloss timeout reversed on DID x%x "
|
||||
@ -565,7 +566,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
|
||||
return fcf_inuse;
|
||||
}
|
||||
|
||||
lpfc_nlp_put(ndlp);
|
||||
if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
lpfc_nlp_put(ndlp);
|
||||
return fcf_inuse;
|
||||
}
|
||||
|
||||
@ -6595,11 +6597,6 @@ lpfc_nlp_get(struct lpfc_nodelist *ndlp)
|
||||
unsigned long flags;
|
||||
|
||||
if (ndlp) {
|
||||
lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
|
||||
"node get: did:x%x flg:x%lx refcnt:x%x",
|
||||
ndlp->nlp_DID, ndlp->nlp_flag,
|
||||
kref_read(&ndlp->kref));
|
||||
|
||||
/* The check of ndlp usage to prevent incrementing the
|
||||
* ndlp reference count that is in the process of being
|
||||
* released.
|
||||
@ -6607,9 +6604,8 @@ lpfc_nlp_get(struct lpfc_nodelist *ndlp)
|
||||
spin_lock_irqsave(&ndlp->lock, flags);
|
||||
if (!kref_get_unless_zero(&ndlp->kref)) {
|
||||
spin_unlock_irqrestore(&ndlp->lock, flags);
|
||||
lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE,
|
||||
"0276 %s: ndlp:x%px refcnt:%d\n",
|
||||
__func__, (void *)ndlp, kref_read(&ndlp->kref));
|
||||
pr_info("0276 %s: NDLP has zero reference count. "
|
||||
"Exiting\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&ndlp->lock, flags);
|
||||
|
||||
@ -1978,6 +1978,11 @@ struct vfsmount *clone_private_mount(const struct path *path)
|
||||
if (!check_mnt(old_mnt))
|
||||
goto invalid;
|
||||
|
||||
if (!ns_capable(old_mnt->mnt_ns->user_ns, CAP_SYS_ADMIN)) {
|
||||
up_read(&namespace_sem);
|
||||
return ERR_PTR(-EPERM);
|
||||
}
|
||||
|
||||
if (has_locked_children(old_mnt, path->dentry))
|
||||
goto invalid;
|
||||
|
||||
|
||||
@ -954,6 +954,7 @@ int sev_do_cmd(int cmd, void *data, int *psp_ret);
|
||||
void *psp_copy_user_blob(u64 uaddr, u32 len);
|
||||
void *snp_alloc_firmware_page(gfp_t mask);
|
||||
void snp_free_firmware_page(void *addr);
|
||||
void sev_platform_shutdown(void);
|
||||
|
||||
#else /* !CONFIG_CRYPTO_DEV_SP_PSP */
|
||||
|
||||
@ -988,6 +989,8 @@ static inline void *snp_alloc_firmware_page(gfp_t mask)
|
||||
|
||||
static inline void snp_free_firmware_page(void *addr) { }
|
||||
|
||||
static inline void sev_platform_shutdown(void) { }
|
||||
|
||||
#endif /* CONFIG_CRYPTO_DEV_SP_PSP */
|
||||
|
||||
#endif /* __PSP_SEV_H__ */
|
||||
|
||||
@ -1632,8 +1632,10 @@ static int tls_decrypt_sg(struct sock *sk, struct iov_iter *out_iov,
|
||||
|
||||
if (unlikely(darg->async)) {
|
||||
err = tls_strp_msg_hold(&ctx->strp, &ctx->async_hold);
|
||||
if (err)
|
||||
__skb_queue_tail(&ctx->async_hold, darg->skb);
|
||||
if (err) {
|
||||
err = tls_decrypt_async_wait(ctx);
|
||||
darg->async = false;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,30 @@
|
||||
* Sun Dec 07 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-611.16.1.el9_7]
|
||||
- CVE-2025-38499 kernel: clone_private_mnt(): make sure that caller has CAP_SYS_ADMIN in the right userns (Abhi Das) [RHEL-129261] {CVE-2025-38499}
|
||||
- tls: wait for pending async decryptions if tls_strp_msg_hold fails (CKI Backport Bot) [RHEL-128860] {CVE-2025-40176}
|
||||
Resolves: RHEL-128860, RHEL-129261
|
||||
|
||||
* Thu Dec 04 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-611.15.1.el9_7]
|
||||
- nbd: override creds to kernel when calling sock_{send,recv}msg() (Ming Lei) [RHEL-123845]
|
||||
- scsi: lpfc: avoid crashing in lpfc_nlp_get() if lpfc_nodelist was freed (Ewan D. Milne) [RHEL-127982]
|
||||
- scsi: lpfc: Fix reusing an ndlp that is marked NLP_DROPPED during FLOGI (Ewan D. Milne) [RHEL-127982]
|
||||
- crypto: ccp - Always pass in an error pointer to __sev_platform_shutdown_locked() (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Fix SNP panic notifier unregistration (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Fix dereferencing uninitialized error pointer (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Fix __sev_snp_shutdown_locked (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Move SEV/SNP Platform initialization to KVM (Lenny Szubowicz) [RHEL-70006]
|
||||
- KVM: SVM: Add support to initialize SEV/SNP functionality in KVM (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Add new SEV/SNP platform shutdown API (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Register SNP panic notifier only if SNP is enabled (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Reset TMR size at SNP Shutdown (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Ensure implicit SEV/SNP init and shutdown in ioctls (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Move dev_info/err messages for SEV/SNP init and shutdown (Lenny Szubowicz) [RHEL-70006]
|
||||
- crypto: ccp - Abort doing SEV INIT if SNP INIT fails (Lenny Szubowicz) [RHEL-70006]
|
||||
Resolves: RHEL-123845, RHEL-127982, RHEL-70006
|
||||
|
||||
* Tue Dec 02 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-611.14.1.el9_7]
|
||||
- iommufd: Fix race during abort for file descriptors (Eder Zulian) [RHEL-123786] {CVE-2025-39966}
|
||||
Resolves: RHEL-123786
|
||||
|
||||
* Sat Nov 29 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-611.13.1.el9_7]
|
||||
- can: j1939: add missing calls in NETDEV_UNREGISTER notification handler (CKI Backport Bot) [RHEL-124105] {CVE-2025-39925}
|
||||
- can: j1939: implement NETDEV_UNREGISTER notification handler (CKI Backport Bot) [RHEL-124105] {CVE-2025-39925}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user