mirror of https://github.com/torvalds/linux.git
Misc x86 fixes:
- Add more model IDs to the AMD microcode version check,
more people are hitting these checks
- Fix a Xen guest boot warning related to AMD northbridge
setup
- Fix SEV guest bugs related to a recent changes in its
locking logic
- Fix a missing definition of PTRS_PER_PMD that assembly
builds can hit
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-----BEGIN PGP SIGNATURE-----
iQJEBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmfMmE0RHG1pbmdvQGtl
cm5lbC5vcmcACgkQEnMQ0APhK1jIyg/3Vrny4hGJEVyDgCVP/KNnecMikBeNcWI0
yFAd5kkU2Kd32JadXJQSvIvCFmnS+mvfqY9wXKZp1/lQCpgsaFQvRFv9z0eFKND0
8GnDwa3SrTsOtYcvsJRFW5WmGkmmytaUqxWPsfIa7oo4TB/7u2OgqI/vdJrr9/nw
HbRBGJL5DAgfzTUxXp8dNJX0Nhz8Nz65pmCSbiCW4YtCd5oPuy0/Ezf26okBxS2k
mRsqJSwUsW304j4r42ov/itVY8bbe1Nxbvyly9eTL3wunuDsRDu+GOJ8pRbdKhyb
JNqHkGwQLNzxkmC7/QG5tQhqachxDT0xrC3rUrUuJsqzfmQMOnrWRiSodiILP3Ly
kpWy1R0KUu5njizf/Kzk5swz9QIiTZIUL22iqvI6CzbDU27FdbQ5cK17GvA99Rda
b5S6gKMXdzklOUjjHBbucBSORK872S+RRZbUuIsw4hbiZqeEApfVUD3FimEUeD7i
et1VacE4smRIplEiHIRI4T7O2VLoO7G05YCNUyTFSWcGIfua1EWMIoVc4iIUA0Aj
+y7yA/j9k9eGxzd+WPcmzh5NRPkixrkRscAzI6Y/gtA1bUthi9GmLgTQlLBW5eLD
ysNOD0XSVXs2j76lvb4hB+5S2PPBX1Zh5TEHsG+N5949ZZGjfzjn+kceoG4vJLCb
wwCfHnIFXA==
=kZCC
-----END PGP SIGNATURE-----
Merge tag 'x86-urgent-2025-03-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull more x86 fixes from Ingo Molnar:
- Add more model IDs to the AMD microcode version check, more people
are hitting these checks
- Fix a Xen guest boot warning related to AMD northbridge setup
- Fix SEV guest bugs related to a recent changes in its locking logic
- Fix a missing definition of PTRS_PER_PMD that assembly builds can hit
* tag 'x86-urgent-2025-03-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/microcode/AMD: Add some forgotten models to the SHA check
x86/mm: Define PTRS_PER_PMD for assembly code too
virt: sev-guest: Move SNP Guest Request data pages handling under snp_cmd_mutex
virt: sev-guest: Allocate request data dynamically
x86/amd_nb: Use rdmsr_safe() in amd_get_mmconfig_range()
This commit is contained in:
commit
b7c90e3e71
|
|
@ -2853,19 +2853,8 @@ struct snp_msg_desc *snp_msg_alloc(void)
|
||||||
if (!mdesc->response)
|
if (!mdesc->response)
|
||||||
goto e_free_request;
|
goto e_free_request;
|
||||||
|
|
||||||
mdesc->certs_data = alloc_shared_pages(SEV_FW_BLOB_MAX_SIZE);
|
|
||||||
if (!mdesc->certs_data)
|
|
||||||
goto e_free_response;
|
|
||||||
|
|
||||||
/* initial the input address for guest request */
|
|
||||||
mdesc->input.req_gpa = __pa(mdesc->request);
|
|
||||||
mdesc->input.resp_gpa = __pa(mdesc->response);
|
|
||||||
mdesc->input.data_gpa = __pa(mdesc->certs_data);
|
|
||||||
|
|
||||||
return mdesc;
|
return mdesc;
|
||||||
|
|
||||||
e_free_response:
|
|
||||||
free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg));
|
|
||||||
e_free_request:
|
e_free_request:
|
||||||
free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg));
|
free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg));
|
||||||
e_unmap:
|
e_unmap:
|
||||||
|
|
@ -2885,7 +2874,6 @@ void snp_msg_free(struct snp_msg_desc *mdesc)
|
||||||
kfree(mdesc->ctx);
|
kfree(mdesc->ctx);
|
||||||
free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg));
|
free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg));
|
||||||
free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg));
|
free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg));
|
||||||
free_shared_pages(mdesc->certs_data, SEV_FW_BLOB_MAX_SIZE);
|
|
||||||
iounmap((__force void __iomem *)mdesc->secrets);
|
iounmap((__force void __iomem *)mdesc->secrets);
|
||||||
|
|
||||||
memset(mdesc, 0, sizeof(*mdesc));
|
memset(mdesc, 0, sizeof(*mdesc));
|
||||||
|
|
@ -3054,7 +3042,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
|
||||||
* sequence number must be incremented or the VMPCK must be deleted to
|
* sequence number must be incremented or the VMPCK must be deleted to
|
||||||
* prevent reuse of the IV.
|
* prevent reuse of the IV.
|
||||||
*/
|
*/
|
||||||
rc = snp_issue_guest_request(req, &mdesc->input, rio);
|
rc = snp_issue_guest_request(req, &req->input, rio);
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case -ENOSPC:
|
case -ENOSPC:
|
||||||
/*
|
/*
|
||||||
|
|
@ -3064,7 +3052,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
|
||||||
* order to increment the sequence number and thus avoid
|
* order to increment the sequence number and thus avoid
|
||||||
* IV reuse.
|
* IV reuse.
|
||||||
*/
|
*/
|
||||||
override_npages = mdesc->input.data_npages;
|
override_npages = req->input.data_npages;
|
||||||
req->exit_code = SVM_VMGEXIT_GUEST_REQUEST;
|
req->exit_code = SVM_VMGEXIT_GUEST_REQUEST;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -3120,7 +3108,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
|
||||||
}
|
}
|
||||||
|
|
||||||
if (override_npages)
|
if (override_npages)
|
||||||
mdesc->input.data_npages = override_npages;
|
req->input.data_npages = override_npages;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -3158,6 +3146,11 @@ int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req
|
||||||
*/
|
*/
|
||||||
memcpy(mdesc->request, &mdesc->secret_request, sizeof(mdesc->secret_request));
|
memcpy(mdesc->request, &mdesc->secret_request, sizeof(mdesc->secret_request));
|
||||||
|
|
||||||
|
/* Initialize the input address for guest request */
|
||||||
|
req->input.req_gpa = __pa(mdesc->request);
|
||||||
|
req->input.resp_gpa = __pa(mdesc->response);
|
||||||
|
req->input.data_gpa = req->certs_data ? __pa(req->certs_data) : 0;
|
||||||
|
|
||||||
rc = __handle_guest_request(mdesc, req, rio);
|
rc = __handle_guest_request(mdesc, req, rio);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (rc == -EIO &&
|
if (rc == -EIO &&
|
||||||
|
|
|
||||||
|
|
@ -23,17 +23,17 @@ typedef union {
|
||||||
#define ARCH_PAGE_TABLE_SYNC_MASK PGTBL_PMD_MODIFIED
|
#define ARCH_PAGE_TABLE_SYNC_MASK PGTBL_PMD_MODIFIED
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* traditional i386 two-level paging structure:
|
* Traditional i386 two-level paging structure:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PGDIR_SHIFT 22
|
#define PGDIR_SHIFT 22
|
||||||
#define PTRS_PER_PGD 1024
|
#define PTRS_PER_PGD 1024
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the i386 is two-level, so we don't really have any
|
* The i386 is two-level, so we don't really have any
|
||||||
* PMD directory physically.
|
* PMD directory physically:
|
||||||
*/
|
*/
|
||||||
|
#define PTRS_PER_PMD 1
|
||||||
|
|
||||||
#define PTRS_PER_PTE 1024
|
#define PTRS_PER_PTE 1024
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,9 @@ struct snp_guest_req {
|
||||||
unsigned int vmpck_id;
|
unsigned int vmpck_id;
|
||||||
u8 msg_version;
|
u8 msg_version;
|
||||||
u8 msg_type;
|
u8 msg_type;
|
||||||
|
|
||||||
|
struct snp_req_data input;
|
||||||
|
void *certs_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -263,9 +266,6 @@ struct snp_msg_desc {
|
||||||
struct snp_guest_msg secret_request, secret_response;
|
struct snp_guest_msg secret_request, secret_response;
|
||||||
|
|
||||||
struct snp_secrets_page *secrets;
|
struct snp_secrets_page *secrets;
|
||||||
struct snp_req_data input;
|
|
||||||
|
|
||||||
void *certs_data;
|
|
||||||
|
|
||||||
struct aesgcm_ctx *ctx;
|
struct aesgcm_ctx *ctx;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,6 @@ bool __init early_is_amd_nb(u32 device)
|
||||||
|
|
||||||
struct resource *amd_get_mmconfig_range(struct resource *res)
|
struct resource *amd_get_mmconfig_range(struct resource *res)
|
||||||
{
|
{
|
||||||
u32 address;
|
|
||||||
u64 base, msr;
|
u64 base, msr;
|
||||||
unsigned int segn_busn_bits;
|
unsigned int segn_busn_bits;
|
||||||
|
|
||||||
|
|
@ -151,13 +150,11 @@ struct resource *amd_get_mmconfig_range(struct resource *res)
|
||||||
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
|
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* assume all cpus from fam10h have mmconfig */
|
/* Assume CPUs from Fam10h have mmconfig, although not all VMs do */
|
||||||
if (boot_cpu_data.x86 < 0x10)
|
if (boot_cpu_data.x86 < 0x10 ||
|
||||||
|
rdmsrl_safe(MSR_FAM10H_MMIO_CONF_BASE, &msr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
address = MSR_FAM10H_MMIO_CONF_BASE;
|
|
||||||
rdmsrl(address, msr);
|
|
||||||
|
|
||||||
/* mmconfig is not enabled */
|
/* mmconfig is not enabled */
|
||||||
if (!(msr & FAM10H_MMIO_CONF_ENABLE))
|
if (!(msr & FAM10H_MMIO_CONF_ENABLE))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -175,23 +175,29 @@ static bool need_sha_check(u32 cur_rev)
|
||||||
{
|
{
|
||||||
switch (cur_rev >> 8) {
|
switch (cur_rev >> 8) {
|
||||||
case 0x80012: return cur_rev <= 0x800126f; break;
|
case 0x80012: return cur_rev <= 0x800126f; break;
|
||||||
|
case 0x80082: return cur_rev <= 0x800820f; break;
|
||||||
case 0x83010: return cur_rev <= 0x830107c; break;
|
case 0x83010: return cur_rev <= 0x830107c; break;
|
||||||
case 0x86001: return cur_rev <= 0x860010e; break;
|
case 0x86001: return cur_rev <= 0x860010e; break;
|
||||||
case 0x86081: return cur_rev <= 0x8608108; break;
|
case 0x86081: return cur_rev <= 0x8608108; break;
|
||||||
case 0x87010: return cur_rev <= 0x8701034; break;
|
case 0x87010: return cur_rev <= 0x8701034; break;
|
||||||
case 0x8a000: return cur_rev <= 0x8a0000a; break;
|
case 0x8a000: return cur_rev <= 0x8a0000a; break;
|
||||||
|
case 0xa0010: return cur_rev <= 0xa00107a; break;
|
||||||
case 0xa0011: return cur_rev <= 0xa0011da; break;
|
case 0xa0011: return cur_rev <= 0xa0011da; break;
|
||||||
case 0xa0012: return cur_rev <= 0xa001243; break;
|
case 0xa0012: return cur_rev <= 0xa001243; break;
|
||||||
|
case 0xa0082: return cur_rev <= 0xa00820e; break;
|
||||||
case 0xa1011: return cur_rev <= 0xa101153; break;
|
case 0xa1011: return cur_rev <= 0xa101153; break;
|
||||||
case 0xa1012: return cur_rev <= 0xa10124e; break;
|
case 0xa1012: return cur_rev <= 0xa10124e; break;
|
||||||
case 0xa1081: return cur_rev <= 0xa108109; break;
|
case 0xa1081: return cur_rev <= 0xa108109; break;
|
||||||
case 0xa2010: return cur_rev <= 0xa20102f; break;
|
case 0xa2010: return cur_rev <= 0xa20102f; break;
|
||||||
case 0xa2012: return cur_rev <= 0xa201212; break;
|
case 0xa2012: return cur_rev <= 0xa201212; break;
|
||||||
|
case 0xa4041: return cur_rev <= 0xa404109; break;
|
||||||
|
case 0xa5000: return cur_rev <= 0xa500013; break;
|
||||||
case 0xa6012: return cur_rev <= 0xa60120a; break;
|
case 0xa6012: return cur_rev <= 0xa60120a; break;
|
||||||
case 0xa7041: return cur_rev <= 0xa704109; break;
|
case 0xa7041: return cur_rev <= 0xa704109; break;
|
||||||
case 0xa7052: return cur_rev <= 0xa705208; break;
|
case 0xa7052: return cur_rev <= 0xa705208; break;
|
||||||
case 0xa7080: return cur_rev <= 0xa708009; break;
|
case 0xa7080: return cur_rev <= 0xa708009; break;
|
||||||
case 0xa70c0: return cur_rev <= 0xa70C009; break;
|
case 0xa70c0: return cur_rev <= 0xa70C009; break;
|
||||||
|
case 0xaa001: return cur_rev <= 0xaa00116; break;
|
||||||
case 0xaa002: return cur_rev <= 0xaa00218; break;
|
case 0xaa002: return cur_rev <= 0xaa00218; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,6 @@ struct snp_guest_dev {
|
||||||
struct miscdevice misc;
|
struct miscdevice misc;
|
||||||
|
|
||||||
struct snp_msg_desc *msg_desc;
|
struct snp_msg_desc *msg_desc;
|
||||||
|
|
||||||
union {
|
|
||||||
struct snp_report_req report;
|
|
||||||
struct snp_derived_key_req derived_key;
|
|
||||||
struct snp_ext_report_req ext_report;
|
|
||||||
} req;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -71,7 +65,7 @@ struct snp_req_resp {
|
||||||
|
|
||||||
static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
|
static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
|
||||||
{
|
{
|
||||||
struct snp_report_req *report_req = &snp_dev->req.report;
|
struct snp_report_req *report_req __free(kfree) = NULL;
|
||||||
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
|
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
|
||||||
struct snp_report_resp *report_resp;
|
struct snp_report_resp *report_resp;
|
||||||
struct snp_guest_req req = {};
|
struct snp_guest_req req = {};
|
||||||
|
|
@ -80,6 +74,10 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
|
||||||
if (!arg->req_data || !arg->resp_data)
|
if (!arg->req_data || !arg->resp_data)
|
||||||
return -EINVAL;
|
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)))
|
if (copy_from_user(report_req, (void __user *)arg->req_data, sizeof(*report_req)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
|
@ -116,7 +114,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
|
||||||
|
|
||||||
static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
|
static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
|
||||||
{
|
{
|
||||||
struct snp_derived_key_req *derived_key_req = &snp_dev->req.derived_key;
|
struct snp_derived_key_req *derived_key_req __free(kfree) = NULL;
|
||||||
struct snp_derived_key_resp derived_key_resp = {0};
|
struct snp_derived_key_resp derived_key_resp = {0};
|
||||||
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
|
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
|
||||||
struct snp_guest_req req = {};
|
struct snp_guest_req req = {};
|
||||||
|
|
@ -136,6 +134,10 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
|
||||||
if (sizeof(buf) < resp_len)
|
if (sizeof(buf) < resp_len)
|
||||||
return -ENOMEM;
|
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,
|
if (copy_from_user(derived_key_req, (void __user *)arg->req_data,
|
||||||
sizeof(*derived_key_req)))
|
sizeof(*derived_key_req)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
@ -168,16 +170,21 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
|
||||||
struct snp_req_resp *io)
|
struct snp_req_resp *io)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct snp_ext_report_req *report_req = &snp_dev->req.ext_report;
|
struct snp_ext_report_req *report_req __free(kfree) = NULL;
|
||||||
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
|
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
|
||||||
struct snp_report_resp *report_resp;
|
struct snp_report_resp *report_resp;
|
||||||
struct snp_guest_req req = {};
|
struct snp_guest_req req = {};
|
||||||
int ret, npages = 0, resp_len;
|
int ret, npages = 0, resp_len;
|
||||||
sockptr_t certs_address;
|
sockptr_t certs_address;
|
||||||
|
struct page *page;
|
||||||
|
|
||||||
if (sockptr_is_null(io->req_data) || sockptr_is_null(io->resp_data))
|
if (sockptr_is_null(io->req_data) || sockptr_is_null(io->resp_data))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
report_req = kzalloc(sizeof(*report_req), GFP_KERNEL_ACCOUNT);
|
||||||
|
if (!report_req)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
if (copy_from_sockptr(report_req, io->req_data, sizeof(*report_req)))
|
if (copy_from_sockptr(report_req, io->req_data, sizeof(*report_req)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
|
@ -203,8 +210,20 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
|
||||||
* the host. If host does not supply any certs in it, then copy
|
* the host. If host does not supply any certs in it, then copy
|
||||||
* zeros to indicate that certificate data was not provided.
|
* zeros to indicate that certificate data was not provided.
|
||||||
*/
|
*/
|
||||||
memset(mdesc->certs_data, 0, report_req->certs_len);
|
|
||||||
npages = report_req->certs_len >> PAGE_SHIFT;
|
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((unsigned long)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:
|
cmd:
|
||||||
/*
|
/*
|
||||||
* The intermediate response buffer is used while decrypting the
|
* The intermediate response buffer is used while decrypting the
|
||||||
|
|
@ -213,10 +232,12 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
|
||||||
*/
|
*/
|
||||||
resp_len = sizeof(report_resp->data) + mdesc->ctx->authsize;
|
resp_len = sizeof(report_resp->data) + mdesc->ctx->authsize;
|
||||||
report_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT);
|
report_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT);
|
||||||
if (!report_resp)
|
if (!report_resp) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto e_free_data;
|
||||||
|
}
|
||||||
|
|
||||||
mdesc->input.data_npages = npages;
|
req.input.data_npages = npages;
|
||||||
|
|
||||||
req.msg_version = arg->msg_version;
|
req.msg_version = arg->msg_version;
|
||||||
req.msg_type = SNP_MSG_REPORT_REQ;
|
req.msg_type = SNP_MSG_REPORT_REQ;
|
||||||
|
|
@ -231,7 +252,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
|
||||||
|
|
||||||
/* If certs length is invalid then copy the returned length */
|
/* If certs length is invalid then copy the returned length */
|
||||||
if (arg->vmm_error == SNP_GUEST_VMM_ERR_INVALID_LEN) {
|
if (arg->vmm_error == SNP_GUEST_VMM_ERR_INVALID_LEN) {
|
||||||
report_req->certs_len = mdesc->input.data_npages << PAGE_SHIFT;
|
report_req->certs_len = req.input.data_npages << PAGE_SHIFT;
|
||||||
|
|
||||||
if (copy_to_sockptr(io->req_data, report_req, sizeof(*report_req)))
|
if (copy_to_sockptr(io->req_data, report_req, sizeof(*report_req)))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
|
|
@ -240,7 +261,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
|
||||||
if (ret)
|
if (ret)
|
||||||
goto e_free;
|
goto e_free;
|
||||||
|
|
||||||
if (npages && copy_to_sockptr(certs_address, mdesc->certs_data, report_req->certs_len)) {
|
if (npages && copy_to_sockptr(certs_address, req.certs_data, report_req->certs_len)) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto e_free;
|
goto e_free;
|
||||||
}
|
}
|
||||||
|
|
@ -250,6 +271,13 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
|
||||||
|
|
||||||
e_free:
|
e_free:
|
||||||
kfree(report_resp);
|
kfree(report_resp);
|
||||||
|
e_free_data:
|
||||||
|
if (npages) {
|
||||||
|
if (set_memory_encrypted((unsigned long)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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue