xref: /linux/arch/powerpc/platforms/pseries/svm.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1d5394c05SAnshuman Khandual // SPDX-License-Identifier: GPL-2.0+
2d5394c05SAnshuman Khandual /*
3d5394c05SAnshuman Khandual  * Secure VM platform
4d5394c05SAnshuman Khandual  *
5d5394c05SAnshuman Khandual  * Copyright 2018 IBM Corporation
6d5394c05SAnshuman Khandual  * Author: Anshuman Khandual <khandual@linux.vnet.ibm.com>
7d5394c05SAnshuman Khandual  */
8d5394c05SAnshuman Khandual 
9d5394c05SAnshuman Khandual #include <linux/mm.h>
10eae9eec4SThiago Jung Bauermann #include <linux/memblock.h>
11e9d1d2bbSTom Lendacky #include <linux/cc_platform.h>
122efbc58fSAnshuman Khandual #include <asm/machdep.h>
132efbc58fSAnshuman Khandual #include <asm/svm.h>
142efbc58fSAnshuman Khandual #include <asm/swiotlb.h>
15d5394c05SAnshuman Khandual #include <asm/ultravisor.h>
16d6bdceb6SPeter Zijlstra #include <asm/dtl.h>
17d5394c05SAnshuman Khandual 
init_svm(void)182efbc58fSAnshuman Khandual static int __init init_svm(void)
192efbc58fSAnshuman Khandual {
202efbc58fSAnshuman Khandual 	if (!is_secure_guest())
212efbc58fSAnshuman Khandual 		return 0;
222efbc58fSAnshuman Khandual 
232efbc58fSAnshuman Khandual 	/* Don't release the SWIOTLB buffer. */
242efbc58fSAnshuman Khandual 	ppc_swiotlb_enable = 1;
252efbc58fSAnshuman Khandual 
262efbc58fSAnshuman Khandual 	/*
272efbc58fSAnshuman Khandual 	 * Since the guest memory is inaccessible to the host, devices always
282efbc58fSAnshuman Khandual 	 * need to use the SWIOTLB buffer for DMA even if dma_capable() says
292efbc58fSAnshuman Khandual 	 * otherwise.
302efbc58fSAnshuman Khandual 	 */
31*8ba2ed1bSChristoph Hellwig 	ppc_swiotlb_flags |= SWIOTLB_ANY | SWIOTLB_FORCE;
322efbc58fSAnshuman Khandual 
332efbc58fSAnshuman Khandual 	/* Share the SWIOTLB buffer with the host. */
342efbc58fSAnshuman Khandual 	swiotlb_update_mem_attributes();
352efbc58fSAnshuman Khandual 
362efbc58fSAnshuman Khandual 	return 0;
372efbc58fSAnshuman Khandual }
382efbc58fSAnshuman Khandual machine_early_initcall(pseries, init_svm);
392efbc58fSAnshuman Khandual 
set_memory_encrypted(unsigned long addr,int numpages)402efbc58fSAnshuman Khandual int set_memory_encrypted(unsigned long addr, int numpages)
412efbc58fSAnshuman Khandual {
42e9d1d2bbSTom Lendacky 	if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
43a449ffafSWill Deacon 		return 0;
44a449ffafSWill Deacon 
452efbc58fSAnshuman Khandual 	if (!PAGE_ALIGNED(addr))
462efbc58fSAnshuman Khandual 		return -EINVAL;
472efbc58fSAnshuman Khandual 
482efbc58fSAnshuman Khandual 	uv_unshare_page(PHYS_PFN(__pa(addr)), numpages);
492efbc58fSAnshuman Khandual 
502efbc58fSAnshuman Khandual 	return 0;
512efbc58fSAnshuman Khandual }
522efbc58fSAnshuman Khandual 
set_memory_decrypted(unsigned long addr,int numpages)532efbc58fSAnshuman Khandual int set_memory_decrypted(unsigned long addr, int numpages)
542efbc58fSAnshuman Khandual {
55e9d1d2bbSTom Lendacky 	if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
56a449ffafSWill Deacon 		return 0;
57a449ffafSWill Deacon 
582efbc58fSAnshuman Khandual 	if (!PAGE_ALIGNED(addr))
592efbc58fSAnshuman Khandual 		return -EINVAL;
602efbc58fSAnshuman Khandual 
612efbc58fSAnshuman Khandual 	uv_share_page(PHYS_PFN(__pa(addr)), numpages);
622efbc58fSAnshuman Khandual 
632efbc58fSAnshuman Khandual 	return 0;
642efbc58fSAnshuman Khandual }
652efbc58fSAnshuman Khandual 
66d5394c05SAnshuman Khandual /* There's one dispatch log per CPU. */
67d5394c05SAnshuman Khandual #define NR_DTL_PAGE (DISPATCH_LOG_BYTES * CONFIG_NR_CPUS / PAGE_SIZE)
68d5394c05SAnshuman Khandual 
69d5394c05SAnshuman Khandual static struct page *dtl_page_store[NR_DTL_PAGE];
70d5394c05SAnshuman Khandual static long dtl_nr_pages;
71d5394c05SAnshuman Khandual 
is_dtl_page_shared(struct page * page)72d5394c05SAnshuman Khandual static bool is_dtl_page_shared(struct page *page)
73d5394c05SAnshuman Khandual {
74d5394c05SAnshuman Khandual 	long i;
75d5394c05SAnshuman Khandual 
76d5394c05SAnshuman Khandual 	for (i = 0; i < dtl_nr_pages; i++)
77d5394c05SAnshuman Khandual 		if (dtl_page_store[i] == page)
78d5394c05SAnshuman Khandual 			return true;
79d5394c05SAnshuman Khandual 
80d5394c05SAnshuman Khandual 	return false;
81d5394c05SAnshuman Khandual }
82d5394c05SAnshuman Khandual 
dtl_cache_ctor(void * addr)83d5394c05SAnshuman Khandual void dtl_cache_ctor(void *addr)
84d5394c05SAnshuman Khandual {
85d5394c05SAnshuman Khandual 	unsigned long pfn = PHYS_PFN(__pa(addr));
86d5394c05SAnshuman Khandual 	struct page *page = pfn_to_page(pfn);
87d5394c05SAnshuman Khandual 
88d5394c05SAnshuman Khandual 	if (!is_dtl_page_shared(page)) {
89d5394c05SAnshuman Khandual 		dtl_page_store[dtl_nr_pages] = page;
90d5394c05SAnshuman Khandual 		dtl_nr_pages++;
91d5394c05SAnshuman Khandual 		WARN_ON(dtl_nr_pages >= NR_DTL_PAGE);
92d5394c05SAnshuman Khandual 		uv_share_page(pfn, 1);
93d5394c05SAnshuman Khandual 	}
94d5394c05SAnshuman Khandual }
95