History

Merge tag 'x86_sev_for_v6.4_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 SEV updates from Borislav Petkov: - Add the necessary glue so that the kernel can run as a confidential SEV-SNP vTOM guest on Hyper-V. A vTOM guest basically splits the address space in two parts: encrypted and unencrypted. The use case being running unmodified guests on the Hyper-V confidential computing hypervisor - Double-buffer messages between the guest and the hardware PSP device so that no partial buffers are copied back'n'forth and thus potential message integrity and leak attacks are possible - Name the return value the sev-guest driver returns when the hw PSP device hasn't been called, explicitly - Cleanups * tag 'x86_sev_for_v6.4_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/hyperv: Change vTOM handling to use standard coco mechanisms init: Call mem_encrypt_init() after Hyper-V hypercall init is done x86/mm: Handle decryption/re-encryption of bss_decrypted consistently Drivers: hv: Explicitly request decrypted in vmap_pfn() calls x86/hyperv: Reorder code to facilitate future work x86/ioremap: Add hypervisor callback for private MMIO mapping in coco VM x86/sev: Change snp_guest_issue_request()'s fw_err argument virt/coco/sev-guest: Double-buffer messages crypto: ccp: Get rid of __sev_platform_init_locked()'s local function pointer crypto: ccp - Name -1 return value as SEV_RET_NO_FW_CALL

Linus Torvalds committed 3 years ago

Commit bc1bb2a2 parents c42b59b 812b05925 files · +311 −168Browse files

Unified · Split

25 files
  1. Documentation/virt/coco/sev-guest.rst +13 −7
  2. arch/x86/coco/core.c +30 −10
  3. arch/x86/hyperv/hv_init.c +0 −11
  4. arch/x86/hyperv/ivm.c +96 −46
  5. arch/x86/include/asm/coco.h +0 −1
  6. arch/x86/include/asm/mem_encrypt.h +1 −0
  7. arch/x86/include/asm/mshyperv.h +10 −6
  8. arch/x86/include/asm/sev-common.h +0 −4
  9. arch/x86/include/asm/sev.h +7 −3
  10. arch/x86/include/asm/x86_init.h +4 −0
  11. arch/x86/kernel/apic/io_apic.c +8 −2
  12. arch/x86/kernel/cpu/mshyperv.c +7 −8
  13. arch/x86/kernel/sev.c +8 −7
  14. arch/x86/kernel/x86_init.c +2 −0
  15. arch/x86/mm/ioremap.c +5 −0
  16. arch/x86/mm/mem_encrypt_amd.c +7 −3
  17. arch/x86/mm/pat/set_memory.c +0 −3
  18. drivers/crypto/ccp/sev-dev.c +14 −8
  19. drivers/hv/ring_buffer.c +1 −1
  20. drivers/hv/vmbus_drv.c +0 −1
  21. drivers/virt/coco/sev-guest/sev-guest.c +62 −37
  22. include/asm-generic/mshyperv.h +2 −0
  23. include/uapi/linux/psp-sev.h +7 −0
  24. include/uapi/linux/sev-guest.h +16 −2
  25. init/main.c +11 −8
