diff mbox series

[RFC,09/45] KVM: arm64: pkvm: Add pkvm_create_hyp_device_mapping()

Message ID 20230201125328.2186498-10-jean-philippe@linaro.org (mailing list archive)
State New, archived
Headers show
Series KVM: Arm SMMUv3 driver for pKVM | expand

Commit Message

Jean-Philippe Brucker Feb. 1, 2023, 12:52 p.m. UTC
Add a function to map a MMIO region in the hypervisor and remove it from
the host. Hypervisor device drivers use this to reserve their regions
during setup.

Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
 arch/arm64/kvm/hyp/include/nvhe/mm.h |  1 +
 arch/arm64/kvm/hyp/nvhe/setup.c      | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

Comments

Mostafa Saleh Feb. 7, 2023, 12:22 p.m. UTC | #1
Hi Jean,

On Wed, Feb 01, 2023 at 12:52:53PM +0000, Jean-Philippe Brucker wrote:
> Add a function to map a MMIO region in the hypervisor and remove it from
> the host. Hypervisor device drivers use this to reserve their regions
> during setup.
> 
> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/mm.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/setup.c      | 17 +++++++++++++++++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> index d5ec972b5c1e..84db840f2057 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> @@ -27,5 +27,6 @@ int __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
>  				  enum kvm_pgtable_prot prot,
>  				  unsigned long *haddr);
>  int pkvm_alloc_private_va_range(size_t size, unsigned long *haddr);
> +int pkvm_create_hyp_device_mapping(u64 base, u64 size, void __iomem *haddr);
>  
>  #endif /* __KVM_HYP_MM_H */
> diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> index 629e74c46b35..de7d60c3c20b 100644
> --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> @@ -259,6 +259,23 @@ static int fix_host_ownership(void)
>  	return 0;
>  }
>  
> +/* Map the MMIO region into the hypervisor and remove it from host */
> +int pkvm_create_hyp_device_mapping(u64 base, u64 size, void __iomem *haddr)
> +{
> +	int ret;
> +
> +	ret = __pkvm_create_private_mapping(base, size, PAGE_HYP_DEVICE, haddr);
> +	if (ret)
> +		return ret;
> +
> +	/* lock not needed during setup */
> +	ret = host_stage2_set_owner_locked(base, size, PKVM_ID_HYP);
> +	if (ret)
> +		return ret;
> +

Do we need to unmap in case of errors from host_stage2_set_owner_locked?

> +	return ret;
> +}
> +
>  static int fix_hyp_pgtable_refcnt(void)
>  {
>  	struct kvm_pgtable_walker walker = {
> -- 
> 2.39.0
>
Jean-Philippe Brucker Feb. 8, 2023, 6:02 p.m. UTC | #2
On Tue, Feb 07, 2023 at 12:22:13PM +0000, Mostafa Saleh wrote:
> > +/* Map the MMIO region into the hypervisor and remove it from host */
> > +int pkvm_create_hyp_device_mapping(u64 base, u64 size, void __iomem *haddr)
> > +{
> > +	int ret;
> > +
> > +	ret = __pkvm_create_private_mapping(base, size, PAGE_HYP_DEVICE, haddr);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* lock not needed during setup */
> > +	ret = host_stage2_set_owner_locked(base, size, PKVM_ID_HYP);
> > +	if (ret)
> > +		return ret;
> > +
> 
> Do we need to unmap in case of errors from host_stage2_set_owner_locked?

I don't think so because this function is meant for hyp setup only, so any
error causes a complete teardown of both hyp and host page tables

I wondered about adding a BUG_ON() here if the function is not used during
setup, but maybe improving the comment would be good enough.

Thanks,
Jean
diff mbox series

Patch

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
index d5ec972b5c1e..84db840f2057 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
@@ -27,5 +27,6 @@  int __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
 				  enum kvm_pgtable_prot prot,
 				  unsigned long *haddr);
 int pkvm_alloc_private_va_range(size_t size, unsigned long *haddr);
+int pkvm_create_hyp_device_mapping(u64 base, u64 size, void __iomem *haddr);
 
 #endif /* __KVM_HYP_MM_H */
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index 629e74c46b35..de7d60c3c20b 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -259,6 +259,23 @@  static int fix_host_ownership(void)
 	return 0;
 }
 
+/* Map the MMIO region into the hypervisor and remove it from host */
+int pkvm_create_hyp_device_mapping(u64 base, u64 size, void __iomem *haddr)
+{
+	int ret;
+
+	ret = __pkvm_create_private_mapping(base, size, PAGE_HYP_DEVICE, haddr);
+	if (ret)
+		return ret;
+
+	/* lock not needed during setup */
+	ret = host_stage2_set_owner_locked(base, size, PKVM_ID_HYP);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
 static int fix_hyp_pgtable_refcnt(void)
 {
 	struct kvm_pgtable_walker walker = {