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 Khandualstatic 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 Khandualint 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 Khandualint 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 Khandualstatic 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 Khandualvoid 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