Documentation/virt/coco/sev-guest.rst+13−7
@@ -37,11 +37,11 @@ along with a description: · 36 unmodified lines
3737 the return value. General error numbers (-ENOMEM, -EINVAL)
3838 are not detailed, but errors with specific meanings are.
3939
40−The guest ioctl should be issued on a file descriptor of the /dev/sev-guest device.
41−The ioctl accepts struct snp_user_guest_request. The input and output structure is
42−specified through the req_data and resp_data field respectively. If the ioctl fails
43−to execute due to a firmware error, then fw_err code will be set otherwise the
44−fw_err will be set to 0x00000000000000ff.
40+The guest ioctl should be issued on a file descriptor of the /dev/sev-guest
41+device. The ioctl accepts struct snp_user_guest_request. The input and
42+output structure is specified through the req_data and resp_data field
43+respectively. If the ioctl fails to execute due to a firmware error, then
44+the fw_error code will be set, otherwise fw_error will be set to -1.
4545
4646 The firmware checks that the message sequence counter is one greater than
4747 the guests message sequence counter. If guest driver fails to increment message
@@ -57,8 +57,14 @@ counter (e.g. counter overflow), then -EIO will be returned. · 9 unmodified lines
5757 __u64 req_data;
5858 __u64 resp_data;
5959
60− /* firmware error code on failure (see psp-sev.h) */
61− __u64 fw_err;
60+ /* bits[63:32]: VMM error code, bits[31:0] firmware error code (see psp-sev.h) */
61+ union {
62+ __u64 exitinfo2;
63+ struct {
64+ __u32 fw_error;
65+ __u32 vmm_error;
66+ };
67+ };
6268 };
6369
6470 2.1 SNP_GET_REPORT
arch/x86/coco/core.c+30−10
@@ -29,6 +29,22 @@ static bool intel_cc_platform_has(enum cc_attr attr) · 28 unmodified lines
2929 }
3030 }
3131
32+/*
33+ * Handle the SEV-SNP vTOM case where sme_me_mask is zero, and
34+ * the other levels of SME/SEV functionality, including C-bit
35+ * based SEV-SNP, are not enabled.
36+ */
37+static __maybe_unused bool amd_cc_platform_vtom(enum cc_attr attr)
38+{
39+ switch (attr) {
40+ case CC_ATTR_GUEST_MEM_ENCRYPT:
41+ case CC_ATTR_MEM_ENCRYPT:
42+ return true;
43+ default:
44+ return false;
45+ }
46+}
47+
3248 /*
3349 * SME and SEV are very similar but they are not the same, so there are
3450 * times that the kernel will need to distinguish between SME and SEV. The
@@ -41,9 +57,14 @@ static bool intel_cc_platform_has(enum cc_attr attr) · 6 unmodified lines
4157 * up under SME the trampoline area cannot be encrypted, whereas under SEV
4258 * the trampoline area must be encrypted.
4359 */
60+
4461 static bool amd_cc_platform_has(enum cc_attr attr)
4562 {
4663 #ifdef CONFIG_AMD_MEM_ENCRYPT
64+
65+ if (sev_status & MSR_AMD64_SNP_VTOM)
66+ return amd_cc_platform_vtom(attr);
67+
4768 switch (attr) {
4869 case CC_ATTR_MEM_ENCRYPT:
4970 return sme_me_mask;
@@ -76,11 +97,6 @@ static bool amd_cc_platform_has(enum cc_attr attr) · 26 unmodified lines
7697 #endif
7798 }
7899
79−static bool hyperv_cc_platform_has(enum cc_attr attr)
80−{
81− return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
82−}
83−
84100 bool cc_platform_has(enum cc_attr attr)
85101 {
86102 switch (vendor) {
@@ -88,8 +104,6 @@ bool cc_platform_has(enum cc_attr attr) · 1 unmodified line
88104 return amd_cc_platform_has(attr);
89105 case CC_VENDOR_INTEL:
90106 return intel_cc_platform_has(attr);
91− case CC_VENDOR_HYPERV:
92− return hyperv_cc_platform_has(attr);
93107 default:
94108 return false;
95109 }
@@ -103,11 +117,14 @@ u64 cc_mkenc(u64 val) · 7 unmodified lines
103117 * encryption status of the page.
104118 *
105119 * - for AMD, bit *set* means the page is encrypted
106− * - for Intel *clear* means encrypted.
120+ * - for AMD with vTOM and for Intel, *clear* means encrypted
107121 */
108122 switch (vendor) {
109123 case CC_VENDOR_AMD:
110− return val | cc_mask;
124+ if (sev_status & MSR_AMD64_SNP_VTOM)
125+ return val & ~cc_mask;
126+ else
127+ return val | cc_mask;
111128 case CC_VENDOR_INTEL:
112129 return val & ~cc_mask;
113130 default:
@@ -120,7 +137,10 @@ u64 cc_mkdec(u64 val) · 6 unmodified lines
120137 /* See comment in cc_mkenc() */
121138 switch (vendor) {
122139 case CC_VENDOR_AMD:
123− return val & ~cc_mask;
140+ if (sev_status & MSR_AMD64_SNP_VTOM)
141+ return val | cc_mask;
142+ else
143+ return val & ~cc_mask;
124144 case CC_VENDOR_INTEL:
125145 return val | cc_mask;
126146 default:
arch/x86/hyperv/hv_init.c+0−11
@@ -29,7 +29,6 @@ · 28 unmodified lines
2929 #include <linux/syscore_ops.h>
3030 #include <clocksource/hyperv_timer.h>
3131 #include <linux/highmem.h>
32−#include <linux/swiotlb.h>
3332
3433 int hyperv_init_cpuhp;
3534 u64 hv_current_partition_id = ~0ull;
@@ -504,16 +503,6 @@ void __init hyperv_init(void) · 468 unmodified lines
504503 /* Query the VMs extended capability once, so that it can be cached. */
505504 hv_query_ext_cap(0);
506505
507−#ifdef CONFIG_SWIOTLB
508− /*
509− * Swiotlb bounce buffer needs to be mapped in extra address
510− * space. Map function doesn't work in the early place and so
511− * call swiotlb_update_mem_attributes() here.
512− */
513− if (hv_is_isolation_supported())
514− swiotlb_update_mem_attributes();
515−#endif
516−
517506 return;
518507
519508 clean_guest_os_id:
arch/x86/hyperv/ivm.c+96−46
@@ -13,6 +13,8 @@ · 12 unmodified lines
1313 #include <asm/svm.h>
1414 #include <asm/sev.h>
1515 #include <asm/io.h>
16+#include <asm/coco.h>
17+#include <asm/mem_encrypt.h>
1618 #include <asm/mshyperv.h>
1719 #include <asm/hypervisor.h>
1820
@@ -233,41 +235,6 @@ void hv_ghcb_msr_read(u64 msr, u64 *value) · 214 unmodified lines
233235 local_irq_restore(flags);
234236 }
235237 EXPORT_SYMBOL_GPL(hv_ghcb_msr_read);
236−#endif
237−
238−enum hv_isolation_type hv_get_isolation_type(void)
239−{
240− if (!(ms_hyperv.priv_high & HV_ISOLATION))
241− return HV_ISOLATION_TYPE_NONE;
242− return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b);
243−}
244−EXPORT_SYMBOL_GPL(hv_get_isolation_type);
245−
246−/*
247− * hv_is_isolation_supported - Check system runs in the Hyper-V
248− * isolation VM.
249− */
250−bool hv_is_isolation_supported(void)
251−{
252− if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
253− return false;
254−
255− if (!hypervisor_is_type(X86_HYPER_MS_HYPERV))
256− return false;
257−
258− return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE;
259−}
260−
261−DEFINE_STATIC_KEY_FALSE(isolation_type_snp);
262−
263−/*
264− * hv_isolation_type_snp - Check system runs in the AMD SEV-SNP based
265− * isolation VM.
266− */
267−bool hv_isolation_type_snp(void)
268−{
269− return static_branch_unlikely(&isolation_type_snp);
270−}
271238
272239 /*
273240 * hv_mark_gpa_visibility - Set pages visible to host via hvcall.
@@ -320,27 +287,25 @@ static int hv_mark_gpa_visibility(u16 count, const u64 pfn[], · 46 unmodified lines
320287 }
321288
322289 /*
323− * hv_set_mem_host_visibility - Set specified memory visible to host.
290+ * hv_vtom_set_host_visibility - Set specified memory visible to host.
324291 *
325292 * In Isolation VM, all guest memory is encrypted from host and guest
326293 * needs to set memory visible to host via hvcall before sharing memory
327294 * with host. This function works as wrap of hv_mark_gpa_visibility()
328295 * with memory base and size.
329296 */
330−int hv_set_mem_host_visibility(unsigned long kbuffer, int pagecount, bool visible)
297+static bool hv_vtom_set_host_visibility(unsigned long kbuffer, int pagecount, bool enc)
331298 {
332− enum hv_mem_host_visibility visibility = visible ?
333− VMBUS_PAGE_VISIBLE_READ_WRITE : VMBUS_PAGE_NOT_VISIBLE;
299+ enum hv_mem_host_visibility visibility = enc ?
300+ VMBUS_PAGE_NOT_VISIBLE : VMBUS_PAGE_VISIBLE_READ_WRITE;
334301 u64 *pfn_array;
335302 int ret = 0;
303+ bool result = true;
336304 int i, pfn;
337305
338− if (!hv_is_isolation_supported() || !hv_hypercall_pg)
339− return 0;
340−
341306 pfn_array = kmalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
342307 if (!pfn_array)
343− return -ENOMEM;
308+ return false;
344309
345310 for (i = 0, pfn = 0; i < pagecount; i++) {
346311 pfn_array[pfn] = virt_to_hvpfn((void *)kbuffer + i * HV_HYP_PAGE_SIZE);
@@ -349,17 +314,68 @@ int hv_set_mem_host_visibility(unsigned long kbuffer, int pagecount, bool visibl · 2 unmodified lines
349314 if (pfn == HV_MAX_MODIFY_GPA_REP_COUNT || i == pagecount - 1) {
350315 ret = hv_mark_gpa_visibility(pfn, pfn_array,
351316 visibility);
352− if (ret)
317+ if (ret) {
318+ result = false;
353319 goto err_free_pfn_array;
320+ }
354321 pfn = 0;
355322 }
356323 }
357324
358325 err_free_pfn_array:
359326 kfree(pfn_array);
360− return ret;
327+ return result;
328+}
329+
330+static bool hv_vtom_tlb_flush_required(bool private)
331+{
332+ return true;
361333 }
362334
335+static bool hv_vtom_cache_flush_required(void)
336+{
337+ return false;
338+}
339+
340+static bool hv_is_private_mmio(u64 addr)
341+{
342+ /*
343+ * Hyper-V always provides a single IO-APIC in a guest VM.
344+ * When a paravisor is used, it is emulated by the paravisor
345+ * in the guest context and must be mapped private.
346+ */
347+ if (addr >= HV_IOAPIC_BASE_ADDRESS &&
348+ addr < (HV_IOAPIC_BASE_ADDRESS + PAGE_SIZE))
349+ return true;
350+
351+ /* Same with a vTPM */
352+ if (addr >= VTPM_BASE_ADDRESS &&
353+ addr < (VTPM_BASE_ADDRESS + PAGE_SIZE))
354+ return true;
355+
356+ return false;
357+}
358+
359+void __init hv_vtom_init(void)
360+{
361+ /*
362+ * By design, a VM using vTOM doesn't see the SEV setting,
363+ * so SEV initialization is bypassed and sev_status isn't set.
364+ * Set it here to indicate a vTOM VM.
365+ */
366+ sev_status = MSR_AMD64_SNP_VTOM;
367+ cc_set_vendor(CC_VENDOR_AMD);
368+ cc_set_mask(ms_hyperv.shared_gpa_boundary);
369+ physical_mask &= ms_hyperv.shared_gpa_boundary - 1;
370+
371+ x86_platform.hyper.is_private_mmio = hv_is_private_mmio;
372+ x86_platform.guest.enc_cache_flush_required = hv_vtom_cache_flush_required;
373+ x86_platform.guest.enc_tlb_flush_required = hv_vtom_tlb_flush_required;
374+ x86_platform.guest.enc_status_change_finish = hv_vtom_set_host_visibility;
375+}
376+
377+#endif /* CONFIG_AMD_MEM_ENCRYPT */
378+
363379 /*
364380 * hv_map_memory - map memory to extra space in the AMD SEV-SNP Isolation VM.
365381 */
@@ -377,7 +393,7 @@ void *hv_map_memory(void *addr, unsigned long size) · 11 unmodified lines
377393 pfns[i] = vmalloc_to_pfn(addr + i * PAGE_SIZE) +
378394 (ms_hyperv.shared_gpa_boundary >> PAGE_SHIFT);
379395
380− vaddr = vmap_pfn(pfns, size / PAGE_SIZE, PAGE_KERNEL_IO);
396+ vaddr = vmap_pfn(pfns, size / PAGE_SIZE, pgprot_decrypted(PAGE_KERNEL));
381397 kfree(pfns);
382398
383399 return vaddr;
@@ -387,3 +403,37 @@ void hv_unmap_memory(void *addr) · 3 unmodified lines
387403 {
388404 vunmap(addr);
389405 }
406+
407+enum hv_isolation_type hv_get_isolation_type(void)
408+{
409+ if (!(ms_hyperv.priv_high & HV_ISOLATION))
410+ return HV_ISOLATION_TYPE_NONE;
411+ return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b);
412+}
413+EXPORT_SYMBOL_GPL(hv_get_isolation_type);
414+
415+/*
416+ * hv_is_isolation_supported - Check system runs in the Hyper-V
417+ * isolation VM.
418+ */
419+bool hv_is_isolation_supported(void)
420+{
421+ if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
422+ return false;
423+
424+ if (!hypervisor_is_type(X86_HYPER_MS_HYPERV))
425+ return false;
426+
427+ return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE;
428+}
429+
430+DEFINE_STATIC_KEY_FALSE(isolation_type_snp);
431+
432+/*
433+ * hv_isolation_type_snp - Check system runs in the AMD SEV-SNP based
434+ * isolation VM.
435+ */
436+bool hv_isolation_type_snp(void)
437+{
438+ return static_branch_unlikely(&isolation_type_snp);
439+}
arch/x86/include/asm/coco.h+0−1
@@ -7,7 +7,6 @@ · 6 unmodified lines
77 enum cc_vendor {
88 CC_VENDOR_NONE,
99 CC_VENDOR_AMD,
10− CC_VENDOR_HYPERV,
1110 CC_VENDOR_INTEL,
1211 };
1312
arch/x86/include/asm/mem_encrypt.h+1−0
@@ -56,6 +56,7 @@ void __init sev_es_init_vc_handling(void); · 55 unmodified lines
5656 #else /* !CONFIG_AMD_MEM_ENCRYPT */
5757
5858 #define sme_me_mask 0ULL
59+#define sev_status 0ULL
5960
6061 static inline void __init sme_early_encrypt(resource_size_t paddr,
6162 unsigned long size) { }
arch/x86/include/asm/mshyperv.h+10−6
@@ -11,6 +11,14 @@ · 10 unmodified lines
1111 #include <asm/paravirt.h>
1212 #include <asm/mshyperv.h>
1313
14+/*
15+ * Hyper-V always provides a single IO-APIC at this MMIO address.
16+ * Ideally, the value should be looked up in ACPI tables, but it
17+ * is needed for mapping the IO-APIC early in boot on Confidential
18+ * VMs, before ACPI functions can be used.
19+ */
20+#define HV_IOAPIC_BASE_ADDRESS 0xfec00000
21+
1422 union hv_ghcb;
1523
1624 DECLARE_STATIC_KEY_FALSE(isolation_type_snp);
@@ -206,18 +214,19 @@ struct irq_domain *hv_create_pci_msi_domain(void); · 189 unmodified lines
206214 int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
207215 struct hv_interrupt_entry *entry);
208216 int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
209−int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible);
210217
211218 #ifdef CONFIG_AMD_MEM_ENCRYPT
212219 void hv_ghcb_msr_write(u64 msr, u64 value);
213220 void hv_ghcb_msr_read(u64 msr, u64 *value);
214221 bool hv_ghcb_negotiate_protocol(void);
215222 void hv_ghcb_terminate(unsigned int set, unsigned int reason);
223+void hv_vtom_init(void);
216224 #else
217225 static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
218226 static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
219227 static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
220228 static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
229+static inline void hv_vtom_init(void) {}
221230 #endif
222231
223232 extern bool hv_isolation_type_snp(void);
@@ -259,11 +268,6 @@ static inline void hv_set_register(unsigned int reg, u64 value) { } · 35 unmodified lines
259268 static inline u64 hv_get_register(unsigned int reg) { return 0; }
260269 static inline void hv_set_non_nested_register(unsigned int reg, u64 value) { }
261270 static inline u64 hv_get_non_nested_register(unsigned int reg) { return 0; }
262−static inline int hv_set_mem_host_visibility(unsigned long addr, int numpages,
263− bool visible)
264−{
265− return -1;
266−}
267271 #endif /* CONFIG_HYPERV */
268272
269273
arch/x86/include/asm/sev-common.h+0−4
@@ -128,10 +128,6 @@ struct snp_psc_desc { · 127 unmodified lines
128128 struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY];
129129 } __packed;
130130
131−/* Guest message request error codes */
132−#define SNP_GUEST_REQ_INVALID_LEN BIT_ULL(32)
133−#define SNP_GUEST_REQ_ERR_BUSY BIT_ULL(33)
134−
135131 #define GHCB_MSR_TERM_REQ 0x100
136132 #define GHCB_MSR_TERM_REASON_SET_POS 12
137133 #define GHCB_MSR_TERM_REASON_SET_MASK 0xf
arch/x86/include/asm/sev.h+7−3
@@ -9,6 +9,8 @@ · 8 unmodified lines
99 #define __ASM_ENCRYPTED_STATE_H
1010
1111 #include <linux/types.h>
12+#include <linux/sev-guest.h>
13+
1214 #include <asm/insn.h>
1315 #include <asm/sev-common.h>
1416 #include <asm/bootparam.h>
@@ -185,6 +187,9 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) · 170 unmodified lines
185187
186188 return rc;
187189 }
190+
191+struct snp_guest_request_ioctl;
192+
188193 void setup_ghcb(void);
189194 void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
190195 unsigned int npages);
@@ -196,7 +201,7 @@ void snp_set_memory_private(unsigned long vaddr, unsigned int npages); · 5 unmodified lines
196201 void snp_set_wakeup_secondary_cpu(void);
197202 bool snp_init(struct boot_params *bp);
198203 void __init __noreturn snp_abort(void);
199−int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err);
204+int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio);
200205 #else
201206 static inline void sev_es_ist_enter(struct pt_regs *regs) { }
202207 static inline void sev_es_ist_exit(void) { }
@@ -216,8 +221,7 @@ static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npag · 13 unmodified lines
216221 static inline void snp_set_wakeup_secondary_cpu(void) { }
217222 static inline bool snp_init(struct boot_params *bp) { return false; }
218223 static inline void snp_abort(void) { }
219−static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input,
220− unsigned long *fw_err)
224+static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio)
221225 {
222226 return -ENOTTY;
223227 }
arch/x86/include/asm/x86_init.h+4−0
@@ -259,11 +259,15 @@ struct x86_legacy_features { · 258 unmodified lines
259259 * VMMCALL under SEV-ES. Needs to return 'false'
260260 * if the checks fail. Called from the #VC
261261 * exception handler.
262+ * @is_private_mmio: For CoCo VMs, must map MMIO address as private.
263+ * Used when device is emulated by a paravisor
264+ * layer in the VM context.
262265 */
263266 struct x86_hyper_runtime {
264267 void (*pin_vcpu)(int cpu);
265268 void (*sev_es_hcall_prepare)(struct ghcb *ghcb, struct pt_regs *regs);
266269 bool (*sev_es_hcall_finish)(struct ghcb *ghcb, struct pt_regs *regs);
270+ bool (*is_private_mmio)(u64 addr);
267271 };
268272
269273 /**
arch/x86/kernel/apic/io_apic.c+8−2
@@ -66,6 +66,7 @@ · 65 unmodified lines
6666 #include <asm/hw_irq.h>
6767 #include <asm/apic.h>
6868 #include <asm/pgtable.h>
69+#include <asm/x86_init.h>
6970
7071 #define for_each_ioapic(idx) \
7172 for ((idx) = 0; (idx) < nr_ioapics; (idx)++)
@@ -2680,10 +2681,15 @@ static void io_apic_set_fixmap(enum fixed_addresses idx, phys_addr_t phys) · 2608 unmodified lines
26802681 pgprot_t flags = FIXMAP_PAGE_NOCACHE;
26812682
26822683 /*
2683− * Ensure fixmaps for IOAPIC MMIO respect memory encryption pgprot
2684+ * Ensure fixmaps for IO-APIC MMIO respect memory encryption pgprot
26842685 * bits, just like normal ioremap():
26852686 */
2686− flags = pgprot_decrypted(flags);
2687+ if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
2688+ if (x86_platform.hyper.is_private_mmio(phys))
2689+ flags = pgprot_encrypted(flags);
2690+ else
2691+ flags = pgprot_decrypted(flags);
2692+ }
26872693
26882694 __set_fixmap(idx, phys, flags);
26892695 }
arch/x86/kernel/cpu/mshyperv.c+7−8
@@ -33,7 +33,6 @@ · 32 unmodified lines
3333 #include <asm/nmi.h>
3434 #include <clocksource/hyperv_timer.h>
3535 #include <asm/numa.h>
36−#include <asm/coco.h>
3736
3837 /* Is Linux running as the root partition? */
3938 bool hv_root_partition;
@@ -401,8 +400,10 @@ static void __init ms_hyperv_init_platform(void) · 361 unmodified lines
401400 if (ms_hyperv.priv_high & HV_ISOLATION) {
402401 ms_hyperv.isolation_config_a = cpuid_eax(HYPERV_CPUID_ISOLATION_CONFIG);
403402 ms_hyperv.isolation_config_b = cpuid_ebx(HYPERV_CPUID_ISOLATION_CONFIG);
404− ms_hyperv.shared_gpa_boundary =
405− BIT_ULL(ms_hyperv.shared_gpa_boundary_bits);
403+
404+ if (ms_hyperv.shared_gpa_boundary_active)
405+ ms_hyperv.shared_gpa_boundary =
406+ BIT_ULL(ms_hyperv.shared_gpa_boundary_bits);
406407
407408 pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n",
408409 ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b);
@@ -413,11 +414,6 @@ static void __init ms_hyperv_init_platform(void) · 4 unmodified lines
413414 swiotlb_unencrypted_base = ms_hyperv.shared_gpa_boundary;
414415 #endif
415416 }
416− /* Isolation VMs are unenlightened SEV-based VMs, thus this check: */
417− if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
418− if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE)
419− cc_set_vendor(CC_VENDOR_HYPERV);
420− }
421417 }
422418
423419 if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
@@ -486,6 +482,9 @@ static void __init ms_hyperv_init_platform(void) · 62 unmodified lines
486482 i8253_clear_counter_on_shutdown = false;
487483
488484 #if IS_ENABLED(CONFIG_HYPERV)
485+ if ((hv_get_isolation_type() == HV_ISOLATION_TYPE_VBS) ||
486+ (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP))
487+ hv_vtom_init();
489488 /*
490489 * Setup the hook to get control post apic initialization.
491490 */
arch/x86/kernel/sev.c+8−7
@@ -22,6 +22,8 @@ · 21 unmodified lines
2222 #include <linux/efi.h>
2323 #include <linux/platform_device.h>
2424 #include <linux/io.h>
25+#include <linux/psp-sev.h>
26+#include <uapi/linux/sev-guest.h>
2527
2628 #include <asm/cpu_entry_area.h>
2729 #include <asm/stacktrace.h>
@@ -2175,7 +2177,7 @@ static int __init init_sev_config(char *str) · 2147 unmodified lines
21752177 }
21762178 __setup("sev=", init_sev_config);
21772179
2178−int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err)
2180+int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio)
21792181 {
21802182 struct ghcb_state state;
21812183 struct es_em_ctxt ctxt;
@@ -2183,8 +2185,7 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned · 1 unmodified line
21832185 struct ghcb *ghcb;
21842186 int ret;
21852187
2186− if (!fw_err)
2187− return -EINVAL;
2188+ rio->exitinfo2 = SEV_RET_NO_FW_CALL;
21882189
21892190 /*
21902191 * __sev_get_ghcb() needs to run with IRQs disabled because it is using
@@ -2209,16 +2210,16 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned · 18 unmodified lines
22092210 if (ret)
22102211 goto e_put;
22112212
2212− *fw_err = ghcb->save.sw_exit_info_2;
2213− switch (*fw_err) {
2213+ rio->exitinfo2 = ghcb->save.sw_exit_info_2;
2214+ switch (rio->exitinfo2) {
22142215 case 0:
22152216 break;
22162217
2217− case SNP_GUEST_REQ_ERR_BUSY:
2218+ case SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_BUSY):
22182219 ret = -EAGAIN;
22192220 break;
22202221
2221− case SNP_GUEST_REQ_INVALID_LEN:
2222+ case SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN):
22222223 /* Number of expected pages are returned in RBX */
22232224 if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST) {
22242225 input->data_npages = ghcb_get_rbx(ghcb);
arch/x86/kernel/x86_init.c+2−0
@@ -134,6 +134,7 @@ static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool · 133 unmodified lines
134134 static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return false; }
135135 static bool enc_tlb_flush_required_noop(bool enc) { return false; }
136136 static bool enc_cache_flush_required_noop(void) { return false; }
137+static bool is_private_mmio_noop(u64 addr) {return false; }
137138
138139 struct x86_platform_ops x86_platform __ro_after_init = {
139140 .calibrate_cpu = native_calibrate_cpu_early,
@@ -149,6 +150,7 @@ struct x86_platform_ops x86_platform __ro_after_init = { · 9 unmodified lines
149150 .realmode_reserve = reserve_real_mode,
150151 .realmode_init = init_real_mode,
151152 .hyper.pin_vcpu = x86_op_int_noop,
153+ .hyper.is_private_mmio = is_private_mmio_noop,
152154
153155 .guest = {
154156 .enc_status_change_prepare = enc_status_change_prepare_noop,
arch/x86/mm/ioremap.c+5−0
@@ -116,6 +116,11 @@ static void __ioremap_check_other(resource_size_t addr, struct ioremap_desc *des · 115 unmodified lines
116116 if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
117117 return;
118118
119+ if (x86_platform.hyper.is_private_mmio(addr)) {
120+ desc->flags |= IORES_MAP_ENCRYPTED;
121+ return;
122+ }
123+
119124 if (!IS_ENABLED(CONFIG_EFI))
120125 return;
121126
arch/x86/mm/mem_encrypt_amd.c+7−3
@@ -513,10 +513,14 @@ void __init mem_encrypt_free_decrypted_mem(void) · 512 unmodified lines
513513 npages = (vaddr_end - vaddr) >> PAGE_SHIFT;
514514
515515 /*
516− * The unused memory range was mapped decrypted, change the encryption
517− * attribute from decrypted to encrypted before freeing it.
516+ * If the unused memory range was mapped decrypted, change the encryption
517+ * attribute from decrypted to encrypted before freeing it. Base the
518+ * re-encryption on the same condition used for the decryption in
519+ * sme_postprocess_startup(). Higher level abstractions, such as
520+ * CC_ATTR_MEM_ENCRYPT, aren't necessarily equivalent in a Hyper-V VM
521+ * using vTOM, where sme_me_mask is always zero.
518522 */
519− if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
523+ if (sme_me_mask) {
520524 r = set_memory_encrypted(vaddr, npages);
521525 if (r) {
522526 pr_warn("failed to free unused decrypted pages\n");
arch/x86/mm/pat/set_memory.c+0−3
@@ -2175,9 +2175,6 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc) · 2174 unmodified lines
21752175
21762176 static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
21772177 {
2178− if (hv_is_isolation_supported())
2179− return hv_set_mem_host_visibility(addr, numpages, !enc);
2180−
21812178 if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
21822179 return __set_memory_enc_pgtable(addr, numpages, enc);
21832180
drivers/crypto/ccp/sev-dev.c+14−8
@@ -442,12 +442,19 @@ static int __sev_init_ex_locked(int *error) · 441 unmodified lines
442442 return __sev_do_cmd_locked(SEV_CMD_INIT_EX, &data, error);
443443 }
444444
445+static inline int __sev_do_init_locked(int *psp_ret)
446+{
447+ if (sev_init_ex_buffer)
448+ return __sev_init_ex_locked(psp_ret);
449+ else
450+ return __sev_init_locked(psp_ret);
451+}
452+
445453 static int __sev_platform_init_locked(int *error)
446454 {
455+ int rc = 0, psp_ret = SEV_RET_NO_FW_CALL;
447456 struct psp_device *psp = psp_master;
448457 struct sev_device *sev;
449− int rc = 0, psp_ret = -1;
450− int (*init_function)(int *error);
451458
452459 if (!psp || !psp->sev_data)
453460 return -ENODEV;
@@ -458,15 +465,12 @@ static int __sev_platform_init_locked(int *error) · 4 unmodified lines
458465 return 0;
459466
460467 if (sev_init_ex_buffer) {
461− init_function = __sev_init_ex_locked;
462468 rc = sev_read_init_ex_file();
463469 if (rc)
464470 return rc;
465− } else {
466− init_function = __sev_init_locked;
467471 }
468472
469− rc = init_function(&psp_ret);
473+ rc = __sev_do_init_locked(&psp_ret);
470474 if (rc && psp_ret == SEV_RET_SECURE_DATA_INVALID) {
471475 /*
472476 * Initialization command returned an integrity check failure
@@ -475,9 +479,11 @@ static int __sev_platform_init_locked(int *error) · 2 unmodified lines
475479 * initialization function should succeed by replacing the state
476480 * with a reset state.
477481 */
478− dev_err(sev->dev, "SEV: retrying INIT command because of SECURE_DATA_INVALID error. Retrying once to reset PSP SEV state.");
479− rc = init_function(&psp_ret);
482+ dev_err(sev->dev,
483+"SEV: retrying INIT command because of SECURE_DATA_INVALID error. Retrying once to reset PSP SEV state.");
484+ rc = __sev_do_init_locked(&psp_ret);
480485 }
486+
481487 if (error)
482488 *error = psp_ret;
483489
drivers/hv/ring_buffer.c+1−1
@@ -211,7 +211,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, · 210 unmodified lines
211211
212212 ring_info->ring_buffer = (struct hv_ring_buffer *)
213213 vmap_pfn(pfns_wraparound, page_cnt * 2 - 1,
214− PAGE_KERNEL);
214+ pgprot_decrypted(PAGE_KERNEL));
215215 kfree(pfns_wraparound);
216216
217217 if (!ring_info->ring_buffer)
drivers/hv/vmbus_drv.c+0−1
@@ -2156,7 +2156,6 @@ void vmbus_device_unregister(struct hv_device *device_obj) · 2155 unmodified lines
21562156 * VMBUS is an acpi enumerated device. Get the information we
21572157 * need from DSDT.
21582158 */
2159−#define VTPM_BASE_ADDRESS 0xfed40000
21602159 static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
21612160 {
21622161 resource_size_t start = 0;
drivers/virt/coco/sev-guest/sev-guest.c+62−37
@@ -46,7 +46,15 @@ struct snp_guest_dev { · 45 unmodified lines
4646
4747 void *certs_data;
4848 struct snp_guest_crypto *crypto;
49+ /* request and response are in unencrypted memory */
4950 struct snp_guest_msg *request, *response;
51+
52+ /*
53+ * Avoid information leakage by double-buffering shared messages
54+ * in fields that are in regular encrypted memory.
55+ */
56+ struct snp_guest_msg secret_request, secret_response;
57+
5058 struct snp_secrets_page_layout *layout;
5159 struct snp_req_data input;
5260 u32 *os_area_msg_seqno;
@@ -266,14 +274,17 @@ static int dec_payload(struct snp_guest_dev *snp_dev, struct snp_guest_msg *msg, · 213 unmodified lines
266274 static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload, u32 sz)
267275 {
268276 struct snp_guest_crypto *crypto = snp_dev->crypto;
269− struct snp_guest_msg *resp = snp_dev->response;
270− struct snp_guest_msg *req = snp_dev->request;
277+ struct snp_guest_msg *resp = &snp_dev->secret_response;
278+ struct snp_guest_msg *req = &snp_dev->secret_request;
271279 struct snp_guest_msg_hdr *req_hdr = &req->hdr;
272280 struct snp_guest_msg_hdr *resp_hdr = &resp->hdr;
273281
274282 dev_dbg(snp_dev->dev, "response [seqno %lld type %d version %d sz %d]\n",
275283 resp_hdr->msg_seqno, resp_hdr->msg_type, resp_hdr->msg_version, resp_hdr->msg_sz);
276284
285+ /* Copy response from shared memory to encrypted memory. */
286+ memcpy(resp, snp_dev->response, sizeof(*resp));
287+
277288 /* Verify that the sequence counter is incremented by 1 */
278289 if (unlikely(resp_hdr->msg_seqno != (req_hdr->msg_seqno + 1)))
279290 return -EBADMSG;
@@ -297,7 +308,7 @@ static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload, · 17 unmodified lines
297308 static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 type,
298309 void *payload, size_t sz)
299310 {
300− struct snp_guest_msg *req = snp_dev->request;
311+ struct snp_guest_msg *req = &snp_dev->secret_request;
301312 struct snp_guest_msg_hdr *hdr = &req->hdr;
302313
303314 memset(req, 0, sizeof(*req));
@@ -321,11 +332,12 @@ static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 · 17 unmodified lines
321332 return __enc_payload(snp_dev, req, payload, sz);
322333 }
323334
324−static int __handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, __u64 *fw_err)
335+static int __handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code,
336+ struct snp_guest_request_ioctl *rio)
325337 {
326− unsigned long err = 0xff, override_err = 0;
327338 unsigned long req_start = jiffies;
328339 unsigned int override_npages = 0;
340+ u64 override_err = 0;
329341 int rc;
330342
331343 retry_request:
@@ -335,7 +347,7 @@ retry_request: · 3 unmodified lines
335347 * sequence number must be incremented or the VMPCK must be deleted to
336348 * prevent reuse of the IV.
337349 */
338− rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
350+ rc = snp_issue_guest_request(exit_code, &snp_dev->input, rio);
339351 switch (rc) {
340352 case -ENOSPC:
341353 /*
@@ -353,7 +365,7 @@ retry_request: · 11 unmodified lines
353365 * request buffer size was too small and give the caller the
354366 * required buffer size.
355367 */
356− override_err = SNP_GUEST_REQ_INVALID_LEN;
368+ override_err = SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN);
357369
358370 /*
359371 * If this call to the firmware succeeds, the sequence number can
@@ -366,7 +378,7 @@ retry_request: · 6 unmodified lines
366378 goto retry_request;
367379
368380 /*
369− * The host may return SNP_GUEST_REQ_ERR_EBUSY if the request has been
381+ * The host may return SNP_GUEST_VMM_ERR_BUSY if the request has been
370382 * throttled. Retry in the driver to avoid returning and reusing the
371383 * message sequence number on a different message.
372384 */
@@ -387,27 +399,29 @@ retry_request: · 14 unmodified lines
387399 */
388400 snp_inc_msg_seqno(snp_dev);
389401
390− if (fw_err)
391− *fw_err = override_err ?: err;
402+ if (override_err) {
403+ rio->exitinfo2 = override_err;
404+
405+ /*
406+ * If an extended guest request was issued and the supplied certificate
407+ * buffer was not large enough, a standard guest request was issued to
408+ * prevent IV reuse. If the standard request was successful, return -EIO
409+ * back to the caller as would have originally been returned.
410+ */
411+ if (!rc && override_err == SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN))
412+ rc = -EIO;
413+ }
392414
393415 if (override_npages)
394416 snp_dev->input.data_npages = override_npages;
395417
396− /*
397− * If an extended guest request was issued and the supplied certificate
398− * buffer was not large enough, a standard guest request was issued to
399− * prevent IV reuse. If the standard request was successful, return -EIO
400− * back to the caller as would have originally been returned.
401− */
402− if (!rc && override_err == SNP_GUEST_REQ_INVALID_LEN)
403− return -EIO;
404−
405418 return rc;
406419 }
407420
408−static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, int msg_ver,
409− u8 type, void *req_buf, size_t req_sz, void *resp_buf,
410− u32 resp_sz, __u64 *fw_err)
421+static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code,
422+ struct snp_guest_request_ioctl *rio, u8 type,
423+ void *req_buf, size_t req_sz, void *resp_buf,
424+ u32 resp_sz)
411425 {
412426 u64 seqno;
413427 int rc;
@@ -417,19 +431,31 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in · 3 unmodified lines
417431 if (!seqno)
418432 return -EIO;
419433
434+ /* Clear shared memory's response for the host to populate. */
420435 memset(snp_dev->response, 0, sizeof(struct snp_guest_msg));
421436
422− /* Encrypt the userspace provided payload */
423− rc = enc_payload(snp_dev, seqno, msg_ver, type, req_buf, req_sz);
437+ /* Encrypt the userspace provided payload in snp_dev->secret_request. */
438+ rc = enc_payload(snp_dev, seqno, rio->msg_version, type, req_buf, req_sz);
424439 if (rc)
425440 return rc;
426441
427− rc = __handle_guest_request(snp_dev, exit_code, fw_err);
442+ /*
443+ * Write the fully encrypted request to the shared unencrypted
444+ * request page.
445+ */
446+ memcpy(snp_dev->request, &snp_dev->secret_request,
447+ sizeof(snp_dev->secret_request));
448+
449+ rc = __handle_guest_request(snp_dev, exit_code, rio);
428450 if (rc) {
429− if (rc == -EIO && *fw_err == SNP_GUEST_REQ_INVALID_LEN)
451+ if (rc == -EIO &&
452+ rio->exitinfo2 == SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN))
430453 return rc;
431454
432− dev_alert(snp_dev->dev, "Detected error from ASP request. rc: %d, fw_err: %llu\n", rc, *fw_err);
455+ dev_alert(snp_dev->dev,
456+ "Detected error from ASP request. rc: %d, exitinfo2: 0x%llx\n",
457+ rc, rio->exitinfo2);
458+
433459 snp_disable_vmpck(snp_dev);
434460 return rc;
435461 }
@@ -469,9 +495,9 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io · 33 unmodified lines
469495 if (!resp)
470496 return -ENOMEM;
471497
472− rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg->msg_version,
498+ rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg,
473499 SNP_MSG_REPORT_REQ, &req, sizeof(req), resp->data,
474− resp_len, &arg->fw_err);
500+ resp_len);
475501 if (rc)
476502 goto e_free;
477503
@@ -509,9 +535,8 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque · 31 unmodified lines
509535 if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req)))
510536 return -EFAULT;
511537
512− rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg->msg_version,
513− SNP_MSG_KEY_REQ, &req, sizeof(req), buf, resp_len,
514− &arg->fw_err);
538+ rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg,
539+ SNP_MSG_KEY_REQ, &req, sizeof(req), buf, resp_len);
515540 if (rc)
516541 return rc;
517542
@@ -571,12 +596,12 @@ cmd: · 53 unmodified lines
571596 return -ENOMEM;
572597
573598 snp_dev->input.data_npages = npages;
574− ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg->msg_version,
599+ ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg,
575600 SNP_MSG_REPORT_REQ, &req.data,
576− sizeof(req.data), resp->data, resp_len, &arg->fw_err);
601+ sizeof(req.data), resp->data, resp_len);
577602
578603 /* If certs length is invalid then copy the returned length */
579− if (arg->fw_err == SNP_GUEST_REQ_INVALID_LEN) {
604+ if (arg->vmm_error == SNP_GUEST_VMM_ERR_INVALID_LEN) {
580605 req.certs_len = snp_dev->input.data_npages << PAGE_SHIFT;
581606
582607 if (copy_to_user((void __user *)arg->req_data, &req, sizeof(req)))
@@ -611,7 +636,7 @@ static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long · 28 unmodified lines
611636 if (copy_from_user(&input, argp, sizeof(input)))
612637 return -EFAULT;
613638
614− input.fw_err = 0xff;
639+ input.exitinfo2 = 0xff;
615640
616641 /* Message version must be non-zero */
617642 if (!input.msg_version)
@@ -642,7 +667,7 @@ static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long · 24 unmodified lines
642667
643668 mutex_unlock(&snp_cmd_mutex);
644669
645− if (input.fw_err && copy_to_user(argp, &input, sizeof(input)))
670+ if (input.exitinfo2 && copy_to_user(argp, &input, sizeof(input)))
646671 return -EFAULT;
647672
648673 return ret;
include/asm-generic/mshyperv.h+2−0
@@ -26,6 +26,8 @@ · 25 unmodified lines
2626 #include <asm/ptrace.h>
2727 #include <asm/hyperv-tlfs.h>
2828
29+#define VTPM_BASE_ADDRESS 0xfed40000
30+
2931 struct ms_hyperv_info {
3032 u32 features;
3133 u32 priv_high;
include/uapi/linux/psp-sev.h+7−0
@@ -36,6 +36,13 @@ enum { · 35 unmodified lines
3636 * SEV Firmware status code
3737 */
3838 typedef enum {
39+ /*
40+ * This error code is not in the SEV spec. Its purpose is to convey that
41+ * there was an error that prevented the SEV firmware from being called.
42+ * The SEV API error codes are 16 bits, so the -1 value will not overlap
43+ * with possible values from the specification.
44+ */
45+ SEV_RET_NO_FW_CALL = -1,
3946 SEV_RET_SUCCESS = 0,
4047 SEV_RET_INVALID_PLATFORM_STATE,
4148 SEV_RET_INVALID_GUEST_STATE,
include/uapi/linux/sev-guest.h+16−2
@@ -52,8 +52,14 @@ struct snp_guest_request_ioctl { · 51 unmodified lines
5252 __u64 req_data;
5353 __u64 resp_data;
5454
55− /* firmware error code on failure (see psp-sev.h) */
56− __u64 fw_err;
55+ /* bits[63:32]: VMM error code, bits[31:0] firmware error code (see psp-sev.h) */
56+ union {
57+ __u64 exitinfo2;
58+ struct {
59+ __u32 fw_error;
60+ __u32 vmm_error;
61+ };
62+ };
5763 };
5864
5965 struct snp_ext_report_req {
@@ -77,4 +83,12 @@ struct snp_ext_report_req { · 17 unmodified lines
7783 /* Get SNP extended report as defined in the GHCB specification version 2. */
7884 #define SNP_GET_EXT_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x2, struct snp_guest_request_ioctl)
7985
86+/* Guest message request EXIT_INFO_2 constants */
87+#define SNP_GUEST_FW_ERR_MASK GENMASK_ULL(31, 0)
88+#define SNP_GUEST_VMM_ERR_SHIFT 32
89+#define SNP_GUEST_VMM_ERR(x) (((u64)x) << SNP_GUEST_VMM_ERR_SHIFT)
90+
91+#define SNP_GUEST_VMM_ERR_INVALID_LEN 1
92+#define SNP_GUEST_VMM_ERR_BUSY 2
93+
8094 #endif /* __UAPI_LINUX_SEV_GUEST_H_ */
init/main.c+11−8
@@ -1092,14 +1092,6 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) · 1091 unmodified lines
10921092 */
10931093 locking_selftest();
10941094
1095− /*
1096− * This needs to be called before any devices perform DMA
1097− * operations that might use the SWIOTLB bounce buffers. It will
1098− * mark the bounce buffers as decrypted so that their usage will
1099− * not cause "plain-text" data to be decrypted when accessed.
1100− */
1101− mem_encrypt_init();
1102−
11031095 #ifdef CONFIG_BLK_DEV_INITRD
11041096 if (initrd_start && !initrd_below_start_ok &&
11051097 page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
@@ -1116,6 +1108,17 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) · 10 unmodified lines
11161108 late_time_init();
11171109 sched_clock_init();
11181110 calibrate_delay();
1111+
1112+ /*
1113+ * This needs to be called before any devices perform DMA
1114+ * operations that might use the SWIOTLB bounce buffers. It will
1115+ * mark the bounce buffers as decrypted so that their usage will
1116+ * not cause "plain-text" data to be decrypted when accessed. It
1117+ * must be called after late_time_init() so that Hyper-V x86/x64
1118+ * hypercalls work when the SWIOTLB bounce buffers are decrypted.
1119+ */
1120+ mem_encrypt_init();
1121+
11191122 pid_idr_init();
11201123 anon_vma_init();
11211124 #ifdef CONFIG_X86

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t