From nobody Wed Apr 15 08:25:02 2026 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 E658ECCA473 for ; Fri, 22 Jul 2022 23:02:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236815AbiGVXC4 (ORCPT ); Fri, 22 Jul 2022 19:02:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236451AbiGVXCx (ORCPT ); Fri, 22 Jul 2022 19:02:53 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE7D485FA0 for ; Fri, 22 Jul 2022 16:02:51 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31e559f6840so49094857b3.6 for ; Fri, 22 Jul 2022 16:02:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=FiHaCQhNDin1qEUasBSBeGavty7GfFuR81E7xhz62HI=; b=c1rAayLK7iuzyanIxPd2s407NjMvZS1gAWHbj2TnvKwoSzsJmhT2/rBhCxrzweD5bv goe/abBy7tIHD2PSW9W9YnBYWHFtXFPEamWfSvSBZq2LF7vTzdC7PyirE6re1S8KkYnZ 1AJn7Tt3KERZ2wW11owVtqmqOZlc0m6dMwpkpTXh+j1tK0hRBz29NOXYSq0Ytm9thELs gN8CHKC3AqZVebQZ86fJSV7cGNQw6305dLKxSNP9nt7krqnR1itpC6y2U7KVV1R8MlAy e73WJF8p/Qw4XVS91CV+aHr0vsi6LVWd59DTfIH6QGon7pVTvQDEz98LU2Oh2LHM2NzL fBvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=FiHaCQhNDin1qEUasBSBeGavty7GfFuR81E7xhz62HI=; b=IvEctyyqydgF9lBsWLkGbRaeS+a9yEv+5vRNf+GsXMKglvPOXSI7H2AiHx1SoGhzrF U31WTxW2BRHkW8w6mvHpSXtw/LnRsicr3DX5HheAkiPeYKTQ6W0dMPxlFAm92sc0txKo ATMi7vdSPSPQ2KosD+9aF4DQ2HkeCH3DEaGzvSoLxPUvKIr5Ycwg87VWa1cJJQ6biCil twmqGWzW2tWVqeAm8ZekkokjcMGx9mjoA59nm9O5GGVRO6Vjyo6AaQoSDSc+DNswliYj yFllNYPAtBtkskFl+mHeyXAleQeJkPEVKPx/gNPAzvZXcBlCw9JgYM8ygm8Rs08nFCT5 vPpw== X-Gm-Message-State: AJIora980lVEVuCG0voA1eZgGVkvCAz8PsUWXBjezYqVZ15HtP0/jx3q P2MNzR0gyYGSYlDSaEoQOjjQ58//eQA= X-Google-Smtp-Source: AGRyM1t+zExx1lMHouATchHS9iV5z5PPTi5UzQWlQv/TLkhoMSChcKNIDdA7jkdLJ9eLFt4X/Rtsejoq1PI= X-Received: from avagin.kir.corp.google.com ([2620:15c:29:204:5863:d08b:b2f8:4a3e]) (user=avagin job=sendgmr) by 2002:a25:7e42:0:b0:670:9c92:d1ab with SMTP id z63-20020a257e42000000b006709c92d1abmr1933632ybc.638.1658530971110; Fri, 22 Jul 2022 16:02:51 -0700 (PDT) Date: Fri, 22 Jul 2022 16:02:37 -0700 In-Reply-To: <20220722230241.1944655-1-avagin@google.com> Message-Id: <20220722230241.1944655-2-avagin@google.com> Mime-Version: 1.0 References: <20220722230241.1944655-1-avagin@google.com> X-Mailer: git-send-email 2.37.1.359.gd136c6c3e2-goog Subject: [PATCH 1/5] kernel: add a new helper to execute system calls from kernel code From: Andrei Vagin To: Paolo Bonzini Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Andrei Vagin , Sean Christopherson , Wanpeng Li , Vitaly Kuznetsov , Jianfeng Tan , Adin Scannell , Konstantin Bogomolov , Etienne Perot Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This helper will be used to implement a kvm hypercall to call host system calls. The new helper executes seccomp rules and calls trace_sys_{enter,exit} hooks. But it intentionally doesn't call ptrace hooks because calling syscalls are not linked with the current process state. Signed-off-by: Andrei Vagin --- arch/x86/entry/common.c | 50 ++++++++++++++++++++++++++++++++++ arch/x86/include/asm/syscall.h | 1 + 2 files changed, 51 insertions(+) diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 6c2826417b33..7f4c172a9a4e 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -19,6 +19,7 @@ #include #include #include +#include =20 #ifdef CONFIG_XEN_PV #include @@ -37,6 +38,55 @@ =20 #ifdef CONFIG_X86_64 =20 +/* + * do_ksyscall_64 executes a system call. This helper can be used from the + * kernel code. + */ +bool do_ksyscall_64(int nr, struct pt_regs *regs) +{ + struct task_struct *task =3D current; + unsigned long work =3D READ_ONCE(current_thread_info()->syscall_work); + /* + * Convert negative numbers to very high and thus out of range + * numbers for comparisons. + */ + unsigned int unr =3D nr; + +#ifdef CONFIG_IA32_EMULATION + if (task->thread_info.status & TS_COMPAT) + return false; +#endif + + if (work & SYSCALL_WORK_SECCOMP) { + struct seccomp_data sd; + unsigned long args[6]; + + sd.nr =3D nr; + sd.arch =3D AUDIT_ARCH_X86_64; + syscall_get_arguments(task, regs, args); + sd.args[0] =3D args[0]; + sd.args[1] =3D args[1]; + sd.args[2] =3D args[2]; + sd.args[3] =3D args[3]; + sd.args[4] =3D args[4]; + sd.args[5] =3D args[5]; + sd.instruction_pointer =3D regs->ip; + if (__secure_computing(&sd) =3D=3D -1) + return false; + } + + if (likely(unr >=3D NR_syscalls)) + return false; + + unr =3D array_index_nospec(unr, NR_syscalls); + + trace_sys_enter(regs, unr); + regs->ax =3D sys_call_table[unr](regs); + trace_sys_exit(regs, syscall_get_return_value(task, regs)); + return true; +} +EXPORT_SYMBOL_GPL(do_ksyscall_64); + static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr) { /* diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h index 5b85987a5e97..6cde1ddeb50b 100644 --- a/arch/x86/include/asm/syscall.h +++ b/arch/x86/include/asm/syscall.h @@ -126,6 +126,7 @@ static inline int syscall_get_arch(struct task_struct *= task) ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64; } =20 +bool do_ksyscall_64(int nr, struct pt_regs *regs); void do_syscall_64(struct pt_regs *regs, int nr); void do_int80_syscall_32(struct pt_regs *regs); long do_fast_syscall_32(struct pt_regs *regs); --=20 2.37.1.359.gd136c6c3e2-goog From nobody Wed Apr 15 08:25:02 2026 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 3C552C43334 for ; Fri, 22 Jul 2022 23:03:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236971AbiGVXDE (ORCPT ); Fri, 22 Jul 2022 19:03:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236579AbiGVXCz (ORCPT ); Fri, 22 Jul 2022 19:02:55 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C43488E6C5 for ; Fri, 22 Jul 2022 16:02:53 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id 134-20020a63018c000000b0040cf04213a1so2908114pgb.6 for ; Fri, 22 Jul 2022 16:02:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=PKYAm/0aV3bhWo2rNA4kUnanHN9tpgw1D3TRbQRB/9o=; b=lRI5e0Ox5A5pJzsc8ceHqeriWk/S0n2o4DRYoy+eweCV0NrV2mSJaSneriBwNeCzSl EjNuI6u8Lw0Mg0RRaQbudLHcxikI0qQXRNUZFovHPMTpsiTrd6OgMcQEwuhNQRa9pEJN Dw4byaxIfon3dRpoBFL9/ccN8ggLzT235AHW65DMUaTfodhQcOltUccfwqJhjpTE03VG B4q+0lnOiALPxjpgtnBUhGwOSn2u66VCnbw/quRPfH74J04tQk8H1W3qBxsNynCXNw7s Ftjgj57ImdzNUgt/DUFUhV92yk2DtAV4LuhOx6dSSlWkSn+hZnHA9h5sy9BnuKPHgo7O vYtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=PKYAm/0aV3bhWo2rNA4kUnanHN9tpgw1D3TRbQRB/9o=; b=AzBWbJqLv2XOt4kTdOksns2BBmzs9BjcL95pQ2BfNRhJez6gL2bmI3FJN09lPeHGoD OvkAff5nFUNTFZzX2nBlJnUrKY/DtUoRO9O2BhV6J2YEtyRbvX912hKiMKqVyMUGTvpZ 3fA5x2wFI+EqlhUK2jK45yeN2jPv+nYvOWcDmInmO1ACVq0TtDI1m9EjtP/SSFAxAE/M RX/YGY5lkbk8spCfPLa+FANOcRrxhHGE+6AIk86XWV+2UUKDP8BlKZBypu+BzZWa89MS 1o5q61Ug30KYZqg/JR7JNqhgsSkNngpXnACy4dwbCc3/7A5gorhjt5OjnfRDDsK5npDZ PO2A== X-Gm-Message-State: AJIora8pkmwtfkfF/7p017JCT2A9CYbio41gVi9zHjKtTvQQfF/XBEh7 BlIV/zReg3do7Lco41wQ+uz9C1QYHsM= X-Google-Smtp-Source: AGRyM1twrLBpGr4Rz+bwCq0sU1u6HXMQYaN9Ydo7etaUWvEkYD6SXH+Pv7yJf/rikB6rcJ4tVIjl8xKA39o= X-Received: from avagin.kir.corp.google.com ([2620:15c:29:204:5863:d08b:b2f8:4a3e]) (user=avagin job=sendgmr) by 2002:a17:903:11c9:b0:16b:8293:c599 with SMTP id q9-20020a17090311c900b0016b8293c599mr1695061plh.136.1658530973354; Fri, 22 Jul 2022 16:02:53 -0700 (PDT) Date: Fri, 22 Jul 2022 16:02:38 -0700 In-Reply-To: <20220722230241.1944655-1-avagin@google.com> Message-Id: <20220722230241.1944655-3-avagin@google.com> Mime-Version: 1.0 References: <20220722230241.1944655-1-avagin@google.com> X-Mailer: git-send-email 2.37.1.359.gd136c6c3e2-goog Subject: [PATCH 2/5] kvm/x86: add controls to enable/disable paravirtualized system calls From: Andrei Vagin To: Paolo Bonzini Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Andrei Vagin , Sean Christopherson , Wanpeng Li , Vitaly Kuznetsov , Jianfeng Tan , Adin Scannell , Konstantin Bogomolov , Etienne Perot Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The following change will add a new hypercall to execute host syscalls. This hypercall is helpful for user-mode kernel solutions such as gVisor that needs to manage multiple address spaces. The new hypercall is a backdoor for most KVM users, so it must be disabled by default. This change introduces a new capability that has to be set to enable the hypercall. There is another standard way to allow hypercalls by using KVM_SET_CPUID2. It isn't suitable in this case because one of the common ways of using it is to request all available features (KVM_GET_SUPPORTED_CPUID) and let them all together. In this case, it is a hard requirement that the new hypercall can be enabled only intentionally. Signed-off-by: Andrei Vagin --- arch/x86/include/uapi/asm/kvm_para.h | 3 +++ arch/x86/kvm/cpuid.c | 25 +++++++++++++++++++++++++ arch/x86/kvm/cpuid.h | 8 +++++++- arch/x86/kvm/x86.c | 4 ++++ include/uapi/linux/kvm.h | 1 + 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/a= sm/kvm_para.h index 6e64b27b2c1e..84ad13ffc23c 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -37,6 +37,9 @@ #define KVM_FEATURE_HC_MAP_GPA_RANGE 16 #define KVM_FEATURE_MIGRATION_CONTROL 17 =20 +/* Features that are not controlled by KVM_SET_CPUID2. */ +#define KVM_FEATURE_PV_HOST_SYSCALL 31 + #define KVM_HINTS_REALTIME 0 =20 /* The last 8 bits are used to indicate how to interpret the flags field diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index de6d44e07e34..4fdfe9409506 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -104,6 +104,10 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu, return -EINVAL; } =20 + best =3D cpuid_entry2_find(entries, nent, KVM_CPUID_FEATURES, 0); + if (best && (best->eax & (1<arch.pv_cpuid.enforce) + return -EINVAL; + + best =3D kvm_find_cpuid_entry(vcpu, KVM_CPUID_FEATURES, 0); + if (!best) + return -EINVAL; + + if (set) + best->eax |=3D 1 << KVM_FEATURE_PV_HOST_SYSCALL; + else + best->eax &=3D ~(1 << KVM_FEATURE_PV_HOST_SYSCALL); + + kvm_update_pv_runtime(vcpu); + + return 0; +} + void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu) { __kvm_update_cpuid_runtime(vcpu, vcpu->arch.cpuid_entries, vcpu->arch.cpu= id_nent); diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index 8a770b481d9d..80721093b82b 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -219,10 +219,16 @@ static __always_inline void kvm_cpu_cap_check_and_set= (unsigned int x86_feature) static __always_inline bool guest_pv_has(struct kvm_vcpu *vcpu, unsigned int kvm_feature) { - if (!vcpu->arch.pv_cpuid.enforce) + if (!vcpu->arch.pv_cpuid.enforce) { + if (kvm_feature =3D=3D KVM_FEATURE_PV_HOST_SYSCALL) + return false; + return true; + } =20 return vcpu->arch.pv_cpuid.features & (1u << kvm_feature); } =20 +int kvm_vcpu_pv_set_host_syscall(struct kvm_vcpu *vcpu, bool set); + #endif diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e5fa335a4ea7..19e634768161 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5306,6 +5306,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu= *vcpu, kvm_update_pv_runtime(vcpu); =20 return 0; + + case KVM_CAP_PV_HOST_SYSCALL: + return kvm_vcpu_pv_set_host_syscall(vcpu, cap->args[0]); + default: return -EINVAL; } diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 860f867c50c0..89ed59d13877 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1157,6 +1157,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_VM_TSC_CONTROL 214 #define KVM_CAP_SYSTEM_EVENT_DATA 215 #define KVM_CAP_ARM_SYSTEM_SUSPEND 216 +#define KVM_CAP_PV_HOST_SYSCALL 217 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 --=20 2.37.1.359.gd136c6c3e2-goog From nobody Wed Apr 15 08:25:02 2026 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 D9294C43334 for ; Fri, 22 Jul 2022 23:03:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236709AbiGVXDB (ORCPT ); Fri, 22 Jul 2022 19:03:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236831AbiGVXC5 (ORCPT ); Fri, 22 Jul 2022 19:02:57 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3527E8D5E8 for ; Fri, 22 Jul 2022 16:02:56 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id b10-20020a170902d50a00b0016c56d1f90fso3342969plg.21 for ; Fri, 22 Jul 2022 16:02:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=93pRDb/hhCi6rn7HrzOWCC1IRMMdq/ahH9HJBQp/dJg=; b=EUvosg4JwWCErsar9boMExIxd60trxESqOUvfC4H7XMTC55998ES0+6EaKk32Yx4YJ BOBys09yAI3hZK/BjMEiyUcHPvh3D/BXi7DAVvAtcpu2eWLQZ0YkhcHrVH3zSNksmjKa cuVHaBmIQBHZpy4oogMHMpxdPNPhaxDBwnziDcvMiUoorLSx2LhPnOt7FYv6EaWca+ez Y/FTlRddDDLDb7zJzq6+XHgGQXg+9b5hiVjj/0Fcy3KETz7WmM8GLsLL1ztkAz95DHtj eIAqRvf41WwdGlp4bo6xZeEhzPCDhUlTAQhDeVquikPqpyxtqTg+RZbFo4aaTuztDRD/ 9F6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=93pRDb/hhCi6rn7HrzOWCC1IRMMdq/ahH9HJBQp/dJg=; b=A+o2nXRn3UQqQIN8a3ajw1FegfbTthoLLRuqT0ONx3VXfDa610zIyZuRqotlh53SQ1 q8XocoaDOYtfcM6d15tesqVreIQBcZZPsZb9JIv5knnwGx6o7Dy6ilOdnXvup+i+20Co X06Ppzxkzz5Trj00xsHY5/annpAHlKEgflAfSaHQqLsqMreVPY6n23e+qIzVDzT6TmbF 9VEYUNAvxeF3XvFP9KENTEmU0sxU1lAxri9+aAcUKdMnaogH/Qsw8L9sdkLPSm6oYKpB H5R3dSLHhjZBKtVfkGPaErYSnkZLqAyHYawTFzO+UDfqQjqrdZiWToCGDfuFneAg8pva RidA== X-Gm-Message-State: AJIora8zkYDBK5yvN6JQPTCDZKwYrTBCGk3bSLGlFO6USBm/Uhc9Mfrq Xp9tisfxpYzVNvoRP3FRiXYXEn7vKcM= X-Google-Smtp-Source: AGRyM1tuB8T8+TDU+/wEL8IXih3eYVfU3anj1QMIw6F2QkJkLQSIMsTOL2fMQGKvm9YOxs+SKE2f668OjKA= X-Received: from avagin.kir.corp.google.com ([2620:15c:29:204:5863:d08b:b2f8:4a3e]) (user=avagin job=sendgmr) by 2002:a17:902:cf0e:b0:16d:2517:845 with SMTP id i14-20020a170902cf0e00b0016d25170845mr1737227plg.62.1658530975445; Fri, 22 Jul 2022 16:02:55 -0700 (PDT) Date: Fri, 22 Jul 2022 16:02:39 -0700 In-Reply-To: <20220722230241.1944655-1-avagin@google.com> Message-Id: <20220722230241.1944655-4-avagin@google.com> Mime-Version: 1.0 References: <20220722230241.1944655-1-avagin@google.com> X-Mailer: git-send-email 2.37.1.359.gd136c6c3e2-goog Subject: [PATCH 3/5] KVM/x86: add a new hypercall to execute host system calls. From: Andrei Vagin To: Paolo Bonzini Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Andrei Vagin , Sean Christopherson , Wanpeng Li , Vitaly Kuznetsov , Jianfeng Tan , Adin Scannell , Konstantin Bogomolov , Etienne Perot Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" There is a class of applications that use KVM to manage multiple address spaces rather than use it as an isolation boundary. In all other terms, they are normal processes that execute system calls, handle signals, etc. Currently, each time when such a process needs to interact with the operation system, it has to switch to host and back to guest. Such entire switches are expensive and significantly increase the overhead of system calls. The new hypercall reduces this overhead by more than two times. The new hypercall allows to execute host system calls. As for native calls, seccomp filters are executed before calls. It takes one argument that is a pointer to a pt_regs structure in the host address space. It provides registers to execute a system call according to the calling convention. Arguments are passed in %rdi, %rsi, %rdx, %r10, %r8 and %r9 and then a return code is stored in %rax.=C2=A0 The hypercall returns 0 if a system call has been executed. Otherwise, it returns an error code. Signed-off-by: Andrei Vagin --- Documentation/virt/kvm/x86/hypercalls.rst | 18 +++++++++++++ arch/x86/kvm/x86.c | 33 +++++++++++++++++++++++ include/uapi/linux/kvm_para.h | 1 + 3 files changed, 52 insertions(+) diff --git a/Documentation/virt/kvm/x86/hypercalls.rst b/Documentation/virt= /kvm/x86/hypercalls.rst index e56fa8b9cfca..eb18f2128bfe 100644 --- a/Documentation/virt/kvm/x86/hypercalls.rst +++ b/Documentation/virt/kvm/x86/hypercalls.rst @@ -190,3 +190,21 @@ the KVM_CAP_EXIT_HYPERCALL capability. Userspace must = enable that capability before advertising KVM_FEATURE_HC_MAP_GPA_RANGE in the guest CPUID. In addition, if the guest supports KVM_FEATURE_MIGRATION_CONTROL, userspace must also set up an MSR filter to process writes to MSR_KVM_MIGRATION_CONT= ROL. + +9. KVM_HC_HOST_SYSCALL +--------------------- +:Architecture: x86 +:Status: active +:Purpose: Execute a specified system call. + +- a0: pointer to a pt_regs structure in the host addess space. + +This hypercall lets a guest to execute host system calls. The first and on= ly +argument represents process registers that are used as input and output +parameters. + +Returns 0 if the requested syscall has been executed. Otherwise, it return= s an +error code. + +**Implementation note**: The KVM_CAP_PV_HOST_SYSCALL capability has to be = set +to use this hypercall. diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 19e634768161..aa54e180c9d4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -81,6 +81,7 @@ #include #include #include +#include =20 #define CREATE_TRACE_POINTS #include "trace.h" @@ -9253,6 +9254,27 @@ static int complete_hypercall_exit(struct kvm_vcpu *= vcpu) return kvm_skip_emulated_instruction(vcpu); } =20 +static int kvm_pv_host_syscall(unsigned long a0) +{ + struct pt_regs pt_regs =3D {}; + unsigned long sysno; + + if (copy_from_user(&pt_regs, (void *)a0, sizeof(pt_regs))) + return -EFAULT; + + sysno =3D pt_regs.ax; + pt_regs.orig_ax =3D pt_regs.ax; + pt_regs.ax =3D -ENOSYS; + + do_ksyscall_64(sysno, &pt_regs); + + pt_regs.orig_ax =3D -1; + if (copy_to_user((void *)a0, &pt_regs, sizeof(pt_regs))) + return -EFAULT; + + return 0; +} + int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) { unsigned long nr, a0, a1, a2, a3, ret; @@ -9318,6 +9340,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) kvm_sched_yield(vcpu, a0); ret =3D 0; break; + case KVM_HC_MAP_GPA_RANGE: { u64 gpa =3D a0, npages =3D a1, attrs =3D a2; =20 @@ -9340,6 +9363,16 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) vcpu->arch.complete_userspace_io =3D complete_hypercall_exit; return 0; } + + case KVM_HC_HOST_SYSCALL: + if (!guest_pv_has(vcpu, KVM_FEATURE_PV_HOST_SYSCALL)) + break; + + kvm_vcpu_srcu_read_unlock(vcpu); + ret =3D kvm_pv_host_syscall(a0); + kvm_vcpu_srcu_read_lock(vcpu); + break; + default: ret =3D -KVM_ENOSYS; break; diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h index 960c7e93d1a9..3fcfb3241f35 100644 --- a/include/uapi/linux/kvm_para.h +++ b/include/uapi/linux/kvm_para.h @@ -30,6 +30,7 @@ #define KVM_HC_SEND_IPI 10 #define KVM_HC_SCHED_YIELD 11 #define KVM_HC_MAP_GPA_RANGE 12 +#define KVM_HC_HOST_SYSCALL 13 =20 /* * hypercalls use architecture specific --=20 2.37.1.359.gd136c6c3e2-goog From nobody Wed Apr 15 08:25:02 2026 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 A9A16C43334 for ; Fri, 22 Jul 2022 23:03:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236831AbiGVXDJ (ORCPT ); Fri, 22 Jul 2022 19:03:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236563AbiGVXC7 (ORCPT ); Fri, 22 Jul 2022 19:02:59 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 880FE8C8CB for ; Fri, 22 Jul 2022 16:02:58 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id a16-20020a056a001d1000b0052b39ee38c4so2440220pfx.15 for ; Fri, 22 Jul 2022 16:02:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=eFGhzQ9ieMwuMtkU6aZcvdfyIrCCb4Zx8OPekzscmEA=; b=Rj7cNuRUCpucaVioPmXIiaEJWvYU48FgfQkcqWs9BdTDYt6d2xNZVgJ8i05utO5yBA ZqMtib1JRFofx7GuAYB0jClC6Z/GPrAXxXWySG4lG13dtHH0IPj1LlXEUQfm5j160iXS oNDnAdmcLQHunEE4rblSfzNusIGuJJUplpLPYBgPrLuNss0LZFpEk7mHbkYrpzQLn65F yqi5Icj2pEBTjOTFIsLYXrl8+a46/LOnPDZr/Pt5fOYRNsd+iVCQQNdNPQAxrV0u9EON L2Mt20reNxYUDOMIE9FjYFFrCRhKPuHXfbEEZ1HSRskhR5YDguJUb+SR+9FJ6Xo0lbPw p8DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=eFGhzQ9ieMwuMtkU6aZcvdfyIrCCb4Zx8OPekzscmEA=; b=iAFGutEmqOSj4GDDz3XtN4snzPfogCNuU3XNoyF5Jua/wmNmZD8LokqFVa03VBsSny pePftxOO9ROPPoJqt+hepd3SBAAxDW4LCwYr18DodsLuujq4nC89CnrulmJBOeo1vkXO WdBF+y5w3fO+8xVKp4VeglqWfWM2LwYVnRQLgpVQuwNTfbYUVgr6gtbyKGXE9555EusM o6G+MboHHY0Rws0tBQQajid8XQDhPmUqulslrD5CoOBsHe5i1yQmPf0bJJ27evzelQx+ ZJh896Ehy+UzA3YmWmVmaVRabWA0d2vF5e9zBQZ7BPmsA8iwosDZRUrLNYZHPBXKiK9W iZHQ== X-Gm-Message-State: AJIora8CEl0L00ltfzPK5N025QuFWYp+ZnTWiEIUWvfzDqdAXsU0nYs5 +I4nq4/8hEOWjw7GpfSX7nv3TP5f4Bg= X-Google-Smtp-Source: AGRyM1vHj3Wp6OStOx4/akn2IlWiLgNBGkbbYAibl24DPkdzM2wkiTjgHa/vb1rt6Jr8P9Yq76tjVz4UjsU= X-Received: from avagin.kir.corp.google.com ([2620:15c:29:204:5863:d08b:b2f8:4a3e]) (user=avagin job=sendgmr) by 2002:a17:90a:73ca:b0:1f2:2989:b92d with SMTP id n10-20020a17090a73ca00b001f22989b92dmr1934085pjk.182.1658530977975; Fri, 22 Jul 2022 16:02:57 -0700 (PDT) Date: Fri, 22 Jul 2022 16:02:40 -0700 In-Reply-To: <20220722230241.1944655-1-avagin@google.com> Message-Id: <20220722230241.1944655-5-avagin@google.com> Mime-Version: 1.0 References: <20220722230241.1944655-1-avagin@google.com> X-Mailer: git-send-email 2.37.1.359.gd136c6c3e2-goog Subject: [PATCH 4/5] selftests/kvm/x86_64: set rax before vmcall From: Andrei Vagin To: Paolo Bonzini Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Andrei Vagin , Sean Christopherson , Wanpeng Li , Vitaly Kuznetsov , Jianfeng Tan , Adin Scannell , Konstantin Bogomolov , Etienne Perot Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" kvm_hypercall has to place the hypercall number in rax. Trace events show that kvm_pv_test doesn't work properly: kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0 kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0 kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0 With this change, it starts working as expected: kvm_pv_test-54285: kvm_hypercall: nr 0x5 a0 0x0 a1 0x0 a2 0x0 a3 0x0 kvm_pv_test-54285: kvm_hypercall: nr 0xa a0 0x0 a1 0x0 a2 0x0 a3 0x0 kvm_pv_test-54285: kvm_hypercall: nr 0xb a0 0x0 a1 0x0 a2 0x0 a3 0x0 Signed-off-by: Andrei Vagin --- tools/testing/selftests/kvm/lib/x86_64/processor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/tes= ting/selftests/kvm/lib/x86_64/processor.c index ead7011ee8f6..5d85e1c021da 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -1422,7 +1422,7 @@ uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint= 64_t a1, uint64_t a2, =20 asm volatile("vmcall" : "=3Da"(r) - : "b"(a0), "c"(a1), "d"(a2), "S"(a3)); + : "a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3)); return r; } =20 --=20 2.37.1.359.gd136c6c3e2-goog From nobody Wed Apr 15 08:25:02 2026 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 DDE06C433EF for ; Fri, 22 Jul 2022 23:03:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237179AbiGVXDW (ORCPT ); Fri, 22 Jul 2022 19:03:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52600 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236379AbiGVXDD (ORCPT ); Fri, 22 Jul 2022 19:03:03 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8157CA897D for ; Fri, 22 Jul 2022 16:03:00 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id d10-20020a170902ceca00b0016bea2dc145so3303874plg.7 for ; Fri, 22 Jul 2022 16:03:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ohjmvic4E29z52GxL81iJJ/NoT9cQn3Y4MQIK9DNO8c=; b=NUPStMJh9IgIejquXH41dWpPzb0keBnwKYv/YW8pfw5tOHeupTpouxU7AoPrEITB+l vNcaNvL+2+sjkec80bqYbPcI9dy4syJ0u7saxw8sIFI6mmNy68pkpcr/P3WesShFzO6/ 3QCbtoKA8mfc2zzeMa7JVT75czfnmJejoWd2iIGQiYUGJWQfXX6ahwwZoyd3PpJQ2hS8 N/BGy3AwdK+1zeIIPoghK96lusqX0lMGsYPJoOybcjl2A+VUVjVr4JRgoAhKz1DElQHO GJoToXM2Q9s9MWEmr3E5U/MdvlCXqTBRWfscu+Dqkuwf+lreJM5wnjvyb/Jc4jYcoHzv NLTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ohjmvic4E29z52GxL81iJJ/NoT9cQn3Y4MQIK9DNO8c=; b=cc+TGYC4ZqITkDiTwblM+J4kfDEgfSl3Gcr9vJ1oaN82WawM9HXpFER0xLYqYTWgQS ojUwUnqI92PjuhRvdNze3RpCyRL5/Rd5ZlgELfLmRneRsQwlNBUpMJy7jEd0lhlIRYnS g+L2SIDZw9A4tV6XyY4J3dV07/aTfVv1nFsrYMpV4kTYxXvUpb0ne8OGu8Dhdl9Z+oYY Bo9bNC91zbwR68aEN8/b3Sh966uYL2Hzug2Qc/pY0dv3VpjtWueUxZAERZioEYvFe/5C B6nZGBaUMTQ9n7d9Jk++RrDV8S0mrKEtcxhCEjgdi/sFBHN7EyXAIzcrX3IiEvCgVYZI ZYTQ== X-Gm-Message-State: AJIora+dL7Wv7uqRdNzrMCXxlXmleHzqETunZk7JK/G3doqiyfkdUVuf qgEAfLBikAO66C0KlZ5kCyK7P9B3K5g= X-Google-Smtp-Source: AGRyM1vzNfKx1ntihwPeEq0EYbJkTHi1QJ88thF08Vd6neFyCEJbIjBBCh8im7RSQIkoT/hFtNaXPTG+FJo= X-Received: from avagin.kir.corp.google.com ([2620:15c:29:204:5863:d08b:b2f8:4a3e]) (user=avagin job=sendgmr) by 2002:a05:6a00:17aa:b0:52a:e94b:67e5 with SMTP id s42-20020a056a0017aa00b0052ae94b67e5mr2199067pfg.76.1658530980244; Fri, 22 Jul 2022 16:03:00 -0700 (PDT) Date: Fri, 22 Jul 2022 16:02:41 -0700 In-Reply-To: <20220722230241.1944655-1-avagin@google.com> Message-Id: <20220722230241.1944655-6-avagin@google.com> Mime-Version: 1.0 References: <20220722230241.1944655-1-avagin@google.com> X-Mailer: git-send-email 2.37.1.359.gd136c6c3e2-goog Subject: [PATCH 5/5] selftests/kvm/x86_64: add tests for KVM_HC_HOST_SYSCALL From: Andrei Vagin To: Paolo Bonzini Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Andrei Vagin , Sean Christopherson , Wanpeng Li , Vitaly Kuznetsov , Jianfeng Tan , Adin Scannell , Konstantin Bogomolov , Etienne Perot Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" * check that syscall are executed. * check that non-existing syscalls return ENOSYS. Signed-off-by: Andrei Vagin --- 0000-kvm-host-syscall.patch | 7 + tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/include/x86_64/processor.h | 4 + .../kvm/x86_64/kvm_pv_syscall_test.c | 145 ++++++++++++++++++ 5 files changed, 158 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_pv_syscall_test.c diff --git a/0000-kvm-host-syscall.patch b/0000-kvm-host-syscall.patch index 364db7471abc..653430d57c62 100644 --- a/0000-kvm-host-syscall.patch +++ b/0000-kvm-host-syscall.patch @@ -57,6 +57,13 @@ In the Google kernel, we have a kvm-like subsystem desig= ned especially for gVisor. This change is the first step of integrating it into the KVM code base and making it available to all Linux users. =20 +Cc: Paolo Bonzini +Cc: Sean Christopherson +Cc: Wanpeng Li +Cc: Vitaly Kuznetsov +Cc: Jianfeng Tan +Cc: Adin Scannell + Andrei Vagin (5): kernel: add a new helper to execute system calls from kernel code kvm: add controls to enable/disable paravirtualized system calls diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftes= ts/kvm/.gitignore index 4509a3a7eeae..57d39fec6fdd 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -21,6 +21,7 @@ /x86_64/get_msr_index_features /x86_64/kvm_clock_test /x86_64/kvm_pv_test +/x86_64/kvm_pv_syscall_test /x86_64/hyperv_clock /x86_64/hyperv_cpuid /x86_64/hyperv_features diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests= /kvm/Makefile index 22423c871ed6..e6459f3e5318 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -82,6 +82,7 @@ TEST_GEN_PROGS_x86_64 +=3D x86_64/hyperv_features TEST_GEN_PROGS_x86_64 +=3D x86_64/hyperv_svm_test TEST_GEN_PROGS_x86_64 +=3D x86_64/kvm_clock_test TEST_GEN_PROGS_x86_64 +=3D x86_64/kvm_pv_test +TEST_GEN_PROGS_x86_64 +=3D x86_64/kvm_pv_syscall_test TEST_GEN_PROGS_x86_64 +=3D x86_64/mmio_warning_test TEST_GEN_PROGS_x86_64 +=3D x86_64/mmu_role_test TEST_GEN_PROGS_x86_64 +=3D x86_64/platform_info_test diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools= /testing/selftests/kvm/include/x86_64/processor.h index 6ce185449259..4503e9556279 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -17,6 +17,7 @@ =20 #include "../kvm_util.h" =20 +#ifndef X86_EFLAGS_FIXED #define X86_EFLAGS_FIXED (1u << 1) =20 #define X86_CR4_VME (1ul << 0) @@ -40,6 +41,7 @@ #define X86_CR4_SMEP (1ul << 20) #define X86_CR4_SMAP (1ul << 21) #define X86_CR4_PKE (1ul << 22) +#endif =20 /* CPUID.1.ECX */ #define CPUID_VMX (1ul << 5) @@ -503,6 +505,7 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, u= int64_t paddr, int level) /* * Basic CPU control in CR0 */ +#ifndef X86_CR0_PE #define X86_CR0_PE (1UL<<0) /* Protection Enable */ #define X86_CR0_MP (1UL<<1) /* Monitor Coprocessor */ #define X86_CR0_EM (1UL<<2) /* Emulation */ @@ -514,6 +517,7 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, u= int64_t paddr, int level) #define X86_CR0_NW (1UL<<29) /* Not Write-through */ #define X86_CR0_CD (1UL<<30) /* Cache Disable */ #define X86_CR0_PG (1UL<<31) /* Paging */ +#endif =20 #define XSTATE_XTILE_CFG_BIT 17 #define XSTATE_XTILE_DATA_BIT 18 diff --git a/tools/testing/selftests/kvm/x86_64/kvm_pv_syscall_test.c b/too= ls/testing/selftests/kvm/x86_64/kvm_pv_syscall_test.c new file mode 100644 index 000000000000..601f84b11711 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/kvm_pv_syscall_test.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020, Google LLC. + * + * Tests for KVM paravirtual feature disablement + */ +#include +#include +#include +#include + +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" + +struct pt_regs regs_dup =3D { + .rax =3D __NR_dup, + .rdi =3D -1, +}; + +struct pt_regs regs_nosys =3D { + .rax =3D -1, +}; + +struct hcall_data { + const char *name; + struct pt_regs *regs; + long ret; +}; + +#define TEST_HCALL(hc) { .nr =3D hc, .name =3D #hc } +#define UCALL_PR_HCALL 0xdeadc0de +#define PR_HCALL(hc) ucall(UCALL_PR_HCALL, 1, hc) + +/* + * KVM hypercalls to test. Expect -KVM_ENOSYS when called, as the correspo= nding + * features have been cleared in KVM_CPUID_FEATURES. + */ +static struct hcall_data hcalls_to_test[] =3D { + {.name =3D "dup", .regs =3D ®s_dup, .ret =3D -EBADF}, + {.name =3D "enosys", .regs =3D ®s_nosys, .ret =3D -ENOSYS}, +}; + +static void test_hcall(struct hcall_data *hc) +{ + uint64_t r; + + PR_HCALL(hc); + r =3D kvm_hypercall(KVM_HC_HOST_SYSCALL, (unsigned long)hc->regs, 0, 0, 0= ); + GUEST_ASSERT(r =3D=3D 0); +} + +static void guest_main(void) +{ + int i; + + for (i =3D 0; i < ARRAY_SIZE(hcalls_to_test); i++) + test_hcall(&hcalls_to_test[i]); + + GUEST_DONE(); +} + +static void pr_hcall(struct ucall *uc) +{ + struct hcall_data *hc =3D (struct hcall_data *)uc->args[0]; + + pr_info("testing hcall: %s\n", hc->name); +} + +static void handle_abort(struct ucall *uc) +{ + TEST_FAIL("%s at %s:%ld", (const char *)uc->args[0], + __FILE__, uc->args[1]); +} + +#define VCPU_ID 0 + +static void enter_guest(struct kvm_vm *vm) +{ + struct kvm_run *run; + struct ucall uc; + int r, i; + + run =3D vcpu_state(vm, VCPU_ID); + + while (true) { + r =3D _vcpu_run(vm, VCPU_ID); + TEST_ASSERT(!r, "vcpu_run failed: %d\n", r); + TEST_ASSERT(run->exit_reason =3D=3D KVM_EXIT_IO, + "unexpected exit reason: %u (%s)", + run->exit_reason, exit_reason_str(run->exit_reason)); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_PR_HCALL: + pr_hcall(&uc); + break; + case UCALL_ABORT: + handle_abort(&uc); + return; + case UCALL_DONE: + goto out; + } + } + +out: + for (i =3D 0; i < ARRAY_SIZE(hcalls_to_test); i++) { + struct hcall_data *hc =3D &hcalls_to_test[i]; + + TEST_ASSERT(hc->ret =3D=3D hc->regs->rax, "%s: ret %ld (expected %ld)", + hc->name, hc->ret, hc->regs->rax); + } +} + +int main(void) +{ + struct kvm_enable_cap cap =3D {0}; + struct kvm_cpuid2 *best; + struct kvm_vm *vm; + + if (!kvm_check_cap(KVM_CAP_ENFORCE_PV_FEATURE_CPUID)) { + pr_info("will skip kvm paravirt restriction tests.\n"); + return 0; + } + + vm =3D vm_create_default(VCPU_ID, 0, guest_main); + + cap.cap =3D KVM_CAP_ENFORCE_PV_FEATURE_CPUID; + cap.args[0] =3D 1; + vcpu_enable_cap(vm, VCPU_ID, &cap); + + best =3D kvm_get_supported_cpuid(); + vcpu_set_cpuid(vm, VCPU_ID, best); + + cap.cap =3D KVM_CAP_PV_HOST_SYSCALL; + cap.args[0] =3D 1; + vcpu_enable_cap(vm, VCPU_ID, &cap); + + vm_init_descriptor_tables(vm); + vcpu_init_descriptor_tables(vm, VCPU_ID); + + enter_guest(vm); + kvm_vm_free(vm); +} --=20 2.37.1.359.gd136c6c3e2-goog