mbox series

[v11,00/21] GenieZone hypervisor drivers

Message ID 20240529084239.11478-1-liju-clr.chen@mediatek.com
Headers show
Series GenieZone hypervisor drivers | expand

Message

Liju-clr Chen (陳麗如) May 29, 2024, 8:42 a.m. UTC
From: Liju-Clr Chen <liju-clr.chen@mediatek.com>

This series is based on linux-next, tag: next-20240529.

GenieZone hypervisor(gzvm) is a type-1 hypervisor that supports various virtual
machine types and provides security features such as TEE-like scenarios and
secure boot. It can create guest VMs for security use cases and has
virtualization capabilities for both platform and interrupt. Although the
hypervisor can be booted independently, it requires the assistance of GenieZone
hypervisor kernel driver(gzvm-ko) to leverage the ability of Linux kernel for
vCPU scheduling, memory management, inter-VM communication and virtio backend
support.

Changes in v11:
- Resolve low memory issue by using only one api to get pages for guest VM.
- The GenieZone hypervisor acts as a vendor firmware to enable platform
  virtualization, offering an implementation that is independent of
  Linux-specific implementations. So, relocate dt-binding yaml file to
  the firmware path, as the dts node is used to confirm the presence of
  the geniezone hypervisor firmware.
- Fix coding style from viewer suggestion and checking tools.

Changes in v10:
https://lore.kernel.org/all/20240412065718.29105-1-yi-de.wu@mediatek.com/
- Optimize memory allocation: query hypervisor demand paging capability before
  VM memory population.
- Fix goto syntax according to ACK reviewer in `gzvm_vcpu.c`.
- Fix coding style from viewer suggestion and checking tools.

Changes in v9:
https://lore.kernel.org/all/20240129083302.26044-1-yi-de.wu@mediatek.com/
- Add gzvm_vm_allocate_guest_page function for demand paging support and
  protected VM memory performance optimization.
- Fix coding style from viewer suggestion and checking tools.

Changes in v8:
https://lore.kernel.org/all/20231228105147.13752-1-yi-de.wu@mediatek.com/
- Add reasons for using dt solution in dt-bindings.
- Add locks for memory pin/unpin and relinquish operations.
- Add VM memory stats in debugfs.
- Add tracing support for hypercall and vcpu exit reasons.
- Enable PTP for timing synchronization between host and guests.
- Optimize memory performance for protected VMs.
- Refactor wording and titles in documentation.

Changes in v7:
https://lore.kernel.org/all/20231116152756.4250-1-yi-de.wu@mediatek.com/
- Rebase these patches to the Linux 6.7-rc1 release.
- Refactor patches 1 to 15 to improve coding style while ensuring they do not
  violate the majority of the changes made in v6
- Provide individual VM memory statistics within debugfs in patch 16.
- Add tracing support for hyper call and vcpu exit_reason.

Changes in v6:
https://lore.kernel.org/all/20230919111210.19615-1-yi-de.wu@mediatek.com/
- Rebase based on kernel 6.6-rc1
- Keep dt solution and leave the reasons in the commit message
- Remove arch/arm64/include/uapi/asm/gzvm_arch.h due to simplicity
- Remove resampler in drivers/virt/geniezone/gzvm_irqfd.c due to defeature for
  now
- Remove PPI in arch/arm64/geniezone/vgic.c
- Refactor vm related components into 3 smaller patches, namely adding vm
  support, setting user memory region and checking vm capability
- Refactor vcpu and vm component to remove unnecessary ARM prefix
- Add demand paging to fix crash on destroying memory page, acclerate on booting
  and support ballooning deflate
- Add memory pin/unpin memory mechanism to support protected VM
- Add block-based demand paging for performance concern
- Response to reviewers and fix coding style accordingly


