From patchwork Thu Aug 5 07:24:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bharata B Rao X-Patchwork-Id: 1513759 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=kvm-ppc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=q4FyGwJv; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4GgKrJ5Lnkz9sW8 for ; Thu, 5 Aug 2021 17:25:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238195AbhHEHZR (ORCPT ); Thu, 5 Aug 2021 03:25:17 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:1770 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237185AbhHEHZQ (ORCPT ); Thu, 5 Aug 2021 03:25:16 -0400 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 17574UuR093505; Thu, 5 Aug 2021 03:24:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=5tJqV2TtRpFHV5hpDmKcs6lf1xq1s7lkl4b/k8Mn6XY=; b=q4FyGwJvrJqeLq7fJaRenITEbWDv7Qh7CW0OlK86cQZa+CZhwx0UU+YnW22PNpGt3ffw V7n8oMfQ5Ph82UfyHfrpnUvx6YjsReKiZFr3rTr4uMlNMGBt+Bma2gG9bVGsGQrdEHfZ y3gBiTiFkxurIG8NTZiiR9jklqYXvtgFvSReyU7BadiBUoG19sb6NgxlwjGNNjK0CoSt YHXvvDADV1VoJEt7mHUIRudNoFgWBrhuqLgl1yA0/aUWNrMuxQgrooeBmkGeDg0Qxy7h FjXCeXlS3ABidHqHrcDjKPZAt+fztc8hwixLD2n5PN04lMQhOeq9WHd7c2ZJln0DI9G4 2w== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a84mv15ua-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:24:59 -0400 Received: from m0098396.ppops.net (m0098396.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 17577pJ5104163; Thu, 5 Aug 2021 03:24:59 -0400 Received: from ppma06ams.nl.ibm.com (66.31.33a9.ip4.static.sl-reverse.com [169.51.49.102]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a84mv15tw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:24:58 -0400 Received: from pps.filterd (ppma06ams.nl.ibm.com [127.0.0.1]) by ppma06ams.nl.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 17577ZoS009826; Thu, 5 Aug 2021 07:24:56 GMT Received: from b06avi18878370.portsmouth.uk.ibm.com (b06avi18878370.portsmouth.uk.ibm.com [9.149.26.194]) by ppma06ams.nl.ibm.com with ESMTP id 3a4wshtrsb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 07:24:56 +0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06avi18878370.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1757LrUY58130888 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 5 Aug 2021 07:21:53 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 13E8EA4051; Thu, 5 Aug 2021 07:24:53 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0F49BA4083; Thu, 5 Aug 2021 07:24:51 +0000 (GMT) Received: from bharata.ibmuc.com (unknown [9.102.2.73]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 5 Aug 2021 07:24:50 +0000 (GMT) From: Bharata B Rao To: kvm-ppc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: kvm@vger.kernel.org, aneesh.kumar@linux.ibm.com, bharata.rao@gmail.com, Bharata B Rao Subject: [RFC PATCH v0 1/5] powerpc: Define Expropriation interrupt bit to VPA byte offset 0xB9 Date: Thu, 5 Aug 2021 12:54:35 +0530 Message-Id: <20210805072439.501481-2-bharata@linux.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210805072439.501481-1-bharata@linux.ibm.com> References: <20210805072439.501481-1-bharata@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: htbjYfQg01MmUjcbTb45wWuSqXJsVghs X-Proofpoint-ORIG-GUID: K3UsigZW8SiYwiHSuMqSGXA_LV45opEq X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.790 definitions=2021-08-05_02:2021-08-04,2021-08-05 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 priorityscore=1501 clxscore=1015 impostorscore=0 malwarescore=0 adultscore=0 spamscore=0 phishscore=0 suspectscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2108050041 Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org VPA byte offset 0xB9 was named as donate_dedicated_cpu as that was the only used bit. The Expropriation/Subvention support defines a bit in byte offset 0xB9. Define this bit and rename the field in VPA to a generic name. Signed-off-by: Bharata B Rao --- arch/powerpc/include/asm/lppaca.h | 8 +++++++- drivers/cpuidle/cpuidle-pseries.c | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index c390ec377bae..57e432766f3e 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -80,7 +80,7 @@ struct lppaca { u8 ebb_regs_in_use; u8 reserved7[6]; u8 dtl_enable_mask; /* Dispatch Trace Log mask */ - u8 donate_dedicated_cpu; /* Donate dedicated CPU cycles */ + u8 byte_b9; /* Donate dedicated CPU cycles & Expropriation int */ u8 fpregs_in_use; u8 pmcregs_in_use; u8 reserved8[28]; @@ -116,6 +116,12 @@ struct lppaca { #define lppaca_of(cpu) (*paca_ptrs[cpu]->lppaca_ptr) +/* + * Flags for Byte offset 0xB9 + */ +#define LPPACA_DONATE_DED_CPU_CYCLES 0x1 +#define LPPACA_EXP_INT_ENABLED 0x2 + /* * We are using a non architected field to determine if a partition is * shared or dedicated. This currently works on both KVM and PHYP, but diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c index a2b5c6f60cf0..b9d0f41c3f19 100644 --- a/drivers/cpuidle/cpuidle-pseries.c +++ b/drivers/cpuidle/cpuidle-pseries.c @@ -221,7 +221,7 @@ static int dedicated_cede_loop(struct cpuidle_device *dev, u8 old_latency_hint; pseries_idle_prolog(); - get_lppaca()->donate_dedicated_cpu = 1; + get_lppaca()->byte_b9 |= LPPACA_DONATE_DED_CPU_CYCLES; old_latency_hint = get_lppaca()->cede_latency_hint; get_lppaca()->cede_latency_hint = cede_latency_hint[index]; @@ -229,7 +229,7 @@ static int dedicated_cede_loop(struct cpuidle_device *dev, check_and_cede_processor(); local_irq_disable(); - get_lppaca()->donate_dedicated_cpu = 0; + get_lppaca()->byte_b9 &= ~LPPACA_DONATE_DED_CPU_CYCLES; get_lppaca()->cede_latency_hint = old_latency_hint; pseries_idle_epilog(); From patchwork Thu Aug 5 07:24:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bharata B Rao X-Patchwork-Id: 1513760 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=kvm-ppc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=Odv8txRO; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4GgKrL01FWz9t0p for ; Thu, 5 Aug 2021 17:25:05 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238555AbhHEHZT (ORCPT ); Thu, 5 Aug 2021 03:25:19 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:34806 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238153AbhHEHZS (ORCPT ); Thu, 5 Aug 2021 03:25:18 -0400 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 17574AKl190609; Thu, 5 Aug 2021 03:25:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=dyfLrbUYF+bfLKmLM+04hqX0pe2+BPIZfw16sZMuW4U=; b=Odv8txROkw7TPkmiGzqPWJcm02CuK8nRdAMYZ6n6/MD0ej6xqrX5j1wA+/VVYdNrhc4n 5H/6JcrquStwMNSQOvRfVS3iFRpJjCc0GT9mFNgKYZNR4dEkjZ8EwDadnJnoDRWtvWFh wMsmdOx8TOJzzmyhX40DuJ5DY3nwe64lu3vpYH8dA8DE3D1xPyWk0PBBNqkGk9j6V3uU sb8mgWC3jJRm4V9F5vf2uu5VrDunI7fDCHXII+8JqSpWk2+JRJf72bkn5v6qGfmsgPG3 P3Y812iQ5IZiWRGIE7oUuOMmh+IA49E+aUDok3urz6bpQOUbdRjMXaL0+TowT8Zt0KwC 7A== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a8858vttm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:25:02 -0400 Received: from m0098409.ppops.net (m0098409.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 17574BJx190676; Thu, 5 Aug 2021 03:25:01 -0400 Received: from ppma03fra.de.ibm.com (6b.4a.5195.ip4.static.sl-reverse.com [149.81.74.107]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a8858vtsy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:25:01 -0400 Received: from pps.filterd (ppma03fra.de.ibm.com [127.0.0.1]) by ppma03fra.de.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 17577ZqN029911; Thu, 5 Aug 2021 07:24:59 GMT Received: from b06cxnps3075.portsmouth.uk.ibm.com (d06relay10.portsmouth.uk.ibm.com [9.149.109.195]) by ppma03fra.de.ibm.com with ESMTP id 3a4x58snma-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 07:24:59 +0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1757OtI748038366 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 5 Aug 2021 07:24:56 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AB7B1A4051; Thu, 5 Aug 2021 07:24:55 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 99484A405D; Thu, 5 Aug 2021 07:24:53 +0000 (GMT) Received: from bharata.ibmuc.com (unknown [9.102.2.73]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 5 Aug 2021 07:24:53 +0000 (GMT) From: Bharata B Rao To: kvm-ppc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: kvm@vger.kernel.org, aneesh.kumar@linux.ibm.com, bharata.rao@gmail.com, Bharata B Rao Subject: [RFC PATCH v0 2/5] KVM: PPC: Add support for KVM_REQ_ESN_EXIT Date: Thu, 5 Aug 2021 12:54:36 +0530 Message-Id: <20210805072439.501481-3-bharata@linux.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210805072439.501481-1-bharata@linux.ibm.com> References: <20210805072439.501481-1-bharata@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: ao0apLeLEIhah8sEikhfIA4zOIOgPT53 X-Proofpoint-ORIG-GUID: gJYXdwxIfgtarxBhCZTJr-1bD0jviSo_ X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.790 definitions=2021-08-05_02:2021-08-04,2021-08-05 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 mlxscore=0 bulkscore=0 adultscore=0 impostorscore=0 clxscore=1015 suspectscore=0 priorityscore=1501 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2108050041 Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org Add a new KVM exit request KVM_REQ_ESN_EXIT that will be used to exit to userspace (QEMU) whenever subvention notification needs to be sent to the guest. The userspace (QEMU) issues the subvention notification by injecting an interrupt into the guest. Signed-off-by: Bharata B Rao --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kvm/book3s_hv.c | 8 ++++++++ include/uapi/linux/kvm.h | 1 + 3 files changed, 10 insertions(+) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 9f52f282b1aa..204dc2d91388 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -52,6 +52,7 @@ #define KVM_REQ_WATCHDOG KVM_ARCH_REQ(0) #define KVM_REQ_EPR_EXIT KVM_ARCH_REQ(1) #define KVM_REQ_PENDING_TIMER KVM_ARCH_REQ(2) +#define KVM_REQ_ESN_EXIT KVM_ARCH_REQ(3) #include diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 085fb8ecbf68..47ccd4a2df54 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2820,6 +2820,14 @@ static void kvmppc_core_vcpu_free_hv(struct kvm_vcpu *vcpu) static int kvmppc_core_check_requests_hv(struct kvm_vcpu *vcpu) { + /* + * If subvention interrupt needs to be injected to the guest + * exit to user space. + */ + if (kvm_check_request(KVM_REQ_ESN_EXIT, vcpu)) { + vcpu->run->exit_reason = KVM_EXIT_ESN; + return 0; + } /* Indicate we want to get back into the guest */ return 1; } diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index d9e4aabcb31a..47be532ed14b 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -269,6 +269,7 @@ struct kvm_xen_exit { #define KVM_EXIT_AP_RESET_HOLD 32 #define KVM_EXIT_X86_BUS_LOCK 33 #define KVM_EXIT_XEN 34 +#define KVM_EXIT_ESN 35 /* For KVM_EXIT_INTERNAL_ERROR */ /* Emulate instruction failed. */ From patchwork Thu Aug 5 07:24:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bharata B Rao X-Patchwork-Id: 1513761 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=kvm-ppc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=JN7+l7nx; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4GgKrQ6QYJz9sRK for ; Thu, 5 Aug 2021 17:25:10 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238153AbhHEHZX (ORCPT ); Thu, 5 Aug 2021 03:25:23 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:20360 "EHLO mx0b-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238587AbhHEHZW (ORCPT ); Thu, 5 Aug 2021 03:25:22 -0400 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 17573LYK057190; Thu, 5 Aug 2021 03:25:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=1LTIEE11FWqPIVM4A8yHwxW9O0PlIoIiN6eN5E97rtw=; b=JN7+l7nxPAKPcZ8lZW0dWfvy1kZcsSj5gdJbpA6G8gGbecX5rZAyEEJDcMRVVFjEmcqS ieZSEnFWiVs/j2NhnwiesdhcC4cC/oQDl1QeRvSda0eGwmKQGgZGSUQ4o/99S4QpX6Mi aI+GaNAvhHmW71QfYyuE7d6LjjBw3/YXynOm5CqIYemqZ38rTGyHUVVxqbNUPeXVVn+N g2iefZoJYJYyTEnA4Y/eMDQd6E3v8pbep9ubImnjq2QksLuSAtP/xmguScjV93A+stth h+zchoPWUY2PjI5IQ0qKY7K1A7otMd+Jb4KmgfxW9kSJyHnLxZ1/50wt9uaAKhQ0a/yU eA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a7b790p0t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:25:04 -0400 Received: from m0098417.ppops.net (m0098417.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 17573NOG057483; Thu, 5 Aug 2021 03:25:03 -0400 Received: from ppma04ams.nl.ibm.com (63.31.33a9.ip4.static.sl-reverse.com [169.51.49.99]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a7b790nyt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:25:03 -0400 Received: from pps.filterd (ppma04ams.nl.ibm.com [127.0.0.1]) by ppma04ams.nl.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 17577bRL009127; Thu, 5 Aug 2021 07:25:02 GMT Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by ppma04ams.nl.ibm.com with ESMTP id 3a4x592r9r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 07:25:01 +0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1757Owvd53346604 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 5 Aug 2021 07:24:58 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3FCA8A4078; Thu, 5 Aug 2021 07:24:58 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 333E0A4057; Thu, 5 Aug 2021 07:24:56 +0000 (GMT) Received: from bharata.ibmuc.com (unknown [9.102.2.73]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 5 Aug 2021 07:24:55 +0000 (GMT) From: Bharata B Rao To: kvm-ppc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: kvm@vger.kernel.org, aneesh.kumar@linux.ibm.com, bharata.rao@gmail.com, Bharata B Rao Subject: [RFC PATCH v0 3/5] KVM: PPC: Book3S: Enable setting SRR1 flags for DSI Date: Thu, 5 Aug 2021 12:54:37 +0530 Message-Id: <20210805072439.501481-4-bharata@linux.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210805072439.501481-1-bharata@linux.ibm.com> References: <20210805072439.501481-1-bharata@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: bOchKJX_XWy-xJV9s14JkNU7v2Yiv-Mx X-Proofpoint-ORIG-GUID: QjzlV6MH5NU946n9fD0V6NZEThJsj20k X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.790 definitions=2021-08-05_02:2021-08-04,2021-08-05 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 clxscore=1015 mlxscore=0 lowpriorityscore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 spamscore=0 mlxlogscore=801 priorityscore=1501 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2108050041 Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org kvmppc_core_queue_data_storage() doesn't provide an option to set SRR1 flags when raising DSI. Since kvmppc_inject_interrupt() allows for such a provision, add an argument to allow the same. This will be used to raise DSI with SRR1_PROGTRAP set when expropriation interrupt needs to be injected to the guest. Signed-off-by: Bharata B Rao --- arch/powerpc/include/asm/kvm_ppc.h | 3 ++- arch/powerpc/kvm/book3s.c | 6 +++--- arch/powerpc/kvm/book3s_64_mmu_radix.c | 6 +++--- arch/powerpc/kvm/book3s_hv.c | 4 ++-- arch/powerpc/kvm/book3s_hv_nested.c | 4 ++-- arch/powerpc/kvm/book3s_pr.c | 4 ++-- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 2d88944f9f34..09235bdfd4ac 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -143,7 +143,8 @@ extern void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, ulong dear_flags, ulong esr_flags); extern void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, ulong dear_flags, - ulong esr_flags); + ulong esr_flags, + ulong srr1_flags); extern void kvmppc_core_queue_itlb_miss(struct kvm_vcpu *vcpu); extern void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong esr_flags); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 79833f78d1da..f7f6641a788d 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -284,11 +284,11 @@ void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu) } void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, ulong dar, - ulong flags) + ulong dsisr, ulong srr1) { kvmppc_set_dar(vcpu, dar); - kvmppc_set_dsisr(vcpu, flags); - kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE, 0); + kvmppc_set_dsisr(vcpu, dsisr); + kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE, srr1); } EXPORT_SYMBOL_GPL(kvmppc_core_queue_data_storage); diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index b5905ae4377c..618206a504b0 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -946,7 +946,7 @@ int kvmppc_book3s_radix_page_fault(struct kvm_vcpu *vcpu, if (dsisr & DSISR_BADACCESS) { /* Reflect to the guest as DSI */ pr_err("KVM: Got radix HV page fault with DSISR=%lx\n", dsisr); - kvmppc_core_queue_data_storage(vcpu, ea, dsisr); + kvmppc_core_queue_data_storage(vcpu, ea, dsisr, 0); return RESUME_GUEST; } @@ -971,7 +971,7 @@ int kvmppc_book3s_radix_page_fault(struct kvm_vcpu *vcpu, * Bad address in guest page table tree, or other * unusual error - reflect it to the guest as DSI. */ - kvmppc_core_queue_data_storage(vcpu, ea, dsisr); + kvmppc_core_queue_data_storage(vcpu, ea, dsisr, 0); return RESUME_GUEST; } return kvmppc_hv_emulate_mmio(vcpu, gpa, ea, writing); @@ -981,7 +981,7 @@ int kvmppc_book3s_radix_page_fault(struct kvm_vcpu *vcpu, if (writing) { /* give the guest a DSI */ kvmppc_core_queue_data_storage(vcpu, ea, DSISR_ISSTORE | - DSISR_PROTFAULT); + DSISR_PROTFAULT, 0); return RESUME_GUEST; } kvm_ro = true; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 47ccd4a2df54..d07e9065f7c1 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1592,7 +1592,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, if (!(vcpu->arch.fault_dsisr & (DSISR_NOHPTE | DSISR_PROTFAULT))) { kvmppc_core_queue_data_storage(vcpu, - vcpu->arch.fault_dar, vcpu->arch.fault_dsisr); + vcpu->arch.fault_dar, vcpu->arch.fault_dsisr, 0); r = RESUME_GUEST; break; } @@ -1610,7 +1610,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, r = RESUME_PAGE_FAULT; } else { kvmppc_core_queue_data_storage(vcpu, - vcpu->arch.fault_dar, err); + vcpu->arch.fault_dar, err, 0); r = RESUME_GUEST; } break; diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index 898f942eb198..a10ef0d5f925 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c @@ -1556,7 +1556,7 @@ static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu, if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) { if (dsisr & (DSISR_PRTABLE_FAULT | DSISR_BADACCESS)) { /* unusual error -> reflect to the guest as a DSI */ - kvmppc_core_queue_data_storage(vcpu, ea, dsisr); + kvmppc_core_queue_data_storage(vcpu, ea, dsisr, 0); return RESUME_GUEST; } @@ -1567,7 +1567,7 @@ static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu, if (writing) { /* Give the guest a DSI */ kvmppc_core_queue_data_storage(vcpu, ea, - DSISR_ISSTORE | DSISR_PROTFAULT); + DSISR_ISSTORE | DSISR_PROTFAULT, 0); return RESUME_GUEST; } kvm_ro = true; diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 6bc9425acb32..f7fc8e01fd8e 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -754,7 +754,7 @@ static int kvmppc_handle_pagefault(struct kvm_vcpu *vcpu, flags = DSISR_NOHPTE; if (data) { flags |= vcpu->arch.fault_dsisr & DSISR_ISSTORE; - kvmppc_core_queue_data_storage(vcpu, eaddr, flags); + kvmppc_core_queue_data_storage(vcpu, eaddr, flags, 0); } else { kvmppc_core_queue_inst_storage(vcpu, flags); } @@ -1229,7 +1229,7 @@ int kvmppc_handle_exit_pr(struct kvm_vcpu *vcpu, unsigned int exit_nr) r = kvmppc_handle_pagefault(vcpu, dar, exit_nr); srcu_read_unlock(&vcpu->kvm->srcu, idx); } else { - kvmppc_core_queue_data_storage(vcpu, dar, fault_dsisr); + kvmppc_core_queue_data_storage(vcpu, dar, fault_dsisr, 0); r = RESUME_GUEST; } break; From patchwork Thu Aug 5 07:24:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bharata B Rao X-Patchwork-Id: 1513762 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=kvm-ppc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=QkVXouRY; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4GgKrV5CzHz9sW8 for ; Thu, 5 Aug 2021 17:25:14 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238629AbhHEHZ1 (ORCPT ); Thu, 5 Aug 2021 03:25:27 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:60058 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238564AbhHEHZ0 (ORCPT ); Thu, 5 Aug 2021 03:25:26 -0400 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 1757AqPq140665; Thu, 5 Aug 2021 03:25:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=MdCheDWnBppDIy9sh3oS7YgKj6laB9rFnnhYQlgJHeU=; b=QkVXouRYZSQYRHQBo5I2huLTy5UQNYB8dGL5fOtS7lo0S69ldHWcUpP6F+F7z0TkTBqc hYHj2pb1iVxkG1pm0r5NENy8zOcbW040Ct6/VVNgwHDSTO3XOpkjayDLGsyKvqTdrz8K +mw74/IyNoZlpz4avBLOKznZx0FCMosWWkOeEzbH6v/1xFZ9c+X/JA/HzbEwrHIA1gGM wC8ee5yt+j6j5ddxhDHOXvmLueHxgIP8260wdcMon8UZxq6WiuQugHcdViSvC6FWm+HY LuZSptOaFWKwacARQClFUM1w5cbz9tyCH1Rq73kX1eqi0gH25wQalrKSjwMQVfNHAPEO Ew== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a89p12m8m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:25:10 -0400 Received: from m0098404.ppops.net (m0098404.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1757BlCd144086; Thu, 5 Aug 2021 03:25:09 -0400 Received: from ppma02fra.de.ibm.com (47.49.7a9f.ip4.static.sl-reverse.com [159.122.73.71]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a89p12m7s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:25:09 -0400 Received: from pps.filterd (ppma02fra.de.ibm.com [127.0.0.1]) by ppma02fra.de.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 17576adW004901; Thu, 5 Aug 2021 07:25:07 GMT Received: from b06avi18626390.portsmouth.uk.ibm.com (b06avi18626390.portsmouth.uk.ibm.com [9.149.26.192]) by ppma02fra.de.ibm.com with ESMTP id 3a4x58sncn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 07:25:05 +0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06avi18626390.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1757M40760752134 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 5 Aug 2021 07:22:04 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0A615A4069; Thu, 5 Aug 2021 07:25:01 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BA87BA4070; Thu, 5 Aug 2021 07:24:58 +0000 (GMT) Received: from bharata.ibmuc.com (unknown [9.102.2.73]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 5 Aug 2021 07:24:58 +0000 (GMT) From: Bharata B Rao To: kvm-ppc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: kvm@vger.kernel.org, aneesh.kumar@linux.ibm.com, bharata.rao@gmail.com, Bharata B Rao Subject: [RFC PATCH v0 4/5] KVM: PPC: BOOK3S HV: Async PF support Date: Thu, 5 Aug 2021 12:54:38 +0530 Message-Id: <20210805072439.501481-5-bharata@linux.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210805072439.501481-1-bharata@linux.ibm.com> References: <20210805072439.501481-1-bharata@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: H-uWUjMlLWAlrVjX87LEPxxgpQKmQjIP X-Proofpoint-ORIG-GUID: okt15hAaFT4Hd5RpHjqE3TaQAJmXMWUM X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.790 definitions=2021-08-05_02:2021-08-04,2021-08-05 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 priorityscore=1501 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 impostorscore=0 spamscore=0 clxscore=1015 phishscore=0 malwarescore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2108050041 Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org Add asynchronous page fault support for PowerKVM by making use of the Expropriation/Subvention Notification Option defined by PAPR specifications. 1. When guest accessed page isn't immediately available in the host, update the vcpu's VPA with a unique expropriation correlation number and inject a DSI to the guest with SRR1_PROGTRAP bit set in SRR1. This informs the guest vcpu to put the process to wait and schedule a different process. - Async PF is supported for data pages in this implementation though PAPR allows it for code pages too. - Async PF is supported only for user pages here. - The feature is currently limited only to radix guests. 2. When the page becomes available, update the Subvention Notification Structure with the corresponding expropriation correlation number and and inform the guest via subvention interrupt. - Subvention Notification Structure (SNS) is a region of memory shared between host and guest via which the communication related to expropriated and subvened pages happens between guest and host. - SNS region is registered by the guest via H_REG_SNS hcall which is implemented in QEMU. - H_REG_SNS implementation in QEMU needs a new ioctl KVM_PPC_SET_SNS. This ioctl is used to map and pin the guest page containing SNS in the host. - Subvention notification interrupt is raised to the guest by QEMU in response to the guest exit via KVM_REQ_ESN_EXIT. This interrupt informs the guest about the availability of the pages. TODO: - H_REG_SNS is implemented in QEMU because this hcall needs to return the interrupt source number associated with the subvention interrupt. Claiming of IRQ line and raising an external interrupt seem to be straightforward from QEMU. Figure out the in-kernel equivalents for these two so that, we can save on guest exit for each expropriated page and move the entire hcall implementation into the host kernel. - The code is pretty much experimental and is barely able to boot a guest. I do see some requests for expropriated pages not getting fulfilled by host leading the long delays in guest. This needs some debugging. - A few other aspects recommended by PAPR around this feature(like setting of page state flags) need to be evaluated and incorporated into the implementation if found appropriate. Signed-off-by: Bharata B Rao --- Documentation/virt/kvm/api.rst | 15 ++ arch/powerpc/include/asm/hvcall.h | 1 + arch/powerpc/include/asm/kvm_book3s_esn.h | 24 +++ arch/powerpc/include/asm/kvm_host.h | 21 +++ arch/powerpc/include/asm/kvm_ppc.h | 1 + arch/powerpc/include/asm/lppaca.h | 12 +- arch/powerpc/include/uapi/asm/kvm.h | 6 + arch/powerpc/kvm/Kconfig | 2 + arch/powerpc/kvm/Makefile | 5 +- arch/powerpc/kvm/book3s_64_mmu_radix.c | 3 + arch/powerpc/kvm/book3s_hv.c | 25 +++ arch/powerpc/kvm/book3s_hv_esn.c | 189 ++++++++++++++++++++++ include/uapi/linux/kvm.h | 1 + tools/include/uapi/linux/kvm.h | 1 + 14 files changed, 303 insertions(+), 3 deletions(-) create mode 100644 arch/powerpc/include/asm/kvm_book3s_esn.h create mode 100644 arch/powerpc/kvm/book3s_hv_esn.c diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index dae68e68ca23..512f078b9d02 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -5293,6 +5293,21 @@ the trailing ``'\0'``, is indicated by ``name_size`` in the header. The Stats Data block contains an array of 64-bit values in the same order as the descriptors in Descriptors block. +4.134 KVM_PPC_SET_SNS +--------------------- + +:Capability: basic +:Architectures: powerpc +:Type: vm ioctl +:Parameters: none +:Returns: 0 on successful completion, + +As part of H_REG_SNS hypercall, this ioctl is used to map and pin +the guest provided SNS structure in the host. + +This is used for providing asynchronous page fault support for +powerpc pseries KVM guests. + 5. The kvm_run structure ======================== diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 9bcf345cb208..9e33500c1723 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -321,6 +321,7 @@ #define H_SCM_UNBIND_ALL 0x3FC #define H_SCM_HEALTH 0x400 #define H_SCM_PERFORMANCE_STATS 0x418 +#define H_REG_SNS 0x41C #define H_RPT_INVALIDATE 0x448 #define H_SCM_FLUSH 0x44C #define MAX_HCALL_OPCODE H_SCM_FLUSH diff --git a/arch/powerpc/include/asm/kvm_book3s_esn.h b/arch/powerpc/include/asm/kvm_book3s_esn.h new file mode 100644 index 000000000000..d79a441ea31d --- /dev/null +++ b/arch/powerpc/include/asm/kvm_book3s_esn.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_KVM_BOOK3S_ESN_H__ +#define __ASM_KVM_BOOK3S_ESN_H__ + +/* SNS buffer EQ state flags */ +#define SNS_EQ_STATE_OPERATIONAL 0X0 +#define SNS_EQ_STATE_OVERFLOW 0x1 + +/* SNS buffer Notification control bits */ +#define SNS_EQ_CNTRL_TRIGGER 0x1 + +struct kvmppc_sns { + unsigned long gpa; + unsigned long len; + void *hva; + uint16_t exp_corr_nr; + uint16_t *eq; + uint8_t *eq_cntrl; + uint8_t *eq_state; + unsigned long next_eq_entry; + unsigned long nr_eq_entries; +}; + +#endif /* __ASM_KVM_BOOK3S_ESN_H__ */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 204dc2d91388..8d7f73085ef5 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -25,6 +25,7 @@ #include #include #include +#include #define KVM_MAX_VCPUS NR_CPUS #define KVM_MAX_VCORES NR_CPUS @@ -325,6 +326,7 @@ struct kvm_arch { #endif struct kvmppc_ops *kvm_ops; #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + struct kvmppc_sns sns; struct mutex uvmem_lock; struct list_head uvmem_pfns; struct mutex mmu_setup_lock; /* nests inside vcpu mutexes */ @@ -855,6 +857,25 @@ struct kvm_vcpu_arch { #define __KVM_HAVE_ARCH_WQP #define __KVM_HAVE_CREATE_DEVICE +/* Async pf */ +#define ASYNC_PF_PER_VCPU 64 +struct kvm_arch_async_pf { + unsigned long exp_token; +}; +int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, + unsigned long gpa, unsigned long hva); + +void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, + struct kvm_async_pf *work); + +bool kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, + struct kvm_async_pf *work); + +void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, + struct kvm_async_pf *work); +bool kvm_arch_can_dequeue_async_page_present(struct kvm_vcpu *vcpu); +static inline void kvm_arch_async_page_present_queued(struct kvm_vcpu *vcpu) {} + static inline void kvm_arch_hardware_disable(void) {} static inline void kvm_arch_hardware_unsetup(void) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 09235bdfd4ac..c14a84041d0e 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -228,6 +228,7 @@ extern long kvm_vm_ioctl_resize_hpt_commit(struct kvm *kvm, int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); extern int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp); +long kvm_vm_ioctl_set_sns(struct kvm *kvm, struct kvm_ppc_sns_reg *sns_reg); extern int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu); extern void kvmppc_rtas_tokens_free(struct kvm *kvm); diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 57e432766f3e..17e89c3865e8 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -104,7 +104,17 @@ struct lppaca { volatile __be32 dispersion_count; /* dispatch changed physical cpu */ volatile __be64 cmo_faults; /* CMO page fault count */ volatile __be64 cmo_fault_time; /* CMO page fault time */ - u8 reserved10[104]; + + /* + * TODO: Insert this at correct offset + * 0x17D - Exp flags (1 byte) + * 0x17E - Exp corr number (2 bytes) + * + * Here I am using only exp corr number at an easy to insert + * offset. + */ + __be16 exp_corr_nr; /* Exproppriation correlation number */ + u8 reserved10[102]; /* cacheline 4-5 */ diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 9f18fa090f1f..d72739126ae5 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -470,6 +470,12 @@ struct kvm_ppc_cpu_char { #define KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ULL << 61) #define KVM_PPC_CPU_BEHAV_FLUSH_COUNT_CACHE (1ull << 58) +/* For KVM_PPC_SET_SNS */ +struct kvm_ppc_sns_reg { + __u64 addr; + __u64 len; +}; + /* Per-vcpu XICS interrupt controller state */ #define KVM_REG_PPC_ICP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c) diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index e45644657d49..4f552649a4b2 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -85,6 +85,8 @@ config KVM_BOOK3S_64_HV depends on KVM_BOOK3S_64 && PPC_POWERNV select KVM_BOOK3S_HV_POSSIBLE select MMU_NOTIFIER + select KVM_ASYNC_PF + select KVM_ASYNC_PF_SYNC select CMA help Support running unmodified book3s_64 guest kernels in diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 583c14ef596e..603ab382d021 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -6,7 +6,7 @@ ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm KVM := ../../../virt/kvm -common-objs-y = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/binary_stats.o +common-objs-y = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/binary_stats.o $(KVM)/async_pf.o common-objs-$(CONFIG_KVM_VFIO) += $(KVM)/vfio.o common-objs-$(CONFIG_KVM_MMIO) += $(KVM)/coalesced_mmio.o @@ -70,7 +70,8 @@ kvm-hv-y += \ book3s_hv_interrupts.o \ book3s_64_mmu_hv.o \ book3s_64_mmu_radix.o \ - book3s_hv_nested.o + book3s_hv_nested.o \ + book3s_hv_esn.o kvm-hv-$(CONFIG_PPC_UV) += \ book3s_hv_uvmem.o diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index 618206a504b0..1985f84bfebe 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -837,6 +837,9 @@ int kvmppc_book3s_instantiate_page(struct kvm_vcpu *vcpu, } else { unsigned long pfn; + if (kvm_arch_setup_async_pf(vcpu, gpa, hva)) + return RESUME_GUEST; + /* Call KVM generic code to do the slow-path check */ pfn = __gfn_to_pfn_memslot(memslot, gfn, false, NULL, writing, upgrade_p, NULL); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index d07e9065f7c1..5cc564321521 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -77,6 +77,7 @@ #include #include #include +#include #include "book3s.h" @@ -4570,6 +4571,11 @@ static int kvmppc_vcpu_run_hv(struct kvm_vcpu *vcpu) return -EINTR; } + if (kvm_request_pending(vcpu)) { + if (!kvmppc_core_check_requests(vcpu)) + return 0; + } + kvm = vcpu->kvm; atomic_inc(&kvm->arch.vcpus_running); /* Order vcpus_running vs. mmu_ready, see kvmppc_alloc_reset_hpt */ @@ -4591,6 +4597,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_vcpu *vcpu) vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST; do { + kvm_check_async_pf_completion(vcpu); if (cpu_has_feature(CPU_FTR_ARCH_300)) r = kvmhv_run_single_vcpu(vcpu, ~(u64)0, vcpu->arch.vcore->lpcr); @@ -5257,6 +5264,8 @@ static void kvmppc_free_vcores(struct kvm *kvm) static void kvmppc_core_destroy_vm_hv(struct kvm *kvm) { + struct kvm_ppc_sns_reg sns_reg; + debugfs_remove_recursive(kvm->arch.debugfs_dir); if (!cpu_has_feature(CPU_FTR_ARCH_300)) @@ -5283,6 +5292,11 @@ static void kvmppc_core_destroy_vm_hv(struct kvm *kvm) kvmppc_free_lpid(kvm->arch.lpid); kvmppc_free_pimap(kvm); + + /* Needed for de-registering SNS buffer */ + sns_reg.addr = -1; + sns_reg.len = 0; + kvm_vm_ioctl_set_sns(kvm, &sns_reg); } /* We don't need to emulate any privileged instructions or dcbz */ @@ -5561,6 +5575,17 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp, break; } + case KVM_PPC_SET_SNS: { + struct kvm_ppc_sns_reg sns_reg; + + r = -EFAULT; + if (copy_from_user(&sns_reg, argp, sizeof(sns_reg))) + break; + + r = kvm_vm_ioctl_set_sns(kvm, &sns_reg); + break; + } + default: r = -ENOTTY; } diff --git a/arch/powerpc/kvm/book3s_hv_esn.c b/arch/powerpc/kvm/book3s_hv_esn.c new file mode 100644 index 000000000000..b322a14c1f83 --- /dev/null +++ b/arch/powerpc/kvm/book3s_hv_esn.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Async page fault support via PAPR Expropriation/Subvention Notification + * option(ESN) + * + * Copyright 2020 Bharata B Rao, IBM Corp. + */ + +#include +#include +#include + +static DEFINE_SPINLOCK(async_exp_lock); /* for updating exp_corr_nr */ +static DEFINE_SPINLOCK(async_sns_lock); /* SNS buffer updated under this lock */ + +int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, + unsigned long gpa, unsigned long hva) +{ + struct kvm_arch_async_pf arch; + struct lppaca *vpa = vcpu->arch.vpa.pinned_addr; + u64 msr = kvmppc_get_msr(vcpu); + struct kvmppc_sns *sns = &vcpu->kvm->arch.sns; + + /* + * If VPA hasn't been registered yet, can't support + * async pf. + */ + if (!vpa) + return 0; + + /* + * If SNS memory area hasn't been registered yet, + * can't support async pf. + */ + if (!vcpu->kvm->arch.sns.eq) + return 0; + + /* + * If guest hasn't enabled expropriation interrupt, + * don't try async pf. + */ + if (!(vpa->byte_b9 & LPPACA_EXP_INT_ENABLED)) + return 0; + + /* + * If the fault is in the guest kernel, don,t + * try async pf. + */ + if (!(msr & MSR_PR) && !(msr & MSR_HV)) + return 0; + + spin_lock(&async_sns_lock); + /* + * Check if subvention event queue can + * overflow, if so, don't try async pf. + */ + if (*(sns->eq + sns->next_eq_entry)) { + pr_err("%s: SNS buffer overflow\n", __func__); + spin_unlock(&async_sns_lock); + return 0; + } + spin_unlock(&async_sns_lock); + + /* + * TODO: + * + * 1. Update exp flags bit 7 to 1 + * ("The Subvened page data will be restored") + * + * 2. Check if request to this page has been + * notified to guest earlier, if so send back + * the same exp corr number. + * + * 3. exp_corr_nr could be a random but non-zero + * number. Not taking care of wrapping here. Fix + * it. + */ + spin_lock(&async_exp_lock); + vpa->exp_corr_nr = cpu_to_be16(vcpu->kvm->arch.sns.exp_corr_nr); + arch.exp_token = vcpu->kvm->arch.sns.exp_corr_nr++; + spin_unlock(&async_exp_lock); + + return kvm_setup_async_pf(vcpu, gpa, hva, &arch); +} + +bool kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, + struct kvm_async_pf *work) +{ + /* Inject DSI to guest with srr1 bit 46 set */ + kvmppc_core_queue_data_storage(vcpu, kvmppc_get_dar(vcpu), DSISR_NOHPTE, SRR1_PROGTRAP); + return true; +} + +void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, + struct kvm_async_pf *work) +{ + struct kvmppc_sns *sns = &vcpu->kvm->arch.sns; + + spin_lock(&async_sns_lock); + if (*sns->eq_cntrl != SNS_EQ_CNTRL_TRIGGER) { + pr_err("%s: SNS Notification Trigger not set by guest\n", __func__); + spin_unlock(&async_sns_lock); + /* TODO: Terminate the guest? */ + return; + } + + if (arch_cmpxchg(sns->eq + sns->next_eq_entry, 0, + work->arch.exp_token)) { + *sns->eq_state |= SNS_EQ_STATE_OVERFLOW; + pr_err("%s: SNS buffer overflow\n", __func__); + spin_unlock(&async_sns_lock); + /* TODO: Terminate the guest? */ + return; + } + + sns->next_eq_entry = (sns->next_eq_entry + 1) % sns->nr_eq_entries; + spin_unlock(&async_sns_lock); + + /* + * Request a guest exit so that ESN virtual interrupt can + * be injected by QEMU. + */ + kvm_make_request(KVM_REQ_ESN_EXIT, vcpu); +} + +void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) +{ + /* We will inject the page directly */ +} + +bool kvm_arch_can_dequeue_async_page_present(struct kvm_vcpu *vcpu) +{ + /* + * PowerPC will always inject the page directly, + * but we still want check_async_completion to cleanup + */ + return true; +} + +long kvm_vm_ioctl_set_sns(struct kvm *kvm, struct kvm_ppc_sns_reg *sns_reg) +{ + unsigned long nb; + + /* Deregister */ + if (sns_reg->addr == -1) { + if (!kvm->arch.sns.hva) + return 0; + + pr_info("%s: Deregistering SNS buffer for LPID %d\n", + __func__, kvm->arch.lpid); + kvmppc_unpin_guest_page(kvm, kvm->arch.sns.hva, kvm->arch.sns.gpa, false); + kvm->arch.sns.gpa = -1; + kvm->arch.sns.hva = 0; + return 0; + } + + /* + * Already registered with the same address? + */ + if (sns_reg->addr == kvm->arch.sns.gpa) + return 0; + + /* If previous registration exists, free it */ + if (kvm->arch.sns.hva) { + pr_info("%s: Deregistering Previous SNS buffer for LPID %d\n", + __func__, kvm->arch.lpid); + kvmppc_unpin_guest_page(kvm, kvm->arch.sns.hva, kvm->arch.sns.gpa, false); + kvm->arch.sns.gpa = -1; + kvm->arch.sns.hva = 0; + } + + kvm->arch.sns.gpa = sns_reg->addr; + kvm->arch.sns.hva = kvmppc_pin_guest_page(kvm, kvm->arch.sns.gpa, &nb); + kvm->arch.sns.len = sns_reg->len; + kvm->arch.sns.nr_eq_entries = (kvm->arch.sns.len - 2) / sizeof(uint16_t); + kvm->arch.sns.next_eq_entry = 0; + kvm->arch.sns.eq = kvm->arch.sns.hva + 2; + kvm->arch.sns.eq_cntrl = kvm->arch.sns.hva; + kvm->arch.sns.eq_state = kvm->arch.sns.hva + 1; + kvm->arch.sns.exp_corr_nr = 1; /* Should be non-zero */ + + *(kvm->arch.sns.eq_state) = SNS_EQ_STATE_OPERATIONAL; + + pr_info("%s: Registering SNS buffer for LPID %d sns_addr %llx eq %lx\n", + __func__, kvm->arch.lpid, sns_reg->addr, + (unsigned long)kvm->arch.sns.eq); + + return 0; +} diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 47be532ed14b..dbe65e8d68d8 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1459,6 +1459,7 @@ struct kvm_s390_ucas_mapping { #define KVM_SET_PMU_EVENT_FILTER _IOW(KVMIO, 0xb2, struct kvm_pmu_event_filter) #define KVM_PPC_SVM_OFF _IO(KVMIO, 0xb3) #define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte_tags) +#define KVM_PPC_SET_SNS _IOR(KVMIO, 0xb5, struct kvm_ppc_sns_reg) /* ioctl for vm fd */ #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index d9e4aabcb31a..e9dea164498f 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h @@ -1458,6 +1458,7 @@ struct kvm_s390_ucas_mapping { #define KVM_SET_PMU_EVENT_FILTER _IOW(KVMIO, 0xb2, struct kvm_pmu_event_filter) #define KVM_PPC_SVM_OFF _IO(KVMIO, 0xb3) #define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte_tags) +#define KVM_PPC_SET_SNS _IOR(KVMIO, 0xb5, struct kvm_ppc_sns_reg) /* ioctl for vm fd */ #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) From patchwork Thu Aug 5 07:24:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bharata B Rao X-Patchwork-Id: 1513763 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=kvm-ppc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=rjBxqSUN; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4GgKrW5Wtpz9t0Z for ; Thu, 5 Aug 2021 17:25:15 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238572AbhHEHZ2 (ORCPT ); Thu, 5 Aug 2021 03:25:28 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:22886 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238611AbhHEHZ0 (ORCPT ); Thu, 5 Aug 2021 03:25:26 -0400 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 1757ArRc140705; Thu, 5 Aug 2021 03:25:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=zWG0pHLszMGhSn12UZYrNCEJ4kEU5e+/nJEH1VtnCbY=; b=rjBxqSUNl1298zvP70DGBEcSvtZNiMRqLq7oxDmMzKjeLoenf2M0VfW5GCGjdMHtjoSw /Ee2QTnAb/6Rma1yfuGZJHwRNpi7z9oL8ETAdBogcqcQFXPqwhdyRCbH78BpmkDJXfiu hNBwcjLYBQddR+tpE7O+CHYZykhi07Iz+AucYCHeprDgVTDFcSPDJ+m76PrSL1PCk5g4 +SFNvGLVuhut3zSZQ2O+75LB0pt68x1558BnfMdOKNgTqPKEtmmtCEGXv78DVO0vRqNQ KKvQvN/FzL7AiPydcJtVCbkEGrJNDe2LKOsxBAiy35IcWfok2V0VpfELChlXSlm/+Lv1 qg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a89p12m8y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:25:11 -0400 Received: from m0098404.ppops.net (m0098404.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1757BB8i142349; Thu, 5 Aug 2021 03:25:10 -0400 Received: from ppma02fra.de.ibm.com (47.49.7a9f.ip4.static.sl-reverse.com [159.122.73.71]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a89p12m8a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 03:25:10 -0400 Received: from pps.filterd (ppma02fra.de.ibm.com [127.0.0.1]) by ppma02fra.de.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 17576Z6O004876; Thu, 5 Aug 2021 07:25:08 GMT Received: from b06cxnps4074.portsmouth.uk.ibm.com (d06relay11.portsmouth.uk.ibm.com [9.149.109.196]) by ppma02fra.de.ibm.com with ESMTP id 3a4x58sncp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Aug 2021 07:25:08 +0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1757P3WA44761538 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 5 Aug 2021 07:25:03 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9623EA4072; Thu, 5 Aug 2021 07:25:03 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9054CA4078; Thu, 5 Aug 2021 07:25:01 +0000 (GMT) Received: from bharata.ibmuc.com (unknown [9.102.2.73]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 5 Aug 2021 07:25:01 +0000 (GMT) From: Bharata B Rao To: kvm-ppc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: kvm@vger.kernel.org, aneesh.kumar@linux.ibm.com, bharata.rao@gmail.com, Bharata B Rao Subject: [RFC PATCH v0 5/5] pseries: Asynchronous page fault support Date: Thu, 5 Aug 2021 12:54:39 +0530 Message-Id: <20210805072439.501481-6-bharata@linux.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210805072439.501481-1-bharata@linux.ibm.com> References: <20210805072439.501481-1-bharata@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 7wOzeE0FsfaShdDy-z2XiZChE7Y6VxLl X-Proofpoint-ORIG-GUID: -Kqv53yqYFxZ7tMee0W8_aVyrDNjzYCw X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.790 definitions=2021-08-05_02:2021-08-04,2021-08-05 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 priorityscore=1501 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 impostorscore=0 spamscore=0 clxscore=1015 phishscore=0 malwarescore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2108050041 Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org Add asynchronous page fault support for pseries guests. 1. Setup the guest to handle async-pf - Issue H_REG_SNS hcall to register the SNS region. - Setup the subvention interrupt irq. - Enable async-pf by updating the byte_b9 of VPA for each CPU. 2. Check if the page fault is an expropriation notification (SRR1_PROGTRAP set in SRR1) and if so put the task on wait queue based on the expropriation correlation number read from the VPA. 3. Handle subvention interrupt to wake any waiting tasks. The wait and wakeup mechanism from x86 async-pf implementation is being reused here. TODO: - Check how to keep this feature together with other CMO features. - The async-pf check in the page fault handler path is limited to guest with an #ifdef. This isn't sufficient and hence needs to be replaced by an appropriate check. Signed-off-by: Bharata B Rao --- arch/powerpc/include/asm/async-pf.h | 12 ++ arch/powerpc/mm/fault.c | 7 +- arch/powerpc/platforms/pseries/Makefile | 2 +- arch/powerpc/platforms/pseries/async-pf.c | 219 ++++++++++++++++++++++ 4 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/include/asm/async-pf.h create mode 100644 arch/powerpc/platforms/pseries/async-pf.c diff --git a/arch/powerpc/include/asm/async-pf.h b/arch/powerpc/include/asm/async-pf.h new file mode 100644 index 000000000000..95d6c3da9f50 --- /dev/null +++ b/arch/powerpc/include/asm/async-pf.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Async page fault support via PAPR Expropriation/Subvention Notification + * option(ESN) + * + * Copyright 2020 Bharata B Rao, IBM Corp. + */ + +#ifndef _ASM_POWERPC_ASYNC_PF_H +int handle_async_page_fault(struct pt_regs *regs, unsigned long addr); +#define _ASM_POWERPC_ASYNC_PF_H +#endif diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index a8d0ce85d39a..bbdc61605885 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -44,7 +44,7 @@ #include #include #include - +#include /* * do_page_fault error handling helpers @@ -395,6 +395,11 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address, vm_fault_t fault, major = 0; bool kprobe_fault = kprobe_page_fault(regs, 11); +#ifdef CONFIG_PPC_PSERIES + if (handle_async_page_fault(regs, address)) + return 0; +#endif + if (unlikely(debugger_fault_handler(regs) || kprobe_fault)) return 0; diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 4cda0ef87be0..e0ada605ef20 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -6,7 +6,7 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \ of_helpers.o \ setup.o iommu.o event_sources.o ras.o \ firmware.o power.o dlpar.o mobility.o rng.o \ - pci.o pci_dlpar.o eeh_pseries.o msi.o + pci.o pci_dlpar.o eeh_pseries.o msi.o async-pf.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_KEXEC_CORE) += kexec.o diff --git a/arch/powerpc/platforms/pseries/async-pf.c b/arch/powerpc/platforms/pseries/async-pf.c new file mode 100644 index 000000000000..c2f3bbc0d674 --- /dev/null +++ b/arch/powerpc/platforms/pseries/async-pf.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Async page fault support via PAPR Expropriation/Subvention Notification + * option(ESN) + * + * Copyright 2020 Bharata B Rao, IBM Corp. + */ + +#include +#include +#include +#include +#include +#include + +static char sns_buffer[PAGE_SIZE] __aligned(4096); +static uint16_t *esn_q = (uint16_t *)sns_buffer + 1; +static unsigned long next_eq_entry, nr_eq_entries; + +#define ASYNC_PF_SLEEP_HASHBITS 8 +#define ASYNC_PF_SLEEP_HASHSIZE (1<list) { + struct async_pf_sleep_node *n = + hlist_entry(p, typeof(*n), link); + if (n->token == token) + return n; + } + + return NULL; +} +static int async_pf_queue_task(u64 token, struct async_pf_sleep_node *n) +{ + u64 key = hash_64(token, ASYNC_PF_SLEEP_HASHBITS); + struct async_pf_sleep_head *b = &async_pf_sleepers[key]; + struct async_pf_sleep_node *e; + + raw_spin_lock(&b->lock); + e = _find_apf_task(b, token); + if (e) { + /* dummy entry exist -> wake up was delivered ahead of PF */ + hlist_del(&e->link); + raw_spin_unlock(&b->lock); + kfree(e); + return false; + } + + n->token = token; + n->cpu = smp_processor_id(); + init_swait_queue_head(&n->wq); + hlist_add_head(&n->link, &b->list); + raw_spin_unlock(&b->lock); + return true; +} + +/* + * Handle Expropriation notification. + */ +int handle_async_page_fault(struct pt_regs *regs, unsigned long addr) +{ + struct async_pf_sleep_node n; + DECLARE_SWAITQUEUE(wait); + unsigned long exp_corr_nr; + + /* Is this Expropriation notification? */ + if (!(mfspr(SPRN_SRR1) & SRR1_PROGTRAP)) + return 0; + + if (unlikely(!user_mode(regs))) + panic("Host injected async PF in kernel mode\n"); + + exp_corr_nr = be16_to_cpu(get_lppaca()->exp_corr_nr); + if (!async_pf_queue_task(exp_corr_nr, &n)) + return 0; + + for (;;) { + prepare_to_swait_exclusive(&n.wq, &wait, TASK_UNINTERRUPTIBLE); + if (hlist_unhashed(&n.link)) + break; + + local_irq_enable(); + schedule(); + local_irq_disable(); + } + + finish_swait(&n.wq, &wait); + return 1; +} + +static void apf_task_wake_one(struct async_pf_sleep_node *n) +{ + hlist_del_init(&n->link); + if (swq_has_sleeper(&n->wq)) + swake_up_one(&n->wq); +} + +static void async_pf_wake_task(u64 token) +{ + u64 key = hash_64(token, ASYNC_PF_SLEEP_HASHBITS); + struct async_pf_sleep_head *b = &async_pf_sleepers[key]; + struct async_pf_sleep_node *n; + +again: + raw_spin_lock(&b->lock); + n = _find_apf_task(b, token); + if (!n) { + /* + * async PF was not yet handled. + * Add dummy entry for the token. + */ + n = kzalloc(sizeof(*n), GFP_ATOMIC); + if (!n) { + /* + * Allocation failed! Busy wait while other cpu + * handles async PF. + */ + raw_spin_unlock(&b->lock); + cpu_relax(); + goto again; + } + n->token = token; + n->cpu = smp_processor_id(); + init_swait_queue_head(&n->wq); + hlist_add_head(&n->link, &b->list); + } else { + apf_task_wake_one(n); + } + raw_spin_unlock(&b->lock); +} + +/* + * Handle Subvention notification. + */ +static irqreturn_t async_pf_handler(int irq, void *dev_id) +{ + uint16_t exp_token, old; + + raw_spin_lock(&async_sns_guest_lock); + do { + exp_token = *(esn_q + next_eq_entry); + if (!exp_token) + break; + + old = arch_cmpxchg(esn_q + next_eq_entry, exp_token, 0); + BUG_ON(old != exp_token); + + async_pf_wake_task(exp_token); + next_eq_entry = (next_eq_entry + 1) % nr_eq_entries; + } while (1); + raw_spin_unlock(&async_sns_guest_lock); + return IRQ_HANDLED; +} + +static int __init pseries_async_pf_init(void) +{ + long rc; + unsigned long ret[PLPAR_HCALL_BUFSIZE]; + unsigned int irq, cpu; + int i; + + /* Register buffer via H_REG_SNS */ + rc = plpar_hcall(H_REG_SNS, ret, __pa(sns_buffer), PAGE_SIZE); + if (rc != H_SUCCESS) + return -1; + + nr_eq_entries = (PAGE_SIZE - 2) / sizeof(uint16_t); + + /* Register irq handler */ + irq = irq_create_mapping(NULL, ret[1]); + if (!irq) { + plpar_hcall(H_REG_SNS, ret, -1, PAGE_SIZE); + return -1; + } + + rc = request_irq(irq, async_pf_handler, 0, "sns-interrupt", NULL); + if (rc < 0) { + plpar_hcall(H_REG_SNS, ret, -1, PAGE_SIZE); + return -1; + } + + for (i = 0; i < ASYNC_PF_SLEEP_HASHSIZE; i++) + raw_spin_lock_init(&async_pf_sleepers[i].lock); + + /* + * Enable subvention notifications from the hypervisor + * by setting bit 0, byte 0 of SNS buffer + */ + *sns_buffer |= 0x1; + + /* Enable LPPACA_EXP_INT_ENABLED in VPA */ + for_each_possible_cpu(cpu) + lppaca_of(cpu).byte_b9 |= LPPACA_EXP_INT_ENABLED; + + pr_err("%s: Enabled Async PF\n", __func__); + return 0; +} + +machine_arch_initcall(pseries, pseries_async_pf_init);