ANDROID: KVM: arm64: Add functions needed by EL2 modules in module ops

EL2 IOMMU moduels need extra functions from module ops, to map memory,
interact with the IOMMU layer and use the hyp allocator.

Also, export ___pkvm_host_donate_hyp, instead of a function that always
accept MMIO, as modules would use this function for both memory and
MMIO.

Bug: 357781595
Bug: 384432312
Change-Id: If3b807ef2181a0e9465599fdf260ba2904000f45
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
Mostafa Saleh
2023-08-16 15:02:44 +00:00
parent a2829fafa6
commit 60707bba73
2 changed files with 54 additions and 8 deletions
+38 -2
View File
@@ -8,6 +8,9 @@
#include <linux/export.h>
typedef void (*dyn_hcall_t)(struct user_pt_regs *);
struct kvm_hyp_iommu;
struct iommu_iotlb_gather;
struct kvm_hyp_iommu_domain;
#ifdef CONFIG_MODULES
enum pkvm_psci_notification {
@@ -105,6 +108,8 @@ enum pkvm_psci_notification {
* is called before remasking SErrors.
* @host_donate_hyp: The page @pfn is unmapped from the host and
* full control is given to the hypervisor.
* @host_donate_hyp_prot: As host_donate_hyp_prot, but this variant sets
* the prot of the hyp.
* @hyp_donate_host: The page @pfn whom control has previously been
* given to the hypervisor (@host_donate_hyp) is
* given back to the host.
@@ -127,6 +132,19 @@ enum pkvm_psci_notification {
* @hyp_va: Convert a physical address into a virtual one.
* @kern_hyp_va: Convert a kernel virtual address into an
* hypervisor virtual one.
* @hyp_alloc: Allocate memory in hyp VA space.
* @hyp_alloc_errno: Error in case hyp_alloc() returns NULL.
* @hyp_free: Free memory allocated from hyp_alloc().
* @iommu_donate_pages: Allocate memory from IOMMU pool.
* @iommu_reclaim_pages: Reclaim memory from iommu_donate_pages()
* @iommu_request: Fill a request that is returned from the entry HVC (see hyp-main.c).
* @iommu_init_device: Initialize common IOMMU fields.
* @udelay: Delay in us.
* @hyp_alloc_missing_donations:
Missing donations if allocator returns NULL
* @__list_add_valid_or_report: Needed if the code uses linked lists.
* @__list_del_entry_valid_or_report:
Needed if the code uses linked lists.
*/
struct pkvm_module_ops {
int (*create_private_mapping)(phys_addr_t phys, size_t size,
@@ -154,7 +172,8 @@ struct pkvm_module_ops {
int (*register_psci_notifier)(void (*cb)(enum pkvm_psci_notification, struct user_pt_regs *));
int (*register_hyp_panic_notifier)(void (*cb)(struct user_pt_regs *));
int (*register_unmask_serror)(bool (*unmask)(void), void (*mask)(void));
int (*host_donate_hyp)(u64 pfn, u64 nr_pages);
int (*host_donate_hyp)(u64 pfn, u64 nr_pages, bool accept_mmio);
int (*host_donate_hyp_prot)(u64 pfn, u64 nr_pages, bool accept_mmio, enum kvm_pgtable_prot prot);
int (*hyp_donate_host)(u64 pfn, u64 nr_pages);
int (*host_share_hyp)(u64 pfn);
int (*host_unshare_hyp)(u64 pfn);
@@ -169,7 +188,24 @@ struct pkvm_module_ops {
void* (*tracing_reserve_entry)(unsigned long length);
void (*tracing_commit_entry)(void);
void (*tracing_mod_hyp_printk)(u8 fmt_id, u64 a, u64 b, u64 c, u64 d);
void * (*hyp_alloc)(size_t size);
int (*hyp_alloc_errno)(void);
void (*hyp_free)(void *addr);
u8 (*hyp_alloc_missing_donations)(void);
void * (*iommu_donate_pages)(u8 order, int flags);
void (*iommu_reclaim_pages)(void *p, u8 order);
int (*iommu_init_device)(struct kvm_hyp_iommu *iommu);
void (*udelay)(unsigned long usecs);
void (*iommu_iotlb_gather_add_page)(struct kvm_hyp_iommu_domain *domain,
struct iommu_iotlb_gather *gather,
unsigned long iova,
size_t size);
int (*pkvm_host_unuse_dma)(phys_addr_t phys_addr, size_t size);
#ifdef CONFIG_LIST_HARDENED
/* These 2 functions change calling convention based on CONFIG_DEBUG_LIST. */
typeof(__list_add_valid_or_report) *list_add_valid_or_report;
typeof(__list_del_entry_valid_or_report) *list_del_entry_valid_or_report;
#endif
ANDROID_KABI_RESERVE(1);
ANDROID_KABI_RESERVE(2);
ANDROID_KABI_RESERVE(3);
+16 -6
View File
@@ -6,6 +6,8 @@
#include <asm/kvm_pkvm_module.h>
#include <asm/kvm_hypevents.h>
#include <nvhe/alloc.h>
#include <nvhe/iommu.h>
#include <nvhe/mem_protect.h>
#include <nvhe/modules.h>
#include <nvhe/mm.h>
@@ -79,11 +81,6 @@ void __pkvm_close_module_registration(void)
*/
}
static int __pkvm_module_host_donate_hyp(u64 pfn, u64 nr_pages)
{
return ___pkvm_host_donate_hyp(pfn, nr_pages, true);
}
static void tracing_mod_hyp_printk(u8 fmt_id, u64 a, u64 b, u64 c, u64 d)
{
#ifdef CONFIG_TRACING
@@ -130,7 +127,8 @@ const struct pkvm_module_ops module_ops = {
.register_psci_notifier = __pkvm_register_psci_notifier,
.register_hyp_panic_notifier = __pkvm_register_hyp_panic_notifier,
.register_unmask_serror = __pkvm_register_unmask_serror,
.host_donate_hyp = __pkvm_module_host_donate_hyp,
.host_donate_hyp = ___pkvm_host_donate_hyp,
.host_donate_hyp_prot = ___pkvm_host_donate_hyp_prot,
.hyp_donate_host = __pkvm_hyp_donate_host,
.host_share_hyp = __pkvm_host_share_hyp,
.host_unshare_hyp = __pkvm_host_unshare_hyp,
@@ -145,6 +143,18 @@ const struct pkvm_module_ops module_ops = {
.tracing_reserve_entry = tracing_reserve_entry,
.tracing_commit_entry = tracing_commit_entry,
.tracing_mod_hyp_printk = tracing_mod_hyp_printk,
.hyp_alloc = hyp_alloc,
.hyp_alloc_errno = hyp_alloc_errno,
.hyp_free = hyp_free,
.hyp_alloc_missing_donations = hyp_alloc_missing_donations,
.iommu_donate_pages = kvm_iommu_donate_pages,
.iommu_reclaim_pages = kvm_iommu_reclaim_pages,
.iommu_init_device = kvm_iommu_init_device,
.udelay = pkvm_udelay,
#ifdef CONFIG_LIST_HARDENED
.list_add_valid_or_report = __list_add_valid_or_report,
.list_del_entry_valid_or_report = __list_del_entry_valid_or_report,
#endif
};
int __pkvm_init_module(void *module_init)