Changes in v5:
https://lore.kernel.org/all/20230727080005.14474-1-yi-de.wu@mediatek.com/
- Add dt solution back for device initialization
- Add GZVM_EXIT_GZ reason for gzvm_vcpu_run()
- Add patch for guest page fault handler
- Add patch for supporitng pin/unpin memory
- Remove unused enum members, namely GZVM_FUNC_GET_REGS and GZVM_FUNC_SET_REGS
- Use dev_debug() for debugging when platform device is available, and use
  pr_debug() otherwise
- Response to reviewers and fix bugs accordingly


Changes in v4:
https://lore.kernel.org/all/20230609085214.31071-1-yi-de.wu@mediatek.com/
- Add macro to set VM as protected without triggering pvmfw in AVF.
- Add support to pass dtb config to hypervisor.
- Add support for virtual timer.
- Add UAPI to pass memory region metadata to hypervisor.
- Define our own macros for ARM's interrupt number
- Elaborate more on GenieZone hyperivsor in documentation
- Fix coding style.
- Implement our own module for coverting ipa to pa
- Modify the way of initializing device from dt to a more discoverable way
- Move refactoring changes into indepedent patches.

Changes in v3:
https://lore.kernel.org/all/20230512080405.12043-1-yi-de.wu@mediatek.com/
- Refactor: separate arch/arm64/geniezone/gzvm_arch.c into vm.c/vcpu.c/vgic.c
- Remove redundant functions
- Fix reviewer's comments

Changes in v2:
https://lore.kernel.org/all/20230428103622.18291-1-yi-de.wu@mediatek.com/
- Refactor: move to drivers/virt/geniezone
- Refactor: decouple arch-dependent and arch-independent
- Check pending signal before entering guest context
- Fix reviewer's comments

Initial Commit in v1:
https://lore.kernel.org/all/20230413090735.4182-1-yi-de.wu@mediatek.com/

