/* * The VMPCK ID represents the key used by the SNP guest to communicate with the * SEV firmware in the AMD Secure Processor (ASP, aka PSP). By default, the key * used will be the key associated with the VMPL at which the guest is running. * Should the default key be wiped (see snp_disable_vmpck()), this parameter * allows for using one of the remaining VMPCKs.
*/ staticint vmpck_id = -1;
module_param(vmpck_id, int, 0444);
MODULE_PARM_DESC(vmpck_id, "The VMPCK ID to use when communicating with the PSP.");
if (!arg->req_data || !arg->resp_data) return -EINVAL;
report_req = kzalloc(sizeof(*report_req), GFP_KERNEL_ACCOUNT); if (!report_req) return -ENOMEM;
if (copy_from_user(report_req, (void __user *)arg->req_data, sizeof(*report_req))) return -EFAULT;
/* * The intermediate response buffer is used while decrypting the * response payload. Make sure that it has enough space to cover the * authtag.
*/
resp_len = sizeof(report_resp->data) + mdesc->ctx->authsize;
report_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT); if (!report_resp) return -ENOMEM;
if (!arg->req_data || !arg->resp_data) return -EINVAL;
/* * The intermediate response buffer is used while decrypting the * response payload. Make sure that it has enough space to cover the * authtag.
*/
resp_len = sizeof(derived_key_resp->data) + mdesc->ctx->authsize;
derived_key_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT); if (!derived_key_resp) return -ENOMEM;
derived_key_req = kzalloc(sizeof(*derived_key_req), GFP_KERNEL_ACCOUNT); if (!derived_key_req) return -ENOMEM;
if (copy_from_user(derived_key_req, (void __user *)arg->req_data, sizeof(*derived_key_req))) return -EFAULT;
/* * Initialize the intermediate buffer with all zeros. This buffer * is used in the guest request message to get the certs blob from * the host. If host does not supply any certs in it, then copy * zeros to indicate that certificate data was not provided.
*/
npages = report_req->certs_len >> PAGE_SHIFT;
page = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_ZERO,
get_order(report_req->certs_len)); if (!page) return -ENOMEM;
req.certs_data = page_address(page);
ret = set_memory_decrypted((unsignedlong)req.certs_data, npages); if (ret) {
pr_err("failed to mark page shared, ret=%d\n", ret);
__free_pages(page, get_order(report_req->certs_len)); return -EFAULT;
}
cmd: /* * The intermediate response buffer is used while decrypting the * response payload. Make sure that it has enough space to cover the * authtag.
*/
resp_len = sizeof(report_resp->data) + mdesc->ctx->authsize;
report_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT); if (!report_resp) {
ret = -ENOMEM; goto e_free_data;
}
ret = snp_send_guest_request(mdesc, &req);
arg->exitinfo2 = req.exitinfo2;
/* If certs length is invalid then copy the returned length */ if (arg->vmm_error == SNP_GUEST_VMM_ERR_INVALID_LEN) {
report_req->certs_len = req.input.data_npages << PAGE_SHIFT;
if (copy_to_sockptr(io->req_data, report_req, sizeof(*report_req)))
ret = -EFAULT;
}
if (ret) goto e_free;
if (npages && copy_to_sockptr(certs_address, req.certs_data, report_req->certs_len)) {
ret = -EFAULT; goto e_free;
}
if (copy_to_sockptr(io->resp_data, report_resp, sizeof(*report_resp)))
ret = -EFAULT;
e_free:
kfree(report_resp);
e_free_data: if (npages) { if (set_memory_encrypted((unsignedlong)req.certs_data, npages))
WARN_ONCE(ret, "failed to restore encryption mask (leak it)\n"); else
__free_pages(page, get_order(report_req->certs_len));
} return ret;
}
if (copy_from_user(&input, argp, sizeof(input))) return -EFAULT;
input.exitinfo2 = 0xff;
/* Message version must be non-zero */ if (!input.msg_version) return -EINVAL;
switch (ioctl) { case SNP_GET_REPORT:
ret = get_report(snp_dev, &input); break; case SNP_GET_DERIVED_KEY:
ret = get_derived_key(snp_dev, &input); break; case SNP_GET_EXT_REPORT: /* * As get_ext_report() may be called from the ioctl() path and a * kernel internal path (configfs-tsm), decorate the passed * buffers as user pointers.
*/
io.req_data = USER_SOCKPTR((void __user *)input.req_data);
io.resp_data = USER_SOCKPTR((void __user *)input.resp_data);
ret = get_ext_report(snp_dev, &input, &io); break; default: break;
}
if (input.exitinfo2 && copy_to_user(argp, &input, sizeof(input))) return -EFAULT;
/* * Allocate all the blob memory buffers at once so that the cleanup is * done for errors that occur after the first allocation (i.e. before * using no_free_ptr()).
*/
rep_len = ac.report_buf.len; void *rbuf __free(kvfree) = kvzalloc(rep_len, GFP_KERNEL);
/* Suspicious that the response populated entries without populating size */ if (!certs_size && i)
dev_warn_ratelimited(snp_dev->dev, "certificate slots conveyed without size\n");
/* No certs to report */ if (!certs_size) return 0;
/* Suspicious that the certificate blob size contract was violated
*/ if (certs_size > ext_size) {
dev_warn_ratelimited(snp_dev->dev, "certificate data truncated\n");
certs_size = ext_size;
}
void *cbuf __free(kvfree) = kvzalloc(certs_size, GFP_KERNEL); if (!cbuf) return -ENOMEM;
staticbool sev_report_attr_visible(int n)
{ switch (n) { case TSM_REPORT_GENERATION: case TSM_REPORT_PROVIDER: case TSM_REPORT_PRIVLEVEL: case TSM_REPORT_PRIVLEVEL_FLOOR: returntrue; case TSM_REPORT_SERVICE_PROVIDER: case TSM_REPORT_SERVICE_GUID: case TSM_REPORT_SERVICE_MANIFEST_VER: return snp_vmpl;
}
returnfalse;
}
staticbool sev_report_bin_attr_visible(int n)
{ switch (n) { case TSM_REPORT_INBLOB: case TSM_REPORT_OUTBLOB: case TSM_REPORT_AUXBLOB: returntrue; case TSM_REPORT_MANIFESTBLOB: return snp_vmpl;
}
/* * This driver is meant to be a common SEV guest interface driver and to * support any SEV guest API. As such, even though it has been introduced * with the SEV-SNP support, it is named "sev-guest". * * sev_guest_remove() lives in .exit.text. For drivers registered via * module_platform_driver_probe() this is ok because they cannot get unbound * at runtime. So mark the driver struct with __refdata to prevent modpost * triggering a section mismatch warning.
*/ staticstruct platform_driver sev_guest_driver __refdata = {
.remove = __exit_p(sev_guest_remove),
.driver = {
.name = "sev-guest",
},
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.