blob: 9f5312956d5e2b252cc6fc0e64d6f174d7357dc2 [file] [log] [blame]
Joerg Roedeleaf78262020-03-24 10:41:54 +01001// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Kernel-based Virtual Machine driver for Linux
4 *
5 * AMD SVM-SEV support
6 *
7 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
8 */
9
10#include <linux/kvm_types.h>
11#include <linux/kvm_host.h>
12#include <linux/kernel.h>
13#include <linux/highmem.h>
14#include <linux/psp-sev.h>
Borislav Petkovb2bce0a2020-04-11 18:09:27 +020015#include <linux/pagemap.h>
Joerg Roedeleaf78262020-03-24 10:41:54 +010016#include <linux/swap.h>
Tom Lendackyadd5e2f2020-12-10 11:09:40 -060017#include <linux/processor.h>
Tom Lendackyd523ab6b2020-12-10 11:09:48 -060018#include <linux/trace_events.h>
Tom Lendacky86137772020-12-10 11:10:07 -060019#include <asm/fpu/internal.h>
Joerg Roedeleaf78262020-03-24 10:41:54 +010020
Tom Lendacky8640ca52020-12-15 12:44:07 -050021#include <asm/trapnr.h>
22
Joerg Roedeleaf78262020-03-24 10:41:54 +010023#include "x86.h"
24#include "svm.h"
Sean Christopherson35a78312020-12-30 16:27:00 -080025#include "svm_ops.h"
Tom Lendacky291bd202020-12-10 11:09:47 -060026#include "cpuid.h"
Tom Lendackyd523ab6b2020-12-10 11:09:48 -060027#include "trace.h"
Joerg Roedeleaf78262020-03-24 10:41:54 +010028
Tom Lendacky86137772020-12-10 11:10:07 -060029#define __ex(x) __kvm_handle_fault_on_reboot(x)
30
Tom Lendacky1edc1452020-12-10 11:09:49 -060031static u8 sev_enc_bit;
Joerg Roedeleaf78262020-03-24 10:41:54 +010032static int sev_flush_asids(void);
33static DECLARE_RWSEM(sev_deactivate_lock);
34static DEFINE_MUTEX(sev_bitmap_lock);
35unsigned int max_sev_asid;
36static unsigned int min_sev_asid;
37static unsigned long *sev_asid_bitmap;
38static unsigned long *sev_reclaim_asid_bitmap;
Joerg Roedeleaf78262020-03-24 10:41:54 +010039
40struct enc_region {
41 struct list_head list;
42 unsigned long npages;
43 struct page **pages;
44 unsigned long uaddr;
45 unsigned long size;
46};
47
48static int sev_flush_asids(void)
49{
50 int ret, error = 0;
51
52 /*
53 * DEACTIVATE will clear the WBINVD indicator causing DF_FLUSH to fail,
54 * so it must be guarded.
55 */
56 down_write(&sev_deactivate_lock);
57
58 wbinvd_on_all_cpus();
59 ret = sev_guest_df_flush(&error);
60
61 up_write(&sev_deactivate_lock);
62
63 if (ret)
64 pr_err("SEV: DF_FLUSH failed, ret=%d, error=%#x\n", ret, error);
65
66 return ret;
67}
68
Nathan Tempelman54526d12021-04-08 22:32:14 +000069static inline bool is_mirroring_enc_context(struct kvm *kvm)
70{
71 return !!to_kvm_svm(kvm)->sev_info.enc_context_owner;
72}
73
Joerg Roedeleaf78262020-03-24 10:41:54 +010074/* Must be called with the sev_bitmap_lock held */
Tom Lendacky80675b32020-12-10 11:10:05 -060075static bool __sev_recycle_asids(int min_asid, int max_asid)
Joerg Roedeleaf78262020-03-24 10:41:54 +010076{
77 int pos;
78
79 /* Check if there are any ASIDs to reclaim before performing a flush */
Tom Lendacky80675b32020-12-10 11:10:05 -060080 pos = find_next_bit(sev_reclaim_asid_bitmap, max_sev_asid, min_asid);
81 if (pos >= max_asid)
Joerg Roedeleaf78262020-03-24 10:41:54 +010082 return false;
83
84 if (sev_flush_asids())
85 return false;
86
Tom Lendacky80675b32020-12-10 11:10:05 -060087 /* The flush process will flush all reclaimable SEV and SEV-ES ASIDs */
Joerg Roedeleaf78262020-03-24 10:41:54 +010088 bitmap_xor(sev_asid_bitmap, sev_asid_bitmap, sev_reclaim_asid_bitmap,
89 max_sev_asid);
90 bitmap_zero(sev_reclaim_asid_bitmap, max_sev_asid);
91
92 return true;
93}
94
Sean Christopherson9fa15212021-03-30 20:19:35 -070095static int sev_asid_new(bool es_active)
Joerg Roedeleaf78262020-03-24 10:41:54 +010096{
Tom Lendacky80675b32020-12-10 11:10:05 -060097 int pos, min_asid, max_asid;
Joerg Roedeleaf78262020-03-24 10:41:54 +010098 bool retry = true;
Joerg Roedeleaf78262020-03-24 10:41:54 +010099
100 mutex_lock(&sev_bitmap_lock);
101
102 /*
Tom Lendacky80675b32020-12-10 11:10:05 -0600103 * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
104 * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
Joerg Roedeleaf78262020-03-24 10:41:54 +0100105 */
Sean Christopherson9fa15212021-03-30 20:19:35 -0700106 min_asid = es_active ? 0 : min_sev_asid - 1;
107 max_asid = es_active ? min_sev_asid - 1 : max_sev_asid;
Joerg Roedeleaf78262020-03-24 10:41:54 +0100108again:
Tom Lendacky80675b32020-12-10 11:10:05 -0600109 pos = find_next_zero_bit(sev_asid_bitmap, max_sev_asid, min_asid);
110 if (pos >= max_asid) {
111 if (retry && __sev_recycle_asids(min_asid, max_asid)) {
Joerg Roedeleaf78262020-03-24 10:41:54 +0100112 retry = false;
113 goto again;
114 }
115 mutex_unlock(&sev_bitmap_lock);
116 return -EBUSY;
117 }
118
119 __set_bit(pos, sev_asid_bitmap);
120
121 mutex_unlock(&sev_bitmap_lock);
122
123 return pos + 1;
124}
125
126static int sev_get_asid(struct kvm *kvm)
127{
128 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
129
130 return sev->asid;
131}
132
133static void sev_asid_free(int asid)
134{
135 struct svm_cpu_data *sd;
136 int cpu, pos;
137
138 mutex_lock(&sev_bitmap_lock);
139
140 pos = asid - 1;
141 __set_bit(pos, sev_reclaim_asid_bitmap);
142
143 for_each_possible_cpu(cpu) {
144 sd = per_cpu(svm_data, cpu);
145 sd->sev_vmcbs[pos] = NULL;
146 }
147
148 mutex_unlock(&sev_bitmap_lock);
149}
150
151static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
152{
153 struct sev_data_decommission *decommission;
154 struct sev_data_deactivate *data;
155
156 if (!handle)
157 return;
158
159 data = kzalloc(sizeof(*data), GFP_KERNEL);
160 if (!data)
161 return;
162
163 /* deactivate handle */
164 data->handle = handle;
165
166 /* Guard DEACTIVATE against WBINVD/DF_FLUSH used in ASID recycling */
167 down_read(&sev_deactivate_lock);
168 sev_guest_deactivate(data, NULL);
169 up_read(&sev_deactivate_lock);
170
171 kfree(data);
172
173 decommission = kzalloc(sizeof(*decommission), GFP_KERNEL);
174 if (!decommission)
175 return;
176
177 /* decommission handle */
178 decommission->handle = handle;
179 sev_guest_decommission(decommission, NULL);
180
181 kfree(decommission);
182}
183
184static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
185{
186 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
Sean Christopherson9fa15212021-03-30 20:19:35 -0700187 bool es_active = argp->id == KVM_SEV_ES_INIT;
Joerg Roedeleaf78262020-03-24 10:41:54 +0100188 int asid, ret;
189
Sean Christopherson87279062021-03-30 20:19:36 -0700190 if (kvm->created_vcpus)
191 return -EINVAL;
192
Joerg Roedeleaf78262020-03-24 10:41:54 +0100193 ret = -EBUSY;
194 if (unlikely(sev->active))
195 return ret;
196
Sean Christopherson9fa15212021-03-30 20:19:35 -0700197 asid = sev_asid_new(es_active);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100198 if (asid < 0)
199 return ret;
200
201 ret = sev_platform_init(&argp->error);
202 if (ret)
203 goto e_free;
204
205 sev->active = true;
Sean Christopherson9fa15212021-03-30 20:19:35 -0700206 sev->es_active = es_active;
Joerg Roedeleaf78262020-03-24 10:41:54 +0100207 sev->asid = asid;
208 INIT_LIST_HEAD(&sev->regions_list);
209
210 return 0;
211
212e_free:
213 sev_asid_free(asid);
214 return ret;
215}
216
217static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error)
218{
219 struct sev_data_activate *data;
220 int asid = sev_get_asid(kvm);
221 int ret;
222
223 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
224 if (!data)
225 return -ENOMEM;
226
227 /* activate ASID on the given handle */
228 data->handle = handle;
229 data->asid = asid;
230 ret = sev_guest_activate(data, error);
231 kfree(data);
232
233 return ret;
234}
235
236static int __sev_issue_cmd(int fd, int id, void *data, int *error)
237{
238 struct fd f;
239 int ret;
240
241 f = fdget(fd);
242 if (!f.file)
243 return -EBADF;
244
245 ret = sev_issue_cmd_external_user(f.file, id, data, error);
246
247 fdput(f);
248 return ret;
249}
250
251static int sev_issue_cmd(struct kvm *kvm, int id, void *data, int *error)
252{
253 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
254
255 return __sev_issue_cmd(sev->fd, id, data, error);
256}
257
258static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
259{
260 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
261 struct sev_data_launch_start *start;
262 struct kvm_sev_launch_start params;
263 void *dh_blob, *session_blob;
264 int *error = &argp->error;
265 int ret;
266
267 if (!sev_guest(kvm))
268 return -ENOTTY;
269
270 if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
271 return -EFAULT;
272
273 start = kzalloc(sizeof(*start), GFP_KERNEL_ACCOUNT);
274 if (!start)
275 return -ENOMEM;
276
277 dh_blob = NULL;
278 if (params.dh_uaddr) {
279 dh_blob = psp_copy_user_blob(params.dh_uaddr, params.dh_len);
280 if (IS_ERR(dh_blob)) {
281 ret = PTR_ERR(dh_blob);
282 goto e_free;
283 }
284
285 start->dh_cert_address = __sme_set(__pa(dh_blob));
286 start->dh_cert_len = params.dh_len;
287 }
288
289 session_blob = NULL;
290 if (params.session_uaddr) {
291 session_blob = psp_copy_user_blob(params.session_uaddr, params.session_len);
292 if (IS_ERR(session_blob)) {
293 ret = PTR_ERR(session_blob);
294 goto e_free_dh;
295 }
296
297 start->session_address = __sme_set(__pa(session_blob));
298 start->session_len = params.session_len;
299 }
300
301 start->handle = params.handle;
302 start->policy = params.policy;
303
304 /* create memory encryption context */
305 ret = __sev_issue_cmd(argp->sev_fd, SEV_CMD_LAUNCH_START, start, error);
306 if (ret)
307 goto e_free_session;
308
309 /* Bind ASID to this guest */
310 ret = sev_bind_asid(kvm, start->handle, error);
311 if (ret)
312 goto e_free_session;
313
314 /* return handle to userspace */
315 params.handle = start->handle;
316 if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params))) {
317 sev_unbind_asid(kvm, start->handle);
318 ret = -EFAULT;
319 goto e_free_session;
320 }
321
322 sev->handle = start->handle;
323 sev->fd = argp->sev_fd;
324
325e_free_session:
326 kfree(session_blob);
327e_free_dh:
328 kfree(dh_blob);
329e_free:
330 kfree(start);
331 return ret;
332}
333
334static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
335 unsigned long ulen, unsigned long *n,
336 int write)
337{
338 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
John Hubbard78824fa2020-05-25 23:22:06 -0700339 unsigned long npages, size;
340 int npinned;
Joerg Roedeleaf78262020-03-24 10:41:54 +0100341 unsigned long locked, lock_limit;
342 struct page **pages;
343 unsigned long first, last;
Dan Carpenterff2bd9f2020-07-14 17:23:51 +0300344 int ret;
Joerg Roedeleaf78262020-03-24 10:41:54 +0100345
Peter Gonda19a23da2021-01-27 08:15:24 -0800346 lockdep_assert_held(&kvm->lock);
347
Joerg Roedeleaf78262020-03-24 10:41:54 +0100348 if (ulen == 0 || uaddr + ulen < uaddr)
Paolo Bonzinia8d908b2020-06-23 05:12:24 -0400349 return ERR_PTR(-EINVAL);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100350
351 /* Calculate number of pages. */
352 first = (uaddr & PAGE_MASK) >> PAGE_SHIFT;
353 last = ((uaddr + ulen - 1) & PAGE_MASK) >> PAGE_SHIFT;
354 npages = (last - first + 1);
355
356 locked = sev->pages_locked + npages;
357 lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
358 if (locked > lock_limit && !capable(CAP_IPC_LOCK)) {
359 pr_err("SEV: %lu locked pages exceed the lock limit of %lu.\n", locked, lock_limit);
Paolo Bonzinia8d908b2020-06-23 05:12:24 -0400360 return ERR_PTR(-ENOMEM);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100361 }
362
John Hubbard78824fa2020-05-25 23:22:06 -0700363 if (WARN_ON_ONCE(npages > INT_MAX))
Paolo Bonzinia8d908b2020-06-23 05:12:24 -0400364 return ERR_PTR(-EINVAL);
John Hubbard78824fa2020-05-25 23:22:06 -0700365
Joerg Roedeleaf78262020-03-24 10:41:54 +0100366 /* Avoid using vmalloc for smaller buffers. */
367 size = npages * sizeof(struct page *);
368 if (size > PAGE_SIZE)
Christoph Hellwig88dca4c2020-06-01 21:51:40 -0700369 pages = __vmalloc(size, GFP_KERNEL_ACCOUNT | __GFP_ZERO);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100370 else
371 pages = kmalloc(size, GFP_KERNEL_ACCOUNT);
372
373 if (!pages)
Paolo Bonzinia8d908b2020-06-23 05:12:24 -0400374 return ERR_PTR(-ENOMEM);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100375
376 /* Pin the user virtual address. */
John Hubbarddc42c8a2020-05-25 23:22:07 -0700377 npinned = pin_user_pages_fast(uaddr, npages, write ? FOLL_WRITE : 0, pages);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100378 if (npinned != npages) {
379 pr_err("SEV: Failure locking %lu pages.\n", npages);
Dan Carpenterff2bd9f2020-07-14 17:23:51 +0300380 ret = -ENOMEM;
Joerg Roedeleaf78262020-03-24 10:41:54 +0100381 goto err;
382 }
383
384 *n = npages;
385 sev->pages_locked = locked;
386
387 return pages;
388
389err:
Dan Carpenterff2bd9f2020-07-14 17:23:51 +0300390 if (npinned > 0)
John Hubbarddc42c8a2020-05-25 23:22:07 -0700391 unpin_user_pages(pages, npinned);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100392
393 kvfree(pages);
Dan Carpenterff2bd9f2020-07-14 17:23:51 +0300394 return ERR_PTR(ret);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100395}
396
397static void sev_unpin_memory(struct kvm *kvm, struct page **pages,
398 unsigned long npages)
399{
400 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
401
John Hubbarddc42c8a2020-05-25 23:22:07 -0700402 unpin_user_pages(pages, npages);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100403 kvfree(pages);
404 sev->pages_locked -= npages;
405}
406
407static void sev_clflush_pages(struct page *pages[], unsigned long npages)
408{
409 uint8_t *page_virtual;
410 unsigned long i;
411
Krish Sadhukhane1ebb2b2020-09-17 21:20:38 +0000412 if (this_cpu_has(X86_FEATURE_SME_COHERENT) || npages == 0 ||
413 pages == NULL)
Joerg Roedeleaf78262020-03-24 10:41:54 +0100414 return;
415
416 for (i = 0; i < npages; i++) {
417 page_virtual = kmap_atomic(pages[i]);
418 clflush_cache_range(page_virtual, PAGE_SIZE);
419 kunmap_atomic(page_virtual);
420 }
421}
422
423static unsigned long get_num_contig_pages(unsigned long idx,
424 struct page **inpages, unsigned long npages)
425{
426 unsigned long paddr, next_paddr;
427 unsigned long i = idx + 1, pages = 1;
428
429 /* find the number of contiguous pages starting from idx */
430 paddr = __sme_page_pa(inpages[idx]);
431 while (i < npages) {
432 next_paddr = __sme_page_pa(inpages[i++]);
433 if ((paddr + PAGE_SIZE) == next_paddr) {
434 pages++;
435 paddr = next_paddr;
436 continue;
437 }
438 break;
439 }
440
441 return pages;
442}
443
444static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
445{
446 unsigned long vaddr, vaddr_end, next_vaddr, npages, pages, size, i;
447 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
448 struct kvm_sev_launch_update_data params;
449 struct sev_data_launch_update_data *data;
450 struct page **inpages;
451 int ret;
452
453 if (!sev_guest(kvm))
454 return -ENOTTY;
455
456 if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
457 return -EFAULT;
458
459 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
460 if (!data)
461 return -ENOMEM;
462
463 vaddr = params.uaddr;
464 size = params.len;
465 vaddr_end = vaddr + size;
466
467 /* Lock the user memory. */
468 inpages = sev_pin_memory(kvm, vaddr, size, &npages, 1);
Dan Carpenterff2bd9f2020-07-14 17:23:51 +0300469 if (IS_ERR(inpages)) {
470 ret = PTR_ERR(inpages);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100471 goto e_free;
472 }
473
474 /*
Paolo Bonzini14e3dd82020-09-23 13:01:33 -0400475 * Flush (on non-coherent CPUs) before LAUNCH_UPDATE encrypts pages in
476 * place; the cache may contain the data that was written unencrypted.
Joerg Roedeleaf78262020-03-24 10:41:54 +0100477 */
478 sev_clflush_pages(inpages, npages);
479
480 for (i = 0; vaddr < vaddr_end; vaddr = next_vaddr, i += pages) {
481 int offset, len;
482
483 /*
484 * If the user buffer is not page-aligned, calculate the offset
485 * within the page.
486 */
487 offset = vaddr & (PAGE_SIZE - 1);
488
489 /* Calculate the number of pages that can be encrypted in one go. */
490 pages = get_num_contig_pages(i, inpages, npages);
491
492 len = min_t(size_t, ((pages * PAGE_SIZE) - offset), size);
493
494 data->handle = sev->handle;
495 data->len = len;
496 data->address = __sme_page_pa(inpages[i]) + offset;
497 ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_DATA, data, &argp->error);
498 if (ret)
499 goto e_unpin;
500
501 size -= len;
502 next_vaddr = vaddr + len;
503 }
504
505e_unpin:
506 /* content of memory is updated, mark pages dirty */
507 for (i = 0; i < npages; i++) {
508 set_page_dirty_lock(inpages[i]);
509 mark_page_accessed(inpages[i]);
510 }
511 /* unlock the user pages */
512 sev_unpin_memory(kvm, inpages, npages);
513e_free:
514 kfree(data);
515 return ret;
516}
517
Tom Lendackyad731092020-12-10 11:10:09 -0600518static int sev_es_sync_vmsa(struct vcpu_svm *svm)
519{
520 struct vmcb_save_area *save = &svm->vmcb->save;
521
522 /* Check some debug related fields before encrypting the VMSA */
523 if (svm->vcpu.guest_debug || (save->dr7 & ~DR7_FIXED_1))
524 return -EINVAL;
525
526 /* Sync registgers */
527 save->rax = svm->vcpu.arch.regs[VCPU_REGS_RAX];
528 save->rbx = svm->vcpu.arch.regs[VCPU_REGS_RBX];
529 save->rcx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
530 save->rdx = svm->vcpu.arch.regs[VCPU_REGS_RDX];
531 save->rsp = svm->vcpu.arch.regs[VCPU_REGS_RSP];
532 save->rbp = svm->vcpu.arch.regs[VCPU_REGS_RBP];
533 save->rsi = svm->vcpu.arch.regs[VCPU_REGS_RSI];
534 save->rdi = svm->vcpu.arch.regs[VCPU_REGS_RDI];
Paolo Bonzinid45f89f2020-12-16 13:08:21 -0500535#ifdef CONFIG_X86_64
Tom Lendackyad731092020-12-10 11:10:09 -0600536 save->r8 = svm->vcpu.arch.regs[VCPU_REGS_R8];
537 save->r9 = svm->vcpu.arch.regs[VCPU_REGS_R9];
538 save->r10 = svm->vcpu.arch.regs[VCPU_REGS_R10];
539 save->r11 = svm->vcpu.arch.regs[VCPU_REGS_R11];
540 save->r12 = svm->vcpu.arch.regs[VCPU_REGS_R12];
541 save->r13 = svm->vcpu.arch.regs[VCPU_REGS_R13];
542 save->r14 = svm->vcpu.arch.regs[VCPU_REGS_R14];
543 save->r15 = svm->vcpu.arch.regs[VCPU_REGS_R15];
Paolo Bonzinid45f89f2020-12-16 13:08:21 -0500544#endif
Tom Lendackyad731092020-12-10 11:10:09 -0600545 save->rip = svm->vcpu.arch.regs[VCPU_REGS_RIP];
546
547 /* Sync some non-GPR registers before encrypting */
548 save->xcr0 = svm->vcpu.arch.xcr0;
549 save->pkru = svm->vcpu.arch.pkru;
550 save->xss = svm->vcpu.arch.ia32_xss;
551
552 /*
553 * SEV-ES will use a VMSA that is pointed to by the VMCB, not
554 * the traditional VMSA that is part of the VMCB. Copy the
555 * traditional VMSA as it has been built so far (in prep
556 * for LAUNCH_UPDATE_VMSA) to be the initial SEV-ES state.
557 */
558 memcpy(svm->vmsa, save, sizeof(*save));
559
560 return 0;
561}
562
563static int sev_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
564{
565 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
566 struct sev_data_launch_update_vmsa *vmsa;
Sean Christophersonc36b16d2021-03-30 20:19:34 -0700567 struct kvm_vcpu *vcpu;
Tom Lendackyad731092020-12-10 11:10:09 -0600568 int i, ret;
569
570 if (!sev_es_guest(kvm))
571 return -ENOTTY;
572
573 vmsa = kzalloc(sizeof(*vmsa), GFP_KERNEL);
574 if (!vmsa)
575 return -ENOMEM;
576
Sean Christophersonc36b16d2021-03-30 20:19:34 -0700577 kvm_for_each_vcpu(i, vcpu, kvm) {
578 struct vcpu_svm *svm = to_svm(vcpu);
Tom Lendackyad731092020-12-10 11:10:09 -0600579
580 /* Perform some pre-encryption checks against the VMSA */
581 ret = sev_es_sync_vmsa(svm);
582 if (ret)
583 goto e_free;
584
585 /*
586 * The LAUNCH_UPDATE_VMSA command will perform in-place
587 * encryption of the VMSA memory content (i.e it will write
588 * the same memory region with the guest's key), so invalidate
589 * it first.
590 */
591 clflush_cache_range(svm->vmsa, PAGE_SIZE);
592
593 vmsa->handle = sev->handle;
594 vmsa->address = __sme_pa(svm->vmsa);
595 vmsa->len = PAGE_SIZE;
596 ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_VMSA, vmsa,
597 &argp->error);
598 if (ret)
599 goto e_free;
600
601 svm->vcpu.arch.guest_state_protected = true;
602 }
603
604e_free:
605 kfree(vmsa);
606 return ret;
607}
608
Joerg Roedeleaf78262020-03-24 10:41:54 +0100609static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
610{
611 void __user *measure = (void __user *)(uintptr_t)argp->data;
612 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
613 struct sev_data_launch_measure *data;
614 struct kvm_sev_launch_measure params;
615 void __user *p = NULL;
616 void *blob = NULL;
617 int ret;
618
619 if (!sev_guest(kvm))
620 return -ENOTTY;
621
622 if (copy_from_user(&params, measure, sizeof(params)))
623 return -EFAULT;
624
625 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
626 if (!data)
627 return -ENOMEM;
628
629 /* User wants to query the blob length */
630 if (!params.len)
631 goto cmd;
632
633 p = (void __user *)(uintptr_t)params.uaddr;
634 if (p) {
635 if (params.len > SEV_FW_BLOB_MAX_SIZE) {
636 ret = -EINVAL;
637 goto e_free;
638 }
639
640 ret = -ENOMEM;
Sean Christophersoneba04b22021-03-30 19:30:25 -0700641 blob = kmalloc(params.len, GFP_KERNEL_ACCOUNT);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100642 if (!blob)
643 goto e_free;
644
645 data->address = __psp_pa(blob);
646 data->len = params.len;
647 }
648
649cmd:
650 data->handle = sev->handle;
651 ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_MEASURE, data, &argp->error);
652
653 /*
654 * If we query the session length, FW responded with expected data.
655 */
656 if (!params.len)
657 goto done;
658
659 if (ret)
660 goto e_free_blob;
661
662 if (blob) {
663 if (copy_to_user(p, blob, params.len))
664 ret = -EFAULT;
665 }
666
667done:
668 params.len = data->len;
669 if (copy_to_user(measure, &params, sizeof(params)))
670 ret = -EFAULT;
671e_free_blob:
672 kfree(blob);
673e_free:
674 kfree(data);
675 return ret;
676}
677
678static int sev_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp)
679{
680 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
681 struct sev_data_launch_finish *data;
682 int ret;
683
684 if (!sev_guest(kvm))
685 return -ENOTTY;
686
687 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
688 if (!data)
689 return -ENOMEM;
690
691 data->handle = sev->handle;
692 ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_FINISH, data, &argp->error);
693
694 kfree(data);
695 return ret;
696}
697
698static int sev_guest_status(struct kvm *kvm, struct kvm_sev_cmd *argp)
699{
700 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
701 struct kvm_sev_guest_status params;
702 struct sev_data_guest_status *data;
703 int ret;
704
705 if (!sev_guest(kvm))
706 return -ENOTTY;
707
708 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
709 if (!data)
710 return -ENOMEM;
711
712 data->handle = sev->handle;
713 ret = sev_issue_cmd(kvm, SEV_CMD_GUEST_STATUS, data, &argp->error);
714 if (ret)
715 goto e_free;
716
717 params.policy = data->policy;
718 params.state = data->state;
719 params.handle = data->handle;
720
721 if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params)))
722 ret = -EFAULT;
723e_free:
724 kfree(data);
725 return ret;
726}
727
728static int __sev_issue_dbg_cmd(struct kvm *kvm, unsigned long src,
729 unsigned long dst, int size,
730 int *error, bool enc)
731{
732 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
733 struct sev_data_dbg *data;
734 int ret;
735
736 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
737 if (!data)
738 return -ENOMEM;
739
740 data->handle = sev->handle;
741 data->dst_addr = dst;
742 data->src_addr = src;
743 data->len = size;
744
745 ret = sev_issue_cmd(kvm,
746 enc ? SEV_CMD_DBG_ENCRYPT : SEV_CMD_DBG_DECRYPT,
747 data, error);
748 kfree(data);
749 return ret;
750}
751
752static int __sev_dbg_decrypt(struct kvm *kvm, unsigned long src_paddr,
753 unsigned long dst_paddr, int sz, int *err)
754{
755 int offset;
756
757 /*
758 * Its safe to read more than we are asked, caller should ensure that
759 * destination has enough space.
760 */
Joerg Roedeleaf78262020-03-24 10:41:54 +0100761 offset = src_paddr & 15;
Ashish Kalra854c57f2020-11-10 22:42:05 +0000762 src_paddr = round_down(src_paddr, 16);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100763 sz = round_up(sz + offset, 16);
764
765 return __sev_issue_dbg_cmd(kvm, src_paddr, dst_paddr, sz, err, false);
766}
767
768static int __sev_dbg_decrypt_user(struct kvm *kvm, unsigned long paddr,
769 unsigned long __user dst_uaddr,
770 unsigned long dst_paddr,
771 int size, int *err)
772{
773 struct page *tpage = NULL;
774 int ret, offset;
775
776 /* if inputs are not 16-byte then use intermediate buffer */
777 if (!IS_ALIGNED(dst_paddr, 16) ||
778 !IS_ALIGNED(paddr, 16) ||
779 !IS_ALIGNED(size, 16)) {
780 tpage = (void *)alloc_page(GFP_KERNEL);
781 if (!tpage)
782 return -ENOMEM;
783
784 dst_paddr = __sme_page_pa(tpage);
785 }
786
787 ret = __sev_dbg_decrypt(kvm, paddr, dst_paddr, size, err);
788 if (ret)
789 goto e_free;
790
791 if (tpage) {
792 offset = paddr & 15;
793 if (copy_to_user((void __user *)(uintptr_t)dst_uaddr,
794 page_address(tpage) + offset, size))
795 ret = -EFAULT;
796 }
797
798e_free:
799 if (tpage)
800 __free_page(tpage);
801
802 return ret;
803}
804
805static int __sev_dbg_encrypt_user(struct kvm *kvm, unsigned long paddr,
806 unsigned long __user vaddr,
807 unsigned long dst_paddr,
808 unsigned long __user dst_vaddr,
809 int size, int *error)
810{
811 struct page *src_tpage = NULL;
812 struct page *dst_tpage = NULL;
813 int ret, len = size;
814
815 /* If source buffer is not aligned then use an intermediate buffer */
816 if (!IS_ALIGNED(vaddr, 16)) {
817 src_tpage = alloc_page(GFP_KERNEL);
818 if (!src_tpage)
819 return -ENOMEM;
820
821 if (copy_from_user(page_address(src_tpage),
822 (void __user *)(uintptr_t)vaddr, size)) {
823 __free_page(src_tpage);
824 return -EFAULT;
825 }
826
827 paddr = __sme_page_pa(src_tpage);
828 }
829
830 /*
831 * If destination buffer or length is not aligned then do read-modify-write:
832 * - decrypt destination in an intermediate buffer
833 * - copy the source buffer in an intermediate buffer
834 * - use the intermediate buffer as source buffer
835 */
836 if (!IS_ALIGNED(dst_vaddr, 16) || !IS_ALIGNED(size, 16)) {
837 int dst_offset;
838
839 dst_tpage = alloc_page(GFP_KERNEL);
840 if (!dst_tpage) {
841 ret = -ENOMEM;
842 goto e_free;
843 }
844
845 ret = __sev_dbg_decrypt(kvm, dst_paddr,
846 __sme_page_pa(dst_tpage), size, error);
847 if (ret)
848 goto e_free;
849
850 /*
851 * If source is kernel buffer then use memcpy() otherwise
852 * copy_from_user().
853 */
854 dst_offset = dst_paddr & 15;
855
856 if (src_tpage)
857 memcpy(page_address(dst_tpage) + dst_offset,
858 page_address(src_tpage), size);
859 else {
860 if (copy_from_user(page_address(dst_tpage) + dst_offset,
861 (void __user *)(uintptr_t)vaddr, size)) {
862 ret = -EFAULT;
863 goto e_free;
864 }
865 }
866
867 paddr = __sme_page_pa(dst_tpage);
868 dst_paddr = round_down(dst_paddr, 16);
869 len = round_up(size, 16);
870 }
871
872 ret = __sev_issue_dbg_cmd(kvm, paddr, dst_paddr, len, error, true);
873
874e_free:
875 if (src_tpage)
876 __free_page(src_tpage);
877 if (dst_tpage)
878 __free_page(dst_tpage);
879 return ret;
880}
881
882static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec)
883{
884 unsigned long vaddr, vaddr_end, next_vaddr;
885 unsigned long dst_vaddr;
886 struct page **src_p, **dst_p;
887 struct kvm_sev_dbg debug;
888 unsigned long n;
889 unsigned int size;
890 int ret;
891
892 if (!sev_guest(kvm))
893 return -ENOTTY;
894
895 if (copy_from_user(&debug, (void __user *)(uintptr_t)argp->data, sizeof(debug)))
896 return -EFAULT;
897
898 if (!debug.len || debug.src_uaddr + debug.len < debug.src_uaddr)
899 return -EINVAL;
900 if (!debug.dst_uaddr)
901 return -EINVAL;
902
903 vaddr = debug.src_uaddr;
904 size = debug.len;
905 vaddr_end = vaddr + size;
906 dst_vaddr = debug.dst_uaddr;
907
908 for (; vaddr < vaddr_end; vaddr = next_vaddr) {
909 int len, s_off, d_off;
910
911 /* lock userspace source and destination page */
912 src_p = sev_pin_memory(kvm, vaddr & PAGE_MASK, PAGE_SIZE, &n, 0);
Dan Carpenterff2bd9f2020-07-14 17:23:51 +0300913 if (IS_ERR(src_p))
914 return PTR_ERR(src_p);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100915
916 dst_p = sev_pin_memory(kvm, dst_vaddr & PAGE_MASK, PAGE_SIZE, &n, 1);
Dan Carpenterff2bd9f2020-07-14 17:23:51 +0300917 if (IS_ERR(dst_p)) {
Joerg Roedeleaf78262020-03-24 10:41:54 +0100918 sev_unpin_memory(kvm, src_p, n);
Dan Carpenterff2bd9f2020-07-14 17:23:51 +0300919 return PTR_ERR(dst_p);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100920 }
921
922 /*
Paolo Bonzini14e3dd82020-09-23 13:01:33 -0400923 * Flush (on non-coherent CPUs) before DBG_{DE,EN}CRYPT read or modify
924 * the pages; flush the destination too so that future accesses do not
925 * see stale data.
Joerg Roedeleaf78262020-03-24 10:41:54 +0100926 */
927 sev_clflush_pages(src_p, 1);
928 sev_clflush_pages(dst_p, 1);
929
930 /*
931 * Since user buffer may not be page aligned, calculate the
932 * offset within the page.
933 */
934 s_off = vaddr & ~PAGE_MASK;
935 d_off = dst_vaddr & ~PAGE_MASK;
936 len = min_t(size_t, (PAGE_SIZE - s_off), size);
937
938 if (dec)
939 ret = __sev_dbg_decrypt_user(kvm,
940 __sme_page_pa(src_p[0]) + s_off,
941 dst_vaddr,
942 __sme_page_pa(dst_p[0]) + d_off,
943 len, &argp->error);
944 else
945 ret = __sev_dbg_encrypt_user(kvm,
946 __sme_page_pa(src_p[0]) + s_off,
947 vaddr,
948 __sme_page_pa(dst_p[0]) + d_off,
949 dst_vaddr,
950 len, &argp->error);
951
952 sev_unpin_memory(kvm, src_p, n);
953 sev_unpin_memory(kvm, dst_p, n);
954
955 if (ret)
956 goto err;
957
958 next_vaddr = vaddr + len;
959 dst_vaddr = dst_vaddr + len;
960 size -= len;
961 }
962err:
963 return ret;
964}
965
966static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp)
967{
968 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
969 struct sev_data_launch_secret *data;
970 struct kvm_sev_launch_secret params;
971 struct page **pages;
972 void *blob, *hdr;
Cfir Cohen50085be2020-08-07 17:37:46 -0700973 unsigned long n, i;
Joerg Roedeleaf78262020-03-24 10:41:54 +0100974 int ret, offset;
975
976 if (!sev_guest(kvm))
977 return -ENOTTY;
978
979 if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
980 return -EFAULT;
981
982 pages = sev_pin_memory(kvm, params.guest_uaddr, params.guest_len, &n, 1);
Paolo Bonzinia8d908b2020-06-23 05:12:24 -0400983 if (IS_ERR(pages))
984 return PTR_ERR(pages);
Joerg Roedeleaf78262020-03-24 10:41:54 +0100985
986 /*
Paolo Bonzini14e3dd82020-09-23 13:01:33 -0400987 * Flush (on non-coherent CPUs) before LAUNCH_SECRET encrypts pages in
988 * place; the cache may contain the data that was written unencrypted.
Cfir Cohen50085be2020-08-07 17:37:46 -0700989 */
990 sev_clflush_pages(pages, n);
991
992 /*
Joerg Roedeleaf78262020-03-24 10:41:54 +0100993 * The secret must be copied into contiguous memory region, lets verify
994 * that userspace memory pages are contiguous before we issue command.
995 */
996 if (get_num_contig_pages(0, pages, n) != n) {
997 ret = -EINVAL;
998 goto e_unpin_memory;
999 }
1000
1001 ret = -ENOMEM;
1002 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
1003 if (!data)
1004 goto e_unpin_memory;
1005
1006 offset = params.guest_uaddr & (PAGE_SIZE - 1);
1007 data->guest_address = __sme_page_pa(pages[0]) + offset;
1008 data->guest_len = params.guest_len;
1009
1010 blob = psp_copy_user_blob(params.trans_uaddr, params.trans_len);
1011 if (IS_ERR(blob)) {
1012 ret = PTR_ERR(blob);
1013 goto e_free;
1014 }
1015
1016 data->trans_address = __psp_pa(blob);
1017 data->trans_len = params.trans_len;
1018
1019 hdr = psp_copy_user_blob(params.hdr_uaddr, params.hdr_len);
1020 if (IS_ERR(hdr)) {
1021 ret = PTR_ERR(hdr);
1022 goto e_free_blob;
1023 }
1024 data->hdr_address = __psp_pa(hdr);
1025 data->hdr_len = params.hdr_len;
1026
1027 data->handle = sev->handle;
1028 ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_SECRET, data, &argp->error);
1029
1030 kfree(hdr);
1031
1032e_free_blob:
1033 kfree(blob);
1034e_free:
1035 kfree(data);
1036e_unpin_memory:
Cfir Cohen50085be2020-08-07 17:37:46 -07001037 /* content of memory is updated, mark pages dirty */
1038 for (i = 0; i < n; i++) {
1039 set_page_dirty_lock(pages[i]);
1040 mark_page_accessed(pages[i]);
1041 }
Joerg Roedeleaf78262020-03-24 10:41:54 +01001042 sev_unpin_memory(kvm, pages, n);
1043 return ret;
1044}
1045
Brijesh Singh2c07ded2021-01-04 09:17:49 -06001046static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp)
1047{
1048 void __user *report = (void __user *)(uintptr_t)argp->data;
1049 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
1050 struct sev_data_attestation_report *data;
1051 struct kvm_sev_attestation_report params;
1052 void __user *p;
1053 void *blob = NULL;
1054 int ret;
1055
1056 if (!sev_guest(kvm))
1057 return -ENOTTY;
1058
1059 if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
1060 return -EFAULT;
1061
1062 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
1063 if (!data)
1064 return -ENOMEM;
1065
1066 /* User wants to query the blob length */
1067 if (!params.len)
1068 goto cmd;
1069
1070 p = (void __user *)(uintptr_t)params.uaddr;
1071 if (p) {
1072 if (params.len > SEV_FW_BLOB_MAX_SIZE) {
1073 ret = -EINVAL;
1074 goto e_free;
1075 }
1076
1077 ret = -ENOMEM;
Sean Christophersoneba04b22021-03-30 19:30:25 -07001078 blob = kmalloc(params.len, GFP_KERNEL_ACCOUNT);
Brijesh Singh2c07ded2021-01-04 09:17:49 -06001079 if (!blob)
1080 goto e_free;
1081
1082 data->address = __psp_pa(blob);
1083 data->len = params.len;
1084 memcpy(data->mnonce, params.mnonce, sizeof(params.mnonce));
1085 }
1086cmd:
1087 data->handle = sev->handle;
1088 ret = sev_issue_cmd(kvm, SEV_CMD_ATTESTATION_REPORT, data, &argp->error);
1089 /*
1090 * If we query the session length, FW responded with expected data.
1091 */
1092 if (!params.len)
1093 goto done;
1094
1095 if (ret)
1096 goto e_free_blob;
1097
1098 if (blob) {
1099 if (copy_to_user(p, blob, params.len))
1100 ret = -EFAULT;
1101 }
1102
1103done:
1104 params.len = data->len;
1105 if (copy_to_user(report, &params, sizeof(params)))
1106 ret = -EFAULT;
1107e_free_blob:
1108 kfree(blob);
1109e_free:
1110 kfree(data);
1111 return ret;
1112}
1113
Brijesh Singh4cfdd472021-04-15 15:53:14 +00001114/* Userspace wants to query session length. */
1115static int
1116__sev_send_start_query_session_length(struct kvm *kvm, struct kvm_sev_cmd *argp,
1117 struct kvm_sev_send_start *params)
1118{
1119 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
1120 struct sev_data_send_start *data;
1121 int ret;
1122
1123 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
1124 if (data == NULL)
1125 return -ENOMEM;
1126
1127 data->handle = sev->handle;
1128 ret = sev_issue_cmd(kvm, SEV_CMD_SEND_START, data, &argp->error);
1129 if (ret < 0)
1130 goto out;
1131
1132 params->session_len = data->session_len;
1133 if (copy_to_user((void __user *)(uintptr_t)argp->data, params,
1134 sizeof(struct kvm_sev_send_start)))
1135 ret = -EFAULT;
1136
1137out:
1138 kfree(data);
1139 return ret;
1140}
1141
1142static int sev_send_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
1143{
1144 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
1145 struct sev_data_send_start *data;
1146 struct kvm_sev_send_start params;
1147 void *amd_certs, *session_data;
1148 void *pdh_cert, *plat_certs;
1149 int ret;
1150
1151 if (!sev_guest(kvm))
1152 return -ENOTTY;
1153
1154 if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data,
1155 sizeof(struct kvm_sev_send_start)))
1156 return -EFAULT;
1157
1158 /* if session_len is zero, userspace wants to query the session length */
1159 if (!params.session_len)
1160 return __sev_send_start_query_session_length(kvm, argp,
1161 &params);
1162
1163 /* some sanity checks */
1164 if (!params.pdh_cert_uaddr || !params.pdh_cert_len ||
1165 !params.session_uaddr || params.session_len > SEV_FW_BLOB_MAX_SIZE)
1166 return -EINVAL;
1167
1168 /* allocate the memory to hold the session data blob */
1169 session_data = kmalloc(params.session_len, GFP_KERNEL_ACCOUNT);
1170 if (!session_data)
1171 return -ENOMEM;
1172
1173 /* copy the certificate blobs from userspace */
1174 pdh_cert = psp_copy_user_blob(params.pdh_cert_uaddr,
1175 params.pdh_cert_len);
1176 if (IS_ERR(pdh_cert)) {
1177 ret = PTR_ERR(pdh_cert);
1178 goto e_free_session;
1179 }
1180
1181 plat_certs = psp_copy_user_blob(params.plat_certs_uaddr,
1182 params.plat_certs_len);
1183 if (IS_ERR(plat_certs)) {
1184 ret = PTR_ERR(plat_certs);
1185 goto e_free_pdh;
1186 }
1187
1188 amd_certs = psp_copy_user_blob(params.amd_certs_uaddr,
1189 params.amd_certs_len);
1190 if (IS_ERR(amd_certs)) {
1191 ret = PTR_ERR(amd_certs);
1192 goto e_free_plat_cert;
1193 }
1194
1195 data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
1196 if (data == NULL) {
1197 ret = -ENOMEM;
1198 goto e_free_amd_cert;
1199 }
1200
1201 /* populate the FW SEND_START field with system physical address */
1202 data->pdh_cert_address = __psp_pa(pdh_cert);
1203 data->pdh_cert_len = params.pdh_cert_len;
1204 data->plat_certs_address = __psp_pa(plat_certs);
1205 data->plat_certs_len = params.plat_certs_len;
1206 data->amd_certs_address = __psp_pa(amd_certs);
1207 data->amd_certs_len = params.amd_certs_len;
1208 data->session_address = __psp_pa(session_data);
1209 data->session_len = params.session_len;
1210 data->handle = sev->handle;
1211
1212 ret = sev_issue_cmd(kvm, SEV_CMD_SEND_START, data, &argp->error);
1213
1214 if (!ret && copy_to_user((void __user *)(uintptr_t)params.session_uaddr,
1215 session_data, params.session_len)) {
1216 ret = -EFAULT;
1217 goto e_free;
1218 }
1219
1220 params.policy = data->policy;
1221 params.session_len = data->session_len;
1222 if (copy_to_user((void __user *)(uintptr_t)argp->data, &params,
1223 sizeof(struct kvm_sev_send_start)))
1224 ret = -EFAULT;
1225
1226e_free:
1227 kfree(data);
1228e_free_amd_cert:
1229 kfree(amd_certs);
1230e_free_plat_cert:
1231 kfree(plat_certs);
1232e_free_pdh:
1233 kfree(pdh_cert);
1234e_free_session:
1235 kfree(session_data);
1236 return ret;
1237}
1238
Joerg Roedeleaf78262020-03-24 10:41:54 +01001239int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
1240{
1241 struct kvm_sev_cmd sev_cmd;
1242 int r;
1243
Tom Lendacky916391a2020-12-10 11:09:38 -06001244 if (!svm_sev_enabled() || !sev)
Joerg Roedeleaf78262020-03-24 10:41:54 +01001245 return -ENOTTY;
1246
1247 if (!argp)
1248 return 0;
1249
1250 if (copy_from_user(&sev_cmd, argp, sizeof(struct kvm_sev_cmd)))
1251 return -EFAULT;
1252
1253 mutex_lock(&kvm->lock);
1254
Nathan Tempelman54526d12021-04-08 22:32:14 +00001255 /* enc_context_owner handles all memory enc operations */
1256 if (is_mirroring_enc_context(kvm)) {
1257 r = -EINVAL;
1258 goto out;
1259 }
1260
Joerg Roedeleaf78262020-03-24 10:41:54 +01001261 switch (sev_cmd.id) {
Sean Christopherson9fa15212021-03-30 20:19:35 -07001262 case KVM_SEV_ES_INIT:
1263 if (!sev_es) {
1264 r = -ENOTTY;
1265 goto out;
1266 }
1267 fallthrough;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001268 case KVM_SEV_INIT:
1269 r = sev_guest_init(kvm, &sev_cmd);
1270 break;
1271 case KVM_SEV_LAUNCH_START:
1272 r = sev_launch_start(kvm, &sev_cmd);
1273 break;
1274 case KVM_SEV_LAUNCH_UPDATE_DATA:
1275 r = sev_launch_update_data(kvm, &sev_cmd);
1276 break;
Tom Lendackyad731092020-12-10 11:10:09 -06001277 case KVM_SEV_LAUNCH_UPDATE_VMSA:
1278 r = sev_launch_update_vmsa(kvm, &sev_cmd);
1279 break;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001280 case KVM_SEV_LAUNCH_MEASURE:
1281 r = sev_launch_measure(kvm, &sev_cmd);
1282 break;
1283 case KVM_SEV_LAUNCH_FINISH:
1284 r = sev_launch_finish(kvm, &sev_cmd);
1285 break;
1286 case KVM_SEV_GUEST_STATUS:
1287 r = sev_guest_status(kvm, &sev_cmd);
1288 break;
1289 case KVM_SEV_DBG_DECRYPT:
1290 r = sev_dbg_crypt(kvm, &sev_cmd, true);
1291 break;
1292 case KVM_SEV_DBG_ENCRYPT:
1293 r = sev_dbg_crypt(kvm, &sev_cmd, false);
1294 break;
1295 case KVM_SEV_LAUNCH_SECRET:
1296 r = sev_launch_secret(kvm, &sev_cmd);
1297 break;
Brijesh Singh2c07ded2021-01-04 09:17:49 -06001298 case KVM_SEV_GET_ATTESTATION_REPORT:
1299 r = sev_get_attestation_report(kvm, &sev_cmd);
1300 break;
Brijesh Singh4cfdd472021-04-15 15:53:14 +00001301 case KVM_SEV_SEND_START:
1302 r = sev_send_start(kvm, &sev_cmd);
1303 break;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001304 default:
1305 r = -EINVAL;
1306 goto out;
1307 }
1308
1309 if (copy_to_user(argp, &sev_cmd, sizeof(struct kvm_sev_cmd)))
1310 r = -EFAULT;
1311
1312out:
1313 mutex_unlock(&kvm->lock);
1314 return r;
1315}
1316
1317int svm_register_enc_region(struct kvm *kvm,
1318 struct kvm_enc_region *range)
1319{
1320 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
1321 struct enc_region *region;
1322 int ret = 0;
1323
1324 if (!sev_guest(kvm))
1325 return -ENOTTY;
1326
Nathan Tempelman54526d12021-04-08 22:32:14 +00001327 /* If kvm is mirroring encryption context it isn't responsible for it */
1328 if (is_mirroring_enc_context(kvm))
1329 return -EINVAL;
1330
Joerg Roedeleaf78262020-03-24 10:41:54 +01001331 if (range->addr > ULONG_MAX || range->size > ULONG_MAX)
1332 return -EINVAL;
1333
1334 region = kzalloc(sizeof(*region), GFP_KERNEL_ACCOUNT);
1335 if (!region)
1336 return -ENOMEM;
1337
Peter Gonda19a23da2021-01-27 08:15:24 -08001338 mutex_lock(&kvm->lock);
Joerg Roedeleaf78262020-03-24 10:41:54 +01001339 region->pages = sev_pin_memory(kvm, range->addr, range->size, &region->npages, 1);
Paolo Bonzinia8d908b2020-06-23 05:12:24 -04001340 if (IS_ERR(region->pages)) {
1341 ret = PTR_ERR(region->pages);
Peter Gonda19a23da2021-01-27 08:15:24 -08001342 mutex_unlock(&kvm->lock);
Joerg Roedeleaf78262020-03-24 10:41:54 +01001343 goto e_free;
1344 }
1345
Peter Gonda19a23da2021-01-27 08:15:24 -08001346 region->uaddr = range->addr;
1347 region->size = range->size;
1348
1349 list_add_tail(&region->list, &sev->regions_list);
1350 mutex_unlock(&kvm->lock);
1351
Joerg Roedeleaf78262020-03-24 10:41:54 +01001352 /*
1353 * The guest may change the memory encryption attribute from C=0 -> C=1
1354 * or vice versa for this memory range. Lets make sure caches are
1355 * flushed to ensure that guest data gets written into memory with
1356 * correct C-bit.
1357 */
1358 sev_clflush_pages(region->pages, region->npages);
1359
Joerg Roedeleaf78262020-03-24 10:41:54 +01001360 return ret;
1361
1362e_free:
1363 kfree(region);
1364 return ret;
1365}
1366
1367static struct enc_region *
1368find_enc_region(struct kvm *kvm, struct kvm_enc_region *range)
1369{
1370 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
1371 struct list_head *head = &sev->regions_list;
1372 struct enc_region *i;
1373
1374 list_for_each_entry(i, head, list) {
1375 if (i->uaddr == range->addr &&
1376 i->size == range->size)
1377 return i;
1378 }
1379
1380 return NULL;
1381}
1382
1383static void __unregister_enc_region_locked(struct kvm *kvm,
1384 struct enc_region *region)
1385{
1386 sev_unpin_memory(kvm, region->pages, region->npages);
1387 list_del(&region->list);
1388 kfree(region);
1389}
1390
1391int svm_unregister_enc_region(struct kvm *kvm,
1392 struct kvm_enc_region *range)
1393{
1394 struct enc_region *region;
1395 int ret;
1396
Nathan Tempelman54526d12021-04-08 22:32:14 +00001397 /* If kvm is mirroring encryption context it isn't responsible for it */
1398 if (is_mirroring_enc_context(kvm))
1399 return -EINVAL;
1400
Joerg Roedeleaf78262020-03-24 10:41:54 +01001401 mutex_lock(&kvm->lock);
1402
1403 if (!sev_guest(kvm)) {
1404 ret = -ENOTTY;
1405 goto failed;
1406 }
1407
1408 region = find_enc_region(kvm, range);
1409 if (!region) {
1410 ret = -EINVAL;
1411 goto failed;
1412 }
1413
1414 /*
1415 * Ensure that all guest tagged cache entries are flushed before
1416 * releasing the pages back to the system for use. CLFLUSH will
1417 * not do this, so issue a WBINVD.
1418 */
1419 wbinvd_on_all_cpus();
1420
1421 __unregister_enc_region_locked(kvm, region);
1422
1423 mutex_unlock(&kvm->lock);
1424 return 0;
1425
1426failed:
1427 mutex_unlock(&kvm->lock);
1428 return ret;
1429}
1430
Nathan Tempelman54526d12021-04-08 22:32:14 +00001431int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd)
1432{
1433 struct file *source_kvm_file;
1434 struct kvm *source_kvm;
1435 struct kvm_sev_info *mirror_sev;
1436 unsigned int asid;
1437 int ret;
1438
1439 source_kvm_file = fget(source_fd);
1440 if (!file_is_kvm(source_kvm_file)) {
1441 ret = -EBADF;
1442 goto e_source_put;
1443 }
1444
1445 source_kvm = source_kvm_file->private_data;
1446 mutex_lock(&source_kvm->lock);
1447
1448 if (!sev_guest(source_kvm)) {
1449 ret = -EINVAL;
1450 goto e_source_unlock;
1451 }
1452
1453 /* Mirrors of mirrors should work, but let's not get silly */
1454 if (is_mirroring_enc_context(source_kvm) || source_kvm == kvm) {
1455 ret = -EINVAL;
1456 goto e_source_unlock;
1457 }
1458
1459 asid = to_kvm_svm(source_kvm)->sev_info.asid;
1460
1461 /*
1462 * The mirror kvm holds an enc_context_owner ref so its asid can't
1463 * disappear until we're done with it
1464 */
1465 kvm_get_kvm(source_kvm);
1466
1467 fput(source_kvm_file);
1468 mutex_unlock(&source_kvm->lock);
1469 mutex_lock(&kvm->lock);
1470
1471 if (sev_guest(kvm)) {
1472 ret = -EINVAL;
1473 goto e_mirror_unlock;
1474 }
1475
1476 /* Set enc_context_owner and copy its encryption context over */
1477 mirror_sev = &to_kvm_svm(kvm)->sev_info;
1478 mirror_sev->enc_context_owner = source_kvm;
1479 mirror_sev->asid = asid;
1480 mirror_sev->active = true;
1481
1482 mutex_unlock(&kvm->lock);
1483 return 0;
1484
1485e_mirror_unlock:
1486 mutex_unlock(&kvm->lock);
1487 kvm_put_kvm(source_kvm);
1488 return ret;
1489e_source_unlock:
1490 mutex_unlock(&source_kvm->lock);
1491e_source_put:
1492 fput(source_kvm_file);
1493 return ret;
1494}
1495
Joerg Roedeleaf78262020-03-24 10:41:54 +01001496void sev_vm_destroy(struct kvm *kvm)
1497{
1498 struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
1499 struct list_head *head = &sev->regions_list;
1500 struct list_head *pos, *q;
1501
1502 if (!sev_guest(kvm))
1503 return;
1504
Nathan Tempelman54526d12021-04-08 22:32:14 +00001505 /* If this is a mirror_kvm release the enc_context_owner and skip sev cleanup */
1506 if (is_mirroring_enc_context(kvm)) {
1507 kvm_put_kvm(sev->enc_context_owner);
1508 return;
1509 }
1510
Joerg Roedeleaf78262020-03-24 10:41:54 +01001511 mutex_lock(&kvm->lock);
1512
1513 /*
1514 * Ensure that all guest tagged cache entries are flushed before
1515 * releasing the pages back to the system for use. CLFLUSH will
1516 * not do this, so issue a WBINVD.
1517 */
1518 wbinvd_on_all_cpus();
1519
1520 /*
1521 * if userspace was terminated before unregistering the memory regions
1522 * then lets unpin all the registered memory.
1523 */
1524 if (!list_empty(head)) {
1525 list_for_each_safe(pos, q, head) {
1526 __unregister_enc_region_locked(kvm,
1527 list_entry(pos, struct enc_region, list));
David Rientjes7be74942020-08-25 12:56:28 -07001528 cond_resched();
Joerg Roedeleaf78262020-03-24 10:41:54 +01001529 }
1530 }
1531
1532 mutex_unlock(&kvm->lock);
1533
1534 sev_unbind_asid(kvm, sev->handle);
1535 sev_asid_free(sev->asid);
1536}
1537
Tom Lendacky916391a2020-12-10 11:09:38 -06001538void __init sev_hardware_setup(void)
Joerg Roedeleaf78262020-03-24 10:41:54 +01001539{
Tom Lendacky916391a2020-12-10 11:09:38 -06001540 unsigned int eax, ebx, ecx, edx;
1541 bool sev_es_supported = false;
1542 bool sev_supported = false;
1543
1544 /* Does the CPU support SEV? */
1545 if (!boot_cpu_has(X86_FEATURE_SEV))
1546 goto out;
1547
1548 /* Retrieve SEV CPUID information */
1549 cpuid(0x8000001f, &eax, &ebx, &ecx, &edx);
1550
Tom Lendacky1edc1452020-12-10 11:09:49 -06001551 /* Set encryption bit location for SEV-ES guests */
1552 sev_enc_bit = ebx & 0x3f;
1553
Joerg Roedeleaf78262020-03-24 10:41:54 +01001554 /* Maximum number of encrypted guests supported simultaneously */
Tom Lendacky916391a2020-12-10 11:09:38 -06001555 max_sev_asid = ecx;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001556
Paolo Bonzini9ef15302020-04-13 03:20:06 -04001557 if (!svm_sev_enabled())
Tom Lendacky916391a2020-12-10 11:09:38 -06001558 goto out;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001559
1560 /* Minimum ASID value that should be used for SEV guest */
Tom Lendacky916391a2020-12-10 11:09:38 -06001561 min_sev_asid = edx;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001562
1563 /* Initialize SEV ASID bitmaps */
1564 sev_asid_bitmap = bitmap_zalloc(max_sev_asid, GFP_KERNEL);
1565 if (!sev_asid_bitmap)
Tom Lendacky916391a2020-12-10 11:09:38 -06001566 goto out;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001567
1568 sev_reclaim_asid_bitmap = bitmap_zalloc(max_sev_asid, GFP_KERNEL);
1569 if (!sev_reclaim_asid_bitmap)
Tom Lendacky916391a2020-12-10 11:09:38 -06001570 goto out;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001571
Tom Lendacky916391a2020-12-10 11:09:38 -06001572 pr_info("SEV supported: %u ASIDs\n", max_sev_asid - min_sev_asid + 1);
1573 sev_supported = true;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001574
Tom Lendacky916391a2020-12-10 11:09:38 -06001575 /* SEV-ES support requested? */
1576 if (!sev_es)
1577 goto out;
1578
1579 /* Does the CPU support SEV-ES? */
1580 if (!boot_cpu_has(X86_FEATURE_SEV_ES))
1581 goto out;
1582
1583 /* Has the system been allocated ASIDs for SEV-ES? */
1584 if (min_sev_asid == 1)
1585 goto out;
1586
1587 pr_info("SEV-ES supported: %u ASIDs\n", min_sev_asid - 1);
1588 sev_es_supported = true;
1589
1590out:
1591 sev = sev_supported;
1592 sev_es = sev_es_supported;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001593}
1594
1595void sev_hardware_teardown(void)
1596{
Paolo Bonzini9ef15302020-04-13 03:20:06 -04001597 if (!svm_sev_enabled())
1598 return;
1599
Joerg Roedeleaf78262020-03-24 10:41:54 +01001600 bitmap_free(sev_asid_bitmap);
1601 bitmap_free(sev_reclaim_asid_bitmap);
1602
1603 sev_flush_asids();
1604}
1605
Tom Lendackyadd5e2f2020-12-10 11:09:40 -06001606/*
1607 * Pages used by hardware to hold guest encrypted state must be flushed before
1608 * returning them to the system.
1609 */
1610static void sev_flush_guest_memory(struct vcpu_svm *svm, void *va,
1611 unsigned long len)
1612{
1613 /*
1614 * If hardware enforced cache coherency for encrypted mappings of the
1615 * same physical page is supported, nothing to do.
1616 */
1617 if (boot_cpu_has(X86_FEATURE_SME_COHERENT))
1618 return;
1619
1620 /*
1621 * If the VM Page Flush MSR is supported, use it to flush the page
1622 * (using the page virtual address and the guest ASID).
1623 */
1624 if (boot_cpu_has(X86_FEATURE_VM_PAGE_FLUSH)) {
1625 struct kvm_sev_info *sev;
1626 unsigned long va_start;
1627 u64 start, stop;
1628
1629 /* Align start and stop to page boundaries. */
1630 va_start = (unsigned long)va;
1631 start = (u64)va_start & PAGE_MASK;
1632 stop = PAGE_ALIGN((u64)va_start + len);
1633
1634 if (start < stop) {
1635 sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info;
1636
1637 while (start < stop) {
1638 wrmsrl(MSR_AMD64_VM_PAGE_FLUSH,
1639 start | sev->asid);
1640
1641 start += PAGE_SIZE;
1642 }
1643
1644 return;
1645 }
1646
1647 WARN(1, "Address overflow, using WBINVD\n");
1648 }
1649
1650 /*
1651 * Hardware should always have one of the above features,
1652 * but if not, use WBINVD and issue a warning.
1653 */
1654 WARN_ONCE(1, "Using WBINVD to flush guest memory\n");
1655 wbinvd_on_all_cpus();
1656}
1657
1658void sev_free_vcpu(struct kvm_vcpu *vcpu)
1659{
1660 struct vcpu_svm *svm;
1661
1662 if (!sev_es_guest(vcpu->kvm))
1663 return;
1664
1665 svm = to_svm(vcpu);
1666
1667 if (vcpu->arch.guest_state_protected)
1668 sev_flush_guest_memory(svm, svm->vmsa, PAGE_SIZE);
1669 __free_page(virt_to_page(svm->vmsa));
Tom Lendacky8f423a82020-12-10 11:09:53 -06001670
1671 if (svm->ghcb_sa_free)
1672 kfree(svm->ghcb_sa);
Tom Lendackyadd5e2f2020-12-10 11:09:40 -06001673}
1674
Tom Lendacky291bd202020-12-10 11:09:47 -06001675static void dump_ghcb(struct vcpu_svm *svm)
1676{
1677 struct ghcb *ghcb = svm->ghcb;
1678 unsigned int nbits;
1679
1680 /* Re-use the dump_invalid_vmcb module parameter */
1681 if (!dump_invalid_vmcb) {
1682 pr_warn_ratelimited("set kvm_amd.dump_invalid_vmcb=1 to dump internal KVM state.\n");
1683 return;
1684 }
1685
1686 nbits = sizeof(ghcb->save.valid_bitmap) * 8;
1687
1688 pr_err("GHCB (GPA=%016llx):\n", svm->vmcb->control.ghcb_gpa);
1689 pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_code",
1690 ghcb->save.sw_exit_code, ghcb_sw_exit_code_is_valid(ghcb));
1691 pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_1",
1692 ghcb->save.sw_exit_info_1, ghcb_sw_exit_info_1_is_valid(ghcb));
1693 pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_2",
1694 ghcb->save.sw_exit_info_2, ghcb_sw_exit_info_2_is_valid(ghcb));
1695 pr_err("%-20s%016llx is_valid: %u\n", "sw_scratch",
1696 ghcb->save.sw_scratch, ghcb_sw_scratch_is_valid(ghcb));
1697 pr_err("%-20s%*pb\n", "valid_bitmap", nbits, ghcb->save.valid_bitmap);
1698}
1699
1700static void sev_es_sync_to_ghcb(struct vcpu_svm *svm)
1701{
1702 struct kvm_vcpu *vcpu = &svm->vcpu;
1703 struct ghcb *ghcb = svm->ghcb;
1704
1705 /*
1706 * The GHCB protocol so far allows for the following data
1707 * to be returned:
1708 * GPRs RAX, RBX, RCX, RDX
1709 *
Sean Christopherson25009142021-01-22 15:50:47 -08001710 * Copy their values, even if they may not have been written during the
1711 * VM-Exit. It's the guest's responsibility to not consume random data.
Tom Lendacky291bd202020-12-10 11:09:47 -06001712 */
Sean Christopherson25009142021-01-22 15:50:47 -08001713 ghcb_set_rax(ghcb, vcpu->arch.regs[VCPU_REGS_RAX]);
1714 ghcb_set_rbx(ghcb, vcpu->arch.regs[VCPU_REGS_RBX]);
1715 ghcb_set_rcx(ghcb, vcpu->arch.regs[VCPU_REGS_RCX]);
1716 ghcb_set_rdx(ghcb, vcpu->arch.regs[VCPU_REGS_RDX]);
Tom Lendacky291bd202020-12-10 11:09:47 -06001717}
1718
1719static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
1720{
1721 struct vmcb_control_area *control = &svm->vmcb->control;
1722 struct kvm_vcpu *vcpu = &svm->vcpu;
1723 struct ghcb *ghcb = svm->ghcb;
1724 u64 exit_code;
1725
1726 /*
1727 * The GHCB protocol so far allows for the following data
1728 * to be supplied:
1729 * GPRs RAX, RBX, RCX, RDX
1730 * XCR0
1731 * CPL
1732 *
1733 * VMMCALL allows the guest to provide extra registers. KVM also
1734 * expects RSI for hypercalls, so include that, too.
1735 *
1736 * Copy their values to the appropriate location if supplied.
1737 */
1738 memset(vcpu->arch.regs, 0, sizeof(vcpu->arch.regs));
1739
1740 vcpu->arch.regs[VCPU_REGS_RAX] = ghcb_get_rax_if_valid(ghcb);
1741 vcpu->arch.regs[VCPU_REGS_RBX] = ghcb_get_rbx_if_valid(ghcb);
1742 vcpu->arch.regs[VCPU_REGS_RCX] = ghcb_get_rcx_if_valid(ghcb);
1743 vcpu->arch.regs[VCPU_REGS_RDX] = ghcb_get_rdx_if_valid(ghcb);
1744 vcpu->arch.regs[VCPU_REGS_RSI] = ghcb_get_rsi_if_valid(ghcb);
1745
1746 svm->vmcb->save.cpl = ghcb_get_cpl_if_valid(ghcb);
1747
1748 if (ghcb_xcr0_is_valid(ghcb)) {
1749 vcpu->arch.xcr0 = ghcb_get_xcr0(ghcb);
1750 kvm_update_cpuid_runtime(vcpu);
1751 }
1752
1753 /* Copy the GHCB exit information into the VMCB fields */
1754 exit_code = ghcb_get_sw_exit_code(ghcb);
1755 control->exit_code = lower_32_bits(exit_code);
1756 control->exit_code_hi = upper_32_bits(exit_code);
1757 control->exit_info_1 = ghcb_get_sw_exit_info_1(ghcb);
1758 control->exit_info_2 = ghcb_get_sw_exit_info_2(ghcb);
1759
1760 /* Clear the valid entries fields */
1761 memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
1762}
1763
1764static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
1765{
1766 struct kvm_vcpu *vcpu;
1767 struct ghcb *ghcb;
1768 u64 exit_code = 0;
1769
1770 ghcb = svm->ghcb;
1771
1772 /* Only GHCB Usage code 0 is supported */
1773 if (ghcb->ghcb_usage)
1774 goto vmgexit_err;
1775
1776 /*
1777 * Retrieve the exit code now even though is may not be marked valid
1778 * as it could help with debugging.
1779 */
1780 exit_code = ghcb_get_sw_exit_code(ghcb);
1781
1782 if (!ghcb_sw_exit_code_is_valid(ghcb) ||
1783 !ghcb_sw_exit_info_1_is_valid(ghcb) ||
1784 !ghcb_sw_exit_info_2_is_valid(ghcb))
1785 goto vmgexit_err;
1786
1787 switch (ghcb_get_sw_exit_code(ghcb)) {
1788 case SVM_EXIT_READ_DR7:
1789 break;
1790 case SVM_EXIT_WRITE_DR7:
1791 if (!ghcb_rax_is_valid(ghcb))
1792 goto vmgexit_err;
1793 break;
1794 case SVM_EXIT_RDTSC:
1795 break;
1796 case SVM_EXIT_RDPMC:
1797 if (!ghcb_rcx_is_valid(ghcb))
1798 goto vmgexit_err;
1799 break;
1800 case SVM_EXIT_CPUID:
1801 if (!ghcb_rax_is_valid(ghcb) ||
1802 !ghcb_rcx_is_valid(ghcb))
1803 goto vmgexit_err;
1804 if (ghcb_get_rax(ghcb) == 0xd)
1805 if (!ghcb_xcr0_is_valid(ghcb))
1806 goto vmgexit_err;
1807 break;
1808 case SVM_EXIT_INVD:
1809 break;
1810 case SVM_EXIT_IOIO:
Tom Lendacky7ed9abf2020-12-10 11:09:54 -06001811 if (ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_STR_MASK) {
1812 if (!ghcb_sw_scratch_is_valid(ghcb))
Tom Lendacky291bd202020-12-10 11:09:47 -06001813 goto vmgexit_err;
Tom Lendacky7ed9abf2020-12-10 11:09:54 -06001814 } else {
1815 if (!(ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_TYPE_MASK))
1816 if (!ghcb_rax_is_valid(ghcb))
1817 goto vmgexit_err;
1818 }
Tom Lendacky291bd202020-12-10 11:09:47 -06001819 break;
1820 case SVM_EXIT_MSR:
1821 if (!ghcb_rcx_is_valid(ghcb))
1822 goto vmgexit_err;
1823 if (ghcb_get_sw_exit_info_1(ghcb)) {
1824 if (!ghcb_rax_is_valid(ghcb) ||
1825 !ghcb_rdx_is_valid(ghcb))
1826 goto vmgexit_err;
1827 }
1828 break;
1829 case SVM_EXIT_VMMCALL:
1830 if (!ghcb_rax_is_valid(ghcb) ||
1831 !ghcb_cpl_is_valid(ghcb))
1832 goto vmgexit_err;
1833 break;
1834 case SVM_EXIT_RDTSCP:
1835 break;
1836 case SVM_EXIT_WBINVD:
1837 break;
1838 case SVM_EXIT_MONITOR:
1839 if (!ghcb_rax_is_valid(ghcb) ||
1840 !ghcb_rcx_is_valid(ghcb) ||
1841 !ghcb_rdx_is_valid(ghcb))
1842 goto vmgexit_err;
1843 break;
1844 case SVM_EXIT_MWAIT:
1845 if (!ghcb_rax_is_valid(ghcb) ||
1846 !ghcb_rcx_is_valid(ghcb))
1847 goto vmgexit_err;
1848 break;
Tom Lendacky8f423a82020-12-10 11:09:53 -06001849 case SVM_VMGEXIT_MMIO_READ:
1850 case SVM_VMGEXIT_MMIO_WRITE:
1851 if (!ghcb_sw_scratch_is_valid(ghcb))
1852 goto vmgexit_err;
1853 break;
Tom Lendacky4444dfe2020-12-14 11:16:03 -05001854 case SVM_VMGEXIT_NMI_COMPLETE:
Tom Lendacky647daca2021-01-04 14:20:01 -06001855 case SVM_VMGEXIT_AP_HLT_LOOP:
Tom Lendacky8640ca52020-12-15 12:44:07 -05001856 case SVM_VMGEXIT_AP_JUMP_TABLE:
Tom Lendacky291bd202020-12-10 11:09:47 -06001857 case SVM_VMGEXIT_UNSUPPORTED_EVENT:
1858 break;
1859 default:
1860 goto vmgexit_err;
1861 }
1862
1863 return 0;
1864
1865vmgexit_err:
1866 vcpu = &svm->vcpu;
1867
1868 if (ghcb->ghcb_usage) {
1869 vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n",
1870 ghcb->ghcb_usage);
1871 } else {
1872 vcpu_unimpl(vcpu, "vmgexit: exit reason %#llx is not valid\n",
1873 exit_code);
1874 dump_ghcb(svm);
1875 }
1876
1877 vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
1878 vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON;
1879 vcpu->run->internal.ndata = 2;
1880 vcpu->run->internal.data[0] = exit_code;
1881 vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu;
1882
1883 return -EINVAL;
1884}
1885
1886static void pre_sev_es_run(struct vcpu_svm *svm)
1887{
1888 if (!svm->ghcb)
1889 return;
1890
Tom Lendacky8f423a82020-12-10 11:09:53 -06001891 if (svm->ghcb_sa_free) {
1892 /*
1893 * The scratch area lives outside the GHCB, so there is a
1894 * buffer that, depending on the operation performed, may
1895 * need to be synced, then freed.
1896 */
1897 if (svm->ghcb_sa_sync) {
1898 kvm_write_guest(svm->vcpu.kvm,
1899 ghcb_get_sw_scratch(svm->ghcb),
1900 svm->ghcb_sa, svm->ghcb_sa_len);
1901 svm->ghcb_sa_sync = false;
1902 }
1903
1904 kfree(svm->ghcb_sa);
1905 svm->ghcb_sa = NULL;
1906 svm->ghcb_sa_free = false;
1907 }
1908
Tom Lendackyd523ab6b2020-12-10 11:09:48 -06001909 trace_kvm_vmgexit_exit(svm->vcpu.vcpu_id, svm->ghcb);
1910
Tom Lendacky291bd202020-12-10 11:09:47 -06001911 sev_es_sync_to_ghcb(svm);
1912
1913 kvm_vcpu_unmap(&svm->vcpu, &svm->ghcb_map, true);
1914 svm->ghcb = NULL;
1915}
1916
Joerg Roedeleaf78262020-03-24 10:41:54 +01001917void pre_sev_run(struct vcpu_svm *svm, int cpu)
1918{
1919 struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
1920 int asid = sev_get_asid(svm->vcpu.kvm);
1921
Tom Lendacky291bd202020-12-10 11:09:47 -06001922 /* Perform any SEV-ES pre-run actions */
1923 pre_sev_es_run(svm);
1924
Joerg Roedeleaf78262020-03-24 10:41:54 +01001925 /* Assign the asid allocated with this SEV guest */
Paolo Bonzinidee734a2020-11-30 09:39:59 -05001926 svm->asid = asid;
Joerg Roedeleaf78262020-03-24 10:41:54 +01001927
1928 /*
1929 * Flush guest TLB:
1930 *
1931 * 1) when different VMCB for the same ASID is to be run on the same host CPU.
1932 * 2) or this VMCB was executed on different host CPU in previous VMRUNs.
1933 */
1934 if (sd->sev_vmcbs[asid] == svm->vmcb &&
Jim Mattson8a14fe42020-06-03 16:56:22 -07001935 svm->vcpu.arch.last_vmentry_cpu == cpu)
Joerg Roedeleaf78262020-03-24 10:41:54 +01001936 return;
1937
Joerg Roedeleaf78262020-03-24 10:41:54 +01001938 sd->sev_vmcbs[asid] = svm->vmcb;
1939 svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID;
Joerg Roedel06e78522020-06-25 10:03:23 +02001940 vmcb_mark_dirty(svm->vmcb, VMCB_ASID);
Joerg Roedeleaf78262020-03-24 10:41:54 +01001941}
Tom Lendacky291bd202020-12-10 11:09:47 -06001942
Tom Lendacky8f423a82020-12-10 11:09:53 -06001943#define GHCB_SCRATCH_AREA_LIMIT (16ULL * PAGE_SIZE)
1944static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
1945{
1946 struct vmcb_control_area *control = &svm->vmcb->control;
1947 struct ghcb *ghcb = svm->ghcb;
1948 u64 ghcb_scratch_beg, ghcb_scratch_end;
1949 u64 scratch_gpa_beg, scratch_gpa_end;
1950 void *scratch_va;
1951
1952 scratch_gpa_beg = ghcb_get_sw_scratch(ghcb);
1953 if (!scratch_gpa_beg) {
1954 pr_err("vmgexit: scratch gpa not provided\n");
1955 return false;
1956 }
1957
1958 scratch_gpa_end = scratch_gpa_beg + len;
1959 if (scratch_gpa_end < scratch_gpa_beg) {
1960 pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n",
1961 len, scratch_gpa_beg);
1962 return false;
1963 }
1964
1965 if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) {
1966 /* Scratch area begins within GHCB */
1967 ghcb_scratch_beg = control->ghcb_gpa +
1968 offsetof(struct ghcb, shared_buffer);
1969 ghcb_scratch_end = control->ghcb_gpa +
1970 offsetof(struct ghcb, reserved_1);
1971
1972 /*
1973 * If the scratch area begins within the GHCB, it must be
1974 * completely contained in the GHCB shared buffer area.
1975 */
1976 if (scratch_gpa_beg < ghcb_scratch_beg ||
1977 scratch_gpa_end > ghcb_scratch_end) {
1978 pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n",
1979 scratch_gpa_beg, scratch_gpa_end);
1980 return false;
1981 }
1982
1983 scratch_va = (void *)svm->ghcb;
1984 scratch_va += (scratch_gpa_beg - control->ghcb_gpa);
1985 } else {
1986 /*
1987 * The guest memory must be read into a kernel buffer, so
1988 * limit the size
1989 */
1990 if (len > GHCB_SCRATCH_AREA_LIMIT) {
1991 pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n",
1992 len, GHCB_SCRATCH_AREA_LIMIT);
1993 return false;
1994 }
Sean Christophersoneba04b22021-03-30 19:30:25 -07001995 scratch_va = kzalloc(len, GFP_KERNEL_ACCOUNT);
Tom Lendacky8f423a82020-12-10 11:09:53 -06001996 if (!scratch_va)
1997 return false;
1998
1999 if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) {
2000 /* Unable to copy scratch area from guest */
2001 pr_err("vmgexit: kvm_read_guest for scratch area failed\n");
2002
2003 kfree(scratch_va);
2004 return false;
2005 }
2006
2007 /*
2008 * The scratch area is outside the GHCB. The operation will
2009 * dictate whether the buffer needs to be synced before running
2010 * the vCPU next time (i.e. a read was requested so the data
2011 * must be written back to the guest memory).
2012 */
2013 svm->ghcb_sa_sync = sync;
2014 svm->ghcb_sa_free = true;
2015 }
2016
2017 svm->ghcb_sa = scratch_va;
2018 svm->ghcb_sa_len = len;
2019
2020 return true;
2021}
2022
Tom Lendackyd3694662020-12-10 11:09:50 -06002023static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask,
2024 unsigned int pos)
2025{
2026 svm->vmcb->control.ghcb_gpa &= ~(mask << pos);
2027 svm->vmcb->control.ghcb_gpa |= (value & mask) << pos;
2028}
2029
2030static u64 get_ghcb_msr_bits(struct vcpu_svm *svm, u64 mask, unsigned int pos)
2031{
2032 return (svm->vmcb->control.ghcb_gpa >> pos) & mask;
2033}
2034
Tom Lendacky1edc1452020-12-10 11:09:49 -06002035static void set_ghcb_msr(struct vcpu_svm *svm, u64 value)
2036{
2037 svm->vmcb->control.ghcb_gpa = value;
2038}
2039
Tom Lendacky291bd202020-12-10 11:09:47 -06002040static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
2041{
Tom Lendacky1edc1452020-12-10 11:09:49 -06002042 struct vmcb_control_area *control = &svm->vmcb->control;
Tom Lendackyd3694662020-12-10 11:09:50 -06002043 struct kvm_vcpu *vcpu = &svm->vcpu;
Tom Lendacky1edc1452020-12-10 11:09:49 -06002044 u64 ghcb_info;
Tom Lendackyd3694662020-12-10 11:09:50 -06002045 int ret = 1;
Tom Lendacky1edc1452020-12-10 11:09:49 -06002046
2047 ghcb_info = control->ghcb_gpa & GHCB_MSR_INFO_MASK;
2048
Tom Lendacky59e38b52020-12-10 11:09:52 -06002049 trace_kvm_vmgexit_msr_protocol_enter(svm->vcpu.vcpu_id,
2050 control->ghcb_gpa);
2051
Tom Lendacky1edc1452020-12-10 11:09:49 -06002052 switch (ghcb_info) {
2053 case GHCB_MSR_SEV_INFO_REQ:
2054 set_ghcb_msr(svm, GHCB_MSR_SEV_INFO(GHCB_VERSION_MAX,
2055 GHCB_VERSION_MIN,
2056 sev_enc_bit));
2057 break;
Tom Lendackyd3694662020-12-10 11:09:50 -06002058 case GHCB_MSR_CPUID_REQ: {
2059 u64 cpuid_fn, cpuid_reg, cpuid_value;
2060
2061 cpuid_fn = get_ghcb_msr_bits(svm,
2062 GHCB_MSR_CPUID_FUNC_MASK,
2063 GHCB_MSR_CPUID_FUNC_POS);
2064
2065 /* Initialize the registers needed by the CPUID intercept */
2066 vcpu->arch.regs[VCPU_REGS_RAX] = cpuid_fn;
2067 vcpu->arch.regs[VCPU_REGS_RCX] = 0;
2068
Paolo Bonzini63129752021-03-02 14:40:39 -05002069 ret = svm_invoke_exit_handler(vcpu, SVM_EXIT_CPUID);
Tom Lendackyd3694662020-12-10 11:09:50 -06002070 if (!ret) {
2071 ret = -EINVAL;
2072 break;
2073 }
2074
2075 cpuid_reg = get_ghcb_msr_bits(svm,
2076 GHCB_MSR_CPUID_REG_MASK,
2077 GHCB_MSR_CPUID_REG_POS);
2078 if (cpuid_reg == 0)
2079 cpuid_value = vcpu->arch.regs[VCPU_REGS_RAX];
2080 else if (cpuid_reg == 1)
2081 cpuid_value = vcpu->arch.regs[VCPU_REGS_RBX];
2082 else if (cpuid_reg == 2)
2083 cpuid_value = vcpu->arch.regs[VCPU_REGS_RCX];
2084 else
2085 cpuid_value = vcpu->arch.regs[VCPU_REGS_RDX];
2086
2087 set_ghcb_msr_bits(svm, cpuid_value,
2088 GHCB_MSR_CPUID_VALUE_MASK,
2089 GHCB_MSR_CPUID_VALUE_POS);
2090
2091 set_ghcb_msr_bits(svm, GHCB_MSR_CPUID_RESP,
2092 GHCB_MSR_INFO_MASK,
2093 GHCB_MSR_INFO_POS);
2094 break;
2095 }
Tom Lendackye1d71112020-12-10 11:09:51 -06002096 case GHCB_MSR_TERM_REQ: {
2097 u64 reason_set, reason_code;
2098
2099 reason_set = get_ghcb_msr_bits(svm,
2100 GHCB_MSR_TERM_REASON_SET_MASK,
2101 GHCB_MSR_TERM_REASON_SET_POS);
2102 reason_code = get_ghcb_msr_bits(svm,
2103 GHCB_MSR_TERM_REASON_MASK,
2104 GHCB_MSR_TERM_REASON_POS);
2105 pr_info("SEV-ES guest requested termination: %#llx:%#llx\n",
2106 reason_set, reason_code);
2107 fallthrough;
2108 }
Tom Lendacky1edc1452020-12-10 11:09:49 -06002109 default:
Tom Lendackyd3694662020-12-10 11:09:50 -06002110 ret = -EINVAL;
Tom Lendacky1edc1452020-12-10 11:09:49 -06002111 }
2112
Tom Lendacky59e38b52020-12-10 11:09:52 -06002113 trace_kvm_vmgexit_msr_protocol_exit(svm->vcpu.vcpu_id,
2114 control->ghcb_gpa, ret);
2115
Tom Lendackyd3694662020-12-10 11:09:50 -06002116 return ret;
Tom Lendacky291bd202020-12-10 11:09:47 -06002117}
2118
Paolo Bonzini63129752021-03-02 14:40:39 -05002119int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
Tom Lendacky291bd202020-12-10 11:09:47 -06002120{
Paolo Bonzini63129752021-03-02 14:40:39 -05002121 struct vcpu_svm *svm = to_svm(vcpu);
Tom Lendacky291bd202020-12-10 11:09:47 -06002122 struct vmcb_control_area *control = &svm->vmcb->control;
2123 u64 ghcb_gpa, exit_code;
2124 struct ghcb *ghcb;
2125 int ret;
2126
2127 /* Validate the GHCB */
2128 ghcb_gpa = control->ghcb_gpa;
2129 if (ghcb_gpa & GHCB_MSR_INFO_MASK)
2130 return sev_handle_vmgexit_msr_protocol(svm);
2131
2132 if (!ghcb_gpa) {
Paolo Bonzini63129752021-03-02 14:40:39 -05002133 vcpu_unimpl(vcpu, "vmgexit: GHCB gpa is not set\n");
Tom Lendacky291bd202020-12-10 11:09:47 -06002134 return -EINVAL;
2135 }
2136
Paolo Bonzini63129752021-03-02 14:40:39 -05002137 if (kvm_vcpu_map(vcpu, ghcb_gpa >> PAGE_SHIFT, &svm->ghcb_map)) {
Tom Lendacky291bd202020-12-10 11:09:47 -06002138 /* Unable to map GHCB from guest */
Paolo Bonzini63129752021-03-02 14:40:39 -05002139 vcpu_unimpl(vcpu, "vmgexit: error mapping GHCB [%#llx] from guest\n",
Tom Lendacky291bd202020-12-10 11:09:47 -06002140 ghcb_gpa);
2141 return -EINVAL;
2142 }
2143
2144 svm->ghcb = svm->ghcb_map.hva;
2145 ghcb = svm->ghcb_map.hva;
2146
Paolo Bonzini63129752021-03-02 14:40:39 -05002147 trace_kvm_vmgexit_enter(vcpu->vcpu_id, ghcb);
Tom Lendackyd523ab6b2020-12-10 11:09:48 -06002148
Tom Lendacky291bd202020-12-10 11:09:47 -06002149 exit_code = ghcb_get_sw_exit_code(ghcb);
2150
2151 ret = sev_es_validate_vmgexit(svm);
2152 if (ret)
2153 return ret;
2154
2155 sev_es_sync_from_ghcb(svm);
2156 ghcb_set_sw_exit_info_1(ghcb, 0);
2157 ghcb_set_sw_exit_info_2(ghcb, 0);
2158
2159 ret = -EINVAL;
2160 switch (exit_code) {
Tom Lendacky8f423a82020-12-10 11:09:53 -06002161 case SVM_VMGEXIT_MMIO_READ:
2162 if (!setup_vmgexit_scratch(svm, true, control->exit_info_2))
2163 break;
2164
Paolo Bonzini63129752021-03-02 14:40:39 -05002165 ret = kvm_sev_es_mmio_read(vcpu,
Tom Lendacky8f423a82020-12-10 11:09:53 -06002166 control->exit_info_1,
2167 control->exit_info_2,
2168 svm->ghcb_sa);
2169 break;
2170 case SVM_VMGEXIT_MMIO_WRITE:
2171 if (!setup_vmgexit_scratch(svm, false, control->exit_info_2))
2172 break;
2173
Paolo Bonzini63129752021-03-02 14:40:39 -05002174 ret = kvm_sev_es_mmio_write(vcpu,
Tom Lendacky8f423a82020-12-10 11:09:53 -06002175 control->exit_info_1,
2176 control->exit_info_2,
2177 svm->ghcb_sa);
2178 break;
Tom Lendacky4444dfe2020-12-14 11:16:03 -05002179 case SVM_VMGEXIT_NMI_COMPLETE:
Paolo Bonzini63129752021-03-02 14:40:39 -05002180 ret = svm_invoke_exit_handler(vcpu, SVM_EXIT_IRET);
Tom Lendacky4444dfe2020-12-14 11:16:03 -05002181 break;
Tom Lendacky647daca2021-01-04 14:20:01 -06002182 case SVM_VMGEXIT_AP_HLT_LOOP:
Paolo Bonzini63129752021-03-02 14:40:39 -05002183 ret = kvm_emulate_ap_reset_hold(vcpu);
Tom Lendacky647daca2021-01-04 14:20:01 -06002184 break;
Tom Lendacky8640ca52020-12-15 12:44:07 -05002185 case SVM_VMGEXIT_AP_JUMP_TABLE: {
Paolo Bonzini63129752021-03-02 14:40:39 -05002186 struct kvm_sev_info *sev = &to_kvm_svm(vcpu->kvm)->sev_info;
Tom Lendacky8640ca52020-12-15 12:44:07 -05002187
2188 switch (control->exit_info_1) {
2189 case 0:
2190 /* Set AP jump table address */
2191 sev->ap_jump_table = control->exit_info_2;
2192 break;
2193 case 1:
2194 /* Get AP jump table address */
2195 ghcb_set_sw_exit_info_2(ghcb, sev->ap_jump_table);
2196 break;
2197 default:
2198 pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n",
2199 control->exit_info_1);
2200 ghcb_set_sw_exit_info_1(ghcb, 1);
2201 ghcb_set_sw_exit_info_2(ghcb,
2202 X86_TRAP_UD |
2203 SVM_EVTINJ_TYPE_EXEPT |
2204 SVM_EVTINJ_VALID);
2205 }
2206
2207 ret = 1;
2208 break;
2209 }
Tom Lendacky291bd202020-12-10 11:09:47 -06002210 case SVM_VMGEXIT_UNSUPPORTED_EVENT:
Paolo Bonzini63129752021-03-02 14:40:39 -05002211 vcpu_unimpl(vcpu,
Tom Lendacky291bd202020-12-10 11:09:47 -06002212 "vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n",
2213 control->exit_info_1, control->exit_info_2);
2214 break;
2215 default:
Paolo Bonzini63129752021-03-02 14:40:39 -05002216 ret = svm_invoke_exit_handler(vcpu, exit_code);
Tom Lendacky291bd202020-12-10 11:09:47 -06002217 }
2218
2219 return ret;
2220}
Tom Lendacky7ed9abf2020-12-10 11:09:54 -06002221
2222int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
2223{
2224 if (!setup_vmgexit_scratch(svm, in, svm->vmcb->control.exit_info_2))
2225 return -EINVAL;
2226
2227 return kvm_sev_es_string_io(&svm->vcpu, size, port,
2228 svm->ghcb_sa, svm->ghcb_sa_len, in);
2229}
Tom Lendacky376c6d22020-12-10 11:10:06 -06002230
2231void sev_es_init_vmcb(struct vcpu_svm *svm)
2232{
2233 struct kvm_vcpu *vcpu = &svm->vcpu;
2234
2235 svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ES_ENABLE;
2236 svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK;
2237
2238 /*
2239 * An SEV-ES guest requires a VMSA area that is a separate from the
2240 * VMCB page. Do not include the encryption mask on the VMSA physical
2241 * address since hardware will access it using the guest key.
2242 */
2243 svm->vmcb->control.vmsa_pa = __pa(svm->vmsa);
2244
2245 /* Can't intercept CR register access, HV can't modify CR registers */
2246 svm_clr_intercept(svm, INTERCEPT_CR0_READ);
2247 svm_clr_intercept(svm, INTERCEPT_CR4_READ);
2248 svm_clr_intercept(svm, INTERCEPT_CR8_READ);
2249 svm_clr_intercept(svm, INTERCEPT_CR0_WRITE);
2250 svm_clr_intercept(svm, INTERCEPT_CR4_WRITE);
2251 svm_clr_intercept(svm, INTERCEPT_CR8_WRITE);
2252
2253 svm_clr_intercept(svm, INTERCEPT_SELECTIVE_CR0);
2254
2255 /* Track EFER/CR register changes */
2256 svm_set_intercept(svm, TRAP_EFER_WRITE);
2257 svm_set_intercept(svm, TRAP_CR0_WRITE);
2258 svm_set_intercept(svm, TRAP_CR4_WRITE);
2259 svm_set_intercept(svm, TRAP_CR8_WRITE);
2260
2261 /* No support for enable_vmware_backdoor */
2262 clr_exception_intercept(svm, GP_VECTOR);
2263
2264 /* Can't intercept XSETBV, HV can't modify XCR0 directly */
2265 svm_clr_intercept(svm, INTERCEPT_XSETBV);
2266
2267 /* Clear intercepts on selected MSRs */
2268 set_msr_interception(vcpu, svm->msrpm, MSR_EFER, 1, 1);
2269 set_msr_interception(vcpu, svm->msrpm, MSR_IA32_CR_PAT, 1, 1);
2270 set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1);
2271 set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1);
2272 set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
2273 set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
2274}
2275
2276void sev_es_create_vcpu(struct vcpu_svm *svm)
2277{
2278 /*
2279 * Set the GHCB MSR value as per the GHCB specification when creating
2280 * a vCPU for an SEV-ES guest.
2281 */
2282 set_ghcb_msr(svm, GHCB_MSR_SEV_INFO(GHCB_VERSION_MAX,
2283 GHCB_VERSION_MIN,
2284 sev_enc_bit));
2285}
Tom Lendacky86137772020-12-10 11:10:07 -06002286
Michael Rotha7fc06d2021-02-02 13:01:26 -06002287void sev_es_prepare_guest_switch(struct vcpu_svm *svm, unsigned int cpu)
Tom Lendacky86137772020-12-10 11:10:07 -06002288{
2289 struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
2290 struct vmcb_save_area *hostsa;
Tom Lendacky86137772020-12-10 11:10:07 -06002291
2292 /*
2293 * As an SEV-ES guest, hardware will restore the host state on VMEXIT,
2294 * of which one step is to perform a VMLOAD. Since hardware does not
2295 * perform a VMSAVE on VMRUN, the host savearea must be updated.
2296 */
Sean Christopherson35a78312020-12-30 16:27:00 -08002297 vmsave(__sme_page_pa(sd->save_area));
Tom Lendacky86137772020-12-10 11:10:07 -06002298
Tom Lendacky86137772020-12-10 11:10:07 -06002299 /* XCR0 is restored on VMEXIT, save the current host value */
2300 hostsa = (struct vmcb_save_area *)(page_address(sd->save_area) + 0x400);
2301 hostsa->xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
2302
2303 /* PKRU is restored on VMEXIT, save the curent host value */
2304 hostsa->pkru = read_pkru();
2305
2306 /* MSR_IA32_XSS is restored on VMEXIT, save the currnet host value */
2307 hostsa->xss = host_xss;
2308}
2309
Tom Lendacky647daca2021-01-04 14:20:01 -06002310void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector)
2311{
2312 struct vcpu_svm *svm = to_svm(vcpu);
2313
2314 /* First SIPI: Use the values as initially set by the VMM */
2315 if (!svm->received_first_sipi) {
2316 svm->received_first_sipi = true;
2317 return;
2318 }
2319
2320 /*
2321 * Subsequent SIPI: Return from an AP Reset Hold VMGEXIT, where
2322 * the guest will set the CS and RIP. Set SW_EXIT_INFO_2 to a
2323 * non-zero value.
2324 */
Tom Lendackya3ba26e2021-04-09 09:38:42 -05002325 if (!svm->ghcb)
2326 return;
2327
Tom Lendacky647daca2021-01-04 14:20:01 -06002328 ghcb_set_sw_exit_info_2(svm->ghcb, 1);
2329}