Yi-De Wu (21):
  virt: geniezone: enable gzvm-ko in defconfig
  docs: geniezone: Introduce GenieZone hypervisor
  dt-bindings: hypervisor: Add MediaTek GenieZone hypervisor
  virt: geniezone: Add GenieZone hypervisor driver
  virt: geniezone: Add vm support
  virt: geniezone: Add set_user_memory_region for vm
  virt: geniezone: Add vm capability check
  virt: geniezone: Add vcpu support
  virt: geniezone: Add irqchip support for virtual interrupt injection
  virt: geniezone: Add irqfd support
  virt: geniezone: Add ioeventfd support
  virt: geniezone: Add memory region purpose for hypervisor
  virt: geniezone: Add dtb config support
  virt: geniezone: Optimize performance of protected VM memory
  virt: geniezone: Add memory pin/unpin support
  virt: geniezone: Add demand paging support
  virt: geniezone: Add block-based demand paging support
  virt: geniezone: Add memory relinquish support
  virt: geniezone: Provide individual VM memory statistics within
    debugfs
  virt: geniezone: Add tracing support for hyp call and vcpu exit_reason
  virt: geniezone: Enable PTP for synchronizing time between host and
    guest VMs

 .../bindings/firmware/mediatek,geniezone.yaml |  34 +
 Documentation/virt/geniezone/introduction.rst |  87 +++
 Documentation/virt/index.rst                  |   1 +
 MAINTAINERS                                   |  11 +
 arch/arm64/Kbuild                             |   1 +
 arch/arm64/configs/defconfig                  |   2 +
 arch/arm64/geniezone/Makefile                 |   9 +
 arch/arm64/geniezone/gzvm_arch_common.h       | 105 +++
 arch/arm64/geniezone/hvc.c                    |  73 ++
 arch/arm64/geniezone/vcpu.c                   |  80 +++
 arch/arm64/geniezone/vgic.c                   |  50 ++
 arch/arm64/geniezone/vm.c                     | 425 +++++++++++
 drivers/virt/Kconfig                          |   2 +
 drivers/virt/geniezone/Kconfig                |  16 +
 drivers/virt/geniezone/Makefile               |  12 +
 drivers/virt/geniezone/gzvm_common.h          |  12 +
 drivers/virt/geniezone/gzvm_exception.c       |  61 ++
 drivers/virt/geniezone/gzvm_ioeventfd.c       | 281 ++++++++
 drivers/virt/geniezone/gzvm_irqfd.c           | 382 ++++++++++
 drivers/virt/geniezone/gzvm_main.c            | 148 ++++
 drivers/virt/geniezone/gzvm_mmu.c             | 243 +++++++
 drivers/virt/geniezone/gzvm_vcpu.c            | 282 ++++++++
 drivers/virt/geniezone/gzvm_vm.c              | 657 ++++++++++++++++++
 include/linux/soc/mediatek/gzvm_drv.h         | 256 +++++++
 include/trace/events/geniezone.h              |  84 +++
 include/uapi/linux/gzvm.h                     | 402 +++++++++++
 26 files changed, 3716 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/mediatek,geniezone.yaml
 create mode 100644 Documentation/virt/geniezone/introduction.rst
 create mode 100644 arch/arm64/geniezone/Makefile
 create mode 100644 arch/arm64/geniezone/gzvm_arch_common.h
 create mode 100644 arch/arm64/geniezone/hvc.c
 create mode 100644 arch/arm64/geniezone/vcpu.c
 create mode 100644 arch/arm64/geniezone/vgic.c
 create mode 100644 arch/arm64/geniezone/vm.c
 create mode 100644 drivers/virt/geniezone/Kconfig
 create mode 100644 drivers/virt/geniezone/Makefile
 create mode 100644 drivers/virt/geniezone/gzvm_common.h
 create mode 100644 drivers/virt/geniezone/gzvm_exception.c
 create mode 100644 drivers/virt/geniezone/gzvm_ioeventfd.c
 create mode 100644 drivers/virt/geniezone/gzvm_irqfd.c
 create mode 100644 drivers/virt/geniezone/gzvm_main.c
 create mode 100644 drivers/virt/geniezone/gzvm_mmu.c
 create mode 100644 drivers/virt/geniezone/gzvm_vcpu.c
 create mode 100644 drivers/virt/geniezone/gzvm_vm.c
 create mode 100644 include/linux/soc/mediatek/gzvm_drv.h
 create mode 100644 include/trace/events/geniezone.h
 create mode 100644 include/uapi/linux/gzvm.h

Comments

Simon Horman May 31, 2024, 8:36 p.m. UTC | #1
On Wed, May 29, 2024 at 04:42:26PM +0800, Liju-clr Chen wrote:
> From: Yi-De Wu <yi-de.wu@mediatek.com>
> 
> From: "Yingshiuan Pan" <yingshiuan.pan@mediatek.com>

nit: I think there should be at most one From line,
     denoting the author of the patch. Based on the Signed-off-by
     lines I assume that is Yingshiuan Pan.

     If there are multiple authors perhaps
     the Co-developed-by tag should be used below.

     And on that note, it's not clear to me what the significance
     of the Signed-off-by lines, other than that of
     Yingshiuan Pan (presumed author) and Liju Chen (sender) are.
     I'd suggest deleting them unless they are
     accompanied by Co-developed-by tags.

     And, lastly, the sender's signed-off-by line should come last.

     See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin

> 
> VMM use this interface to create vcpu instance which is a fd, and this
> fd will be for any vcpu operations, such as setting vcpu registers and
> accepts the most important ioctl GZVM_VCPU_RUN which requests GenieZone
> hypervisor to do context switch to execute VM's vcpu context.
> 
> Signed-off-by: Yingshiuan Pan <yingshiuan.pan@mediatek.com>
> Signed-off-by: Jerry Wang <ze-yu.wang@mediatek.com>
> Signed-off-by: kevenny hsieh <kevenny.hsieh@mediatek.com>
> Signed-off-by: Liju Chen <liju-clr.chen@mediatek.com>
> Signed-off-by: Yi-De Wu <yi-de.wu@mediatek.com>

