From nobody Fri Sep 20 11:56:03 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 571D9C197A0 for ; Thu, 16 Nov 2023 15:29:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231236AbjKPP3i (ORCPT ); Thu, 16 Nov 2023 10:29:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230527AbjKPP3Y (ORCPT ); Thu, 16 Nov 2023 10:29:24 -0500 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23DE0D4A; Thu, 16 Nov 2023 07:29:17 -0800 (PST) X-UUID: e387ddf8849411ee8051498923ad61e6-20231116 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=Y5JZaqWrBHMUUFdDxc8+X1/3JDw2cNHvU4Amg8pbNQM=; b=EXPnJbiOji24hsIT8zpNbM6yaHCMZTbiqfAYm8x6J9hDdRqH+5eJZSFmLj3GdtFrjsViWgfp7NRI8mymlTThf9+ph83ggfpOqadQgqgQroomsCje4HnyLlJrekBxc/tZPfFwvGbGhclfLMt1BWCsrLJYm8oYI6RNk8rWfnmJ7H4=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.33,REQID:e29a664c-fb6f-4a9e-966f-27985da2279c,IP:0,U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:364b77b,CLOUDID:865c7995-10ce-4e4b-85c2-c9b5229ff92b,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:11|1,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR: NO,DKR:0,DKP:0,BRR:0,BRE:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_ULN,TF_CID_SPAM_SNR X-UUID: e387ddf8849411ee8051498923ad61e6-20231116 Received: from mtkmbs13n2.mediatek.inc [(172.21.101.108)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1783103596; Thu, 16 Nov 2023 23:29:10 +0800 Received: from mtkmbs11n2.mediatek.inc (172.21.101.187) by mtkmbs11n2.mediatek.inc (172.21.101.187) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Thu, 16 Nov 2023 23:29:09 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs11n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Thu, 16 Nov 2023 23:29:09 +0800 From: Yi-De Wu To: Yingshiuan Pan , Ze-Yu Wang , Yi-De Wu , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Catalin Marinas , Will Deacon , Matthias Brugger , AngeloGioacchino Del Regno CC: Arnd Bergmann , , , , , , David Bradil , Trilok Soni , Jade Shih , Ivan Tseng , My Chuang , Shawn Hsiao , PeiLun Suei , Liju Chen , Willix Yeh , Kevenny Hsieh Subject: [PATCH v7 04/16] virt: geniezone: Add vm support Date: Thu, 16 Nov 2023 23:27:44 +0800 Message-ID: <20231116152756.4250-5-yi-de.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20231116152756.4250-1-yi-de.wu@mediatek.com> References: <20231116152756.4250-1-yi-de.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Yingshiuan Pan" The VM component is responsible for setting up the capability and memory management for the protected VMs. The capability is mainly about the lifecycle control and boot context initialization. Signed-off-by: Yingshiuan Pan Signed-off-by: Jerry Wang Signed-off-by: Yi-De Wu Signed-off-by: Liju Chen --- MAINTAINERS | 1 + arch/arm64/geniezone/gzvm_arch_common.h | 9 ++ arch/arm64/geniezone/vm.c | 29 +++++++ drivers/virt/geniezone/Makefile | 2 +- drivers/virt/geniezone/gzvm_main.c | 19 +++++ drivers/virt/geniezone/gzvm_vm.c | 107 ++++++++++++++++++++++++ include/linux/gzvm_drv.h | 26 ++++++ include/uapi/linux/gzvm.h | 25 ++++++ 8 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 drivers/virt/geniezone/gzvm_vm.c create mode 100644 include/uapi/linux/gzvm.h diff --git a/MAINTAINERS b/MAINTAINERS index 49eba202ce1b..33620b534936 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8951,6 +8951,7 @@ F: Documentation/virt/geniezone/ F: arch/arm64/geniezone/ F: drivers/virt/geniezone/ F: include/linux/gzvm_drv.h +F: include/uapi/linux/gzvm.h =20 GENWQE (IBM Generic Workqueue Card) M: Frank Haverkamp diff --git a/arch/arm64/geniezone/gzvm_arch_common.h b/arch/arm64/geniezone= /gzvm_arch_common.h index 10037013ab91..68cc6388f4cc 100644 --- a/arch/arm64/geniezone/gzvm_arch_common.h +++ b/arch/arm64/geniezone/gzvm_arch_common.h @@ -9,6 +9,8 @@ #include =20 enum { + GZVM_FUNC_CREATE_VM =3D 0, + GZVM_FUNC_DESTROY_VM =3D 1, GZVM_FUNC_PROBE =3D 12, NR_GZVM_FUNC, }; @@ -19,6 +21,8 @@ enum { ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \ SMC_ENTITY_MTK, (GZVM_FUNCID_START + (func))) =20 +#define MT_HVC_GZVM_CREATE_VM GZVM_HCALL_ID(GZVM_FUNC_CREATE_VM) +#define MT_HVC_GZVM_DESTROY_VM GZVM_HCALL_ID(GZVM_FUNC_DESTROY_VM) #define MT_HVC_GZVM_PROBE GZVM_HCALL_ID(GZVM_FUNC_PROBE) =20 /** @@ -34,4 +38,9 @@ int gzvm_hypcall_wrapper(unsigned long a0, unsigned long = a1, unsigned long a6, unsigned long a7, struct arm_smccc_res *res); =20 +static inline u16 get_vmid_from_tuple(unsigned int tuple) +{ + return (u16)(tuple >> 16); +} + #endif /* __GZVM_ARCH_COMMON_H__ */ diff --git a/arch/arm64/geniezone/vm.c b/arch/arm64/geniezone/vm.c index aa2d08b9fa88..b9789e2384f6 100644 --- a/arch/arm64/geniezone/vm.c +++ b/arch/arm64/geniezone/vm.c @@ -7,9 +7,12 @@ #include #include =20 +#include #include #include "gzvm_arch_common.h" =20 +#define PAR_PA47_MASK ((((1UL << 48) - 1) >> 12) << 12) + /** * gzvm_hypcall_wrapper() - the wrapper for hvc calls * @a0-a7: arguments passed in registers 0 to 7 @@ -38,3 +41,29 @@ int gzvm_arch_probe(void) =20 return 0; } + +/** + * gzvm_arch_create_vm() - create vm + * @vm_type: VM type. Only supports Linux VM now. + * + * Return: + * * positive value - VM ID + * * -ENOMEM - Memory not enough for storing VM data + */ +int gzvm_arch_create_vm(unsigned long vm_type) +{ + struct arm_smccc_res res; + int ret; + + ret =3D gzvm_hypcall_wrapper(MT_HVC_GZVM_CREATE_VM, vm_type, 0, 0, 0, 0, + 0, 0, &res); + return ret ? ret : res.a1; +} + +int gzvm_arch_destroy_vm(u16 vm_id) +{ + struct arm_smccc_res res; + + return gzvm_hypcall_wrapper(MT_HVC_GZVM_DESTROY_VM, vm_id, 0, 0, 0, 0, + 0, 0, &res); +} diff --git a/drivers/virt/geniezone/Makefile b/drivers/virt/geniezone/Makef= ile index 8c1f0053e773..066efddc0b9c 100644 --- a/drivers/virt/geniezone/Makefile +++ b/drivers/virt/geniezone/Makefile @@ -6,5 +6,5 @@ =20 GZVM_DIR ?=3D ../../../drivers/virt/geniezone =20 -gzvm-y :=3D $(GZVM_DIR)/gzvm_main.o +gzvm-y :=3D $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o =20 diff --git a/drivers/virt/geniezone/gzvm_main.c b/drivers/virt/geniezone/gz= vm_main.c index f7d4f0646d97..4e7d60067c55 100644 --- a/drivers/virt/geniezone/gzvm_main.c +++ b/drivers/virt/geniezone/gzvm_main.c @@ -4,6 +4,7 @@ */ =20 #include +#include #include #include #include @@ -40,7 +41,24 @@ int gzvm_err_to_errno(unsigned long err) return -EINVAL; } =20 +static long gzvm_dev_ioctl(struct file *filp, unsigned int cmd, + unsigned long user_args) +{ + long ret; + + switch (cmd) { + case GZVM_CREATE_VM: + ret =3D gzvm_dev_ioctl_create_vm(user_args); + return ret; + default: + break; + } + + return -ENOTTY; +} + static const struct file_operations gzvm_chardev_ops =3D { + .unlocked_ioctl =3D gzvm_dev_ioctl, .llseek =3D noop_llseek, }; =20 @@ -62,6 +80,7 @@ static int gzvm_drv_probe(struct platform_device *pdev) =20 static int gzvm_drv_remove(struct platform_device *pdev) { + gzvm_destroy_all_vms(); misc_deregister(&gzvm_dev); return 0; } diff --git a/drivers/virt/geniezone/gzvm_vm.c b/drivers/virt/geniezone/gzvm= _vm.c new file mode 100644 index 000000000000..d5e850af924a --- /dev/null +++ b/drivers/virt/geniezone/gzvm_vm.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_MUTEX(gzvm_list_lock); +static LIST_HEAD(gzvm_list); + +static void gzvm_destroy_vm(struct gzvm *gzvm) +{ + pr_debug("VM-%u is going to be destroyed\n", gzvm->vm_id); + + mutex_lock(&gzvm->lock); + + gzvm_arch_destroy_vm(gzvm->vm_id); + + mutex_lock(&gzvm_list_lock); + list_del(&gzvm->vm_list); + mutex_unlock(&gzvm_list_lock); + + mutex_unlock(&gzvm->lock); + + kfree(gzvm); +} + +static int gzvm_vm_release(struct inode *inode, struct file *filp) +{ + struct gzvm *gzvm =3D filp->private_data; + + gzvm_destroy_vm(gzvm); + return 0; +} + +static const struct file_operations gzvm_vm_fops =3D { + .release =3D gzvm_vm_release, + .llseek =3D noop_llseek, +}; + +static struct gzvm *gzvm_create_vm(unsigned long vm_type) +{ + int ret; + struct gzvm *gzvm; + + gzvm =3D kzalloc(sizeof(*gzvm), GFP_KERNEL); + if (!gzvm) + return ERR_PTR(-ENOMEM); + + ret =3D gzvm_arch_create_vm(vm_type); + if (ret < 0) { + kfree(gzvm); + return ERR_PTR(ret); + } + + gzvm->vm_id =3D ret; + gzvm->mm =3D current->mm; + mutex_init(&gzvm->lock); + + mutex_lock(&gzvm_list_lock); + list_add(&gzvm->vm_list, &gzvm_list); + mutex_unlock(&gzvm_list_lock); + + pr_debug("VM-%u is created\n", gzvm->vm_id); + + return gzvm; +} + +/** + * gzvm_dev_ioctl_create_vm - Create vm fd + * @vm_type: VM type. Only supports Linux VM now. + * + * Return: fd of vm, negative if error + */ +int gzvm_dev_ioctl_create_vm(unsigned long vm_type) +{ + struct gzvm *gzvm; + + gzvm =3D gzvm_create_vm(vm_type); + if (IS_ERR(gzvm)) + return PTR_ERR(gzvm); + + return anon_inode_getfd("gzvm-vm", &gzvm_vm_fops, gzvm, + O_RDWR | O_CLOEXEC); +} + +void gzvm_destroy_all_vms(void) +{ + struct gzvm *gzvm, *tmp; + + mutex_lock(&gzvm_list_lock); + if (list_empty(&gzvm_list)) + goto out; + + list_for_each_entry_safe(gzvm, tmp, &gzvm_list, vm_list) + gzvm_destroy_vm(gzvm); + +out: + mutex_unlock(&gzvm_list_lock); +} diff --git a/include/linux/gzvm_drv.h b/include/linux/gzvm_drv.h index 907f2f984de9..f1dce23838e4 100644 --- a/include/linux/gzvm_drv.h +++ b/include/linux/gzvm_drv.h @@ -6,6 +6,12 @@ #ifndef __GZVM_DRV_H__ #define __GZVM_DRV_H__ =20 +#include +#include +#include + +#define INVALID_VM_ID 0xffff + /* * These are the definitions of APIs between GenieZone hypervisor and driv= er, * there's no need to be visible to uapi. Furthermore, we need GenieZone @@ -17,9 +23,29 @@ #define ERR_NOT_IMPLEMENTED (-27) #define ERR_FAULT (-40) =20 +/* + * The following data structures are for data transferring between driver = and + * hypervisor, and they're aligned with hypervisor definitions + */ + +struct gzvm { + /* userspace tied to this vm */ + struct mm_struct *mm; + /* lock for list_add*/ + struct mutex lock; + struct list_head vm_list; + u16 vm_id; +}; + +int gzvm_dev_ioctl_create_vm(unsigned long vm_type); + int gzvm_err_to_errno(unsigned long err); =20 +void gzvm_destroy_all_vms(void); + /* arch-dependant functions */ int gzvm_arch_probe(void); +int gzvm_arch_create_vm(unsigned long vm_type); +int gzvm_arch_destroy_vm(u16 vm_id); =20 #endif /* __GZVM_DRV_H__ */ diff --git a/include/uapi/linux/gzvm.h b/include/uapi/linux/gzvm.h new file mode 100644 index 000000000000..c26c7720fab7 --- /dev/null +++ b/include/uapi/linux/gzvm.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +/** + * DOC: UAPI of GenieZone Hypervisor + * + * This file declares common data structure shared among user space, + * kernel space, and GenieZone hypervisor. + */ +#ifndef __GZVM_H__ +#define __GZVM_H__ + +#include +#include +#include + +/* GZVM ioctls */ +#define GZVM_IOC_MAGIC 0x92 /* gz */ + +/* ioctls for /dev/gzvm fds */ +#define GZVM_CREATE_VM _IO(GZVM_IOC_MAGIC, 0x01) /* Returns = a Geniezone VM fd */ + +#endif /* __GZVM_H__ */ --=20 2.18.0