Skip to content

Commit b7c90e3

Browse files
committed
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()
2 parents 2e51e0a + 058a6be commit b7c90e3

File tree

6 files changed

+67
-43
lines changed

6 files changed

+67
-43
lines changed

arch/x86/coco/sev/core.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,19 +2853,8 @@ struct snp_msg_desc *snp_msg_alloc(void)
28532853
if (!mdesc->response)
28542854
goto e_free_request;
28552855

2856-
mdesc->certs_data = alloc_shared_pages(SEV_FW_BLOB_MAX_SIZE);
2857-
if (!mdesc->certs_data)
2858-
goto e_free_response;
2859-
2860-
/* initial the input address for guest request */
2861-
mdesc->input.req_gpa = __pa(mdesc->request);
2862-
mdesc->input.resp_gpa = __pa(mdesc->response);
2863-
mdesc->input.data_gpa = __pa(mdesc->certs_data);
2864-
28652856
return mdesc;
28662857

2867-
e_free_response:
2868-
free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg));
28692858
e_free_request:
28702859
free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg));
28712860
e_unmap:
@@ -2885,7 +2874,6 @@ void snp_msg_free(struct snp_msg_desc *mdesc)
28852874
kfree(mdesc->ctx);
28862875
free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg));
28872876
free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg));
2888-
free_shared_pages(mdesc->certs_data, SEV_FW_BLOB_MAX_SIZE);
28892877
iounmap((__force void __iomem *)mdesc->secrets);
28902878

