ANDROID: KVM: arm64: iommu: Add new ops iotlb_sync_map()
Some IOMMU drivers might want to implement the iommu_ops iotlb_sync_map() in the hypervisor. Add a new hypercall and a hypervisor ops for that. Bug: 431432127 Change-Id: Ic4ed322b6288ecc421865aaeb3b5e2878e294962 Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
@@ -22743,6 +22743,11 @@ pointer_reference {
|
|||||||
kind: POINTER
|
kind: POINTER
|
||||||
pointee_type_id: 0x977bcf07
|
pointee_type_id: 0x977bcf07
|
||||||
}
|
}
|
||||||
|
pointer_reference {
|
||||||
|
id: 0x2f4f676a
|
||||||
|
kind: POINTER
|
||||||
|
pointee_type_id: 0x977d7b37
|
||||||
|
}
|
||||||
pointer_reference {
|
pointer_reference {
|
||||||
id: 0x2f4f9f95
|
id: 0x2f4f9f95
|
||||||
kind: POINTER
|
kind: POINTER
|
||||||
@@ -43798,6 +43803,11 @@ member {
|
|||||||
id: 0x3a3e9211
|
id: 0x3a3e9211
|
||||||
type_id: 0x67d43857
|
type_id: 0x67d43857
|
||||||
}
|
}
|
||||||
|
member {
|
||||||
|
id: 0x3a6f0eb6
|
||||||
|
type_id: 0x66926050
|
||||||
|
offset: 896
|
||||||
|
}
|
||||||
member {
|
member {
|
||||||
id: 0x3a7ed482
|
id: 0x3a7ed482
|
||||||
type_id: 0x66d53bfd
|
type_id: 0x66d53bfd
|
||||||
@@ -116148,6 +116158,11 @@ member {
|
|||||||
type_id: 0x0c55d62d
|
type_id: 0x0c55d62d
|
||||||
offset: 512
|
offset: 512
|
||||||
}
|
}
|
||||||
|
member {
|
||||||
|
id: 0xc185c03f
|
||||||
|
name: "iotlb_sync_map"
|
||||||
|
type_id: 0x2f4f676a
|
||||||
|
}
|
||||||
member {
|
member {
|
||||||
id: 0xc1a6eb7e
|
id: 0xc1a6eb7e
|
||||||
name: "iotlb_sync_map"
|
name: "iotlb_sync_map"
|
||||||
@@ -227172,6 +227187,16 @@ struct_union {
|
|||||||
member_id: 0x082b1975
|
member_id: 0x082b1975
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
struct_union {
|
||||||
|
id: 0x66926050
|
||||||
|
kind: UNION
|
||||||
|
definition {
|
||||||
|
bytesize: 8
|
||||||
|
member_id: 0xc185c03f
|
||||||
|
member_id: 0x27000c61
|
||||||
|
member_id: 0x36752b74
|
||||||
|
}
|
||||||
|
}
|
||||||
struct_union {
|
struct_union {
|
||||||
id: 0x66d53bfd
|
id: 0x66d53bfd
|
||||||
kind: UNION
|
kind: UNION
|
||||||
@@ -253676,7 +253701,7 @@ struct_union {
|
|||||||
member_id: 0xa60fc2c2
|
member_id: 0xa60fc2c2
|
||||||
member_id: 0xd12a0a5e
|
member_id: 0xd12a0a5e
|
||||||
member_id: 0x80f5a8ec
|
member_id: 0x80f5a8ec
|
||||||
member_id: 0x2d081f94
|
member_id: 0x3a6f0eb6
|
||||||
member_id: 0x63760151
|
member_id: 0x63760151
|
||||||
member_id: 0xac894e49
|
member_id: 0xac894e49
|
||||||
member_id: 0xe0f6393d
|
member_id: 0xe0f6393d
|
||||||
@@ -333806,6 +333831,13 @@ function {
|
|||||||
parameter_id: 0x2bc93f35
|
parameter_id: 0x2bc93f35
|
||||||
parameter_id: 0x0258f96e
|
parameter_id: 0x0258f96e
|
||||||
}
|
}
|
||||||
|
function {
|
||||||
|
id: 0x977d7b37
|
||||||
|
return_type_id: 0x6720d32f
|
||||||
|
parameter_id: 0x28350343
|
||||||
|
parameter_id: 0x33756485
|
||||||
|
parameter_id: 0xf435685e
|
||||||
|
}
|
||||||
function {
|
function {
|
||||||
id: 0x977e98cb
|
id: 0x977e98cb
|
||||||
return_type_id: 0x6720d32f
|
return_type_id: 0x6720d32f
|
||||||
|
@@ -213,3 +213,7 @@ type 'struct scm_stat' changed
|
|||||||
type 'struct scm_fp_list' changed
|
type 'struct scm_fp_list' changed
|
||||||
member 'bool dead' was added
|
member 'bool dead' was added
|
||||||
|
|
||||||
|
type 'struct kvm_iommu_ops' changed
|
||||||
|
member 'u64 android_kabi_reserved1' was removed
|
||||||
|
member 'union { int(* iotlb_sync_map)(struct kvm_hyp_iommu_domain*, unsigned long, size_t); struct { u64 android_kabi_reserved1; }; union { }; }' was added
|
||||||
|
|
||||||
|
@@ -115,6 +115,7 @@ enum __kvm_host_smccc_func {
|
|||||||
__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_iova_to_phys,
|
__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_iova_to_phys,
|
||||||
__KVM_HOST_SMCCC_FUNC___pkvm_host_hvc_pd,
|
__KVM_HOST_SMCCC_FUNC___pkvm_host_hvc_pd,
|
||||||
__KVM_HOST_SMCCC_FUNC___pkvm_stage2_snapshot,
|
__KVM_HOST_SMCCC_FUNC___pkvm_stage2_snapshot,
|
||||||
|
__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_iotlb_sync_map,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start of the dynamically registered hypercalls. Start a bit
|
* Start of the dynamically registered hypercalls. Start a bit
|
||||||
|
@@ -54,6 +54,8 @@ void kvm_iommu_iotlb_gather_add_page(struct kvm_hyp_iommu_domain *domain,
|
|||||||
void kvm_iommu_host_stage2_idmap(phys_addr_t start, phys_addr_t end,
|
void kvm_iommu_host_stage2_idmap(phys_addr_t start, phys_addr_t end,
|
||||||
enum kvm_pgtable_prot prot);
|
enum kvm_pgtable_prot prot);
|
||||||
int kvm_iommu_snapshot_host_stage2(struct kvm_hyp_iommu_domain *domain);
|
int kvm_iommu_snapshot_host_stage2(struct kvm_hyp_iommu_domain *domain);
|
||||||
|
int kvm_iommu_iotlb_sync_map(pkvm_handle_t domain_id,
|
||||||
|
unsigned long iova, size_t size);
|
||||||
|
|
||||||
#define KVM_IOMMU_PADDR_CACHE_MAX ((size_t)511)
|
#define KVM_IOMMU_PADDR_CACHE_MAX ((size_t)511)
|
||||||
/**
|
/**
|
||||||
@@ -112,6 +114,7 @@ static inline void kvm_iommu_unlock(struct kvm_hyp_iommu *iommu)
|
|||||||
* @map_pages: Map pages in a domain.
|
* @map_pages: Map pages in a domain.
|
||||||
* @unmap_pages: Unmap pages from a domain.
|
* @unmap_pages: Unmap pages from a domain.
|
||||||
* @iova_to_phys: get physical address from IOVA in a domain.
|
* @iova_to_phys: get physical address from IOVA in a domain.
|
||||||
|
* @iotlb_sync_map: Sync mapping created using @map_pages to the hardware.
|
||||||
*/
|
*/
|
||||||
struct kvm_iommu_ops {
|
struct kvm_iommu_ops {
|
||||||
int (*init)(unsigned long arg);
|
int (*init)(unsigned long arg);
|
||||||
@@ -138,7 +141,8 @@ struct kvm_iommu_ops {
|
|||||||
struct iommu_iotlb_gather *gather,
|
struct iommu_iotlb_gather *gather,
|
||||||
struct kvm_iommu_paddr_cache *cache);
|
struct kvm_iommu_paddr_cache *cache);
|
||||||
phys_addr_t (*iova_to_phys)(struct kvm_hyp_iommu_domain *domain, unsigned long iova);
|
phys_addr_t (*iova_to_phys)(struct kvm_hyp_iommu_domain *domain, unsigned long iova);
|
||||||
ANDROID_KABI_RESERVE(1);
|
ANDROID_KABI_USE(1, int (*iotlb_sync_map)(struct kvm_hyp_iommu_domain *domain,
|
||||||
|
unsigned long iova, size_t size));
|
||||||
ANDROID_KABI_RESERVE(2);
|
ANDROID_KABI_RESERVE(2);
|
||||||
ANDROID_KABI_RESERVE(3);
|
ANDROID_KABI_RESERVE(3);
|
||||||
ANDROID_KABI_RESERVE(4);
|
ANDROID_KABI_RESERVE(4);
|
||||||
|
@@ -1574,6 +1574,17 @@ static void handle___pkvm_host_iommu_iova_to_phys(struct kvm_cpu_context *host_c
|
|||||||
hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
|
hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle___pkvm_host_iommu_iotlb_sync_map(struct kvm_cpu_context *host_ctxt)
|
||||||
|
{
|
||||||
|
unsigned long ret;
|
||||||
|
DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 1);
|
||||||
|
DECLARE_REG(unsigned long, iova, host_ctxt, 2);
|
||||||
|
DECLARE_REG(size_t, size, host_ctxt, 3);
|
||||||
|
|
||||||
|
ret = kvm_iommu_iotlb_sync_map(domain, iova, size);
|
||||||
|
hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
|
||||||
|
}
|
||||||
|
|
||||||
static void handle___pkvm_iommu_init(struct kvm_cpu_context *host_ctxt)
|
static void handle___pkvm_iommu_init(struct kvm_cpu_context *host_ctxt)
|
||||||
{
|
{
|
||||||
DECLARE_REG(struct kvm_iommu_ops *, ops, host_ctxt, 1);
|
DECLARE_REG(struct kvm_iommu_ops *, ops, host_ctxt, 1);
|
||||||
@@ -1671,6 +1682,7 @@ static const hcall_t host_hcall[] = {
|
|||||||
HANDLE_FUNC(__pkvm_host_iommu_iova_to_phys),
|
HANDLE_FUNC(__pkvm_host_iommu_iova_to_phys),
|
||||||
HANDLE_FUNC(__pkvm_host_hvc_pd),
|
HANDLE_FUNC(__pkvm_host_hvc_pd),
|
||||||
HANDLE_FUNC(__pkvm_stage2_snapshot),
|
HANDLE_FUNC(__pkvm_stage2_snapshot),
|
||||||
|
HANDLE_FUNC(__pkvm_host_iommu_iotlb_sync_map),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
|
static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
|
||||||
|
@@ -825,3 +825,28 @@ int kvm_iommu_snapshot_host_stage2(struct kvm_hyp_iommu_domain *domain)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_iommu_iotlb_sync_map(pkvm_handle_t domain_id,
|
||||||
|
unsigned long iova, size_t size)
|
||||||
|
{
|
||||||
|
struct kvm_hyp_iommu_domain *domain;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!kvm_iommu_ops || !kvm_iommu_ops->iotlb_sync_map)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (!size || (iova + size < iova))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (domain_id == KVM_IOMMU_DOMAIN_IDMAP_ID)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
domain = handle_to_domain(domain_id);
|
||||||
|
|
||||||
|
if (!domain || domain_get(domain))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = kvm_iommu_ops->iotlb_sync_map(domain, iova, size);
|
||||||
|
domain_put(domain);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user