...

> diff --git a/drivers/virt/geniezone/Makefile b/drivers/virt/geniezone/Makefile
> index 25614ea3dea2..9cc453c0819b 100644
> --- a/drivers/virt/geniezone/Makefile
> +++ b/drivers/virt/geniezone/Makefile
> @@ -6,4 +6,5 @@
>  
>  GZVM_DIR ?= ../../../drivers/virt/geniezone
>  
> -gzvm-y := $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o
> +gzvm-y := $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o \
> +	  $(GZVM_DIR)/gzvm_vcpu.o
> diff --git a/drivers/virt/geniezone/gzvm_vcpu.c b/drivers/virt/geniezone/gzvm_vcpu.c
> new file mode 100644
> index 000000000000..1aca13fef422
> --- /dev/null
> +++ b/drivers/virt/geniezone/gzvm_vcpu.c
> @@ -0,0 +1,249 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +
> +#include <asm/sysreg.h>

nit: It's not clear to me that sysreg.h needs to be included in this file.

> +#include <linux/anon_inodes.h>
> +#include <linux/device.h>
> +#include <linux/file.h>
> +#include <linux/mm.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/soc/mediatek/gzvm_drv.h>
> +
> +/* maximum size needed for holding an integer */
> +#define ITOA_MAX_LEN 12
> +
> +static long gzvm_vcpu_update_one_reg(struct gzvm_vcpu *vcpu,
> +				     void __user *argp,
> +				     bool is_write)
> +{
> +	struct gzvm_one_reg reg;
> +	void __user *reg_addr;
> +	u64 data = 0;
> +	u64 reg_size;
> +	long ret;
> +
> +	if (copy_from_user(&reg, argp, sizeof(reg)))
> +		return -EFAULT;
> +
> +	reg_addr = (void __user *)reg.addr;

nit: Perhaps u64_to_user_ptr() is appropriate here.

     Also in gzvm_vm_ioctl_create_device() in patch 09/21.

> +	reg_size = (reg.id & GZVM_REG_SIZE_MASK) >> GZVM_REG_SIZE_SHIFT;
> +	reg_size = BIT(reg_size);
> +
> +	if (reg_size != 1 && reg_size != 2 && reg_size != 4 && reg_size != 8)
> +		return -EINVAL;
> +
> +	if (is_write) {
> +		/* GZ hypervisor would filter out invalid vcpu register access */
> +		if (copy_from_user(&data, reg_addr, reg_size))
> +			return -EFAULT;
> +	} else {
> +		return -EOPNOTSUPP;
> +	}
> +
> +	ret = gzvm_arch_vcpu_update_one_reg(vcpu, reg.id, is_write, &data);
> +
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}

...
Liju-clr Chen (陳麗如) July 29, 2024, 3:35 a.m. UTC | #2
On Fri, 2024-05-31 at 21:36 +0100, Simon Horman wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On Wed, May 29, 2024 at 04:42:26PM +0800, Liju-clr Chen wrote:
> > From: Yi-De Wu <yi-de.wu@mediatek.com>
> > 
> > From: "Yingshiuan Pan" <yingshiuan.pan@mediatek.com>
> 
> nit: I think there should be at most one From line,
>      denoting the author of the patch. Based on the Signed-off-by
>      lines I assume that is Yingshiuan Pan.
> 
>      If there are multiple authors perhaps
>      the Co-developed-by tag should be used below.
> 
>      And on that note, it's not clear to me what the significance
>      of the Signed-off-by lines, other than that of
>      Yingshiuan Pan (presumed author) and Liju Chen (sender) are.
>      I'd suggest deleting them unless they are
>      accompanied by Co-developed-by tags.
> 
>      And, lastly, the sender's signed-off-by line should come last.
> 
>      See: 
> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin

Hi Simon,
Thank you for your review. I will update it in next version.