28912879
memset(mdesc, 0, sizeof(*mdesc));
@@ -3054,7 +3042,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
30543042
* sequence number must be incremented or the VMPCK must be deleted to
30553043
* prevent reuse of the IV.
30563044
*/
3057-
rc = snp_issue_guest_request(req, &mdesc->input, rio);
3045+
rc = snp_issue_guest_request(req, &req->input, rio);
30583046
switch (rc) {
30593047
case -ENOSPC:
30603048
/*
@@ -3064,7 +3052,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
30643052
* order to increment the sequence number and thus avoid
30653053
* IV reuse.
30663054
*/
3067-
override_npages = mdesc->input.data_npages;
3055+
override_npages = req->input.data_npages;
30683056
req->exit_code = SVM_VMGEXIT_GUEST_REQUEST;
30693057

30703058
/*
@@ -3120,7 +3108,7 @@ static int __handle_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_r
31203108
}
31213109

31223110
if (override_npages)
3123-
mdesc->input.data_npages = override_npages;
3111+
req->input.data_npages = override_npages;
31243112

31253113
return rc;
31263114
}
@@ -3158,6 +3146,11 @@ int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req
31583146
*/
31593147
memcpy(mdesc->request, &mdesc->secret_request, sizeof(mdesc->secret_request));
31603148

3149+
/* Initialize the input address for guest request */
3150+
req->input.req_gpa = __pa(mdesc->request);
3151+
req->input.resp_gpa = __pa(mdesc->response);
3152+
req->input.data_gpa = req->certs_data ? __pa(req->certs_data) : 0;
3153+
31613154
rc = __handle_guest_request(mdesc, req, rio);
31623155
if (rc) {
31633156
if (rc == -EIO &&

arch/x86/include/asm/pgtable-2level_types.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ typedef union {
2323
#define ARCH_PAGE_TABLE_SYNC_MASK PGTBL_PMD_MODIFIED
2424

2525
/*
26-
* traditional i386 two-level paging structure:
26+
* Traditional i386 two-level paging structure:
2727
*/
2828

2929
#define PGDIR_SHIFT 22
3030
#define PTRS_PER_PGD 1024
3131

32-
3332
/*
34-
* the i386 is two-level, so we don't really have any
35-
* PMD directory physically.
33+
* The i386 is two-level, so we don't really have any
34+
* PMD directory physically:
3635
*/
36+
#define PTRS_PER_PMD 1
3737

3838
#define PTRS_PER_PTE 1024
3939

arch/x86/include/asm/sev.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ struct snp_guest_req {
203203
unsigned int vmpck_id;
204204
u8 msg_version;
205205
u8 msg_type;
206+
207+
struct snp_req_data input;
208+
void *certs_data;
206209
};
207210

208211
/*
@@ -263,9 +266,6 @@ struct snp_msg_desc {
263266
struct snp_guest_msg secret_request, secret_response;
264267

265268
struct snp_secrets_page *secrets;
266-
struct snp_req_data input;
267-
268-
void *certs_data;
269269

270270
struct aesgcm_ctx *ctx;
271271

arch/x86/kernel/amd_nb.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,21 +143,18 @@ bool __init early_is_amd_nb(u32 device)
143143

144144
struct resource *amd_get_mmconfig_range(struct resource *res)
145145
{
146-
u32 address;
147146
u64 base, msr;
148147
unsigned int segn_busn_bits;
149148

150149
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
151150
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
152151
return NULL;
153152

154-
/* assume all cpus from fam10h have mmconfig */
155-
if (boot_cpu_data.x86 < 0x10)
153+
/* Assume CPUs from Fam10h have mmconfig, although not all VMs do */
154+
if (boot_cpu_data.x86 < 0x10 ||
155+
rdmsrl_safe(MSR_FAM10H_MMIO_CONF_BASE, &msr))
156156
return NULL;
157157

158-
address = MSR_FAM10H_MMIO_CONF_BASE;
159-
rdmsrl(address, msr);
160-
161158
/* mmconfig is not enabled */
162159
if (!(msr & FAM10H_MMIO_CONF_ENABLE))
163160
return NULL;

arch/x86/kernel/cpu/microcode/amd.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,23 +175,29 @@ static bool need_sha_check(u32 cur_rev)
175175
{
176176
switch (cur_rev >> 8) {
177177
case 0x80012: return cur_rev <= 0x800126f; break;
178+
case 0x80082: return cur_rev <= 0x800820f; break;
178179
case 0x83010: return cur_rev <= 0x830107c; break;
179180
case 0x86001: return cur_rev <= 0x860010e; break;
180181
case 0x86081: return cur_rev <= 0x8608108; break;
181182
case 0x87010: return cur_rev <= 0x8701034; break;
182183
case 0x8a000: return cur_rev <= 0x8a0000a; break;
184+
case 0xa0010: return cur_rev <= 0xa00107a; break;
183185
case 0xa0011: return cur_rev <= 0xa0011da; break;
184186
case 0xa0012: return cur_rev <= 0xa001243; break;
187+
case 0xa0082: return cur_rev <= 0xa00820e; break;
185188
case 0xa1011: return cur_rev <= 0xa101153; break;
186189
case 0xa1012: return cur_rev <= 0xa10124e; break;
187190
case 0xa1081: return cur_rev <= 0xa108109; break;
188191
case 0xa2010: return cur_rev <= 0xa20102f; break;
189192
case 0xa2012: return cur_rev <= 0xa201212; break;
193+
case 0xa4041: return cur_rev <= 0xa404109; break;
194+
case 0xa5000: return cur_rev <= 0xa500013; break;
190195
case 0xa6012: return cur_rev <= 0xa60120a; break;
191196
case 0xa7041: return cur_rev <= 0xa704109; break;
192197
case 0xa7052: return cur_rev <= 0xa705208; break;
193198
case 0xa7080: return cur_rev <= 0xa708009; break;
194199
case 0xa70c0: return cur_rev <= 0xa70C009; break;
200+
case 0xaa001: return cur_rev <= 0xaa00116; break;
195201
case 0xaa002: return cur_rev <= 0xaa00218; break;
196202
default: break;
197203
}

drivers/virt/coco/sev-guest/sev-guest.c

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@ struct snp_guest_dev {
3838
struct miscdevice misc;
3939

4040
struct snp_msg_desc *msg_desc;
41-
42-
union {
43-
struct snp_report_req report;
44-
struct snp_derived_key_req derived_key;
45-
struct snp_ext_report_req ext_report;
46-
} req;
4741
};
4842

4943
/*
@@ -71,7 +65,7 @@ struct snp_req_resp {
7165

7266
static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
7367
{
74-
struct snp_report_req *report_req = &snp_dev->req.report;
68+
struct snp_report_req *report_req __free(kfree) = NULL;
7569
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
7670
struct snp_report_resp *report_resp;
7771
struct snp_guest_req req = {};
@@ -80,6 +74,10 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
8074
if (!arg->req_data || !arg->resp_data)
8175
return -EINVAL;
8276

77+
report_req = kzalloc(sizeof(*report_req), GFP_KERNEL_ACCOUNT);
78+
if (!report_req)
79+
return -ENOMEM;
80+
8381
if (copy_from_user(report_req, (void __user *)arg->req_data, sizeof(*report_req)))
8482
return -EFAULT;
8583

@@ -116,7 +114,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
116114

117115
static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
118116
{
119-
struct snp_derived_key_req *derived_key_req = &snp_dev->req.derived_key;
117+
struct snp_derived_key_req *derived_key_req __free(kfree) = NULL;
120118
struct snp_derived_key_resp derived_key_resp = {0};
121119
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
122120
struct snp_guest_req req = {};
@@ -136,6 +134,10 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
136134
if (sizeof(buf) < resp_len)
137135
return -ENOMEM;
138136

137+
derived_key_req = kzalloc(sizeof(*derived_key_req), GFP_KERNEL_ACCOUNT);
138+
if (!derived_key_req)
139+
return -ENOMEM;
140+
139141
if (copy_from_user(derived_key_req, (void __user *)arg->req_data,
140142
sizeof(*derived_key_req)))
141143
return -EFAULT;
@@ -168,16 +170,21 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
168170
struct snp_req_resp *io)
169171

170172
{
171-
struct snp_ext_report_req *report_req = &snp_dev->req.ext_report;
173+
struct snp_ext_report_req *report_req __free(kfree) = NULL;
172174
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
173175
struct snp_report_resp *report_resp;
174176
struct snp_guest_req req = {};
175177
int ret, npages = 0, resp_len;
176178
sockptr_t certs_address;
179+
struct page *page;
177180

178181
if (sockptr_is_null(io->req_data) || sockptr_is_null(io->resp_data))
179182
return -EINVAL;
180183

184+
report_req = kzalloc(sizeof(*report_req), GFP_KERNEL_ACCOUNT);
185+
if (!report_req)
186+
return -ENOMEM;
187+
181188
if (copy_from_sockptr(report_req, io->req_data, sizeof(*report_req)))
182189
return -EFAULT;
183190

@@ -203,8 +210,20 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
203210
* the host. If host does not supply any certs in it, then copy
204211
* zeros to indicate that certificate data was not provided.
205212
*/
206-
memset(mdesc->certs_data, 0, report_req->certs_len);
207213
npages = report_req->certs_len >> PAGE_SHIFT;
214+
page = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_ZERO,
215+
get_order(report_req->certs_len));
216+
if (!page)
217+
return -ENOMEM;
218+
219+
req.certs_data = page_address(page);
220+
ret = set_memory_decrypted((unsigned long)req.certs_data, npages);
221+
if (ret) {
222+
pr_err("failed to mark page shared, ret=%d\n", ret);
223+
__free_pages(page, get_order(report_req->certs_len));
224+
return -EFAULT;
225+
}
226+
208227
cmd:
209228
/*
210229
* 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
213232
*/
214233
resp_len = sizeof(report_resp->data) + mdesc->ctx->authsize;
215234
report_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT);
216-
if (!report_resp)
217-
return -ENOMEM;
235+
if (!report_resp) {
236+
ret = -ENOMEM;
237+
goto e_free_data;
238+
}
218239

219-
mdesc->input.data_npages = npages;
240+
req.input.data_npages = npages;
220241

221242
req.msg_version = arg->msg_version;
222243
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
231252

232253
/* If certs length is invalid then copy the returned length */
233254
if (arg->vmm_error == SNP_GUEST_VMM_ERR_INVALID_LEN) {
234-
report_req->certs_len = mdesc->input.data_npages << PAGE_SHIFT;
255+
report_req->certs_len = req.input.data_npages << PAGE_SHIFT;
235256

236257
if (copy_to_sockptr(io->req_data, report_req, sizeof(*report_req)))
237258
ret = -EFAULT;
@@ -240,7 +261,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
240261
if (ret)
241262
goto e_free;
242263

243-
if (npages && copy_to_sockptr(certs_address, mdesc->certs_data, report_req->certs_len)) {
264+
if (npages && copy_to_sockptr(certs_address, req.certs_data, report_req->certs_len)) {
244265
ret = -EFAULT;
245266
goto e_free;
246267
}
@@ -250,6 +271,13 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
250271

251272
e_free:
252273
kfree(report_resp);
274+
e_free_data:
275+
if (npages) {
276+
if (set_memory_encrypted((unsigned long)req.certs_data, npages))
277+
WARN_ONCE(ret, "failed to restore encryption mask (leak it)\n");
278+
else
279+
__free_pages(page, get_order(report_req->certs_len));
280+
}
253281
return ret;
254282
}
255283

0 commit comments

Comments
 (0)