|
@@ -734,30 +734,13 @@ int create_hyp_mappings(void *from, void *to, pgprot_t prot)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * create_hyp_io_mappings - Map IO into both kernel and HYP
|
|
|
- * @phys_addr: The physical start address which gets mapped
|
|
|
- * @size: Size of the region being mapped
|
|
|
- * @kaddr: Kernel VA for this mapping
|
|
|
- * @haddr: HYP VA for this mapping
|
|
|
- */
|
|
|
-int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
|
|
|
- void __iomem **kaddr,
|
|
|
- void __iomem **haddr)
|
|
|
+static int __create_hyp_private_mapping(phys_addr_t phys_addr, size_t size,
|
|
|
+ unsigned long *haddr, pgprot_t prot)
|
|
|
{
|
|
|
pgd_t *pgd = hyp_pgd;
|
|
|
unsigned long base;
|
|
|
int ret = 0;
|
|
|
|
|
|
- *kaddr = ioremap(phys_addr, size);
|
|
|
- if (!*kaddr)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- if (is_kernel_in_hyp_mode()) {
|
|
|
- *haddr = *kaddr;
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
mutex_lock(&kvm_hyp_pgd_mutex);
|
|
|
|
|
|
/*
|
|
@@ -791,19 +774,74 @@ int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
|
|
|
|
|
|
ret = __create_hyp_mappings(pgd, __kvm_idmap_ptrs_per_pgd(),
|
|
|
base, base + size,
|
|
|
- __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE);
|
|
|
+ __phys_to_pfn(phys_addr), prot);
|
|
|
if (ret)
|
|
|
goto out;
|
|
|
|
|
|
- *haddr = (void __iomem *)base + offset_in_page(phys_addr);
|
|
|
+ *haddr = base + offset_in_page(phys_addr);
|
|
|
|
|
|
out:
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * create_hyp_io_mappings - Map IO into both kernel and HYP
|
|
|
+ * @phys_addr: The physical start address which gets mapped
|
|
|
+ * @size: Size of the region being mapped
|
|
|
+ * @kaddr: Kernel VA for this mapping
|
|
|
+ * @haddr: HYP VA for this mapping
|
|
|
+ */
|
|
|
+int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
|
|
|
+ void __iomem **kaddr,
|
|
|
+ void __iomem **haddr)
|
|
|
+{
|
|
|
+ unsigned long addr;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ *kaddr = ioremap(phys_addr, size);
|
|
|
+ if (!*kaddr)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ if (is_kernel_in_hyp_mode()) {
|
|
|
+ *haddr = *kaddr;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = __create_hyp_private_mapping(phys_addr, size,
|
|
|
+ &addr, PAGE_HYP_DEVICE);
|
|
|
if (ret) {
|
|
|
iounmap(*kaddr);
|
|
|
*kaddr = NULL;
|
|
|
+ *haddr = NULL;
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ *haddr = (void __iomem *)addr;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * create_hyp_exec_mappings - Map an executable range into HYP
|
|
|
+ * @phys_addr: The physical start address which gets mapped
|
|
|
+ * @size: Size of the region being mapped
|
|
|
+ * @haddr: HYP VA for this mapping
|
|
|
+ */
|
|
|
+int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size,
|
|
|
+ void **haddr)
|
|
|
+{
|
|
|
+ unsigned long addr;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ BUG_ON(is_kernel_in_hyp_mode());
|
|
|
+
|
|
|
+ ret = __create_hyp_private_mapping(phys_addr, size,
|
|
|
+ &addr, PAGE_HYP_EXEC);
|
|
|
+ if (ret) {
|
|
|
+ *haddr = NULL;
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ *haddr = (void *)addr;
|
|
|
return 0;
|
|
|
}
|
|
|
|