From patchwork Thu May 23 17:40:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colton Lewis X-Patchwork-Id: 13672106 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 789DCC25B7F for ; Thu, 23 May 2024 17:41:42 +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=txHPLZAARus2UQl4/s4EFDbh6BDOqgZp2StghzgJAbo=; b=D/i K96n3SB+SYDrXKqXqvYXmrGSteKhwK19IXFXbqSvvlZQ2ZEgaa4RvaccZhfD7ok2fDU4GWrap0IJc au0qQyhyp1zk2BsKfIxmk9tS9caPGodzGKTyjudlF56sNUxmYskZFFnYFnfohl6NGzh2+kfaKwHO4 w5Qa0KMYxN2GJp0Z6KNzgyluEhu7rVFChFNd1WX/ccXCggCkwTLBvsSc+8voAE8otWZLpIjGundmr kmn2SmXNBxQN0BaUZgdM34wbwDHAe1MHNjWUKbb3LTs958DcYHMsvBWQ6sRbMzzxlzOWnaGIf9TZI vkqN5FA+/ytcZrUDSN0+Op07UC/05Fw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sACRZ-00000006utJ-1EbS; Thu, 23 May 2024 17:41:33 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sACRS-00000006urU-0u85 for linux-arm-kernel@lists.infradead.org; Thu, 23 May 2024 17:41:31 +0000 Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-df4dfceec00so3819872276.3 for ; Thu, 23 May 2024 10:41:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1716486080; x=1717090880; darn=lists.infradead.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=/Uryc1Ca/yfNSkrAtNfcb1TkId2P2HjsoQz4zGkthUc=; b=4Tz+5BFKOsp1hG8evCzWrhIBXA/7jf58ayxj9yGh9Ul7z4iDP6HHx4A+N4uJgRSWsF ILpeJK1TppazhAmZg/tpGo2oB6LLbyJ/JSAzt9DErxgaEYuS64ghpdiZ3/DrqCtQB0cM iqA1RF5u5qqCsZuoNjhDZgP0yOlzxYk4C5isuxs1FEWHfiuV26oN3Qb/zvDvHfa8PBu0 qbS0Og86tr8mSGHGCgAXFRB9xCBZF453DvTw8ahia9gQ0xn9U4KqY0eCafAwSI65Oeyf pcpHZDtpP1/Nsxf8T31mX01C7mE+EDFoJdUlqRWKF/zRtycaobJp5lcAF4ey7HCEuRA7 mhDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716486080; x=1717090880; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=/Uryc1Ca/yfNSkrAtNfcb1TkId2P2HjsoQz4zGkthUc=; b=Dz3xqsGX1UDPWd9V0TgR3lJ3Y24vSrynIfMEp9pvIg7uwhYdC715txkvqUso440cF6 Sx9roE1oUZt/d8QLACeBsMmBY8tO5NVgN0wZoASRYNHhqLDtdiG8mzSmNDQjgUUn0/MX o1t1Hc2pd0N2ulDmZW+Nm6Fj2AACaBTeXsc9oTQDUt2BzDLBz6foHJlfa5vuACKgRDWF Vpi4w6wtnonuFV7oSYZGN48+0RdcW9rRD3zgEipL13JnIT1wnxJ5K7KNs46/oTobWkzs hN+LIsX7TLTI0sD4LVSe7POk54nqTuyh6kQvBz8bakCLfqXUv9DrgPp8+Yfil6DEZ4Dm Vvow== X-Forwarded-Encrypted: i=1; AJvYcCWThRycs44Lqp3ZTeBNYKwv196l4PZRyZvDz6aQJeLDZLLmf6fPtsRmWab94GJ4Xf63CKxcOXdqlh8mSDHDdPsiP8UuO7kMY+/up3yP+DzPiXl4c40= X-Gm-Message-State: AOJu0YxOygj2mffwTIYQytelgFqwmZFlShFrWxD0BhLZL3C2SIGc36jh B2AA81taSm9KyS/PHcRzqVZDlDs01bxmaeRZdtOnpYXEJx759PIiCvxEvwzJ0SffyrYlCv93b/E z3FbiQFcdTcba5fN8pfpryg== X-Google-Smtp-Source: AGHT+IFlRiZywpr57pi877qryPKiafj4uJohWbfZpe5cezs8n2FI0sD1i4QJM+bXmI8glD4J/d2mQ77lr+EZuSzvnQ== X-Received: from coltonlewis-kvm.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:14ce]) (user=coltonlewis job=sendgmr) by 2002:a05:6902:100a:b0:df7:66dd:5fbd with SMTP id 3f1490d57ef6-df766dd6536mr116228276.3.1716486080473; Thu, 23 May 2024 10:41:20 -0700 (PDT) Date: Thu, 23 May 2024 17:40:55 +0000 Mime-Version: 1.0 X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog Message-ID: <20240523174056.1565133-1-coltonlewis@google.com> Subject: [PATCH v6] 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-20240523_104129_919868_433892E2 X-CRM114-Status: GOOD ( 16.69 ) 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 and notrap. trap enables the trap. notrap disables the trap. Note that when enabled, traps are allowed but not guaranteed by the CPU architecture. Absent an explicitly set policy, default to current behavior: disabling the trap if only a single task is running and enabling otherwise. Signed-off-by: Colton Lewis Reviewed-by: Jing Zhang --- v6: * Rebase to v6.9.1 * Move decision to enable WFx traps back to vcpu load time * Move policy enum to arm.c and mark variable as __read_mostly * Add explicit disclaimer traps are not guaranteed even when setting enabled * Remove explicit "default" case from early param handling as it is not needed v5: https://lore.kernel.org/kvmarm/20240430181444.670773-1-coltonlewis@google.com/ v4: https://lore.kernel.org/kvmarm/20240422181716.237284-1-coltonlewis@google.com/ 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 | 18 +++++ arch/arm64/include/asm/kvm_emulate.h | 16 ----- arch/arm64/kvm/arm.c | 68 ++++++++++++++++++- 3 files changed, 83 insertions(+), 19 deletions(-) -- 2.45.1.288.g0e0cd299f1-goog diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 396137ee018d..f334265a9cfa 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2693,6 +2693,24 @@ [KVM,ARM,EARLY] Allow use of GICv4 for direct injection of LPIs. + kvm-arm.wfe_trap_policy= + [KVM,ARM] Control when to set WFE instruction trap for + KVM VMs. Traps are allowed but not guaranteed by the + CPU architecture. + + trap: set WFE instruction trap + + notrap: clear WFE instruction trap + + kvm-arm.wfi_trap_policy= + [KVM,ARM] Control when to set WFI instruction trap for + KVM VMs. Traps are allowed but not guaranteed by the + CPU architecture. + + trap: set WFI instruction trap + + notrap: clear WFI instruction trap + kvm_cma_resv_ratio=n [PPC,EARLY] Reserves given percentage from system memory area for contiguous memory allocation for KVM hash pagetable diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 975af30af31f..68c4a170b871 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -109,22 +109,6 @@ 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) -{ - vcpu->arch.hcr_el2 &= ~HCR_TWE; - if (atomic_read(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count) || - vcpu->kvm->arch.vgic.nassgireq) - vcpu->arch.hcr_el2 &= ~HCR_TWI; - else - vcpu->arch.hcr_el2 |= HCR_TWI; -} - -static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu) -{ - vcpu->arch.hcr_el2 |= HCR_TWE; - vcpu->arch.hcr_el2 |= HCR_TWI; -} - static inline void vcpu_ptrauth_enable(struct kvm_vcpu *vcpu) { vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK); diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index c4a0a35e02c7..1cd58ca5d410 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -47,6 +47,15 @@ static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT; +enum kvm_wfx_trap_policy { + KVM_WFX_NOTRAP_SINGLE_TASK, /* Default option */ + KVM_WFX_NOTRAP, + KVM_WFX_TRAP, +}; + +static enum kvm_wfx_trap_policy kvm_wfi_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK; +static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK; + DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector); DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); @@ -428,6 +437,24 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) } +static bool kvm_vcpu_should_clear_twi(struct kvm_vcpu *vcpu) +{ + if (likely(kvm_wfi_trap_policy == KVM_WFX_NOTRAP_SINGLE_TASK)) + return single_task_running() && + (atomic_read(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count) || + vcpu->kvm->arch.vgic.nassgireq); + + return kvm_wfi_trap_policy == KVM_WFX_NOTRAP; +} + +static bool kvm_vcpu_should_clear_twe(struct kvm_vcpu *vcpu) +{ + if (likely(kvm_wfe_trap_policy == KVM_WFX_NOTRAP_SINGLE_TASK)) + return single_task_running(); + + return kvm_wfe_trap_policy == KVM_WFX_NOTRAP; +} + void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvm_s2_mmu *mmu; @@ -461,10 +488,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_vcpu_should_clear_twe(vcpu)) + vcpu->arch.hcr_el2 &= ~HCR_TWE; + else + vcpu->arch.hcr_el2 |= HCR_TWE; + + if (kvm_vcpu_should_clear_twi(vcpu)) + vcpu->arch.hcr_el2 &= ~HCR_TWI; else - vcpu_set_wfx_traps(vcpu); + vcpu->arch.hcr_el2 |= HCR_TWI; if (vcpu_has_ptrauth(vcpu)) vcpu_ptrauth_disable(vcpu); @@ -2663,6 +2695,36 @@ 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; + } + + 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;