> 
> > 
> > VMM use this interface to create vcpu instance which is a fd, and
> this
> > fd will be for any vcpu operations, such as setting vcpu registers
> and
> > accepts the most important ioctl GZVM_VCPU_RUN which requests
> GenieZone
> > hypervisor to do context switch to execute VM's vcpu context.
> > 
> > Signed-off-by: Yingshiuan Pan <yingshiuan.pan@mediatek.com>
> > Signed-off-by: Jerry Wang <ze-yu.wang@mediatek.com>
> > Signed-off-by: kevenny hsieh <kevenny.hsieh@mediatek.com>
> > Signed-off-by: Liju Chen <liju-clr.chen@mediatek.com>
> > Signed-off-by: Yi-De Wu <yi-de.wu@mediatek.com>
> 
> ...
> 
> > diff --git a/drivers/virt/geniezone/Makefile
> b/drivers/virt/geniezone/Makefile
> > index 25614ea3dea2..9cc453c0819b 100644
> > --- a/drivers/virt/geniezone/Makefile
> > +++ b/drivers/virt/geniezone/Makefile
> > @@ -6,4 +6,5 @@
> >  
> >  GZVM_DIR ?= ../../../drivers/virt/geniezone
> >  
> > -gzvm-y := $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o
> > +gzvm-y := $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o \
> > +  $(GZVM_DIR)/gzvm_vcpu.o
> > diff --git a/drivers/virt/geniezone/gzvm_vcpu.c
> b/drivers/virt/geniezone/gzvm_vcpu.c
> > new file mode 100644
> > index 000000000000..1aca13fef422
> > --- /dev/null
> > +++ b/drivers/virt/geniezone/gzvm_vcpu.c
> > @@ -0,0 +1,249 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2023 MediaTek Inc.
> > + */
> > +
> > +#include <asm/sysreg.h>
> 
> nit: It's not clear to me that sysreg.h needs to be included in this
> file.

Ok. I will update it in next version.

> 
> > +#include <linux/anon_inodes.h>
> > +#include <linux/device.h>
> > +#include <linux/file.h>
> > +#include <linux/mm.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/slab.h>
> > +#include <linux/soc/mediatek/gzvm_drv.h>
> > +
> > +/* maximum size needed for holding an integer */
> > +#define ITOA_MAX_LEN 12
> > +
> > +static long gzvm_vcpu_update_one_reg(struct gzvm_vcpu *vcpu,
> > +     void __user *argp,
> > +     bool is_write)
> > +{
> > +struct gzvm_one_reg reg;
> > +void __user *reg_addr;
> > +u64 data = 0;
> > +u64 reg_size;
> > +long ret;
> > +
> > +if (copy_from_user(&reg, argp, sizeof(reg)))
> > +return -EFAULT;
> > +
> > +reg_addr = (void __user *)reg.addr;
> 
> nit: Perhaps u64_to_user_ptr() is appropriate here.
> 
>      Also in gzvm_vm_ioctl_create_device() in patch 09/21.

Ok. I will update it in next version.

Thanks,
Liju

> 
> > +reg_size = (reg.id & GZVM_REG_SIZE_MASK) >> GZVM_REG_SIZE_SHIFT;
> > +reg_size = BIT(reg_size);
> > +
> > +if (reg_size != 1 && reg_size != 2 && reg_size != 4 && reg_size !=
> 8)
> > +return -EINVAL;
> > +
> > +if (is_write) {
> > +/* GZ hypervisor would filter out invalid vcpu register access */
> > +if (copy_from_user(&data, reg_addr, reg_size))
> > +return -EFAULT;
> > +} else {
> > +return -EOPNOTSUPP;
> > +}
> > +
> > +ret = gzvm_arch_vcpu_update_one_reg(vcpu, reg.id, is_write,
> &data);
> > +
> > +if (ret)
> > +return ret;
> > +
> > +return 0;
> > +}
> 
> ...