Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Secure VM platform
0004  *
0005  * Copyright 2018 IBM Corporation
0006  * Author: Anshuman Khandual <khandual@linux.vnet.ibm.com>
0007  */
0008 
0009 #include <linux/mm.h>
0010 #include <linux/memblock.h>
0011 #include <linux/cc_platform.h>
0012 #include <asm/machdep.h>
0013 #include <asm/svm.h>
0014 #include <asm/swiotlb.h>
0015 #include <asm/ultravisor.h>
0016 #include <asm/dtl.h>
0017 
0018 static int __init init_svm(void)
0019 {
0020     if (!is_secure_guest())
0021         return 0;
0022 
0023     /* Don't release the SWIOTLB buffer. */
0024     ppc_swiotlb_enable = 1;
0025 
0026     /*
0027      * Since the guest memory is inaccessible to the host, devices always
0028      * need to use the SWIOTLB buffer for DMA even if dma_capable() says
0029      * otherwise.
0030      */
0031     ppc_swiotlb_flags |= SWIOTLB_ANY | SWIOTLB_FORCE;
0032 
0033     /* Share the SWIOTLB buffer with the host. */
0034     swiotlb_update_mem_attributes();
0035 
0036     return 0;
0037 }
0038 machine_early_initcall(pseries, init_svm);
0039 
0040 int set_memory_encrypted(unsigned long addr, int numpages)
0041 {
0042     if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
0043         return 0;
0044 
0045     if (!PAGE_ALIGNED(addr))
0046         return -EINVAL;
0047 
0048     uv_unshare_page(PHYS_PFN(__pa(addr)), numpages);
0049 
0050     return 0;
0051 }
0052 
0053 int set_memory_decrypted(unsigned long addr, int numpages)
0054 {
0055     if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
0056         return 0;
0057 
0058     if (!PAGE_ALIGNED(addr))
0059         return -EINVAL;
0060 
0061     uv_share_page(PHYS_PFN(__pa(addr)), numpages);
0062 
0063     return 0;
0064 }
0065 
0066 /* There's one dispatch log per CPU. */
0067 #define NR_DTL_PAGE (DISPATCH_LOG_BYTES * CONFIG_NR_CPUS / PAGE_SIZE)
0068 
0069 static struct page *dtl_page_store[NR_DTL_PAGE];
0070 static long dtl_nr_pages;
0071 
0072 static bool is_dtl_page_shared(struct page *page)
0073 {
0074     long i;
0075 
0076     for (i = 0; i < dtl_nr_pages; i++)
0077         if (dtl_page_store[i] == page)
0078             return true;
0079 
0080     return false;
0081 }
0082 
0083 void dtl_cache_ctor(void *addr)
0084 {
0085     unsigned long pfn = PHYS_PFN(__pa(addr));
0086     struct page *page = pfn_to_page(pfn);
0087 
0088     if (!is_dtl_page_shared(page)) {
0089         dtl_page_store[dtl_nr_pages] = page;
0090         dtl_nr_pages++;
0091         WARN_ON(dtl_nr_pages >= NR_DTL_PAGE);
0092         uv_share_page(pfn, 1);
0093     }
0094 }