From patchwork Thu Jun 9 11:03:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grzegorz Jaszczyk X-Patchwork-Id: 580718 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 E1BBCCCA473 for ; Thu, 9 Jun 2022 11:04:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243428AbiFILEQ (ORCPT ); Thu, 9 Jun 2022 07:04:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243395AbiFILEO (ORCPT ); Thu, 9 Jun 2022 07:04:14 -0400 Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CF9C3A5CC for ; Thu, 9 Jun 2022 04:04:08 -0700 (PDT) Received: by mail-lf1-x134.google.com with SMTP id y32so37404016lfa.6 for ; Thu, 09 Jun 2022 04:04:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=GBcVSj5vK9dnDN8lJcczVx8WGj5ZJQzjsNKoow4IHFc=; b=i4UDE1ossfnZsiVa66qgLmEidmWOd/unHV8zwBFzNn9+UbYaQivgqK3oVO82HEZM5e Hpu7e1SDgBTH6enOnjI5cEHK0Vy8DUVNCPby6SqzCZKzIuckbceW6Mrh3VSvcvcuYMOn AMqaDsDQO/WQntETGXP1Y3M0yHxodxgwhbwD9tVVTvUh6x35uEUJ4uETd0bDDjYlKSwH ZVPdDA8Dk1Cc4CWz87IYyFRVv7Etx2p8+To7zkyh+DrxFZR8z8C84iO9rbA8UnOQ2RYD lz1QVUqf9AUOvJ3Wn5wPVZ9RWAOWKChJae8UM2RkLiMmt1FQGX6blYg5PD/BIbZxMSix WXAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GBcVSj5vK9dnDN8lJcczVx8WGj5ZJQzjsNKoow4IHFc=; b=vZFqSU7OfJoJbuEKl2Mkc+moHsAaoyprf9oYpVWFRHrKzEHsTGvXF1FxWKF+soeRyl y8jso4pWYz4XamsmEdWwNqLXBu9N/NwdsymjEpaBRLM/pRFpisyM9GmY2Sn2SGSnXqKd c3noXf8Jtq4e28vBGOGNYDQ9FBxzDUVNXMvpzJ5ivFLGFKqwKITnPxzBG68sU3++Z3Rr IiXhfiKSknZwFlR0se2T0yfBwLa2a60n7ben5utzIlNAIuWC6mSySMeMxkjmNCARw843 JQImpq+60pad6+fN4kVWFNtQZ1p/n47Turv+5oDIJvjLStg+NYTJh66DuSomusmdurkw tgoQ== X-Gm-Message-State: AOAM532zs/DsQrE4EKLlVaJ9BmAxXMq0qqJFYYzoRqPPTnbCycI7Gaps v6alojDpT8TrI3Q658pfSCLJNg== X-Google-Smtp-Source: ABdhPJxRYrFR6v6a5u7fHrq0mO1LFNycP0dnjq7nnT44DZJU9DMhLOM/vS0hTdVkj8jD7vbXplyMQg== X-Received: by 2002:a05:6512:16aa:b0:479:7df:cb68 with SMTP id bu42-20020a05651216aa00b0047907dfcb68mr17553534lfb.666.1654772646184; Thu, 09 Jun 2022 04:04:06 -0700 (PDT) Received: from jazctssd.c.googlers.com.com (138.58.228.35.bc.googleusercontent.com. [35.228.58.138]) by smtp.gmail.com with ESMTPSA id a10-20020a194f4a000000b004793605e59dsm2116674lfk.245.2022.06.09.04.04.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jun 2022 04:04:05 -0700 (PDT) From: Grzegorz Jaszczyk To: linux-kernel@vger.kernel.org Cc: jaz@semihalf.com, dmy@semihalf.com, Zide Chen , Peter Fang , Tomasz Nowicki , Paolo Bonzini , Jonathan Corbet , Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)), "H. Peter Anvin" , "Rafael J. Wysocki" , Len Brown , Pavel Machek , Brijesh Singh , Ashish Kalra , Mario Limonciello , Pratik Vishwakarma , Hans de Goede , Sachi King , Arnaldo Carvalho de Melo , David Dunn , Wei Wang , Nicholas Piggin , kvm@vger.kernel.org (open list:KERNEL VIRTUAL MACHINE (KVM)), linux-doc@vger.kernel.org (open list:DOCUMENTATION), linux-acpi@vger.kernel.org (open list:ACPI), linux-pm@vger.kernel.org (open list:HIBERNATION (aka Software Suspend, aka swsusp)) Subject: [PATCH 1/2] x86: notify hypervisor about guest entering s2idle state Date: Thu, 9 Jun 2022 11:03:27 +0000 Message-Id: <20220609110337.1238762-2-jaz@semihalf.com> X-Mailer: git-send-email 2.36.1.476.g0c4daa206d-goog In-Reply-To: <20220609110337.1238762-1-jaz@semihalf.com> References: <20220609110337.1238762-1-jaz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org From: Zide Chen Implement a new "system s2idle" hypercall allowing to notify the hypervisor that the guest is entering s2idle power state. Without introducing this hypercall, hypervisor can not trap on any register write or any other VM exit while the guest is entering s2idle state. Co-developed-by: Peter Fang Signed-off-by: Peter Fang Co-developed-by: Tomasz Nowicki Signed-off-by: Tomasz Nowicki Signed-off-by: Zide Chen Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Grzegorz Jaszczyk --- Documentation/virt/kvm/x86/hypercalls.rst | 7 +++++++ arch/x86/kvm/x86.c | 3 +++ drivers/acpi/x86/s2idle.c | 8 ++++++++ include/linux/suspend.h | 1 + include/uapi/linux/kvm_para.h | 1 + kernel/power/suspend.c | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/Documentation/virt/kvm/x86/hypercalls.rst b/Documentation/virt/kvm/x86/hypercalls.rst index e56fa8b9cfca..9d1836c837e3 100644 --- a/Documentation/virt/kvm/x86/hypercalls.rst +++ b/Documentation/virt/kvm/x86/hypercalls.rst @@ -190,3 +190,10 @@ 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_CONTROL. + +9. KVM_HC_SYSTEM_S2IDLE +------------------------ + +:Architecture: x86 +:Status: active +:Purpose: Notify the hypervisor that the guest is entering s2idle state. diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e9473c7c7390..6ed4bd6e762b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9306,6 +9306,9 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) vcpu->arch.complete_userspace_io = complete_hypercall_exit; return 0; } + case KVM_HC_SYSTEM_S2IDLE: + ret = 0; + break; default: ret = -KVM_ENOSYS; break; diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 2963229062f8..0ae5e11380d2 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "../sleep.h" @@ -520,10 +521,17 @@ void acpi_s2idle_restore_early(void) lps0_dsm_func_mask, lps0_dsm_guid); } +static void s2idle_hypervisor_notify(void) +{ + if (static_cpu_has(X86_FEATURE_HYPERVISOR)) + kvm_hypercall0(KVM_HC_SYSTEM_S2IDLE); +} + static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { .begin = acpi_s2idle_begin, .prepare = acpi_s2idle_prepare, .prepare_late = acpi_s2idle_prepare_late, + .hypervisor_notify = s2idle_hypervisor_notify, .wake = acpi_s2idle_wake, .restore_early = acpi_s2idle_restore_early, .restore = acpi_s2idle_restore, diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 70f2921e2e70..42e04e0fe8b1 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -191,6 +191,7 @@ struct platform_s2idle_ops { int (*begin)(void); int (*prepare)(void); int (*prepare_late)(void); + void (*hypervisor_notify)(void); bool (*wake)(void); void (*restore_early)(void); void (*restore)(void); diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h index 960c7e93d1a9..072e77e40f89 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_SYSTEM_S2IDLE 13 /* * hypercalls use architecture specific diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 827075944d28..c641c643290b 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -100,6 +100,10 @@ static void s2idle_enter(void) /* Push all the CPUs into the idle loop. */ wake_up_all_idle_cpus(); + + if (s2idle_ops && s2idle_ops->hypervisor_notify) + s2idle_ops->hypervisor_notify(); + /* Make the current CPU wait so it can enter the idle loop too. */ swait_event_exclusive(s2idle_wait_head, s2idle_state == S2IDLE_STATE_WAKE);