From patchwork Mon Apr 22 18:17:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colton Lewis X-Patchwork-Id: 13638806 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 81169C07C79 for ; Mon, 22 Apr 2024 18:18:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:Message-ID: Mime-Version:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=R8lZaiQePZGRQQ002T8Ly2Yc72X2shTviIAyJnAa+vo=; b=36b YTQBvcAQIgXVTCm4EUZ8Qsafu7wjejcdqDT0OiphbcmAVqYZx3enfJ6iRyVu3hAzq044hx1edSGsN jNAvKuQ1qCN+PhX4GvtpB+IWmUkBkBwG0E9WhklKXXTaS8KC2lWm4QqNYafPkX+0M1X7zaxgIUotX BHdZKsTYIiJVr7RZCuqR8bEsx7o+8pD2NVN9XelLKqr1cVcvnE+AVcq5wmyXtSnxY2OwYhxJ4O1yp 3YTAHR3s7qX0Lf8Hg/9FaL1reCvVdsehuWFOPA58yyWoK8cq3QQvn0vnqQguFWirFofWQd1uKUDP4 4UYNskkB4PaKFMgG9qjJCFFcDidSIqw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1ryyF0-0000000EZJ9-1qjp; Mon, 22 Apr 2024 18:18:10 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1ryyEx-0000000EZIR-1Rag for linux-arm-kernel@lists.infradead.org; Mon, 22 Apr 2024 18:18:08 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-de45daf49deso10578925276.2 for ; Mon, 22 Apr 2024 11:18:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1713809883; x=1714414683; darn=lists.infradead.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=oI5PsFH5OqKQcxn/PnstoUW6QKwHJtSKvuBDm6LMOPQ=; b=A16gtpVnzbcMccYuMY0oCdMa+bPGDHwu2p7SUhcB95dDHcyR4MWAidNwwG7gGKfrz1 IWPEHh9AM+9is19vMFZcNAy6GzqV39Wazk5b0Ped7OQtv2166yKNIh7/NYlX3zkbenAu GxcHYemB3a06wbPEtCnG2LZkQ1PLfPOACp1oDeNxej8V1geD4hqV1Sl4lrDdDdeI88xd bZlnxEfH6sULG/1YXJOuPTnL9ynqMLGSiKbJRALITZumgP+4mrdTnptjwbFmRymFbIon rmGM9fLn0O/5j2rJ8UiqObPx/Bf5K1JuW11G0IJw4Vex6PDDOb8ZIvWqHtALAkxlCqtD yUkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713809883; x=1714414683; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=oI5PsFH5OqKQcxn/PnstoUW6QKwHJtSKvuBDm6LMOPQ=; b=nYtxh8/48v6QA7nWrijoj93lFv9DeFzxt+baVAFcTTcMuABlOMO8uuzuqMStYncLZS giWZFPlJgjVsm5C/s4cvFj4WckdHgYvfKWMQ74AFcg3AocB1jkYBBfXMYBU3WRMyruEz gdSEZPM6mAaYy4xfw9Diunk/WbUV7S65LeN97I2qH/2SKMeBsGXvPh08N7nEzlu3WP8Y mu2qp1C0Jflh+TOwfr6Ijk7Qd8qzMEf3+9clWMrF7MGQNMx+88pQPq/WqQekIlvdT8QU PxwvSYcczG6CnWeQdk6vz1R/N9SMJ4ankPQwnR7Q5SqiY89FicHwbppZX7wRZCZi46Wi Dn/g== X-Forwarded-Encrypted: i=1; AJvYcCWjc2LXBD8TlFWdFo4w8ubBaG4GAPY58A/SqMX5YKrao98hJ5iHRJrPRsWIpTZsKpCK1dLhXtujRRA9MCtomnm1JUI5vQTsA0AtzGZeX26CZAgQDrQ= X-Gm-Message-State: AOJu0YxQ4zHzA/omsSbGeCxCGgKz6ZUK8CdxR+LgjtCQFOAHsel6v9y6 IZswvd1mHhjHFmA9D7NuORN0BH9cpwolLpxKP5ReyIc/ATigyzbmXI7fZcApEUL7+7zNabxRVri 5BbCRNkOMAqUEXFmGnAcoiQ== X-Google-Smtp-Source: AGHT+IEKODLHt0IICOPUeVBmNrFEXzRI0P6fCZGRCIutCpq1JEBl/VDOZ6TtUkQgtYk3XxRPPL+MJTGy5Ijvtnur4w== X-Received: from coltonlewis-kvm.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:14ce]) (user=coltonlewis job=sendgmr) by 2002:a05:6902:1146:b0:dc7:49a9:6666 with SMTP id p6-20020a056902114600b00dc749a96666mr3364862ybu.3.1713809883531; Mon, 22 Apr 2024 11:18:03 -0700 (PDT) Date: Mon, 22 Apr 2024 18:17:16 +0000 Mime-Version: 1.0 X-Mailer: git-send-email 2.44.0.769.g3c40516874-goog Message-ID: <20240422181716.237284-1-coltonlewis@google.com> Subject: [PATCH v4] KVM: arm64: Add early_param to control WFx trapping From: Colton Lewis To: kvm@vger.kernel.org Cc: Jonathan Corbet , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Zenghui Yu , Catalin Marinas , Will Deacon , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, Colton Lewis X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240422_111807_414564_EA320148 X-CRM114-Status: GOOD ( 17.50 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add an early_params to control WFI and WFE trapping. This is to control the degree guests can wait for interrupts on their own without being trapped by KVM. Options for each param are trap, notrap, and default. trap enables the trap. notrap disables the trap. default preserves current behavior, disabling the trap if only a single task is running and enabling otherwise. Signed-off-by: Colton Lewis --- v4: * Fixed inaccurate names that incorrectly implied this controls interrupts themselves instead of instructions waiting for interrupts and events * Split into two separate params as interrupts (WFI) and events (WFE) do different things and may warrant separate controls. * Document new params in Documentation/admin-guide/kernel-parameters.txt v3: https://lore.kernel.org/kvmarm/20240410175437.793508-1-coltonlewis@google.com/ v2: https://lore.kernel.org/kvmarm/20240319164341.1674863-1-coltonlewis@google.com/ v1: https://lore.kernel.org/kvmarm/20240129213918.3124494-1-coltonlewis@google.com/ .../admin-guide/kernel-parameters.txt | 22 +++++++- arch/arm64/include/asm/kvm_emulate.h | 24 ++++++++- arch/arm64/include/asm/kvm_host.h | 7 +++ arch/arm64/kvm/arm.c | 54 +++++++++++++++++-- 4 files changed, 101 insertions(+), 6 deletions(-) -- 2.44.0.769.g3c40516874-goog diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 31b3a25680d0..f8d16c792e66 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2653,6 +2653,27 @@ [KVM,ARM] Allow use of GICv4 for direct injection of LPIs. + kvm-arm.wfe_trap_policy= + [KVM,ARM] Control when to set wfe instruction trap. + + trap: set wfe instruction trap + + notrap: clear wfe instruction trap + + default: set wfe instruction trap only if multiple + tasks are running on the CPU + + kvm-arm.wfi_trap_policy= + [KVM,ARM] Control when to set wfi instruction trap. + + trap: set wfi instruction trap + + notrap: clear wfi instruction trap + + default: set wfi instruction trap only if multiple + tasks are running on the CPU + + kvm_cma_resv_ratio=n [PPC] Reserves given percentage from system memory area for contiguous memory allocation for KVM hash pagetable @@ -7394,4 +7415,3 @@ memory, and other data can't be written using xmon commands. off xmon is disabled. - diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index b804fe832184..efd0a3fb6f00 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -109,9 +109,13 @@ static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu) return (unsigned long *)&vcpu->arch.hcr_el2; } -static inline void vcpu_clear_wfx_traps(struct kvm_vcpu *vcpu) +static inline void vcpu_clear_wfe_trap(struct kvm_vcpu *vcpu) { vcpu->arch.hcr_el2 &= ~HCR_TWE; +} + +static inline void vcpu_clear_wfi_trap(struct kvm_vcpu *vcpu) +{ if (atomic_read(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count) || vcpu->kvm->arch.vgic.nassgireq) vcpu->arch.hcr_el2 &= ~HCR_TWI; @@ -119,12 +123,28 @@ static inline void vcpu_clear_wfx_traps(struct kvm_vcpu *vcpu) vcpu->arch.hcr_el2 |= HCR_TWI; } -static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu) +static inline void vcpu_clear_wfx_traps(struct kvm_vcpu *vcpu) +{ + vcpu_clear_wfe_trap(vcpu); + vcpu_clear_wfi_trap(vcpu); +} + +static inline void vcpu_set_wfe_trap(struct kvm_vcpu *vcpu) { vcpu->arch.hcr_el2 |= HCR_TWE; +} + +static inline void vcpu_set_wfi_trap(struct kvm_vcpu *vcpu) +{ vcpu->arch.hcr_el2 |= HCR_TWI; } +static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu) +{ + vcpu_set_wfe_trap(vcpu); + vcpu_set_wfi_trap(vcpu); +} + static inline void vcpu_ptrauth_enable(struct kvm_vcpu *vcpu) { vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK); diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 21c57b812569..315ee7bfc1cb 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -67,6 +67,13 @@ enum kvm_mode { KVM_MODE_NV, KVM_MODE_NONE, }; + +enum kvm_wfx_trap_policy { + KVM_WFX_NOTRAP_SINGLE_TASK, /* Default option */ + KVM_WFX_NOTRAP, + KVM_WFX_TRAP, +}; + #ifdef CONFIG_KVM enum kvm_mode kvm_get_mode(void); #else diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index a25265aca432..5106ba5a8a39 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -46,6 +46,8 @@ #include static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT; +static enum kvm_wfx_trap_policy kvm_wfi_trap_policy = KVM_WFX_NOTRAP_SINGLE_TASK; +static enum kvm_wfx_trap_policy kvm_wfe_trap_policy = KVM_WFX_NOTRAP_SINGLE_TASK; DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector); @@ -423,6 +425,12 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) } +static bool kvm_should_clear_wfx_trap(enum kvm_wfx_trap_policy p) +{ + return (p == KVM_WFX_NOTRAP && kvm_vgic_global_state.has_gicv4) + || (p == KVM_WFX_NOTRAP_SINGLE_TASK && single_task_running()); +} + void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvm_s2_mmu *mmu; @@ -456,10 +464,15 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (kvm_arm_is_pvtime_enabled(&vcpu->arch)) kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu); - if (single_task_running()) - vcpu_clear_wfx_traps(vcpu); + if (kvm_should_clear_wfx_trap(kvm_wfi_trap_policy)) + vcpu_clear_wfi_trap(vcpu); else - vcpu_set_wfx_traps(vcpu); + vcpu_set_wfi_trap(vcpu); + + if (kvm_should_clear_wfx_trap(kvm_wfe_trap_policy)) + vcpu_clear_wfe_trap(vcpu); + else + vcpu_set_wfe_trap(vcpu); if (vcpu_has_ptrauth(vcpu)) vcpu_ptrauth_disable(vcpu); @@ -2654,6 +2667,41 @@ static int __init early_kvm_mode_cfg(char *arg) } early_param("kvm-arm.mode", early_kvm_mode_cfg); +static int __init early_kvm_wfx_trap_policy_cfg(char *arg, enum kvm_wfx_trap_policy *p) +{ + if (!arg) + return -EINVAL; + + if (strcmp(arg, "trap") == 0) { + *p = KVM_WFX_TRAP; + return 0; + } + + if (strcmp(arg, "notrap") == 0) { + *p = KVM_WFX_NOTRAP; + return 0; + } + + if (strcmp(arg, "default") == 0) { + *p = KVM_WFX_NOTRAP_SINGLE_TASK; + return 0; + } + + return -EINVAL; +} + +static int __init early_kvm_wfi_trap_policy_cfg(char *arg) +{ + return early_kvm_wfx_trap_policy_cfg(arg, &kvm_wfi_trap_policy); +} +early_param("kvm-arm.wfi_trap_policy", early_kvm_wfi_trap_policy_cfg); + +static int __init early_kvm_wfe_trap_policy_cfg(char *arg) +{ + return early_kvm_wfx_trap_policy_cfg(arg, &kvm_wfe_trap_policy); +} +early_param("kvm-arm.wfe_trap_policy", early_kvm_wfe_trap_policy_cfg); + enum kvm_mode kvm_get_mode(void) { return kvm_mode;