Received: by 2002:a05:6a10:c604:0:0:0:0 with SMTP id y4csp906738pxt; Thu, 5 Aug 2021 14:56:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwysKBYkRKWpYRgJpKALT9LwpTPaTruEMdpTjl0akGCd1ggBiVK+30VaERXGYIFVYfwL2Mg X-Received: by 2002:a17:906:72ce:: with SMTP id m14mr6702863ejl.394.1628200606132; Thu, 05 Aug 2021 14:56:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628200606; cv=none; d=google.com; s=arc-20160816; b=Zzm5K009wDmgY+t69TiSKLV3iBNRfyLJifHjA3YaHC+R0I27tL4VlENw4QTwYr4W29 NAMNcjexOGF0i15qQAfYVANC9gi1YvFS6m8lAigzDTQn2Jmd0HbdAOgip2Ti6t6swGY+ xGhQG31pItZTsOlZX/xHLVZFxuPLbbq00huicSkvIMkgqn0/P238gNG2Zyy6D85vUsST FWD8HZXSDNCj9zEzzFBVz5LTlu+8dVymgL+71EiuEd9eDdE8sd/cIZyzcqEFsV7eabEP 4/WYJOHcDj1YUWvwQsWEgECecTTqL7l8B0QlGXpwLEHsp86ly67reU4gLoWbxwiPJwrS R9IQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature:dkim-filter; bh=Jz/tjbLiFlDhfyN8ijSp3BgdMZc9hWoAx2AIcuixAsg=; b=A7MeZq51jPTyksd7tREWZchiEAK1eG7QJcujny8pf1P0ljcRaRz/XD0NAyQmgfsUnz h4VLcE/D9EOcexpv9ehkdJdSc2ElTkgvZ83p2GoNGc17G8T/xR4aOpNbX3MMCMxfB747 1EiwCyy49hTWoc7ciwHnAztBKVQZxhWF7PGzFy9jh3MdCt0L0S+zf88B+almXYD5+HmS uWA0wbKXkupZFGKG90MsQhj/s7XD7vC/sZGyFCYgS4xmC6b80JkSDFeT8ektPqbV6z3F DjuzYEkE2ANfVYgSFUfVGI+qvPwP9eUpvgrUfcF1w6xlyi2PS75R3TeehL4pY34aJV1M PaAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=ljI90mJR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id cw10si6520671ejc.360.2021.08.05.14.56.22; Thu, 05 Aug 2021 14:56:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=ljI90mJR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242497AbhHEVZn (ORCPT + 99 others); Thu, 5 Aug 2021 17:25:43 -0400 Received: from linux.microsoft.com ([13.77.154.182]:46548 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241491AbhHEVYu (ORCPT ); Thu, 5 Aug 2021 17:24:50 -0400 Received: from linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net (linux.microsoft.com [13.77.154.182]) by linux.microsoft.com (Postfix) with ESMTPSA id 8701020BE667; Thu, 5 Aug 2021 14:24:34 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8701020BE667 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1628198674; bh=Jz/tjbLiFlDhfyN8ijSp3BgdMZc9hWoAx2AIcuixAsg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ljI90mJRtiRtbv0kPV8RLGsxQcz6HVxiwKXWI01mmeQT28hPtEKB8Te4X4e/Dymfc TsLhdpTlBucnKQYmpa0wRjSthWitvvc6zy976pDeE4u0UBkeLFe83RMPoga4YJdVrF LUs10oOq7PVUtoDcv2Q7SPdJRo3+e1VdXl1rCMAE= From: Nuno Das Neves To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org Cc: virtualization@lists.linux-foundation.org, mikelley@microsoft.com, viremana@linux.microsoft.com, sunilmut@microsoft.com, wei.liu@kernel.org, vkuznets@redhat.com, ligrassi@microsoft.com, kys@microsoft.com, sthemmin@microsoft.com, anbelski@linux.microsoft.com Subject: [PATCH 19/19] drivers/hv: Translate GVA to GPA Date: Thu, 5 Aug 2021 14:24:01 -0700 Message-Id: <1628198641-791-20-git-send-email-nunodasneves@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1628198641-791-1-git-send-email-nunodasneves@linux.microsoft.com> References: <1628198641-791-1-git-send-email-nunodasneves@linux.microsoft.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Wei Liu Introduce ioctl for translating Guest Virtual Address (GVA) to Guest Physical Address (GPA) Signed-off-by: Wei Liu Signed-off-by: Nuno Das Neves Signed-off-by: Anatol Belski Reviewed-by: Wei Liu --- drivers/hv/hv_call.c | 44 ++++++++++++++++++++++++++ drivers/hv/mshv.h | 7 ++++ drivers/hv/mshv_main.c | 34 ++++++++++++++++++++ include/asm-generic/hyperv-tlfs.h | 14 ++++++++ include/uapi/asm-generic/hyperv-tlfs.h | 43 +++++++++++++++++++++++++ include/uapi/linux/mshv.h | 8 +++++ 6 files changed, 150 insertions(+) diff --git a/drivers/hv/hv_call.c b/drivers/hv/hv_call.c index 776095de9679..0900e7377826 100644 --- a/drivers/hv/hv_call.c +++ b/drivers/hv/hv_call.c @@ -10,6 +10,7 @@ #include #include +#include #include #include "mshv.h" @@ -696,3 +697,46 @@ int hv_call_set_partition_property( return hv_status_to_errno(status); } + +int hv_call_translate_virtual_address( + u32 vp_index, + u64 partition_id, + u64 flags, + u64 gva, + u64 *gpa, + union hv_translate_gva_result *result) +{ + u64 status; + unsigned long irq_flags; + struct hv_translate_virtual_address_in *input; + struct hv_translate_virtual_address_out *output; + + local_irq_save(irq_flags); + + input = *this_cpu_ptr(hyperv_pcpu_input_arg); + output = *this_cpu_ptr(hyperv_pcpu_output_arg); + + memset(input, 0, sizeof(*input)); + memset(output, 0, sizeof(*output)); + + input->partition_id = partition_id; + input->vp_index = vp_index; + input->control_flags = flags; + input->gva_page = gva >> HV_HYP_PAGE_SHIFT; + + status = hv_do_hypercall(HVCALL_TRANSLATE_VIRTUAL_ADDRESS, input, output); + + if (!hv_result_success(status)) { + pr_err("%s: %s\n", __func__, hv_status_to_string(status)); + goto out; + } + + *result = output->translation_result; + *gpa = (output->gpa_page << HV_HYP_PAGE_SHIFT) + offset_in_hvpage(gva); + +out: + local_irq_restore(irq_flags); + + return hv_status_to_errno(status); +} + diff --git a/drivers/hv/mshv.h b/drivers/hv/mshv.h index 8230368b4257..1a8c94edb9c5 100644 --- a/drivers/hv/mshv.h +++ b/drivers/hv/mshv.h @@ -109,5 +109,12 @@ int hv_call_set_partition_property( u64 partition_id, u64 property_code, u64 property_value); +int hv_call_translate_virtual_address( + u32 vp_index, + u64 partition_id, + u64 flags, + u64 gva, + u64 *gpa, + union hv_translate_gva_result *result); #endif /* _MSHV_H */ diff --git a/drivers/hv/mshv_main.c b/drivers/hv/mshv_main.c index 06aef8b02e6c..08aff91cf260 100644 --- a/drivers/hv/mshv_main.c +++ b/drivers/hv/mshv_main.c @@ -411,6 +411,37 @@ mshv_vp_ioctl_get_set_state(struct mshv_vp *vp, void __user *user_args, bool is_ return 0; } +static long +mshv_vp_ioctl_translate_gva(struct mshv_vp *vp, void __user *user_args) +{ + long ret; + struct mshv_translate_gva args; + u64 gpa; + union hv_translate_gva_result result; + + if (copy_from_user(&args, user_args, sizeof(args))) + return -EFAULT; + + ret = hv_call_translate_virtual_address( + vp->index, + vp->partition->id, + args.flags, + args.gva, + &gpa, + &result); + + if (ret) + return ret; + + if (copy_to_user(args.result, &result, sizeof(*args.result))) + return -EFAULT; + + if (copy_to_user(args.gpa, &gpa, sizeof(*args.gpa))) + return -EFAULT; + + return 0; +} + static long mshv_vp_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -436,6 +467,9 @@ mshv_vp_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) case MSHV_SET_VP_STATE: r = mshv_vp_ioctl_get_set_state(vp, (void __user *)arg, true); break; + case MSHV_TRANSLATE_GVA: + r = mshv_vp_ioctl_translate_gva(vp, (void __user *)arg); + break; default: r = -ENOTTY; break; diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h index 2c0dfd0b8763..2e520e7d765d 100644 --- a/include/asm-generic/hyperv-tlfs.h +++ b/include/asm-generic/hyperv-tlfs.h @@ -158,6 +158,7 @@ struct ms_hyperv_tsc_page { #define HVCALL_CREATE_VP 0x004e #define HVCALL_GET_VP_REGISTERS 0x0050 #define HVCALL_SET_VP_REGISTERS 0x0051 +#define HVCALL_TRANSLATE_VIRTUAL_ADDRESS 0x0052 #define HVCALL_POST_MESSAGE 0x005c #define HVCALL_SIGNAL_EVENT 0x005d #define HVCALL_POST_DEBUG_DATA 0x0069 @@ -901,4 +902,17 @@ struct hv_set_partition_property { u64 property_value; } __packed; +struct hv_translate_virtual_address_in { + u64 partition_id; + u32 vp_index; + u32 padding; + u64 control_flags; + u64 gva_page; +} __packed; + +struct hv_translate_virtual_address_out { + union hv_translate_gva_result translation_result; + u64 gpa_page; +} __packed; + #endif diff --git a/include/uapi/asm-generic/hyperv-tlfs.h b/include/uapi/asm-generic/hyperv-tlfs.h index 5d8d5e89f432..95020e3a67ba 100644 --- a/include/uapi/asm-generic/hyperv-tlfs.h +++ b/include/uapi/asm-generic/hyperv-tlfs.h @@ -196,4 +196,47 @@ enum hv_partition_property_code { HV_PARTITION_PROPERTY_PROCESSOR_VIRTUALIZATION_FEATURES = 0x00080000, }; +enum hv_translate_gva_result_code { + HV_TRANSLATE_GVA_SUCCESS = 0, + + /* Translation failures. */ + HV_TRANSLATE_GVA_PAGE_NOT_PRESENT = 1, + HV_TRANSLATE_GVA_PRIVILEGE_VIOLATION = 2, + HV_TRANSLATE_GVA_INVALIDE_PAGE_TABLE_FLAGS = 3, + + /* GPA access failures. */ + HV_TRANSLATE_GVA_GPA_UNMAPPED = 4, + HV_TRANSLATE_GVA_GPA_NO_READ_ACCESS = 5, + HV_TRANSLATE_GVA_GPA_NO_WRITE_ACCESS = 6, + HV_TRANSLATE_GVA_GPA_ILLEGAL_OVERLAY_ACCESS = 7, + + /* + * Intercept for memory access by either + * - a higher VTL + * - a nested hypervisor (due to a violation of the nested page table) + */ + HV_TRANSLATE_GVA_INTERCEPT = 8, + + HV_TRANSLATE_GVA_GPA_UNACCEPTED = 9, +}; + +union hv_translate_gva_result { + __u64 as_uint64; + struct { + __u32 result_code; /* enum hv_translate_hva_result_code */ + __u32 cache_type : 8; + __u32 overlay_page : 1; + __u32 reserved : 23; + } __packed; +}; + +/* hv_translage_gva flags */ +#define HV_TRANSLATE_GVA_VALIDATE_READ 0x0001 +#define HV_TRANSLATE_GVA_VALIDATE_WRITE 0x0002 +#define HV_TRANSLATE_GVA_VALIDATE_EXECUTE 0x0004 +#define HV_TRANSLATE_GVA_PRIVILEGE_EXCEMP 0x0008 +#define HV_TRANSLATE_GVA_SET_PAGE_TABLE_BITS 0x0010 +#define HV_TRANSLATE_GVA_TLB_FLUSH_INHIBIT 0x0020 +#define HV_TRANSLATE_GVA_CONTROL_MASK 0x003f + #endif diff --git a/include/uapi/linux/mshv.h b/include/uapi/linux/mshv.h index ec8281712430..0c46ce77cbb3 100644 --- a/include/uapi/linux/mshv.h +++ b/include/uapi/linux/mshv.h @@ -72,6 +72,13 @@ struct mshv_partition_property { __u64 property_value; }; +struct mshv_translate_gva { + __u64 gva; + __u64 flags; + union hv_translate_gva_result *result; + __u64 *gpa; +}; + #define MSHV_IOCTL 0xB8 /* mshv device */ @@ -95,6 +102,7 @@ struct mshv_partition_property { #define MSHV_RUN_VP _IOR(MSHV_IOCTL, 0x07, struct hv_message) #define MSHV_GET_VP_STATE _IOWR(MSHV_IOCTL, 0x0A, struct mshv_vp_state) #define MSHV_SET_VP_STATE _IOWR(MSHV_IOCTL, 0x0B, struct mshv_vp_state) +#define MSHV_TRANSLATE_GVA _IOWR(MSHV_IOCTL, 0x0E, struct mshv_translate_gva) /* register page mapping example: * struct hv_vp_register_page *regs = mmap(NULL, -- 2.23.4