0001
0002
0003
0004
0005
0006
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
0024 ppc_swiotlb_enable = 1;
0025
0026
0027
0028
0029
0030
0031 ppc_swiotlb_flags |= SWIOTLB_ANY | SWIOTLB_FORCE;
0032
0033
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
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 }