From patchwork Thu Sep 3 15:25:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754111 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 931361866 for ; Thu, 3 Sep 2020 15:26:42 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5E2662072A for ; Thu, 3 Sep 2020 15:26:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="FAqk9lTB"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="d/cumSf4" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5E2662072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=JJLdJXkWfO7LBhVAG+tko2Snym9ENJwrkSXSavZm0qE=; b=FAqk9lTB2bUSslIN0GyH5jK1g yayWJ6zyXJKvHX0xZv8fVOKaJ+M2StfRJfcjSk8r9ysoMhyXn1Ca1ADizgHg8qIJ2/FolwC+Cioeq CSII5EJgpHuQLD4L9LIw8FqiM9IXKQLRz7tY6BYxfBrPz7KsJc1IAVq3t56+HmxKgWmKrYwtweYWZ X1dbYMVRlibeP5c9ZrUKteYovL7s9ln2g5PkD6gsVbsSWVRfJ1czbTmfKsuj8pZIe51Qome9yVHz2 1zm7Q9z7bKkMD6du0QNb4XQeG4HRjrdfautWayCQFjiEBrE3xOCxe9i2c66/IPU+/QQ29GI1S9wQ3 fmlo3Hqxw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8A-0004tA-J3; Thu, 03 Sep 2020 15:26:30 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr84-0004qM-2B for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:25 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 3388E20786; Thu, 3 Sep 2020 15:26:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146783; bh=dx03lYO45BaSF7PbrJoHAEWSdMagfqHrhZh0pzeUc2A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d/cumSf48v1zSIa0Sv8iWR6AvTERgVoDBKP9OFgw0SQTBD072ur1dBS7srs3u0Gm3 x9guaYCU1Vwt+v5gAYcVApKvf+PLgW7CFiWWhc+CNiaBSAwDEhxdI7VW6JNmZQ3AJJ kGiYK8hlKVv6hHAwzReURj6gbnBN/PkykEOtR1zE= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr81-008vT9-EX; Thu, 03 Sep 2020 16:26:21 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 01/23] irqchip: Add Reduced Virtual Interrupt Controller driver Date: Thu, 3 Sep 2020 16:25:48 +0100 Message-Id: <20200903152610.1078827-2-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112624_265320_8A3EA0B5 X-CRM114-Status: GOOD ( 28.15 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The ARM rVIC is the simplest PV interrupt controller on this side of the universe. I mean it! Signed-off-by: Marc Zyngier --- drivers/irqchip/Kconfig | 6 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-rvic.c | 554 +++++++++++++++++++++++++++++++ include/linux/cpuhotplug.h | 1 + include/linux/irqchip/irq-rvic.h | 77 +++++ 5 files changed, 639 insertions(+) create mode 100644 drivers/irqchip/irq-rvic.c create mode 100644 include/linux/irqchip/irq-rvic.h diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index bfc9719dbcdc..348ff1d06651 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -61,6 +61,12 @@ config ARM_NVIC select IRQ_DOMAIN_HIERARCHY select GENERIC_IRQ_CHIP +config ARM_RVIC + bool + default ARM64 + select IRQ_DOMAIN_HIERARCHY + select GENERIC_IRQ_EFFECTIVE_AFF_MASK + config ARM_VIC bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 133f9c45744a..d2b280efd2e0 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) += irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o +obj-$(CONFIG_ARM_RVIC) += irq-rvic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o obj-$(CONFIG_ARMADA_370_XP_IRQ) += irq-armada-370-xp.o obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o diff --git a/drivers/irqchip/irq-rvic.c b/drivers/irqchip/irq-rvic.c new file mode 100644 index 000000000000..6f37aa4318b6 --- /dev/null +++ b/drivers/irqchip/irq-rvic.c @@ -0,0 +1,554 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * A Reduced Virtual Interrupt Controler driver + * + * Initial draft from Alex Shirshikov + * + * Copyright 2020 Google LLC. + * Author: Marc Zyngier + */ + + +#define pr_fmt(fmt) "rVIC: " fmt + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define RVIC_WARN_INTID_TARGET(r, s, intid, mpid) \ + WARN((r), "Error " s " INTID%ld target %llx (%ld, %ld)\n", \ + (intid), (mpid), \ + RVIC_STATUS_REASON((r)), RVIC_STATUS_INDEX((r))); + +#define RVIC_WARN_INTID(r, s, intid) \ + WARN((r), "Error " s " INTID%ld (%ld, %ld)\n", \ + (intid), \ + RVIC_STATUS_REASON((r)), RVIC_STATUS_INDEX((r))); + +static DEFINE_PER_CPU(unsigned long *, trusted_masked); + +struct rvic_data { + struct fwnode_handle *fwnode; + struct irq_domain *domain; + unsigned int nr_trusted; + unsigned int nr_untrusted; +}; + +static struct rvic_data rvic; + +static inline int rvic_version(unsigned long *version) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_VERSION, &res); + if (res.a0 == RVIC_STATUS_SUCCESS) + *version = res.a1; + return res.a0; +} + +static inline unsigned long rvic_info(unsigned long key, + unsigned long *value) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_INFO, key, &res); + if (res.a0 == RVIC_STATUS_SUCCESS) + *value = res.a1; + return res.a0; +} + +static inline unsigned long rvic_enable(void) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_ENABLE, &res); + return res.a0; +} + +static inline unsigned long rvic_disable(void) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_DISABLE, &res); + return res.a0; +} + +static inline unsigned long rvic_set_masked(unsigned long target, + unsigned long intid) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_SET_MASKED, target, intid, &res); + return res.a0; +} + +static inline unsigned long rvic_clear_masked(unsigned long target, + unsigned long intid) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_CLEAR_MASKED, target, intid, &res); + return res.a0; +} + +static inline unsigned long rvic_is_pending(unsigned long target, + unsigned long intid, + bool *is_pending) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_IS_PENDING, target, intid, &res); + if (res.a0 == RVIC_STATUS_SUCCESS) + *is_pending = res.a1; + return res.a0; +} + +static inline unsigned long rvic_signal(unsigned long target, + unsigned long intid) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_SIGNAL, target, intid, &res); + return res.a0; +} + +static inline unsigned long rvic_clear_pending(unsigned long target, + unsigned long intid) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_CLEAR_PENDING, target, intid, &res); + return res.a0; +} + +static inline unsigned long rvic_acknowledge(unsigned long *intid) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_ACKNOWLEDGE, &res); + if (res.a0 == RVIC_STATUS_SUCCESS) + *intid = res.a1; + return res.a0; +} + +static inline unsigned long rvic_resample(unsigned long intid) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVIC_RESAMPLE, intid, &res); + return res.a0; +} + +static u64 rvic_irq_to_mpidr(struct irq_data *data, int *cpup) +{ + int cpu; + + if (data->hwirq < rvic.nr_trusted) { + *cpup = smp_processor_id(); + return read_cpuid_mpidr() & MPIDR_HWID_BITMASK; + } + + cpu = cpumask_first(data->common->effective_affinity); + *cpup = cpu; + return cpu_logical_map(cpu) & MPIDR_HWID_BITMASK; +} + +static void rvic_irq_mask(struct irq_data *data) +{ + unsigned long ret; + u64 mpidr; + int cpu; + + mpidr = rvic_irq_to_mpidr(data, &cpu); + pr_debug("%llu irq %d hwirq %ld masked\n", + mpidr, data->irq, data->hwirq); + ret = rvic_set_masked(mpidr, data->hwirq); + RVIC_WARN_INTID_TARGET(ret, "masking", data->hwirq, mpidr); + + if (data->hwirq < rvic.nr_trusted) + set_bit(data->hwirq, per_cpu(trusted_masked, cpu)); +} + +static void rvic_irq_unmask(struct irq_data *data) +{ + unsigned long ret; + u64 mpidr; + int cpu; + + mpidr = rvic_irq_to_mpidr(data, &cpu); + pr_debug("%llu irq %d hwirq %ld unmasked\n", + mpidr, data->irq, data->hwirq); + ret = rvic_clear_masked(mpidr, data->hwirq); + RVIC_WARN_INTID_TARGET(ret, "unmasking", data->hwirq, mpidr); + + if (data->hwirq < rvic.nr_trusted) + clear_bit(data->hwirq, per_cpu(trusted_masked, cpu)); +} + +static void rvic_irq_eoi(struct irq_data *data) +{ + bool masked; + + /* Resampling is only available on trusted interrupts for now */ + if (data->hwirq < rvic.nr_trusted && + (irqd_get_trigger_type(data) & IRQ_TYPE_LEVEL_MASK)) { + unsigned long ret; + + ret = rvic_resample(data->hwirq); + RVIC_WARN_INTID(ret, "resampling", data->hwirq); + } + + /* irqd_irq_masked doesn't work on percpu-devid interrupts. */ + if (data->hwirq < rvic.nr_trusted) + masked = test_bit(data->hwirq, *this_cpu_ptr(&trusted_masked)); + else + masked = irqd_irq_masked(data); + + if (!masked) + rvic_irq_unmask(data); +} + +static void rvic_ipi_send_mask(struct irq_data *data, + const struct cpumask *mask) +{ + int cpu; + + for_each_cpu(cpu, mask) { + u64 mpidr = cpu_logical_map(cpu) & MPIDR_HWID_BITMASK; + unsigned long ret; + + ret = rvic_signal(mpidr, data->hwirq); + RVIC_WARN_INTID_TARGET(ret, "signaling", data->hwirq, mpidr); + } +} + +static int rvic_irq_get_irqchip_state(struct irq_data *data, + enum irqchip_irq_state which, bool *val) +{ + unsigned long ret; + u64 mpidr; + int cpu; + + mpidr = rvic_irq_to_mpidr(data, &cpu); + + switch (which) { + case IRQCHIP_STATE_PENDING: + ret = rvic_is_pending(mpidr, data->hwirq, val); + RVIC_WARN_INTID_TARGET(ret, "getting pending state", + data->hwirq, mpidr); + return ret ? -EINVAL : 0; + + default: + return -EINVAL; + }; +} + +static int rvic_irq_set_irqchip_state(struct irq_data *data, + enum irqchip_irq_state which, bool val) +{ + unsigned long ret; + u64 mpidr; + int cpu; + + mpidr = rvic_irq_to_mpidr(data, &cpu); + + switch (which) { + case IRQCHIP_STATE_PENDING: + if (val) + ret = rvic_signal(mpidr, data->hwirq); + else + ret = rvic_clear_pending(mpidr, data->hwirq); + RVIC_WARN_INTID_TARGET(ret, "setting pending state", + data->hwirq, mpidr); + return ret ? -EINVAL : 0; + + case IRQCHIP_STATE_MASKED: + if (val) + ret = rvic_set_masked(mpidr, data->hwirq); + else + ret = rvic_clear_masked(mpidr, data->hwirq); + RVIC_WARN_INTID_TARGET(ret, "setting masked state", + data->hwirq, mpidr); + return ret ? -EINVAL : 0; + + default: + return -EINVAL; + } + +} + +static int rvic_irq_retrigger(struct irq_data *data) +{ + return !!rvic_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, true); +} + +static int rvic_set_type(struct irq_data *data, unsigned int type) +{ + /* + * Nothing to do here, we're always edge under the hood. Just + * weed out untrusted interrupts, as they cannot be level yet. + */ + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: + if (data->hwirq >= rvic.nr_trusted) + return -EINVAL; + + fallthrough; + case IRQ_TYPE_EDGE_RISING: + return 0; + default: + return -EINVAL; + } +} + +static struct irq_chip rvic_chip = { + .name = "rvic", + .irq_mask = rvic_irq_mask, + .irq_unmask = rvic_irq_unmask, + .irq_eoi = rvic_irq_eoi, + .ipi_send_mask = rvic_ipi_send_mask, + .irq_get_irqchip_state = rvic_irq_get_irqchip_state, + .irq_set_irqchip_state = rvic_irq_set_irqchip_state, + .irq_retrigger = rvic_irq_retrigger, + .irq_set_type = rvic_set_type, +}; + +static asmlinkage void __exception_irq_entry rvic_handle_irq(struct pt_regs *regs) +{ + unsigned long ret, intid; + int err; + + ret = rvic_acknowledge(&intid); + if (unlikely(ret == RVIC_STATUS_NO_INTERRUPTS)) { + pr_debug("CPU%d: Spurious interrupt\n", smp_processor_id()); + return; + } + + if ((unlikely(ret))) { + WARN(1, "rVIC: Error acknowledging interrupt (%ld, %ld)\n", + RVIC_STATUS_REASON(ret), + RVIC_STATUS_INDEX(ret)); + return; + } + + if (unlikely(intid >= (rvic.nr_trusted + rvic.nr_untrusted))) { + WARN(1, "Unexpected intid out of range (%lu)\n", intid); + return; + } + + pr_debug("CPU%d: IRQ%ld\n", smp_processor_id(), intid); + err = handle_domain_irq(rvic.domain, intid, regs); + WARN_ONCE(err, "Unexpected interrupt received %d\n", err); +} + +static int rvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + struct irq_fwspec *fwspec = arg; + unsigned int type = IRQ_TYPE_NONE; + irq_hw_number_t hwirq; + int i, ret; + + ret = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + for (i = 0; i < nr_irqs; i++) { + unsigned int intid = hwirq + i; + unsigned int irq = virq + i; + + if (intid < 16) { + irq_set_percpu_devid(irq); + irq_domain_set_info(domain, irq, intid, &rvic_chip, + domain->host_data, + handle_percpu_devid_fasteoi_ipi, + NULL, NULL); + } else if (intid < rvic.nr_trusted) { + irq_set_percpu_devid(irq); + irq_domain_set_info(domain, irq, intid, &rvic_chip, + domain->host_data, + handle_percpu_devid_irq, + NULL, NULL); + } else { + return -EINVAL; + } + } + + return 0; +} + +static void rvic_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + int i; + + for (i = 0; i < nr_irqs; i++) { + struct irq_data *d = irq_domain_get_irq_data(domain, virq + i); + irq_set_handler(virq + i, NULL); + irq_domain_reset_irq_data(d); + } +} + +static const struct irq_domain_ops rvic_irq_domain_ops = { + .translate = irq_domain_translate_twocell, + .alloc = rvic_irq_domain_alloc, + .free = rvic_irq_domain_free, +}; + +static int rvic_cpu_starting(unsigned int cpu) +{ + u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; + unsigned long ret; + int i; + + rvic_disable(); + + for (i = 0; i < (rvic.nr_trusted + rvic.nr_untrusted); i++) { + rvic_set_masked(mpidr, i); + rvic_clear_pending(mpidr, i); + } + + ret = rvic_enable(); + if (ret != RVIC_STATUS_SUCCESS) { + pr_err("rVIC: error enabling instance (%ld, %ld)\n", + RVIC_STATUS_REASON(ret), + RVIC_STATUS_INDEX(ret)); + return -ENXIO; + } + + return 0; +} + +static int rvic_cpu_dying(unsigned int cpu) +{ + unsigned long ret; + + ret = rvic_disable(); + if (ret != RVIC_STATUS_SUCCESS) { + pr_err("rVIC: error disabling instance (%ld, %ld)\n", + RVIC_STATUS_REASON(ret), + RVIC_STATUS_INDEX(ret)); + return -ENXIO; + } + + return 0; +} + +static void __init rvic_smp_init(struct fwnode_handle *fwnode) +{ + struct irq_fwspec ipi_fwspec = { + .fwnode = fwnode, + .param_count = 2, + .param[0] = 0, + .param[1] = IRQ_TYPE_EDGE_RISING, + }; + int base_ipi; + + cpuhp_setup_state(CPUHP_AP_IRQ_RVIC_STARTING, "irqchip/rvic:starting", + rvic_cpu_starting, rvic_cpu_dying); + + base_ipi = __irq_domain_alloc_irqs(rvic.domain, -1, 16, + NUMA_NO_NODE, &ipi_fwspec, + false, NULL); + if (WARN_ON(base_ipi < 0)) + return; + + set_smp_ipi_range(base_ipi, 16); +} + +static int __init rvic_init(struct device_node *node, + struct device_node *parent) +{ + unsigned long ret, version, val; + int cpu; + + if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_1) { + pr_err("SMCCC 1.1 required, abording\n"); + return -EINVAL; + } + + rvic.fwnode = of_node_to_fwnode(node); + + ret = rvic_version(&version); + if (ret != RVIC_STATUS_SUCCESS) { + pr_err("error retrieving version (%ld, %ld)\n", + RVIC_STATUS_REASON(ret), + RVIC_STATUS_INDEX(ret)); + return -ENXIO; + } + + if (version < RVIC_VERSION(0, 3)) { + pr_err("version (%ld, %ld) too old, expected min. (%d, %d)\n", + RVIC_VERSION_MAJOR(version), + RVIC_VERSION_MINOR(version), + 0, 3); + return -ENXIO; + } + + ret = rvic_info(RVIC_INFO_KEY_NR_TRUSTED_INTERRUPTS, &val); + if (ret != RVIC_STATUS_SUCCESS) { + pr_err("error retrieving nr of trusted interrupts (%ld, %ld)\n", + RVIC_STATUS_REASON(ret), + RVIC_STATUS_INDEX(ret)); + return -ENXIO; + } + + rvic.nr_trusted = val; + + ret = rvic_info(RVIC_INFO_KEY_NR_UNTRUSTED_INTERRUPTS, &val); + if (ret != RVIC_STATUS_SUCCESS) { + pr_err("error retrieving nr of untrusted interrupts (%ld, %ld)\n", + RVIC_STATUS_REASON(ret), + RVIC_STATUS_INDEX(ret)); + return -ENXIO; + } + + rvic.nr_untrusted = val; + + pr_info("probed %u trusted interrupts, %u untrusted interrupts\n", + rvic.nr_trusted, rvic.nr_untrusted); + + rvic.domain = irq_domain_create_linear(rvic.fwnode, + rvic.nr_trusted + rvic.nr_untrusted, + &rvic_irq_domain_ops, &rvic); + if (!rvic.domain) { + pr_warn("Failed to allocate irq domain\n"); + return -ENOMEM; + } + + for_each_possible_cpu(cpu) { + unsigned long *map = bitmap_alloc(rvic.nr_trusted, GFP_KERNEL); + + if (!map) { + pr_warn("Failed to allocate trusted bitmap (CPU %d)\n", + cpu); + goto free_percpu; + } + + /* Default to masked */ + bitmap_fill(map, rvic.nr_trusted); + per_cpu(trusted_masked, cpu) = map; + } + + rvic_smp_init(rvic.fwnode); + set_handle_irq(rvic_handle_irq); + + return 0; + +free_percpu: + for_each_possible_cpu(cpu) + kfree(per_cpu(trusted_masked, cpu)); + + irq_domain_remove(rvic.domain); + + return -ENOMEM; +} + +IRQCHIP_DECLARE(rvic, "arm,rvic", rvic_init); diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 3215023d4852..ddaa57157af0 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -101,6 +101,7 @@ enum cpuhp_state { CPUHP_AP_IRQ_HIP04_STARTING, CPUHP_AP_IRQ_ARMADA_XP_STARTING, CPUHP_AP_IRQ_BCM2836_STARTING, + CPUHP_AP_IRQ_RVIC_STARTING, CPUHP_AP_IRQ_MIPS_GIC_STARTING, CPUHP_AP_IRQ_RISCV_STARTING, CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING, diff --git a/include/linux/irqchip/irq-rvic.h b/include/linux/irqchip/irq-rvic.h new file mode 100644 index 000000000000..0176ca7d3c30 --- /dev/null +++ b/include/linux/irqchip/irq-rvic.h @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Definitions for rVIC/rVID PV interrupt controller architecture. + * + * Copyright 2020 Google LLC. + * Author: Marc Zyngier + * + * WARNING: All these constants are subject to change until the spec is final. + */ + +#ifndef __IRQCHIP_IRQ_RVIC_H__ +#define __IRQCHIP_IRQ_RVIC_H__ + +#include + +/* Versioning */ +#define RVIx_VERSION_MAJOR_MASK GENMASK(31, 16) +#define RVIx_VERSION_MINOR_MASK GENMASK(15, 0) + +#define RVIx_VERSION(M, m) \ + (FIELD_PREP(RVIx_VERSION_MAJOR_MASK, (M)) | \ + FIELD_PREP(RVIx_VERSION_MINOR_MASK, (m))) + +#define RVIx_VERSION_MAJOR(v) FIELD_GET(RVIx_VERSION_MAJOR_MASK, (v)) +#define RVIx_VERSION_MINOR(v) FIELD_GET(RVIx_VERSION_MINOR_MASK, (v)) + +/* Error reporting */ +#define RVIx_STATUS_REASON_MASK GENMASK(7, 0) +#define RVIx_STATUS_INDEX_MASK GENMASK(15, 8) + +#define RVIx_STATUS_PACK(r,i) \ + (FIELD_PREP(RVIx_STATUS_REASON_MASK, (r)) | \ + FIELD_PREP(RVIx_STATUS_INDEX_MASK, (i))) + +#define RVIx_STATUS_REASON(c) FIELD_GET(RVIx_STATUS_REASON_MASK, (c)) +#define RVIx_STATUS_INDEX(c) FIELD_GET(RVIx_STATUS_INDEX_MASK, (c)) + +#define RVIx_STATUS_SUCCESS 0 +#define RVIx_STATUS_ERROR_PARAMETER 1 +#define RVIx_STATUS_INVALID_CPU 2 +#define RVIx_STATUS_DISABLED 3 +#define RVIx_STATUS_NO_INTERRUPTS 4 + +/* rVIC functions */ +#define SMC64_RVIC_BASE 0xc5000200 +#define SMC64_RVIC_FN(n) (SMC64_RVIC_BASE + (n)) + +#define SMC64_RVIC_VERSION SMC64_RVIC_FN(0) +#define SMC64_RVIC_INFO SMC64_RVIC_FN(1) +#define SMC64_RVIC_ENABLE SMC64_RVIC_FN(2) +#define SMC64_RVIC_DISABLE SMC64_RVIC_FN(3) +#define SMC64_RVIC_SET_MASKED SMC64_RVIC_FN(4) +#define SMC64_RVIC_CLEAR_MASKED SMC64_RVIC_FN(5) +#define SMC64_RVIC_IS_PENDING SMC64_RVIC_FN(6) +#define SMC64_RVIC_SIGNAL SMC64_RVIC_FN(7) +#define SMC64_RVIC_CLEAR_PENDING SMC64_RVIC_FN(8) +#define SMC64_RVIC_ACKNOWLEDGE SMC64_RVIC_FN(9) +#define SMC64_RVIC_RESAMPLE SMC64_RVIC_FN(10) + +#define RVIC_INFO_KEY_NR_TRUSTED_INTERRUPTS 0 +#define RVIC_INFO_KEY_NR_UNTRUSTED_INTERRUPTS 1 + +#define RVIC_VERSION(M, m) RVIx_VERSION((M), (m)) + +#define RVIC_VERSION_MAJOR(v) RVIx_VERSION_MAJOR((v)) +#define RVIC_VERSION_MINOR(v) RVIx_VERSION_MINOR((v)) + +#define RVIC_STATUS_REASON(c) RVIx_STATUS_REASON((c)) +#define RVIC_STATUS_INDEX(c) RVIx_STATUS_INDEX((c)) + +#define RVIC_STATUS_SUCCESS RVIx_STATUS_SUCCESS +#define RVIC_STATUS_ERROR_PARAMETER RVIx_STATUS_ERROR_PARAMETER +#define RVIC_STATUS_INVALID_CPU RVIx_STATUS_INVALID_CPU +#define RVIC_STATUS_DISABLED RVIx_STATUS_DISABLED +#define RVIC_STATUS_NO_INTERRUPTS RVIx_STATUS_NO_INTERRUPTS + +#endif /* __IRQCHIP_IRQ_RVIC_H__ */ From patchwork Thu Sep 3 15:25:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754139 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CFBF2109B for ; Thu, 3 Sep 2020 15:28:14 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A5F632072A for ; Thu, 3 Sep 2020 15:28:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="dvZVWA4O"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="E/l55asM" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A5F632072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=gM4qpemosLV464iyO+DPntxDFZlbuxuUbZYtvT0nZW8=; b=dvZVWA4OJYuTz2ZgJ5FYbAjn6 gKkMCLK/iTuJQrO7IzH54SYSVtaMTKAsTgIwMooZ++BFY7zLGL+3ccB6P0qNhXZrxxesrUO3nBt0u Eb30KdsYyDCKqxSumMxMw+FqVSs/mYv9n1AwrTldWafOK3YkIYdU4qnAKa5KcihVQEYRNWMBiDcS6 DvXv/ayyK2wUDungFjKHbI9Wz8xob2JdNNqsLZIOjroIdBHGKL5Qo//swjR0CprTAlVKSxWf6r2Wi ArxLR1xURAUjvbLPue+hT3UAkpqKPBuKBkdYDeM6yOY8Mkz5F+g/mOU/haYkUDCXCRI6TDqE9B6Cv vjeYGdCnw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8D-0004uA-6z; Thu, 03 Sep 2020 15:26:33 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr84-0004qa-Dt for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:25 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id BBEFB208B3; Thu, 3 Sep 2020 15:26:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146783; bh=7LhuvEdZhLPAHAyHA7l/m2l3Ifej9lF2CP2ElSpnsoc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=E/l55asM97OjhFg1PYSYfZXX6sGk97GlTvUiCkdOz9Cle8jaVkX2sdKgEzLQKlPHy KPrpqm6OGGWKJEBFax6WBjzwghI7kdB5fDF3OVwak9lDOQ1UcocaT/Mf4j5pAGJ586 HEoetApPvUe3rMQqRsWkaljLJ2QuX/v4KvaZSu1M= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr82-008vT9-4G; Thu, 03 Sep 2020 16:26:22 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 02/23] irqchip/rvic: Add support for untrusted interrupt allocation Date: Thu, 3 Sep 2020 16:25:49 +0100 Message-Id: <20200903152610.1078827-3-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112624_598350_459B840E X-CRM114-Status: GOOD ( 20.37 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Signed-off-by: Marc Zyngier --- drivers/irqchip/irq-rvic.c | 47 +++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-rvic.c b/drivers/irqchip/irq-rvic.c index 6f37aa4318b6..2747a452202f 100644 --- a/drivers/irqchip/irq-rvic.c +++ b/drivers/irqchip/irq-rvic.c @@ -37,6 +37,8 @@ static DEFINE_PER_CPU(unsigned long *, trusted_masked); struct rvic_data { struct fwnode_handle *fwnode; struct irq_domain *domain; + unsigned long *bitmap; + struct mutex lock; unsigned int nr_trusted; unsigned int nr_untrusted; }; @@ -356,9 +358,26 @@ static int rvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, irq_hw_number_t hwirq; int i, ret; - ret = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type); - if (ret) - return ret; + if (fwspec) { + ret = irq_domain_translate_twocell(domain, fwspec, + &hwirq, &type); + if (ret) + return ret; + } else { + /* rVID wants untrusted interrupts */ + mutex_lock(&rvic.lock); + hwirq = bitmap_find_next_zero_area(rvic.bitmap, + rvic.nr_untrusted, + 0, nr_irqs, 0); + if (hwirq < rvic.nr_untrusted) + bitmap_set(rvic.bitmap, hwirq, nr_irqs); + mutex_unlock(&rvic.lock); + + if (hwirq >= rvic.nr_untrusted) + return -ENOSPC; + + hwirq += rvic.nr_trusted; + } for (i = 0; i < nr_irqs; i++) { unsigned int intid = hwirq + i; @@ -376,6 +395,12 @@ static int rvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, domain->host_data, handle_percpu_devid_irq, NULL, NULL); + } else if (intid < (rvic.nr_trusted + rvic.nr_untrusted)) { + irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq))); + irq_domain_set_info(domain, irq, intid, &rvic_chip, + domain->host_data, + handle_fasteoi_irq, + NULL, NULL); } else { return -EINVAL; } @@ -391,6 +416,11 @@ static void rvic_irq_domain_free(struct irq_domain *domain, unsigned int virq, for (i = 0; i < nr_irqs; i++) { struct irq_data *d = irq_domain_get_irq_data(domain, virq + i); + if (d->hwirq >= rvic.nr_trusted) { + mutex_lock(&rvic.lock); + __clear_bit(d->hwirq, rvic.bitmap); + mutex_unlock(&rvic.lock); + } irq_set_handler(virq + i, NULL); irq_domain_reset_irq_data(d); } @@ -523,6 +553,12 @@ static int __init rvic_init(struct device_node *node, return -ENOMEM; } + rvic.bitmap = bitmap_alloc(rvic.nr_untrusted, GFP_KERNEL | __GFP_ZERO); + if (!rvic.bitmap) { + pr_warn("Failed to allocate untrusted bitmap\n"); + goto free_domain; + } + for_each_possible_cpu(cpu) { unsigned long *map = bitmap_alloc(rvic.nr_trusted, GFP_KERNEL); @@ -537,6 +573,8 @@ static int __init rvic_init(struct device_node *node, per_cpu(trusted_masked, cpu) = map; } + mutex_init(&rvic.lock); + rvic_smp_init(rvic.fwnode); set_handle_irq(rvic_handle_irq); @@ -546,6 +584,9 @@ static int __init rvic_init(struct device_node *node, for_each_possible_cpu(cpu) kfree(per_cpu(trusted_masked, cpu)); + kfree(rvic.bitmap); + +free_domain: irq_domain_remove(rvic.domain); return -ENOMEM; From patchwork Thu Sep 3 15:25:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754113 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A2037109B for ; Thu, 3 Sep 2020 15:26:48 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6D05C20775 for ; Thu, 3 Sep 2020 15:26:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="wCP+0vHs"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="U0WuPxRx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6D05C20775 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=LhhTGGQz+1gukRrYuHHeBZgg5wtVxYxOvj5gXudR180=; b=wCP+0vHs5KqgvrB+dLNyIOJO0 2aXwYEUTQ9o3A5vEjGON/l+EdYBn2yarrVpSzcGq2gFamAptgEfRzBU6QNQIaXSC7bYMYOjOfxQcB TWoasTitf6HTJkkJ93kILxO/wzAg9SQq4QzzDNvKIOvqUroFi4BUiOrxTO8Hj91XjsdQ0YUmWapN0 GlURz3fkJAv5KfyrJp12nrwh4cmiEJlQHMEnlXsU19vhTa5QF2iRdJYyVe7aMOyybXeQG1Y7nBbA3 tqwMSiqqAXUXK/V+f9HRxqLQ86rwRaQCshUMOCVYmQroZACkk8E1jcSNBtcmqkVzSKBjpNvlzeEoC eWc37P4EA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8H-0004v1-At; Thu, 03 Sep 2020 15:26:37 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr85-0004r2-2T for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:26 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5C381208CA; Thu, 3 Sep 2020 15:26:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146784; bh=UgL5h2/N4AaKwcBf0Fqm/Wf8W19Iwr6g3G+3eOn1h1g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U0WuPxRxlpht9j/tIBc1SKbf8RKtMZHQw3Az5TvPyVABskke0c/zO1wH1YgL1iJMx zMZKSzDYidYwGi8a1waBkriX5j2NFn2CwqGMlDu/4HAoFoKkTtJ8umKbOTUob3QT1D edzUoeTYFy9aR9nicWWU/dYsCeLy8wGL22vB+Fv8= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr82-008vT9-No; Thu, 03 Sep 2020 16:26:22 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 03/23] irqchip: Add Reduced Virtual Interrupt Distributor support Date: Thu, 3 Sep 2020 16:25:50 +0100 Message-Id: <20200903152610.1078827-4-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112625_261268_E6B979BD X-CRM114-Status: GOOD ( 29.14 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Signed-off-by: Marc Zyngier --- drivers/irqchip/Kconfig | 6 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-rvid.c | 259 +++++++++++++++++++++++++++++++ include/linux/irqchip/irq-rvic.h | 19 +++ 4 files changed, 285 insertions(+) create mode 100644 drivers/irqchip/irq-rvid.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 348ff1d06651..731e8da9ae0c 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -67,6 +67,12 @@ config ARM_RVIC select IRQ_DOMAIN_HIERARCHY select GENERIC_IRQ_EFFECTIVE_AFF_MASK +config ARM_RVID + bool + default ARM64 + select IRQ_DOMAIN_HIERARCHY + select GENERIC_IRQ_EFFECTIVE_AFF_MASK + config ARM_VIC bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index d2b280efd2e0..cbcc23f92d31 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o obj-$(CONFIG_ARM_RVIC) += irq-rvic.o +obj-$(CONFIG_ARM_RVID) += irq-rvid.o obj-$(CONFIG_ARM_VIC) += irq-vic.o obj-$(CONFIG_ARMADA_370_XP_IRQ) += irq-armada-370-xp.o obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o diff --git a/drivers/irqchip/irq-rvid.c b/drivers/irqchip/irq-rvid.c new file mode 100644 index 000000000000..953f654e58d4 --- /dev/null +++ b/drivers/irqchip/irq-rvid.c @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2020 Google LLC. + * Author: Marc Zyngier + */ + +#define pr_fmt(fmt) "rVID: " fmt + +#include +#include +#include +#include +#include +#include + +#include + +struct rvid_data { + struct fwnode_handle *fwnode; + struct irq_domain *domain; +}; + +static struct rvid_data rvid; + +static inline int rvid_version(unsigned long *version) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVID_VERSION, &res); + if (res.a0 == RVID_STATUS_SUCCESS) + *version = res.a1; + return res.a0; +} + +static inline int rvid_map(unsigned long input, + unsigned long target, unsigned long intid) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVID_MAP, input, target, intid, &res); + return res.a0; +} + +static inline int rvid_unmap(unsigned long input) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC64_RVID_UNMAP, input, &res); + return res.a0; +} + +static int rvid_irq_set_affinity(struct irq_data *data, + const struct cpumask *mask_val, + bool force) +{ + unsigned int old_cpu, cpu; + bool masked, pending; + int err = 0, ret; + u64 mpidr; + + if (force) + cpu = cpumask_first(mask_val); + else + cpu = cpumask_any_and(mask_val, cpu_online_mask); + + if (cpu >= nr_cpu_ids) + return -EINVAL; + + mpidr = cpu_logical_map(cpu) & MPIDR_HWID_BITMASK; + old_cpu = cpumask_first(data->common->effective_affinity); + if (cpu == old_cpu) + return 0; + + /* Mask on source */ + masked = irqd_irq_masked(data); + if (!masked) + irq_chip_mask_parent(data); + + /* Switch to target */ + irq_data_update_effective_affinity(data, cpumask_of(cpu)); + + /* Mask on target */ + irq_chip_mask_parent(data); + + /* Map the input signal to the new target */ + ret = rvid_map(data->hwirq, mpidr, data->parent_data->hwirq); + if (ret != RVID_STATUS_SUCCESS) { + err = -ENXIO; + goto unmask; + } + + /* Back to the source */ + irq_data_update_effective_affinity(data, cpumask_of(old_cpu)); + + /* Sample pending state and clear it if necessary */ + err = irq_chip_get_parent_state(data, IRQCHIP_STATE_PENDING, &pending); + if (err) + goto unmask; + if (pending) + irq_chip_set_parent_state(data, IRQCHIP_STATE_PENDING, false); + + /* + * To the target again (for good this time), propagating the + * pending bit if required. + */ + irq_data_update_effective_affinity(data, cpumask_of(cpu)); + if (pending) + irq_chip_set_parent_state(data, IRQCHIP_STATE_PENDING, true); +unmask: + /* Propagate the masking state */ + if (!masked) + irq_chip_unmask_parent(data); + + return err; +} + +static struct irq_chip rvid_chip = { + .name = "rvid", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_get_irqchip_state = irq_chip_get_parent_state, + .irq_set_irqchip_state = irq_chip_set_parent_state, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_type = irq_chip_set_type_parent, + .irq_set_affinity = rvid_irq_set_affinity, +}; + +static int rvid_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + struct irq_fwspec *fwspec = arg; + unsigned int type = IRQ_TYPE_NONE; + irq_hw_number_t hwirq; + int i, ret; + + ret = irq_domain_translate_onecell(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + for (i = 0; i < nr_irqs; i++) { + unsigned int intid = hwirq + i; + unsigned int irq = virq + i; + + /* Get the rVIC to allocate any untrusted intid */ + ret = irq_domain_alloc_irqs_parent(domain, irq, 1, NULL); + if (WARN_ON(ret)) + return ret; + + irq_domain_set_hwirq_and_chip(domain, irq, intid, + &rvid_chip, &rvid); + irqd_set_affinity_on_activate(irq_get_irq_data(irq)); + } + + return 0; +} + +static void rvid_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + int i; + + irq_domain_free_irqs_parent(domain, virq, nr_irqs); + + for (i = 0; i < nr_irqs; i++) { + struct irq_data *d; + + d = irq_domain_get_irq_data(domain, virq + i); + irq_set_handler(virq + i, NULL); + irq_domain_reset_irq_data(d); + } +} + +static int rvid_irq_domain_activate(struct irq_domain *domain, + struct irq_data *data, bool reserve) +{ + unsigned long ret; + int cpu, err = 0; + u64 mpidr; + + cpu = get_cpu(); + mpidr = cpu_logical_map(cpu) & MPIDR_HWID_BITMASK; + + /* Map the input signal */ + ret = rvid_map(data->hwirq, mpidr, data->parent_data->hwirq); + if (ret != RVID_STATUS_SUCCESS) { + err = -ENXIO; + goto out; + } + + irq_data_update_effective_affinity(data, cpumask_of(cpu)); + +out: + put_cpu(); + return err; +} + +static void rvid_irq_domain_deactivate(struct irq_domain *domain, + struct irq_data *data) +{ + rvid_unmap(data->hwirq); +} + +static const struct irq_domain_ops rvid_irq_domain_ops = { + .translate = irq_domain_translate_onecell, + .alloc = rvid_irq_domain_alloc, + .free = rvid_irq_domain_free, + .activate = rvid_irq_domain_activate, + .deactivate = rvid_irq_domain_deactivate, +}; + +static int __init rvid_init(struct device_node *node, + struct device_node *parent) +{ + struct irq_domain *parent_domain; + unsigned long ret, version; + + if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_1) { + pr_err("SMCCC 1.1 required, aborting\n"); + return -EINVAL; + } + + if (!parent) + return -ENXIO; + + parent_domain = irq_find_host(parent); + if (!parent_domain) + return -ENXIO; + + rvid.fwnode = of_node_to_fwnode(node); + + ret = rvid_version(&version); + if (ret != RVID_STATUS_SUCCESS) { + pr_err("error retrieving version (%ld, %ld)\n", + RVID_STATUS_REASON(ret), RVID_STATUS_INDEX(ret)); + return -ENXIO; + } + + if (version < RVID_VERSION(0, 3)) { + pr_err("version (%ld, %ld) too old, expected min. (%d, %d)\n", + RVID_VERSION_MAJOR(version), RVID_VERSION_MINOR(version), + 0, 3); + return -ENXIO; + } + + pr_info("distributing interrupts to %pOF\n", parent); + + rvid.domain = irq_domain_create_hierarchy(parent_domain, 0, 0, + rvid.fwnode, + &rvid_irq_domain_ops, &rvid); + if (!rvid.domain) { + pr_warn("Failed to allocate irq domain\n"); + return -ENOMEM; + } + + return 0; +} + +IRQCHIP_DECLARE(rvic, "arm,rvid", rvid_init); diff --git a/include/linux/irqchip/irq-rvic.h b/include/linux/irqchip/irq-rvic.h index 0176ca7d3c30..4545c1e89741 100644 --- a/include/linux/irqchip/irq-rvic.h +++ b/include/linux/irqchip/irq-rvic.h @@ -74,4 +74,23 @@ #define RVIC_STATUS_DISABLED RVIx_STATUS_DISABLED #define RVIC_STATUS_NO_INTERRUPTS RVIx_STATUS_NO_INTERRUPTS +/* rVID functions */ +#define SMC64_RVID_BASE 0xc5000100 +#define SMC64_RVID_FN(n) (SMC64_RVID_BASE + (n)) + +#define SMC64_RVID_VERSION SMC64_RVID_FN(0) +#define SMC64_RVID_MAP SMC64_RVID_FN(1) +#define SMC64_RVID_UNMAP SMC64_RVID_FN(2) + +#define RVID_VERSION(M, m) RVIx_VERSION((M), (m)) + +#define RVID_VERSION_MAJOR(v) RVIx_VERSION_MAJOR((v)) +#define RVID_VERSION_MINOR(v) RVIx_VERSION_MINOR((v)) + +#define RVID_STATUS_REASON(c) RVIx_STATUS_REASON((c)) +#define RVID_STATUS_INDEX(c) RVIx_STATUS_INDEX((c)) + +#define RVID_STATUS_SUCCESS RVIx_STATUS_SUCCESS +#define RVID_STATUS_ERROR_PARAMETER RVIx_STATUS_ERROR_PARAMETER + #endif /* __IRQCHIP_IRQ_RVIC_H__ */ From patchwork Thu Sep 3 15:25:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754143 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 86428109B for ; Thu, 3 Sep 2020 15:28:20 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5CE612072A for ; Thu, 3 Sep 2020 15:28:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="2mH4r/FH"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="Uciye53R" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5CE612072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=2mr6rzdOKhTyYAD5wj7ayc0qBZA8MQ+S/eshPgRzzLg=; b=2mH4r/FHn+hd9w9JJ+DamVOfi ly48SziLRKds1TCnKlwEPTr5xsmU1w49lKUD5oMtj6ZWb3RYzy5vs44ArsQ2ZM2KN6KZDHmNfO6CG zOjZkFgPpG9FOJSFIRiO5JRA/UVeth86Yq9r+24fV0e7+h/zwJ2HAz2HZeRXwYXia+qOn0ZXtHwtc qZjTUiCD+edSqQq/6ZDpve9xqO8luqO8WyQG6mmKL6k8blWGFr4JiuZBG20Inv+9hfNIIFCte11w2 jqCLc8rszCArEnFnoq95tGyX2ShahgArifjGSntZTD/zuk9V3A+pvkKQcQ3vIekO88tbM1apWAJ21 XzZFLIOBg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8K-0004w2-Ij; Thu, 03 Sep 2020 15:26:40 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr85-0004rN-Ou for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:27 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 08531208FE; Thu, 3 Sep 2020 15:26:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146785; bh=ceS8NE2MW+txLmS/EWVjLDcRc/17UR1qG/NRs/CDH60=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Uciye53Rz0ao2HSHPhxALTU36xXXtoFDxua7X+zyhfs/RLATZ3OTrvBbYzluD8Xju 5AgwZnGRMb/e6YEhsXXUEJz0p9qszaM0xCSa1pJ4vd7CpFj8YOX4RdpeKMDQEW1ABr 4m4oHkunthOYOMD+zIBB+hit4TKacp6SLIUOGPus= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr83-008vT9-BF; Thu, 03 Sep 2020 16:26:23 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 04/23] irqchip/rvid: Add PCI MSI support Date: Thu, 3 Sep 2020 16:25:51 +0100 Message-Id: <20200903152610.1078827-5-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112625_971966_F81E721C X-CRM114-Status: GOOD ( 27.51 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Signed-off-by: Marc Zyngier --- drivers/irqchip/irq-rvid.c | 182 +++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/drivers/irqchip/irq-rvid.c b/drivers/irqchip/irq-rvid.c index 953f654e58d4..250f95ad1a09 100644 --- a/drivers/irqchip/irq-rvid.c +++ b/drivers/irqchip/irq-rvid.c @@ -12,12 +12,19 @@ #include #include #include +#include #include struct rvid_data { struct fwnode_handle *fwnode; struct irq_domain *domain; + struct irq_domain *msi_domain; + struct irq_domain *pci_domain; + unsigned long *msi_map; + struct mutex msi_lock; + u32 msi_base; + u32 msi_nr; }; static struct rvid_data rvid; @@ -209,6 +216,177 @@ static const struct irq_domain_ops rvid_irq_domain_ops = { .deactivate = rvid_irq_domain_deactivate, }; +#ifdef CONFIG_PCI_MSI +/* + * The MSI irqchip is completely transparent. The only purpose of the + * corresponding irq domain is to provide the MSI allocator, and feed + * the allocated inputs to the main rVID irq domain for mapping at the + * rVIC level. + */ +static struct irq_chip rvid_msi_chip = { + .name = "rvid-MSI", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_get_irqchip_state = irq_chip_get_parent_state, + .irq_set_irqchip_state = irq_chip_set_parent_state, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_type = irq_chip_set_type_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, +}; + +static int rvid_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + int ret, hwirq, i; + + mutex_lock(&rvid.msi_lock); + hwirq = bitmap_find_free_region(rvid.msi_map, rvid.msi_nr, + get_count_order(nr_irqs)); + mutex_unlock(&rvid.msi_lock); + + if (hwirq < 0) + return -ENOSPC; + + for (i = 0; i < nr_irqs; i++) { + /* Use the rVID domain to map the input to something */ + struct irq_fwspec fwspec = (struct irq_fwspec) { + .fwnode = domain->parent->fwnode, + .param_count = 1, + .param[0] = rvid.msi_base + hwirq + i, + }; + + ret = irq_domain_alloc_irqs_parent(domain, virq + i, 1, &fwspec); + if (WARN_ON(ret)) + goto out; + + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &rvid_msi_chip, &rvid); + } + + return 0; + +out: + mutex_lock(&rvid.msi_lock); + bitmap_release_region(rvid.msi_map, hwirq, get_count_order(nr_irqs)); + mutex_unlock(&rvid.msi_lock); + + return ret; +} + +static void rvid_msi_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + irq_hw_number_t hwirq = d->hwirq; + + /* This is a bit cheeky, but hey, recursion never hurt anyone... */ + rvid_irq_domain_free(domain, virq, nr_irqs); + + mutex_lock(&rvid.msi_lock); + bitmap_release_region(rvid.msi_map, hwirq, get_count_order(nr_irqs)); + mutex_unlock(&rvid.msi_lock); +} + +static struct irq_domain_ops rvid_msi_domain_ops = { + .alloc = rvid_msi_domain_alloc, + .free = rvid_msi_domain_free, +}; + +/* + * The PCI irq chip only provides the minimal stuff, as most of the + * other methods will be provided as defaults. + */ +static void rvid_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) +{ + /* Random address, the rVID doesn't really have a doorbell */ + msg->address_hi = 0; + msg->address_lo = 0xba5e0000; + + /* + * We are called from the PCI domain, and what we program in + * the device is the rVID input pin, which is located two + * levels down in the interrupt chain (PCI -> MSI -> rVID). + */ + msg->data = data->parent_data->parent_data->hwirq; +} + +static void rvid_pci_mask(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void rvid_pci_unmask(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip rvid_pci_chip = { + .name = "PCI-MSI", + .irq_mask = rvid_pci_mask, + .irq_unmask = rvid_pci_unmask, + .irq_eoi = irq_chip_eoi_parent, + .irq_compose_msi_msg = rvid_compose_msi_msg, + .irq_write_msi_msg = pci_msi_domain_write_msg, +}; + +static struct msi_domain_info rvid_pci_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), + .chip = &rvid_pci_chip, +}; + +static void __init rvid_msi_setup(struct device_node *np) +{ + if (!of_property_read_bool(np, "msi-controller")) + return; + + if (of_property_read_u32_index(np, "msi-range", 0, &rvid.msi_base) || + of_property_read_u32_index(np, "msi-range", 1, &rvid.msi_nr)) { + pr_err("Invalid or missing msi-range\n"); + return; + } + + mutex_init(&rvid.msi_lock); + + rvid.msi_map = bitmap_alloc(rvid.msi_nr, GFP_KERNEL | __GFP_ZERO); + if (!rvid.msi_map) + return; + + rvid.msi_domain = irq_domain_create_hierarchy(rvid.domain, 0, 0, + rvid.fwnode, + &rvid_msi_domain_ops, + &rvid); + if (!rvid.msi_domain) { + pr_err("Failed to allocate MSI domain\n"); + goto out; + } + + irq_domain_update_bus_token(rvid.msi_domain, DOMAIN_BUS_NEXUS); + + rvid.pci_domain = pci_msi_create_irq_domain(rvid.domain->fwnode, + &rvid_pci_domain_info, + rvid.msi_domain); + if (!rvid.pci_domain) { + pr_err("Failed to allocate PCI domain\n"); + goto out; + } + + pr_info("MSIs available as inputs [%d:%d]\n", + rvid.msi_base, rvid.msi_base + rvid.msi_nr - 1); + return; + +out: + if (rvid.msi_domain) + irq_domain_remove(rvid.msi_domain); + kfree(rvid.msi_map); +} +#else +static inline void rvid_msi_setup(struct device_node *np) {} +#endif + static int __init rvid_init(struct device_node *node, struct device_node *parent) { @@ -253,6 +431,10 @@ static int __init rvid_init(struct device_node *node, return -ENOMEM; } + irq_domain_update_bus_token(rvid.domain, DOMAIN_BUS_WIRED); + + rvid_msi_setup(node); + return 0; } From patchwork Thu Sep 3 15:25:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754127 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6544C109B for ; Thu, 3 Sep 2020 15:27:06 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2D0892072A for ; Thu, 3 Sep 2020 15:27:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="E+oRjTKt"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="MqFoI44a" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2D0892072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=WQlFdu8erZPC/8Db8JY9bAhMHGkaI30pvmnhBGKzWno=; b=E+oRjTKtvig7p6HOrLyUNXt+K CyZYyRngxivhZZ2RGGWmPyN5fFNQ30ysPqqf116re9+01hg5a26Fyz2ElRFRqq3nqbKtuJfqAeAC5 ZntugVvc1vK54MbWEFhmkO5wqJ3OZOXuAkR3sDJf1H6VgEswwnBiTdc99GaeEAksy1EjTPjhUWteJ 3jghJ7o/8e72/gBd0Bsg+VC/XhW5YcsGg5mCOoMk9yRkI9e/easRkScW6TRGKd+mB73ZkNhY16Jsw HZr1s2AhDPEBq1JZ4UJi+ZrcOcNJFwMKPeFP+DXGShgE7P1cCMjnMgLyRBoIQwJTbKIE36UPUNJPs s2NeWINaw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8U-0004zG-E7; Thu, 03 Sep 2020 15:26:50 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr86-0004rn-FI for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:30 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 9244A2098B; Thu, 3 Sep 2020 15:26:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146785; bh=8hk5dvN5QgbcKtLB/YnBZWm60piZDPywsqMa1ZLHOg0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MqFoI44aTtBOiDxlcpxaLQXprmwYvbATSASgLh2UE49UK8P1sK6oC1JwdaC0GpNzh SZ8iX1gmrohGGUzuIE31eXpjhV2vc6cElJBp1je2JUSs+/X0rB+j7kSEWzBxtsPSHu BZ+8zxaVUd2w98dcmhOTrIRSjMesuWWn/uk/PGzI= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr84-008vT9-08; Thu, 03 Sep 2020 16:26:24 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 05/23] KVM: arm64: Move GIC model out of the distributor Date: Thu, 3 Sep 2020 16:25:52 +0100 Message-Id: <20200903152610.1078827-6-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112626_810673_17FAEA87 X-CRM114-Status: GOOD ( 31.54 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org In order to allow more than just GIC implementations in the future, let's move the GIC model outside of the distributor. This also allows us to back irqchip_in_kernel() with its own irqchip type (IRQCHIP_USER), removing another field from the distributor. New helpers are provided as a convenience. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/include/asm/kvm_irq.h | 20 ++++++++++++++++++++ arch/arm64/kvm/vgic/vgic-debug.c | 5 +++-- arch/arm64/kvm/vgic/vgic-init.c | 26 ++++++++++++-------------- arch/arm64/kvm/vgic/vgic-kvm-device.c | 16 ++++++++++++---- arch/arm64/kvm/vgic/vgic-mmio-v3.c | 2 +- arch/arm64/kvm/vgic/vgic-mmio.c | 10 ++++------ arch/arm64/kvm/vgic/vgic-v3.c | 20 ++++++++------------ include/kvm/arm_vgic.h | 5 ----- 9 files changed, 62 insertions(+), 44 deletions(-) create mode 100644 arch/arm64/include/asm/kvm_irq.h diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e52c927aade5..f0e30e12b523 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #define __KVM_HAVE_ARCH_INTC_INITIALIZED @@ -98,6 +99,7 @@ struct kvm_arch { int max_vcpus; /* Interrupt controller */ + enum kvm_irqchip_type irqchip_type; struct vgic_dist vgic; /* Mandated version of PSCI */ diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h new file mode 100644 index 000000000000..46bffb6026f8 --- /dev/null +++ b/arch/arm64/include/asm/kvm_irq.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - Google LLC + * Author: Marc Zyngier + */ + +#ifndef __ARM64_KVM_IRQ_H__ +#define __ARM64_KVM_IRQ_H__ + +enum kvm_irqchip_type { + IRQCHIP_USER, /* Implemented in userspace */ + IRQCHIP_GICv2, /* v2 on v2, or v2 on v3 */ + IRQCHIP_GICv3, /* v3 on v3 */ +}; + +#define irqchip_in_kernel(k) ((k)->arch.irqchip_type != IRQCHIP_USER) +#define irqchip_is_gic_v2(k) ((k)->arch.irqchip_type == IRQCHIP_GICv2) +#define irqchip_is_gic_v3(k) ((k)->arch.irqchip_type == IRQCHIP_GICv3) + +#endif diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c index b13a9e3f99dd..2d19fd55fc7b 100644 --- a/arch/arm64/kvm/vgic/vgic-debug.c +++ b/arch/arm64/kvm/vgic/vgic-debug.c @@ -61,7 +61,7 @@ static void iter_init(struct kvm *kvm, struct vgic_state_iter *iter, iter->nr_cpus = nr_cpus; iter->nr_spis = kvm->arch.vgic.nr_spis; - if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { + if (irqchip_is_gic_v3(kvm)) { iter->nr_lpis = vgic_copy_lpi_list(kvm, NULL, &iter->lpi_array); if (iter->nr_lpis < 0) iter->nr_lpis = 0; @@ -142,7 +142,8 @@ static void vgic_debug_stop(struct seq_file *s, void *v) static void print_dist_state(struct seq_file *s, struct vgic_dist *dist) { - bool v3 = dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3; + struct kvm *kvm = container_of(dist, struct kvm, arch.vgic); + bool v3 = irqchip_is_gic_v3(kvm); seq_printf(s, "Distributor\n"); seq_printf(s, "===========\n"); diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 32e32d67a127..8157171b8af3 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -106,8 +106,8 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) goto out_unlock; } - kvm->arch.vgic.in_kernel = true; - kvm->arch.vgic.vgic_model = type; + kvm->arch.irqchip_type = (type == KVM_DEV_TYPE_ARM_VGIC_V2 ? + IRQCHIP_GICv2 : IRQCHIP_GICv3); kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; @@ -155,12 +155,12 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis) irq->vcpu = NULL; irq->target_vcpu = vcpu0; kref_init(&irq->refcount); - switch (dist->vgic_model) { - case KVM_DEV_TYPE_ARM_VGIC_V2: + switch (kvm->arch.irqchip_type) { + case IRQCHIP_GICv2: irq->targets = 0; irq->group = 0; break; - case KVM_DEV_TYPE_ARM_VGIC_V3: + case IRQCHIP_GICv3: irq->mpidr = 0; irq->group = 1; break; @@ -185,7 +185,6 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis) int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - struct vgic_dist *dist = &vcpu->kvm->arch.vgic; int ret = 0; int i; @@ -225,7 +224,7 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) * If we are creating a VCPU with a GICv3 we must also register the * KVM io device for the redistributor that belongs to this VCPU. */ - if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { + if (irqchip_is_gic_v3(vcpu->kvm)) { mutex_lock(&vcpu->kvm->lock); ret = vgic_register_redist_iodev(vcpu); mutex_unlock(&vcpu->kvm->lock); @@ -278,12 +277,12 @@ int vgic_init(struct kvm *kvm) for (i = 0; i < VGIC_NR_PRIVATE_IRQS; i++) { struct vgic_irq *irq = &vgic_cpu->private_irqs[i]; - switch (dist->vgic_model) { - case KVM_DEV_TYPE_ARM_VGIC_V3: + switch (kvm->arch.irqchip_type) { + case IRQCHIP_GICv3: irq->group = 1; irq->mpidr = kvm_vcpu_get_mpidr_aff(vcpu); break; - case KVM_DEV_TYPE_ARM_VGIC_V2: + case IRQCHIP_GICv2: irq->group = 0; irq->targets = 1U << idx; break; @@ -336,7 +335,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm) dist->spis = NULL; dist->nr_spis = 0; - if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { + if (irqchip_is_gic_v3(kvm)) { list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list) { list_del(&rdreg->list); kfree(rdreg); @@ -402,7 +401,7 @@ int vgic_lazy_init(struct kvm *kvm) * be explicitly initialized once setup with the respective * KVM device call. */ - if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2) + if (!irqchip_is_gic_v2(kvm)) return -EBUSY; mutex_lock(&kvm->lock); @@ -425,14 +424,13 @@ int vgic_lazy_init(struct kvm *kvm) */ int kvm_vgic_map_resources(struct kvm *kvm) { - struct vgic_dist *dist = &kvm->arch.vgic; int ret = 0; mutex_lock(&kvm->lock); if (!irqchip_in_kernel(kvm)) goto out; - if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2) + if (irqchip_is_gic_v2(kvm)) ret = vgic_v2_map_resources(kvm); else ret = vgic_v3_map_resources(kvm); diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c index 44419679f91a..928afb224540 100644 --- a/arch/arm64/kvm/vgic/vgic-kvm-device.c +++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c @@ -31,10 +31,18 @@ int vgic_check_ioaddr(struct kvm *kvm, phys_addr_t *ioaddr, static int vgic_check_type(struct kvm *kvm, int type_needed) { - if (kvm->arch.vgic.vgic_model != type_needed) - return -ENODEV; - else - return 0; + switch (type_needed) { + case KVM_DEV_TYPE_ARM_VGIC_V2: + if (irqchip_is_gic_v2(kvm)) + return 0; + break; + case KVM_DEV_TYPE_ARM_VGIC_V3: + if (irqchip_is_gic_v3(kvm)) + return 0; + break; + } + + return -ENODEV; } /** diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c index 5c786b915cd3..6234e1409b4d 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -42,7 +42,7 @@ bool vgic_has_its(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; - if (dist->vgic_model != KVM_DEV_TYPE_ARM_VGIC_V3) + if (!irqchip_is_gic_v3(kvm)) return false; return dist->has_its; diff --git a/arch/arm64/kvm/vgic/vgic-mmio.c b/arch/arm64/kvm/vgic/vgic-mmio.c index b2d73fc0d1ef..865f12030ab5 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio.c +++ b/arch/arm64/kvm/vgic/vgic-mmio.c @@ -263,8 +263,7 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq) { - return (vgic_irq_is_sgi(irq->intid) && - vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2); + return (vgic_irq_is_sgi(irq->intid) && irqchip_is_gic_v2(vcpu->kvm)); } void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, @@ -450,7 +449,7 @@ int vgic_uaccess_write_cpending(struct kvm_vcpu *vcpu, */ static void vgic_access_active_prepare(struct kvm_vcpu *vcpu, u32 intid) { - if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 || + if (irqchip_is_gic_v3(vcpu->kvm) || intid >= VGIC_NR_PRIVATE_IRQS) kvm_arm_halt_guest(vcpu->kvm); } @@ -458,7 +457,7 @@ static void vgic_access_active_prepare(struct kvm_vcpu *vcpu, u32 intid) /* See vgic_access_active_prepare */ static void vgic_access_active_finish(struct kvm_vcpu *vcpu, u32 intid) { - if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 || + if (irqchip_is_gic_v3(vcpu->kvm) || intid >= VGIC_NR_PRIVATE_IRQS) kvm_arm_resume_guest(vcpu->kvm); } @@ -539,7 +538,6 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq, */ irq->active = false; } else { - u32 model = vcpu->kvm->arch.vgic.vgic_model; u8 active_source; irq->active = active; @@ -557,7 +555,7 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq, */ active_source = (requester_vcpu) ? requester_vcpu->vcpu_id : 0; - if (model == KVM_DEV_TYPE_ARM_VGIC_V2 && + if (irqchip_is_gic_v2(vcpu->kvm) && active && vgic_irq_is_sgi(irq->intid)) irq->active_source = active_source; } diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 76e2d85789ed..c6fdb1222453 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -32,7 +32,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; struct vgic_v3_cpu_if *cpuif = &vgic_cpu->vgic_v3; - u32 model = vcpu->kvm->arch.vgic.vgic_model; + bool is_v3 = irqchip_is_gic_v3(vcpu->kvm); int lr; DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); @@ -48,7 +48,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) cpuid = val & GICH_LR_PHYSID_CPUID; cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; - if (model == KVM_DEV_TYPE_ARM_VGIC_V3) { + if (is_v3) { intid = val & ICH_LR_VIRTUAL_ID_MASK; } else { intid = val & GICH_LR_VIRTUALID; @@ -117,12 +117,11 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) /* Requires the irq to be locked already */ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) { - u32 model = vcpu->kvm->arch.vgic.vgic_model; + bool is_v2 = irqchip_is_gic_v2(vcpu->kvm); u64 val = irq->intid; bool allow_pending = true, is_v2_sgi; - is_v2_sgi = (vgic_irq_is_sgi(irq->intid) && - model == KVM_DEV_TYPE_ARM_VGIC_V2); + is_v2_sgi = (vgic_irq_is_sgi(irq->intid) && is_v2); if (irq->active) { val |= ICH_LR_ACTIVE_BIT; @@ -163,8 +162,7 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) if (irq->config == VGIC_CONFIG_EDGE) irq->pending_latch = false; - if (vgic_irq_is_sgi(irq->intid) && - model == KVM_DEV_TYPE_ARM_VGIC_V2) { + if (vgic_irq_is_sgi(irq->intid) && is_v2) { u32 src = ffs(irq->source); if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n", @@ -205,10 +203,9 @@ void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr) void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) { struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; - u32 model = vcpu->kvm->arch.vgic.vgic_model; u32 vmcr; - if (model == KVM_DEV_TYPE_ARM_VGIC_V2) { + if (irqchip_is_gic_v2(vcpu->kvm)) { vmcr = (vmcrp->ackctl << ICH_VMCR_ACK_CTL_SHIFT) & ICH_VMCR_ACK_CTL_MASK; vmcr |= (vmcrp->fiqen << ICH_VMCR_FIQ_EN_SHIFT) & @@ -235,12 +232,11 @@ void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) { struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; - u32 model = vcpu->kvm->arch.vgic.vgic_model; u32 vmcr; vmcr = cpu_if->vgic_vmcr; - if (model == KVM_DEV_TYPE_ARM_VGIC_V2) { + if (irqchip_is_gic_v2(vcpu->kvm)) { vmcrp->ackctl = (vmcr & ICH_VMCR_ACK_CTL_MASK) >> ICH_VMCR_ACK_CTL_SHIFT; vmcrp->fiqen = (vmcr & ICH_VMCR_FIQ_EN_MASK) >> @@ -285,7 +281,7 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu) * Also, we don't support any form of IRQ/FIQ bypass. * This goes with the spec allowing the value to be RAO/WI. */ - if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { + if (irqchip_is_gic_v3(vcpu->kvm)) { vgic_v3->vgic_sre = (ICC_SRE_EL1_DIB | ICC_SRE_EL1_DFB | ICC_SRE_EL1_SRE); diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index a8d8fdcd3723..88461ecfa854 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -201,13 +201,9 @@ struct vgic_redist_region { }; struct vgic_dist { - bool in_kernel; bool ready; bool initialized; - /* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */ - u32 vgic_model; - /* Implementation revision as reported in the GICD_IIDR */ u32 implementation_rev; @@ -361,7 +357,6 @@ void kvm_vgic_load(struct kvm_vcpu *vcpu); void kvm_vgic_put(struct kvm_vcpu *vcpu); void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu); -#define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) #define vgic_initialized(k) ((k)->arch.vgic.initialized) #define vgic_ready(k) ((k)->arch.vgic.ready) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ From patchwork Thu Sep 3 15:25:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754121 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 156921575 for ; Thu, 3 Sep 2020 15:26:55 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DE3F220775 for ; Thu, 3 Sep 2020 15:26:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="K5GhER8b"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="x1flBPDm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DE3F220775 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=eDoog3KGTfHn/6K+cDLGGARpVQXyh6v0riUJH/ojb3w=; b=K5GhER8bVEgp0g78VX2IINdkX mOBTXKFS1IBVBPB3F4tP3w3qKXZVac21DDLY2b/tT6BzomncIZo0fiGpQSH+gY1EaPBtTTiuQ8nWT Fsdl2PSwxaFfbKQkpNxC+BcSCVCxHIGJUcXz3h6NHih0+7D8NZjiv03E9zzGY5pyv2+bfVpl0oG5Z FHGAcAwwotpYEXHRgyTdI4pD3/P1nQT5OEe9QRHapuUbX+duyg00Ym8U7fGRcMdVaBqifSwCPzdl1 Je74OPAr/RKN/8vWpSVoZpMwkAtD/pLS+JFTodv7x5hzTfhgD/2CWjJIEk8vv/IdkS1gQHPxTvuzt x0PRQmfQg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8M-0004wf-Tz; Thu, 03 Sep 2020 15:26:42 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr86-0004rq-SS for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:29 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 25E812072A; Thu, 3 Sep 2020 15:26:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146786; bh=3GwlQXC6rqZcwdvQL6Cznwbl4GbO5TFs/sVjhxfanos=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=x1flBPDmW/jxJ/a4aG/VS9HEuAHUbSaI98O7DHosNPJSduZGjAkVACXZsE3x4pVem thRA+UwWc7qwVMST6SFp7v17mSTEACsD8RiO/ZNDFec1puJCkXIdKvvUtz969N4c9T jPRi4h9Xtyj189+gysNGXqCjh9dcwq5yg4SfT7mE= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr84-008vT9-Il; Thu, 03 Sep 2020 16:26:24 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 06/23] KVM: arm64: vgic-v3: Move early init to kvm_vgic_create() Date: Thu, 3 Sep 2020 16:25:53 +0100 Message-Id: <20200903152610.1078827-7-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112627_167054_B15D7C37 X-CRM114-Status: GOOD ( 16.70 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The current early init for the GIC is pretty silly. The data it initializes only matters for GICv3, which is guaranteed to be created via a kvm_create_device call. Given that, it is pointless to initialize the data early, before userspace can get a file descriptor and mess with it. Move everything to kvm_vgic_create(). Signed-off-by: Marc Zyngier --- arch/arm64/kvm/arm.c | 2 -- arch/arm64/kvm/vgic/vgic-init.c | 24 +++++------------------- include/kvm/arm_vgic.h | 1 - 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 46dc3d75cf13..41f98564f507 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -120,8 +120,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (ret) goto out_free_stage2_pgd; - kvm_vgic_early_init(kvm); - /* The maximum number of VCPUs is limited by the host's GIC model */ kvm->arch.max_vcpus = kvm_arm_default_max_vcpus(); diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 8157171b8af3..76cce0db63a7 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -39,25 +39,6 @@ * allocation is allowed there. */ -/* EARLY INIT */ - -/** - * kvm_vgic_early_init() - Initialize static VGIC VCPU data structures - * @kvm: The VM whose VGIC districutor should be initialized - * - * Only do initialization of static structures that don't require any - * allocation or sizing information from userspace. vgic_init() called - * kvm_vgic_dist_init() which takes care of the rest. - */ -void kvm_vgic_early_init(struct kvm *kvm) -{ - struct vgic_dist *dist = &kvm->arch.vgic; - - INIT_LIST_HEAD(&dist->lpi_list_head); - INIT_LIST_HEAD(&dist->lpi_translation_cache); - raw_spin_lock_init(&dist->lpi_list_lock); -} - /* CREATION */ /** @@ -72,6 +53,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) { int i, ret; struct kvm_vcpu *vcpu; + struct vgic_dist *dist = &kvm->arch.vgic; if (irqchip_in_kernel(kvm)) return -EEXIST; @@ -116,6 +98,10 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) else INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions); + INIT_LIST_HEAD(&dist->lpi_list_head); + INIT_LIST_HEAD(&dist->lpi_translation_cache); + raw_spin_lock_init(&dist->lpi_list_lock); + out_unlock: unlock_all_vcpus(kvm); return ret; diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 88461ecfa854..8d30fc645148 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -335,7 +335,6 @@ extern struct static_key_false vgic_v2_cpuif_trap; extern struct static_key_false vgic_v3_cpuif_trap; int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); -void kvm_vgic_early_init(struct kvm *kvm); int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); int kvm_vgic_create(struct kvm *kvm, u32 type); void kvm_vgic_destroy(struct kvm *kvm); From patchwork Thu Sep 3 15:25:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754141 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 39B301575 for ; Thu, 3 Sep 2020 15:28:16 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0F97F2072A for ; Thu, 3 Sep 2020 15:28:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="EEA/7hY4"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="PppcZONE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0F97F2072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=gz85qI6UfSNN0C6SwQDyNkcMA1SfAbzoB1PjwXHCe9U=; b=EEA/7hY4Kzo+C0AI6U7Zh4ovM H2DYPF+bJI+pxv2CovY7EDRttw4fLLSfu3L98Y8fl4y4uet8bqz2kChFqKru5VmelABQnK0FnKZjh /ftbd7xPj6wUgBlfuOIrntb9l8W2tg1rY8Dkfi9/x0CldEOIpWrASD06OYVbkStVwwmla9vEOdwdQ 8ocq4oiiaA9/SMjHDDN1gB9vozXbYCJMxMtu2Aasdzhmdc9FNuz/DiCTtn2P5jdBCxztTKdAwsb3p Ql/DXIp+A160EN7N4A95ww/jiX2m1A0YE/XZMmLbRIgFELWpf8/XYrD6L6r1LzC/XddqSuTWXVB1I R7akCaS1w==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8P-0004xY-3n; Thu, 03 Sep 2020 15:26:45 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr87-0004sB-Fn for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:29 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C39A1208C7; Thu, 3 Sep 2020 15:26:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146786; bh=wXj+MzUSlzqCPZ4DfFe3HKrFKIE2+Uir+iEwtYqABWk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PppcZONE5Vx7PAKAOs9M++PS6byf3UAu4kuczVkm12sfMttWmEF+WwI3AURD2PDw3 Vh1Pt1Znsfd/EAoq4n48JW9t5fdLqlHN6gDgbwZ/0Pi8cnrbcYEIkj8GzrdfDDnriD fdKznP5LBg07MzxTX5aqX7jAuNgOP0AKnVLj1KIg= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr85-008vT9-67; Thu, 03 Sep 2020 16:26:25 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 07/23] KVM: arm64: Add irqchip callback structure to kvm_arch Date: Thu, 3 Sep 2020 16:25:54 +0100 Message-Id: <20200903152610.1078827-8-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112627_695408_87B0BF5D X-CRM114-Status: GOOD ( 18.94 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org As we are about to abstract part of the vgic implementation in order to make it more modular, let's start by adding a data structure that will eventually contain interrupt controller specific callbacks, as well as helpers to call them (or gracefully skip them if they aren't implemented. It is empty so far, so no functional changes are anticipated. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/include/asm/kvm_irq.h | 29 +++++++++++++++++++++++++++++ arch/arm64/kvm/vgic/vgic-init.c | 5 +++++ 3 files changed, 35 insertions(+) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index f0e30e12b523..52b502f3076f 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -100,6 +100,7 @@ struct kvm_arch { /* Interrupt controller */ enum kvm_irqchip_type irqchip_type; + struct kvm_irqchip_flow irqchip_flow; struct vgic_dist vgic; /* Mandated version of PSCI */ diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 46bffb6026f8..7a70bb803560 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -17,4 +17,33 @@ enum kvm_irqchip_type { #define irqchip_is_gic_v2(k) ((k)->arch.irqchip_type == IRQCHIP_GICv2) #define irqchip_is_gic_v3(k) ((k)->arch.irqchip_type == IRQCHIP_GICv3) +struct kvm_irqchip_flow { +}; + +/* + * Macro galore. At the point this is included, the various types are + * not defined yet. Yes, this is terminally ugly. + */ +#define __kvm_irqchip_action(k, x, ...) \ + do { \ + if (likely((k)->arch.irqchip_flow.irqchip_##x)) \ + (k)->arch.irqchip_flow.irqchip_##x(__VA_ARGS__); \ + } while (0) + +#define __kvm_irqchip_action_ret(k, x, ...) \ + ({ \ + typeof ((k)->arch.irqchip_flow.irqchip_##x(__VA_ARGS__)) ret; \ + ret = (likely((k)->arch.irqchip_flow.irqchip_##x) ? \ + (k)->arch.irqchip_flow.irqchip_##x(__VA_ARGS__) : \ + 0); \ + \ + ret; \ + }) + +#define __vcpu_irqchip_action(v, ...) \ + __kvm_irqchip_action((v)->kvm, __VA_ARGS__) + +#define __vcpu_irqchip_action_ret(v, ...) \ + __kvm_irqchip_action_ret((v)->kvm, __VA_ARGS__) + #endif diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 76cce0db63a7..6b8f0518c074 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -12,6 +12,9 @@ #include #include "vgic.h" +static struct kvm_irqchip_flow vgic_irqchip_flow = { +}; + /* * Initialization rules: there are multiple stages to the vgic * initialization, both for the distributor and the CPU interfaces. The basic @@ -98,6 +101,8 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) else INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions); + kvm->arch.irqchip_flow = vgic_irqchip_flow; + INIT_LIST_HEAD(&dist->lpi_list_head); INIT_LIST_HEAD(&dist->lpi_translation_cache); raw_spin_lock_init(&dist->lpi_list_lock); From patchwork Thu Sep 3 15:25:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754145 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 39066109B for ; Thu, 3 Sep 2020 15:28:27 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0F37F2072A for ; Thu, 3 Sep 2020 15:28:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="dppIrFyN"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="i8RlzDHl" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0F37F2072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=WZMR2IR8xDF8gOS3QdSzKYf/H+vmCY6gNeuM/k9SCvE=; b=dppIrFyNP7Evfz6jvH7m1mSja v9K1n/GcCx43ISHLAGWQIwZZ03CYj2xRF5f2R6nkcro9qIBrGZP8IlMkMhDUAOPE3rMeN9UvBliUv sPllMY7a4u3+K/u5BFUYPsTS75ohFdw/cojm3uguk3/67Dqv5TPmUaMECRDc18UIC7LHRQG4mWmum WvFoBxkArpyUqEdxlaFjCW+dfHM30d7SzeuzhfSKA1a/IU2ZhZPzH0oX+gnQCb4BW6+A2gQAgfhwJ cYDxNgEfDf0jkrzaDSL97+EFaYPxNE1WPtUYApYvqCrSZgBSHjneXpQG3L1EjHdQ4OfxIq+NFHaiE BauNoCvyg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8a-00052z-1R; Thu, 03 Sep 2020 15:26:56 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr88-0004sh-5B for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:30 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 70AD420BED; Thu, 3 Sep 2020 15:26:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146787; bh=lgvTIsBwIP9Y/PcN/yqslqFkcX9YiCZ8blsuaMOPDkc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i8RlzDHlKY+D5mo66/XjpZhjegAirCBEbltXSFY7q09KIP73f/eVVTF/+d6GXF7k5 eDwoBUVS13yui6Ckq1GknNgOl1viwaPwbHiAV4XAwItt/Q+CPhTpjUAbVXZVql9cUB IU8J9yvDyDsLNeouqZlgn0M3anr9xt17Hp/phbuA= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr85-008vT9-RB; Thu, 03 Sep 2020 16:26:25 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 08/23] KVM: arm64: Move kvm_vgic_destroy to kvm_irqchip_flow Date: Thu, 3 Sep 2020 16:25:55 +0100 Message-Id: <20200903152610.1078827-9-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112628_370461_000ED55C X-CRM114-Status: GOOD ( 18.13 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Let's start the VGIC split by moving the act of destroying it, as it is simple and doesn't require much effort. Whilst we're at it, make kvm_vgic_vcpu_destroy() static, as it isn't called from anywhere else. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 4 ++++ arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/vgic/vgic-init.c | 7 +++++-- include/kvm/arm_vgic.h | 2 -- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 7a70bb803560..f83594257bc4 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -18,6 +18,7 @@ enum kvm_irqchip_type { #define irqchip_is_gic_v3(k) ((k)->arch.irqchip_type == IRQCHIP_GICv3) struct kvm_irqchip_flow { + void (*irqchip_destroy)(struct kvm *); }; /* @@ -46,4 +47,7 @@ struct kvm_irqchip_flow { #define __vcpu_irqchip_action_ret(v, ...) \ __kvm_irqchip_action_ret((v)->kvm, __VA_ARGS__) +#define kvm_irqchip_destroy(k) \ + __kvm_irqchip_action((k), destroy, (k)) + #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 41f98564f507..09b4bcb2c805 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -143,7 +143,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) { int i; - kvm_vgic_destroy(kvm); + kvm_irqchip_destroy(kvm); for (i = 0; i < KVM_MAX_VCPUS; ++i) { if (kvm->vcpus[i]) { diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 6b8f0518c074..4e2c23a7dab1 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -12,7 +12,10 @@ #include #include "vgic.h" +static void kvm_vgic_destroy(struct kvm *kvm); + static struct kvm_irqchip_flow vgic_irqchip_flow = { + .irqchip_destroy = kvm_vgic_destroy, }; /* @@ -341,7 +344,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm) vgic_v4_teardown(kvm); } -void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) +static void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; @@ -368,7 +371,7 @@ static void __kvm_vgic_destroy(struct kvm *kvm) kvm_vgic_dist_destroy(kvm); } -void kvm_vgic_destroy(struct kvm *kvm) +static void kvm_vgic_destroy(struct kvm *kvm) { mutex_lock(&kvm->lock); __kvm_vgic_destroy(kvm); diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 8d30fc645148..e8bdc304ec9b 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -337,8 +337,6 @@ extern struct static_key_false vgic_v3_cpuif_trap; int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); int kvm_vgic_create(struct kvm *kvm, u32 type); -void kvm_vgic_destroy(struct kvm *kvm); -void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); int kvm_vgic_map_resources(struct kvm *kvm); int kvm_vgic_hyp_init(void); void kvm_vgic_init_cpu_hardware(void); From patchwork Thu Sep 3 15:25:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754129 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A6055109B for ; Thu, 3 Sep 2020 15:27:13 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7B36D2072A for ; Thu, 3 Sep 2020 15:27:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="oOpLrdTA"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="uoFb6Cdy" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7B36D2072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=wqJoKmPvpUwvQm+5Jby/wf3fnfpWjlYGYN/6vdAY1qg=; b=oOpLrdTAIxYvv4WgyT8j1Avcg oMtHkmiRPmv/skkZGc8ogpoGXQKr0u2pB+qOLUfiwN3Fx7p52B3VZoUZtXb5PGHUS4mFM6aJcCvdC uWpXnnL3B77PMHod85HC5Ix8FIqGfWQUUMrnEFzEW1MdM/xJmsWlAfhM5iJG/WK3aNlQY1JiXqTuL r/Rc7ZvnSJVnzO0SVYERboASuwD3KYXKOHtjTnC+GQZbnyw1LMZ34R96PfPR2YjqTn+wC4OoVBRfI NMLIukb105zATLx65vBVtDgDh3b6f2OPEqoorpw7Vi9inJkvhY07ZYe4y8IKGv09f84KxpBfwNCnr 1HiFTlSDA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr8e-00055G-Rc; Thu, 03 Sep 2020 15:27:00 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDr88-0004sj-Q2 for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:26:31 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 011C720C09; Thu, 3 Sep 2020 15:26:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599146788; bh=HBjR8yqpG73ePWO3TJecMmjtceWadFNU+gdwbXpG+SI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uoFb6CdyZLtnPLWXFpdfmJZw1Tg/GSjEE+49gDnsyYj1dDONEVOOO9gWFO/X4RBdu L2nKnp4CiwzTNztHbRWuPqDjlDT7nCooNHLAAOts236MPkuqCBfVurtLJVZQwJpgMm AR7y41dXI4Dv20HN7jPrNyYF29q0uEuBi72gAeS4= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr86-008vT9-DY; Thu, 03 Sep 2020 16:26:26 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 09/23] KVM: arm64: Move kvm_vgic_vcpu_init() to irqchip_flow Date: Thu, 3 Sep 2020 16:25:56 +0100 Message-Id: <20200903152610.1078827-10-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_112629_019518_3181B4CE X-CRM114-Status: GOOD ( 25.00 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Abstract kvm_vgic_vcpu_init() by moving it to the irqchip_flow structure. This results in a minor change of the way we initialize vcpus: VCPUs created prior to the creation of the vgic device don't have their local view of the vgic initialized. This means that on vgic instantiation, we must "catch up" and initialise the CPU interfaces for these vcpus. VCPUs created after the vgic device will follow the unusual flow. Special care must be taken to accomodate the different locking contexts though. The function can then be made static and the irqchip_in_kernel() test dropped, as we only get here if a vgic has been created. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 4 ++++ arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/vgic/vgic-init.c | 37 +++++++++++++++++++++++++------- include/kvm/arm_vgic.h | 1 - 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index f83594257bc4..09df1f46d4de 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -19,6 +19,7 @@ enum kvm_irqchip_type { struct kvm_irqchip_flow { void (*irqchip_destroy)(struct kvm *); + int (*irqchip_vcpu_init)(struct kvm_vcpu *); }; /* @@ -50,4 +51,7 @@ struct kvm_irqchip_flow { #define kvm_irqchip_destroy(k) \ __kvm_irqchip_action((k), destroy, (k)) +#define kvm_irqchip_vcpu_init(v) \ + __vcpu_irqchip_action_ret((v), vcpu_init, (v)) + #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 09b4bcb2c805..d82d348a36c3 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -265,7 +265,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; - err = kvm_vgic_vcpu_init(vcpu); + err = kvm_irqchip_vcpu_init(vcpu); if (err) return err; diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 4e2c23a7dab1..d845699c6966 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -12,10 +12,12 @@ #include #include "vgic.h" +static int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); static void kvm_vgic_destroy(struct kvm *kvm); static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_destroy = kvm_vgic_destroy, + .irqchip_vcpu_init = kvm_vgic_vcpu_init, }; /* @@ -45,6 +47,8 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { * allocation is allowed there. */ +static int __kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); + /* CREATION */ /** @@ -110,6 +114,17 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) INIT_LIST_HEAD(&dist->lpi_translation_cache); raw_spin_lock_init(&dist->lpi_list_lock); + /* + * vcpus may have been created before the GIC. Initialize + * them. Careful that kvm->lock is held already on the + * KVM_CREATE_DEVICE path, so use the non-locking version. + */ + kvm_for_each_vcpu(i, vcpu, kvm) { + ret = __kvm_vgic_vcpu_init(vcpu); + if (ret) + break; + } + out_unlock: unlock_all_vcpus(kvm); return ret; @@ -176,7 +191,7 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis) * Only do initialization, but do not actually enable the * VGIC CPU interface */ -int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) +static int __kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; int ret = 0; @@ -211,18 +226,24 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) } } - if (!irqchip_in_kernel(vcpu->kvm)) - return 0; - /* * If we are creating a VCPU with a GICv3 we must also register the * KVM io device for the redistributor that belongs to this VCPU. */ - if (irqchip_is_gic_v3(vcpu->kvm)) { - mutex_lock(&vcpu->kvm->lock); + if (irqchip_is_gic_v3(vcpu->kvm)) ret = vgic_register_redist_iodev(vcpu); - mutex_unlock(&vcpu->kvm->lock); - } + + return ret; +} + +static int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) +{ + int ret; + + mutex_lock(&vcpu->kvm->lock); + ret = __kvm_vgic_vcpu_init(vcpu); + mutex_unlock(&vcpu->kvm->lock); + return ret; } diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index e8bdc304ec9b..b2fd0e39af11 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -335,7 +335,6 @@ extern struct static_key_false vgic_v2_cpuif_trap; extern struct static_key_false vgic_v3_cpuif_trap; int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); -int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); int kvm_vgic_create(struct kvm *kvm, u32 type); int kvm_vgic_map_resources(struct kvm *kvm); int kvm_vgic_hyp_init(void); From patchwork Thu Sep 3 15:25:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754189 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D6D741751 for ; Thu, 3 Sep 2020 15:56:15 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AD2C12072A for ; Thu, 3 Sep 2020 15:56:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Z4CRuWp1"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="ct6hyqPk" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AD2C12072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=PsTpHMpOrSk9ViO/7t6NOQcLW1TUTXen6xVv+Nw0GYU=; b=Z4CRuWp1hN5FINonwWxPpVQ3u 5IhrLybQrwCENpVNahyyQ4u8jRI+rQNYyXgj/ExY8epIqTF3mAT+KkEyEcoVXCQNi9kvjvGltJJqI 6hl4IJOhU9q/5pf/4o9WA1mAwuF15Sg0QtEXiQ9dJkwKS9LO9uTBEEkdn7t7V7NA4G1wo1He8R9yh Rk2413WFEW7ilMyY4YSzcOzH3Z/PI0Eamy1J0MfbwS53+6tOGQ0FqEG/r2MofFns+z7+e/crYc4JG YTN8e9rNxmd5eShKtAQAL55w0wtKqPdBCntk9lCZyE9JChIeKMGHtPEwyOVXprJ0oXX+bTh5coVJa Wr42dwPVw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrac-0000ll-5t; Thu, 03 Sep 2020 15:55:54 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDraZ-0000lH-MA for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:55:52 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E0E3320639; Thu, 3 Sep 2020 15:55:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148551; bh=YzRkIx+dZ17MEeaeOr7j+6LyvyofGqD9uMAxfbSGWQk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ct6hyqPkh0Ha2pp2k/BgpHhTnCeivhZkzVrbFHphW74G+vrKKzueWdZH4VHBFgch7 nGmY85bU2dns9zUQNyIp35wWk6OEylG09zmHdj0bUR6ps8FxHg0GfF6j9qzf1ftbja AM1HaFi3w8T2hIYD9cSEZaen3SSNOO6UGsAt9Yq0= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr87-008vT9-06; Thu, 03 Sep 2020 16:26:27 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 10/23] KVM: arm64: Move kvm_vgic_vcpu_[un]blocking() to irqchip_flow Date: Thu, 3 Sep 2020 16:25:57 +0100 Message-Id: <20200903152610.1078827-11-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115551_979599_92F18929 X-CRM114-Status: GOOD ( 20.57 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Move the code dedicated to blocking/unblocking on WFI to the vgic code itself, and abstract it via the irqchip_flow structure. No functional change. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 8 ++++++++ arch/arm64/kvm/arm.c | 19 ++----------------- arch/arm64/kvm/vgic/vgic-init.c | 2 ++ arch/arm64/kvm/vgic/vgic.c | 25 ++++++++++++++++++++++--- arch/arm64/kvm/vgic/vgic.h | 3 +++ include/kvm/arm_vgic.h | 1 - 6 files changed, 37 insertions(+), 21 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 09df1f46d4de..493b59dae256 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -20,6 +20,8 @@ enum kvm_irqchip_type { struct kvm_irqchip_flow { void (*irqchip_destroy)(struct kvm *); int (*irqchip_vcpu_init)(struct kvm_vcpu *); + void (*irqchip_vcpu_blocking)(struct kvm_vcpu *); + void (*irqchip_vcpu_unblocking)(struct kvm_vcpu *); }; /* @@ -54,4 +56,10 @@ struct kvm_irqchip_flow { #define kvm_irqchip_vcpu_init(v) \ __vcpu_irqchip_action_ret((v), vcpu_init, (v)) +#define kvm_irqchip_vcpu_blocking(v) \ + __vcpu_irqchip_action((v), vcpu_blocking, (v)) + +#define kvm_irqchip_vcpu_unblocking(v) \ + __vcpu_irqchip_action((v), vcpu_unblocking, (v)) + #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index d82d348a36c3..b60265f575cd 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -295,27 +295,12 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) { - /* - * If we're about to block (most likely because we've just hit a - * WFI), we need to sync back the state of the GIC CPU interface - * so that we have the latest PMR and group enables. This ensures - * that kvm_arch_vcpu_runnable has up-to-date data to decide - * whether we have pending interrupts. - * - * For the same reason, we want to tell GICv4 that we need - * doorbells to be signalled, should an interrupt become pending. - */ - preempt_disable(); - kvm_vgic_vmcr_sync(vcpu); - vgic_v4_put(vcpu, true); - preempt_enable(); + kvm_irqchip_vcpu_blocking(vcpu); } void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) { - preempt_disable(); - vgic_v4_load(vcpu); - preempt_enable(); + kvm_irqchip_vcpu_unblocking(vcpu); } void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index d845699c6966..b519fb56a8cd 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -18,6 +18,8 @@ static void kvm_vgic_destroy(struct kvm *kvm); static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_destroy = kvm_vgic_destroy, .irqchip_vcpu_init = kvm_vgic_vcpu_init, + .irqchip_vcpu_blocking = kvm_vgic_vcpu_blocking, + .irqchip_vcpu_unblocking = kvm_vgic_vcpu_unblocking, }; /* diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index c3643b7f101b..f576273c5608 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -939,15 +939,34 @@ void kvm_vgic_put(struct kvm_vcpu *vcpu) vgic_v3_put(vcpu); } -void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu) +void kvm_vgic_vcpu_blocking(struct kvm_vcpu *vcpu) { - if (unlikely(!irqchip_in_kernel(vcpu->kvm))) - return; + /* + * If we're about to block (most likely because we've just hit a + * WFI), we need to sync back the state of the GIC CPU interface + * so that we have the latest PMR and group enables. This ensures + * that kvm_arch_vcpu_runnable has up-to-date data to decide + * whether we have pending interrupts. + * + * For the same reason, we want to tell GICv4 that we need + * doorbells to be signalled, should an interrupt become pending. + */ + preempt_disable(); if (kvm_vgic_global_state.type == VGIC_V2) vgic_v2_vmcr_sync(vcpu); else vgic_v3_vmcr_sync(vcpu); + + vgic_v4_put(vcpu, true); + preempt_enable(); +} + +void kvm_vgic_vcpu_unblocking(struct kvm_vcpu *vcpu) +{ + preempt_disable(); + vgic_v4_load(vcpu); + preempt_enable(); } int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index 64fcd7511110..d8a0e3729de4 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -227,6 +227,9 @@ void vgic_v3_load(struct kvm_vcpu *vcpu); void vgic_v3_put(struct kvm_vcpu *vcpu); void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu); +void kvm_vgic_vcpu_blocking(struct kvm_vcpu *vcpu); +void kvm_vgic_vcpu_unblocking(struct kvm_vcpu *vcpu); + bool vgic_has_its(struct kvm *kvm); int kvm_vgic_register_its_device(void); void vgic_enable_lpis(struct kvm_vcpu *vcpu); diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index b2fd0e39af11..2bffc2d513ef 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -351,7 +351,6 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); void kvm_vgic_load(struct kvm_vcpu *vcpu); void kvm_vgic_put(struct kvm_vcpu *vcpu); -void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu); #define vgic_initialized(k) ((k)->arch.vgic.initialized) #define vgic_ready(k) ((k)->arch.vgic.ready) From patchwork Thu Sep 3 15:25:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754213 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DE5F01575 for ; Thu, 3 Sep 2020 15:56:49 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B7BFD20775 for ; Thu, 3 Sep 2020 15:56:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="HSV85/fM"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="jCQWNSw0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B7BFD20775 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=MDL3f2656ZOlQBi1U9/EqiOWquNG8FN5zI6Mr6ZmJog=; b=HSV85/fM41MEP3vo57TJWwH4k E+C8vFQbCEOESNmeuylHuu/iyZ9jmNsuDS5wyCck7f0bKR718B8Z01fbub0/Phc8xvQnRZ2hW0RPh 43vBWv2TfVre6jFTMLwIGM1R68tITEH9Z1em1kxCBOH8G5PbsAIZ7FsouNJRusV+l99lwSTtZE9fK Th1glMrf01hHh1OMDt2Ufjq9cXn+BW3KEnpiXPdAaOttqWOf+kozaBFshm+Ji0vRn1ykrXKTL/YCt c+g4kNBeuPIqndQE2BS3SiySvtoo6lwX9z3Sp8edxM04Gans5id6Kn1CkIiUAQz0VeoZEQwuZaqFx 5QnWBXMKg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrbJ-00013D-Kk; Thu, 03 Sep 2020 15:56:37 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDraq-0000qd-3J for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:09 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 595F8206EB; Thu, 3 Sep 2020 15:56:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148567; bh=aj+Fs9Q6pOgZaVj6SGqCD2Sw6aTbniJQUhxSCCJXvQQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jCQWNSw0bGkHV2+MuDGlMsuuESUnitk2BSfQn+Sln8Qe1TMFsu57MYEj6S9I1Q/lc DxL5jb1p07isW/F9yZrs4DZGWpMRoiGtm/2o9jVKfQUWX4q3THYZcrIKYs9qqlKZ1P OI6JhupaRQC4vV1bxFZvZoRN7tuSj7YsSoAwcwN0= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr87-008vT9-Jh; Thu, 03 Sep 2020 16:26:27 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 11/23] KVM: arm64: Move kvm_vgic_vcpu_load/put() to irqchip_flow Date: Thu, 3 Sep 2020 16:25:58 +0100 Message-Id: <20200903152610.1078827-12-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115608_324293_FA2E8CC2 X-CRM114-Status: GOOD ( 17.78 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Abstract the calls to kvm_vgic_vcpu_load/put() via the irqchip_flow structure. No functional change. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 8 ++++++++ arch/arm64/kvm/arm.c | 4 ++-- arch/arm64/kvm/vgic/vgic-init.c | 2 ++ arch/arm64/kvm/vgic/vgic.h | 3 +++ include/kvm/arm_vgic.h | 3 --- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 493b59dae256..50dfd641cd67 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -22,6 +22,8 @@ struct kvm_irqchip_flow { int (*irqchip_vcpu_init)(struct kvm_vcpu *); void (*irqchip_vcpu_blocking)(struct kvm_vcpu *); void (*irqchip_vcpu_unblocking)(struct kvm_vcpu *); + void (*irqchip_vcpu_load)(struct kvm_vcpu *); + void (*irqchip_vcpu_put)(struct kvm_vcpu *); }; /* @@ -62,4 +64,10 @@ struct kvm_irqchip_flow { #define kvm_irqchip_vcpu_unblocking(v) \ __vcpu_irqchip_action((v), vcpu_unblocking, (v)) +#define kvm_irqchip_vcpu_load(v) \ + __vcpu_irqchip_action((v), vcpu_load, (v)) + +#define kvm_irqchip_vcpu_put(v) \ + __vcpu_irqchip_action((v), vcpu_put, (v)) + #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index b60265f575cd..84d48c312b84 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -322,7 +322,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vcpu->cpu = cpu; - kvm_vgic_load(vcpu); + kvm_irqchip_vcpu_load(vcpu); kvm_timer_vcpu_load(vcpu); if (has_vhe()) kvm_vcpu_load_sysregs_vhe(vcpu); @@ -346,7 +346,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) if (has_vhe()) kvm_vcpu_put_sysregs_vhe(vcpu); kvm_timer_vcpu_put(vcpu); - kvm_vgic_put(vcpu); + kvm_irqchip_vcpu_put(vcpu); kvm_vcpu_pmu_restore_host(vcpu); vcpu->cpu = -1; diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index b519fb56a8cd..24b3ed9bae5d 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -20,6 +20,8 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_vcpu_init = kvm_vgic_vcpu_init, .irqchip_vcpu_blocking = kvm_vgic_vcpu_blocking, .irqchip_vcpu_unblocking = kvm_vgic_vcpu_unblocking, + .irqchip_vcpu_load = kvm_vgic_load, + .irqchip_vcpu_put = kvm_vgic_put, }; /* diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index d8a0e3729de4..190737402365 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -321,4 +321,7 @@ int vgic_v4_init(struct kvm *kvm); void vgic_v4_teardown(struct kvm *kvm); void vgic_v4_configure_vsgis(struct kvm *kvm); +void kvm_vgic_load(struct kvm_vcpu *vcpu); +void kvm_vgic_put(struct kvm_vcpu *vcpu); + #endif diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 2bffc2d513ef..a06d9483e3a6 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -349,9 +349,6 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); -void kvm_vgic_load(struct kvm_vcpu *vcpu); -void kvm_vgic_put(struct kvm_vcpu *vcpu); - #define vgic_initialized(k) ((k)->arch.vgic.initialized) #define vgic_ready(k) ((k)->arch.vgic.ready) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ From patchwork Thu Sep 3 15:25:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754235 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2E803109B for ; Thu, 3 Sep 2020 15:58:34 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0492B2072A for ; Thu, 3 Sep 2020 15:58:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="XQPMt8y2"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="QRFsVSlg" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0492B2072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=wGOZDU4l/MYEDH6T3i94uAqznxzbN70zUTzeZHhjT1E=; b=XQPMt8y2sTQnN63UnQ4UyHCTo i07NVT36mXEKAjRC9oRofdtY9OU+ORrPvMtPd5vM9uDSTWlfH01pYvhc3jVRMJ2hOFt+8x3zCQxAV 3AsG/PLgjrDDoNjS7wTc+GN6SqlcA5ARYCSFSPugCZ5qpO5uJKB6xsEGgm+Zk5O+bRzw0sfVWpfzM ZYcqemxVqtd/1acAbpPLElSQeSfy687rgbkEsSa4Z+xem/fQWTGXlx2bXjJkkptrzFalO57LgGPK0 6NZh6QHDTkbl/dEJv7ggOjbWPtPiKSduKd9Xv+7Ib/AP0k5oiWt8ksZhvLrDf2Zsz8ilLkPQSEWnr G1x36Yl9A==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrbS-00018l-VB; Thu, 03 Sep 2020 15:56:47 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrar-0000r7-SG for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:10 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 20BF720786; Thu, 3 Sep 2020 15:56:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148569; bh=YZ/pztr3vl93u3bbVzuK03akBTWI2lok4N89WyFl2kU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QRFsVSlgo3f+7pdacR80/iD5214GeqozUyq6/fKeg+SzdG5ZjHCdLtEREg8VEnsWY NWXpyP647aGtTCw54PnwdqRZZ4CQbbCpoINVYTEspG0McR0B1awk/6rTe8VqNYNYOM Nja/++jfZn92NDy34FIilbHKf4PI7Ps3QpdZw4IY= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr88-008vT9-7d; Thu, 03 Sep 2020 16:26:28 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 12/23] KVM: arm64: Move kvm_vgic_vcpu_pending_irq() to irqchip_flow Date: Thu, 3 Sep 2020 16:25:59 +0100 Message-Id: <20200903152610.1078827-13-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115610_059618_D4DF9F9B X-CRM114-Status: GOOD ( 17.60 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Abstract the calls to kvm_vgic_vcpu_pending_irq() via the irqchip_flow structure. No functional change. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 4 ++++ arch/arm64/kvm/arm.c | 4 ++-- arch/arm64/kvm/vgic/vgic-init.c | 1 + arch/arm64/kvm/vgic/vgic.h | 6 ++++++ include/kvm/arm_vgic.h | 3 --- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 50dfd641cd67..e7a244176ade 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -24,6 +24,7 @@ struct kvm_irqchip_flow { void (*irqchip_vcpu_unblocking)(struct kvm_vcpu *); void (*irqchip_vcpu_load)(struct kvm_vcpu *); void (*irqchip_vcpu_put)(struct kvm_vcpu *); + int (*irqchip_vcpu_pending_irq)(struct kvm_vcpu *); }; /* @@ -70,4 +71,7 @@ struct kvm_irqchip_flow { #define kvm_irqchip_vcpu_put(v) \ __vcpu_irqchip_action((v), vcpu_put, (v)) +#define kvm_irqchip_vcpu_pending_irq(v) \ + __vcpu_irqchip_action_ret((v), vcpu_pending_irq, (v)) + #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 84d48c312b84..3496d200e488 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -399,8 +399,8 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) { bool irq_lines = *vcpu_hcr(v) & (HCR_VI | HCR_VF); - return ((irq_lines || kvm_vgic_vcpu_pending_irq(v)) - && !v->arch.power_off && !v->arch.pause); + return ((irq_lines || kvm_irqchip_vcpu_pending_irq(v)) && + !v->arch.power_off && !v->arch.pause); } bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 24b3ed9bae5d..8bb847045ef9 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -22,6 +22,7 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_vcpu_unblocking = kvm_vgic_vcpu_unblocking, .irqchip_vcpu_load = kvm_vgic_load, .irqchip_vcpu_put = kvm_vgic_put, + .irqchip_vcpu_pending_irq = kvm_vgic_vcpu_pending_irq, }; /* diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index 190737402365..c5511823eec5 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -321,7 +321,13 @@ int vgic_v4_init(struct kvm *kvm); void vgic_v4_teardown(struct kvm *kvm); void vgic_v4_configure_vsgis(struct kvm *kvm); +int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); + void kvm_vgic_load(struct kvm_vcpu *vcpu); void kvm_vgic_put(struct kvm_vcpu *vcpu); +void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); +void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); + + #endif diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index a06d9483e3a6..b2adf9cca334 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -347,14 +347,11 @@ int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); -int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); - #define vgic_initialized(k) ((k)->arch.vgic.initialized) #define vgic_ready(k) ((k)->arch.vgic.ready) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) -bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu); void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid); From patchwork Thu Sep 3 15:26:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754215 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 89DCD1575 for ; Thu, 3 Sep 2020 15:57:12 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 344BB2072A for ; Thu, 3 Sep 2020 15:57:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="FQBYJpWN"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ai05p6rz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 344BB2072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=F+KAXWGCMPgQsdrwDuRDE+i1XsbUEz2aeBDQMwb0plU=; b=FQBYJpWN3YivkiAAmdcGUm5wk VFy4CGd68R4neEcGMifIVqpVkB8g/phiWina91CkAnTVFaU2RglzyPP5sQ2+FxYhazgS/30szhidO BL71nln018U7JOshJPFdo99HCnRLWaalZkAQAHG4X9M6bHdu7vtV6ZaewuskocMq9u6AsCje7nrQe x+HJSHlySObf/RIBKhZ8cMzjduLbJjcPVOSwYYRmeL3wmjJWzcCNsY3KhCAGvsMAguPo0FrWWxZfI 8F5oh6p1nkkfigb20jNyVQ/+ws0lU7YqIMCaXgVur9xyE/8mCJNHOk1xu8I/d1kl2lmQotihEPhUJ pb78PZboA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrbY-0001CC-3y; Thu, 03 Sep 2020 15:56:52 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrau-0000sD-A0 for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:13 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 855B6208CA; Thu, 3 Sep 2020 15:56:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148571; bh=aS/t6svxjVTLIqQIL8YmKTnPTqDezWb7MZUb4MsYTCQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ai05p6rz3xI0in+U7g0P8DQj9BwcgAHYcO7VsuZpqZbc+BACTixZS2zLSPMCWJLZA 1QmYwzBmJyIkEJrhL4v+N3ACQQO5MWDbgb6AR+Fsc+qNw7U85HGPFNxDS5650i/8Oo d9GrPQfF29SnaMWCO4QJ6ExxmtDepMmXy4qvH2DY= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr88-008vT9-T3; Thu, 03 Sep 2020 16:26:29 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 13/23] KVM: arm64: Move vgic resource mapping on first run to irqchip_flow Date: Thu, 3 Sep 2020 16:26:00 +0100 Message-Id: <20200903152610.1078827-14-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115612_530820_1F30A1B6 X-CRM114-Status: GOOD ( 27.11 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The "first run" part of the vgic init is pretty cumbersome, as it leaks all over the place. Reduce its footprint by moving it to an actual per-vcpu "first run" callback, and let it deal with the resource mapping. This allows the vgic_ready() macro to be made vgic-private, and placed in the common vgic code instead of the architecture backends. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 4 ++++ arch/arm64/kvm/arm.c | 12 +++--------- arch/arm64/kvm/vgic/vgic-init.c | 13 ++++++++++--- arch/arm64/kvm/vgic/vgic-v2.c | 5 ----- arch/arm64/kvm/vgic/vgic-v3.c | 4 ---- arch/arm64/kvm/vgic/vgic.h | 2 ++ include/kvm/arm_vgic.h | 2 -- 7 files changed, 19 insertions(+), 23 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index e7a244176ade..7d888f10aabe 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -25,6 +25,7 @@ struct kvm_irqchip_flow { void (*irqchip_vcpu_load)(struct kvm_vcpu *); void (*irqchip_vcpu_put)(struct kvm_vcpu *); int (*irqchip_vcpu_pending_irq)(struct kvm_vcpu *); + int (*irqchip_vcpu_first_run)(struct kvm_vcpu *); }; /* @@ -74,4 +75,7 @@ struct kvm_irqchip_flow { #define kvm_irqchip_vcpu_pending_irq(v) \ __vcpu_irqchip_action_ret((v), vcpu_pending_irq, (v)) +#define kvm_irqchip_vcpu_first_run(v) \ + __vcpu_irqchip_action_ret((v), vcpu_first_run, (v)) + #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 3496d200e488..0db71d2a38a4 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -503,15 +503,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) vcpu->arch.has_run_once = true; if (likely(irqchip_in_kernel(kvm))) { - /* - * Map the VGIC hardware resources before running a vcpu the - * first time on this VM. - */ - if (unlikely(!vgic_ready(kvm))) { - ret = kvm_vgic_map_resources(kvm); - if (ret) - return ret; - } + ret = kvm_irqchip_vcpu_first_run(vcpu); + if (ret) + return ret; } else { /* * Tell the rest of the code that there are userspace irqchip diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 8bb847045ef9..8ec8064467a7 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -12,6 +12,7 @@ #include #include "vgic.h" +static int kvm_vgic_vcpu_first_run(struct kvm_vcpu *vcpu); static int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); static void kvm_vgic_destroy(struct kvm *kvm); @@ -23,6 +24,7 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_vcpu_load = kvm_vgic_load, .irqchip_vcpu_put = kvm_vgic_put, .irqchip_vcpu_pending_irq = kvm_vgic_vcpu_pending_irq, + .irqchip_vcpu_first_run = kvm_vgic_vcpu_first_run, }; /* @@ -440,14 +442,17 @@ int vgic_lazy_init(struct kvm *kvm) * Also map the virtual CPU interface into the VM. * v2/v3 derivatives call vgic_init if not already done. * vgic_ready() returns true if this function has succeeded. - * @kvm: kvm struct pointer + * @vcpu: vcpu struct pointer */ -int kvm_vgic_map_resources(struct kvm *kvm) +static int kvm_vgic_vcpu_first_run(struct kvm_vcpu *vcpu) { + struct kvm *kvm = vcpu->kvm; + struct vgic_dist *dist = &kvm->arch.vgic; int ret = 0; mutex_lock(&kvm->lock); - if (!irqchip_in_kernel(kvm)) + + if (vgic_ready(kvm)) goto out; if (irqchip_is_gic_v2(kvm)) @@ -457,6 +462,8 @@ int kvm_vgic_map_resources(struct kvm *kvm) if (ret) __kvm_vgic_destroy(kvm); + else + dist->ready = true; out: mutex_unlock(&kvm->lock); diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c index ebf53a4e1296..a6aaffd2124f 100644 --- a/arch/arm64/kvm/vgic/vgic-v2.c +++ b/arch/arm64/kvm/vgic/vgic-v2.c @@ -306,9 +306,6 @@ int vgic_v2_map_resources(struct kvm *kvm) struct vgic_dist *dist = &kvm->arch.vgic; int ret = 0; - if (vgic_ready(kvm)) - goto out; - if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || IS_VGIC_ADDR_UNDEF(dist->vgic_cpu_base)) { kvm_err("Need to set vgic cpu and dist addresses first\n"); @@ -348,8 +345,6 @@ int vgic_v2_map_resources(struct kvm *kvm) } } - dist->ready = true; - out: return ret; } diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index c6fdb1222453..d176ad9bab85 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -496,9 +496,6 @@ int vgic_v3_map_resources(struct kvm *kvm) int ret = 0; int c; - if (vgic_ready(kvm)) - goto out; - kvm_for_each_vcpu(c, vcpu, kvm) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; @@ -538,7 +535,6 @@ int vgic_v3_map_resources(struct kvm *kvm) if (kvm_vgic_global_state.has_gicv4_1) vgic_v4_configure_vsgis(kvm); - dist->ready = true; out: return ret; diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index c5511823eec5..48e9efda9d8b 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -98,6 +98,8 @@ #define DEBUG_SPINLOCK_BUG_ON(p) #endif +#define vgic_ready(k) ((k)->arch.vgic.ready) + /* Requires the irq_lock to be held by the caller. */ static inline bool irq_is_pending(struct vgic_irq *irq) { diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index b2adf9cca334..fad523007e2b 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -336,7 +336,6 @@ extern struct static_key_false vgic_v3_cpuif_trap; int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); int kvm_vgic_create(struct kvm *kvm, u32 type); -int kvm_vgic_map_resources(struct kvm *kvm); int kvm_vgic_hyp_init(void); void kvm_vgic_init_cpu_hardware(void); @@ -348,7 +347,6 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); #define vgic_initialized(k) ((k)->arch.vgic.initialized) -#define vgic_ready(k) ((k)->arch.vgic.ready) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) From patchwork Thu Sep 3 15:26:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754231 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DE3901575 for ; Thu, 3 Sep 2020 15:57:58 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B4DFA2072A for ; Thu, 3 Sep 2020 15:57:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="3QgGu711"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="07CUHzAc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B4DFA2072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=HwKCs+gLEtMxxPbiPfcM17VevKXnvbZHTPuHmB39ZZ0=; b=3QgGu711hCHnZEHNKSwPAgCC7 uD614Z6KR6FfmYonuHrEFicsFMVMFopyuVSLtChDePn670+iteTIl9G3qt8+f4FcLelF55Zh+vO5W pbm51JkNiSs6CsMtPX7opQydIB49cl773lC2fc+MUkGQPzJ/MaUdBW2syrxxm3BsRWvDCGm0LP1nL iSUODHqpmSQQpdqDdGjLfe+4InxI8mJhwNK8wtUOVZHoQhpOODMFpKTHDchvXH2gIieBT9B5FUlI7 axTLHq+IHY1b6vF9U2JyJwLxLDuqgbb9JYssnPHW7rHVonXbOGFeBiXhvtXIp/TE3g0rbzF7EvVZz K16zsoGvA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrat-0000rY-52; Thu, 03 Sep 2020 15:56:11 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrai-0000nu-Li for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:02 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id EAB2020775; Thu, 3 Sep 2020 15:55:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148560; bh=Zmy7IjMeRTgXirbjiJ59TU+qyqamGmOSjVIBZBkIHO8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=07CUHzAcH4m+iOTvLUkUCCUoc1GUB1B/Co2s6UdlcDCK8y/Of12EkqkU//5hsUsf8 JlwLNMJR1jTVsWolMtZbaqa8oJGS8KoQUNVg1n5qHJ327TiHnR9hE2sK1eZrXcUx0N iEsR5rnTossPGBlrPly7fgnnTeJiwvHH1pRp96z0= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr89-008vT9-GE; Thu, 03 Sep 2020 16:26:29 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 14/23] KVM: arm64: Move kvm_vgic_vcpu_{sync, flush}_hwstate() to irqchip_flow Date: Thu, 3 Sep 2020 16:26:01 +0100 Message-Id: <20200903152610.1078827-15-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115600_956026_6E79A765 X-CRM114-Status: GOOD ( 17.63 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Abstract the calls to kvm_vgic_vcpu_({sync,flush}_hwstate) via the irqchip_flow structure. No functional change. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 8 ++++++++ arch/arm64/kvm/arm.c | 6 +++--- arch/arm64/kvm/vgic/vgic-init.c | 2 ++ include/kvm/arm_vgic.h | 2 -- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 7d888f10aabe..92aaec05ee75 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -26,6 +26,8 @@ struct kvm_irqchip_flow { void (*irqchip_vcpu_put)(struct kvm_vcpu *); int (*irqchip_vcpu_pending_irq)(struct kvm_vcpu *); int (*irqchip_vcpu_first_run)(struct kvm_vcpu *); + void (*irqchip_vcpu_flush_hwstate)(struct kvm_vcpu *); + void (*irqchip_vcpu_sync_hwstate)(struct kvm_vcpu *); }; /* @@ -78,4 +80,10 @@ struct kvm_irqchip_flow { #define kvm_irqchip_vcpu_first_run(v) \ __vcpu_irqchip_action_ret((v), vcpu_first_run, (v)) +#define kvm_irqchip_vcpu_flush_hwstate(v) \ + __vcpu_irqchip_action((v), vcpu_flush_hwstate, (v)) + +#define kvm_irqchip_vcpu_sync_hwstate(v) \ + __vcpu_irqchip_action((v), vcpu_sync_hwstate, (v)) + #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 0db71d2a38a4..875e68514661 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -661,7 +661,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) local_irq_disable(); - kvm_vgic_flush_hwstate(vcpu); + kvm_irqchip_vcpu_flush_hwstate(vcpu); /* * Exit if we have a signal pending so that we can deliver the @@ -702,7 +702,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) kvm_pmu_sync_hwstate(vcpu); if (static_branch_unlikely(&userspace_irqchip_in_use)) kvm_timer_sync_user(vcpu); - kvm_vgic_sync_hwstate(vcpu); + kvm_irqchip_vcpu_sync_hwstate(vcpu); local_irq_enable(); preempt_enable(); continue; @@ -738,7 +738,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) * the timer code needs to know if the virtual timer * interrupts are active. */ - kvm_vgic_sync_hwstate(vcpu); + kvm_irqchip_vcpu_sync_hwstate(vcpu); /* * Sync the timer hardware state before enabling interrupts as diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 8ec8064467a7..53fadbf4ca89 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -25,6 +25,8 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_vcpu_put = kvm_vgic_put, .irqchip_vcpu_pending_irq = kvm_vgic_vcpu_pending_irq, .irqchip_vcpu_first_run = kvm_vgic_vcpu_first_run, + .irqchip_vcpu_flush_hwstate = kvm_vgic_flush_hwstate, + .irqchip_vcpu_sync_hwstate = kvm_vgic_sync_hwstate, }; /* diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index fad523007e2b..4b3a334185fa 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -350,8 +350,6 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) -void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); -void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid); void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1); From patchwork Thu Sep 3 15:26:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754207 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4C1DF109B for ; Thu, 3 Sep 2020 15:56:35 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 252AF206EB for ; Thu, 3 Sep 2020 15:56:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="YbC40bGt"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="SKTN2arc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 252AF206EB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=GowUx92tdxg1FQeIpGxCtZptYeKN36A0/X2mREoJbfA=; b=YbC40bGtTOSq21XV3+/536ug3 K58YHQoNb2GgkfBuYwBpW5FHzLhCF86uk1Ai0ky3Z73AaMHj8PaGHtFn+f5fabsTIO4xZpnIvGkQk /NhEWXAPoE2dkk9B5z9sj7VxzCsbLhHtMF8AHYzUKoBI+GZ5X27CAbnFz7jqBV7eiUxZehkWKy9N9 jVjESHP/XgwZkBaKNDQU1hRf3MzM7awch+j4HDfcw+TzFglatSa+QuSQ/RT/obtES++dHP1uFmmCs 0hMfnWwHqd7VH0yRdNdAY2z7HwYb8RH/36iFf+CwyPND0Fmhw8DOFU8161O9t4fqg8OfeMUxJQJL/ IXDIxUUEg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrb0-0000tC-Mq; Thu, 03 Sep 2020 15:56:18 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrak-0000oS-Gc for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:03 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AC3AA206EB; Thu, 3 Sep 2020 15:56:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148561; bh=MxTISM6aCyrfQEcNTQysLq4QgrXvqcQfw2UVVj/1QTE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SKTN2arcW3+/OVvmAw/EsiV18c4pdfCk/A5pJMqkJHRwpBZyLRvT/ovABD5E9s2Ax qaFEepyGhgEym2a3LLyDX1NLS8xdOxbVqz6LFyRcagzk0yokcU4WT/g12F9bDhb4HJ 62BzrJmdrUYvdMt7qpGdIPU3P7d6/GYU1y6vnBbk= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8A-008vT9-2r; Thu, 03 Sep 2020 16:26:30 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 15/23] KVM: arm64: nVHE: Only save/restore GICv3 state if modeling a GIC Date: Thu, 3 Sep 2020 16:26:02 +0100 Message-Id: <20200903152610.1078827-16-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115602_636264_97BF1A1B X-CRM114-Status: GOOD ( 14.62 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org If we aren't modeling a GIC, there is no need to save/restore the GICv3 state at all. Note that this only matters for nVHE, as VHE already has this code outside of the world switch. Signed-off-by: Marc Zyngier --- arch/arm64/kvm/hyp/nvhe/switch.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 0970442d2dbc..be77eb156542 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -101,16 +101,22 @@ static void __deactivate_vm(struct kvm_vcpu *vcpu) /* Save VGICv3 state on non-VHE systems */ static void __hyp_vgic_save_state(struct kvm_vcpu *vcpu) { - if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) { + struct kvm *kvm = kern_hyp_va(vcpu->kvm); + + if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) && + (irqchip_is_gic_v2(kvm) || irqchip_is_gic_v3(kvm))) { __vgic_v3_save_state(&vcpu->arch.vgic_cpu.vgic_v3); __vgic_v3_deactivate_traps(&vcpu->arch.vgic_cpu.vgic_v3); } } -/* Restore VGICv3 state on non_VEH systems */ +/* Restore VGICv3 state on non-VHE systems */ static void __hyp_vgic_restore_state(struct kvm_vcpu *vcpu) { - if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) { + struct kvm *kvm = kern_hyp_va(vcpu->kvm); + + if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) && + (irqchip_is_gic_v2(kvm) || irqchip_is_gic_v3(kvm))) { __vgic_v3_activate_traps(&vcpu->arch.vgic_cpu.vgic_v3); __vgic_v3_restore_state(&vcpu->arch.vgic_cpu.vgic_v3); } From patchwork Thu Sep 3 15:26:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754209 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1852D1575 for ; Thu, 3 Sep 2020 15:56:42 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E660620775 for ; Thu, 3 Sep 2020 15:56:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="tAyLSxeY"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="1UjjiO2e" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E660620775 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=sJg4wnHHXOwCQeQ9mJEpT56pJDeR4oFofYFXXZKXv8U=; b=tAyLSxeYDUbYL3OOf/7OhOdi0 qYa0ZSdyVSnvGeKrlprzOHdElqfgbgNONJ+sDzkOZY96BwKRaTcfytKOHGnh2HoECe4a3TdespWid yhJuXZri2jYwjw9HQ4JW72y2995XTKmaq3Ay2ELBC2NZQfoIjyUljvAIsJzgBh+T6M7EOt8wNgDcB XL4uP5ExktEZkrZ30Z1xHvqveMkjSWesuggpujid+Dr+vvkFFMWnaQXvyFYD2u6jm5rNYvc++n25m LaWaHZC6WxoUAuF3o3RxcBL7hvZIVIoT5a8HglDyrgoAqXv1IcVkYIj64AJUtv/Mr7bL0To7AbEOr jN7s5VeDw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrbA-0000yv-P2; Thu, 03 Sep 2020 15:56:28 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDram-0000p5-79 for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:05 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 763C62072A; Thu, 3 Sep 2020 15:56:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148563; bh=RtheV7zntSjszuTkTZNq3N4qWHVjJZ30ZDdbYBqb6bQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1UjjiO2eov6+tvS5ukHhmY1PUoxZ30d8DWaNcfYPOqEntFLNM9uB8uj2vp+R7lsxB EXf8cBNX5Zx6iSVlKXXyFqwsbT/oQgaKTFAFxNRTHCZttUzN4qoHaVNODXJ2RZBwOR Bq1FPFjCsXrG3/Ao577lZ56K9HWIxXEeHMWjEFI4= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8A-008vT9-M8; Thu, 03 Sep 2020 16:26:30 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 16/23] KVM: arm64: Move interrupt injection to irqchip_flow Date: Thu, 3 Sep 2020 16:26:03 +0100 Message-Id: <20200903152610.1078827-17-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115604_443677_4F86DCF8 X-CRM114-Status: GOOD ( 22.65 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org As we continue abstracting away the VGIC, let's make a small change while we're at it: Let's offer two callbacks for "wired" interrupt injection: - Interrupts generated from the kernel itself - Interrupts generated by userspace via the KVM_IRQ_LINE ioctl The various checks are pushed into the vgic code. MSI injection, such as the one used by userspace to tickle the ITS are left alone for now. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 11 +++++++++++ arch/arm64/kvm/arch_timer.c | 8 ++++---- arch/arm64/kvm/arm.c | 12 ++++-------- arch/arm64/kvm/pmu-emul.c | 4 ++-- arch/arm64/kvm/vgic/vgic-init.c | 2 ++ arch/arm64/kvm/vgic/vgic.c | 20 +++++++++++++++++++- arch/arm64/kvm/vgic/vgic.h | 6 ++++++ include/kvm/arm_vgic.h | 2 -- 8 files changed, 48 insertions(+), 17 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 92aaec05ee75..f816d4814fcf 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -28,6 +28,11 @@ struct kvm_irqchip_flow { int (*irqchip_vcpu_first_run)(struct kvm_vcpu *); void (*irqchip_vcpu_flush_hwstate)(struct kvm_vcpu *); void (*irqchip_vcpu_sync_hwstate)(struct kvm_vcpu *); + int (*irqchip_inject_irq)(struct kvm *, unsigned int cpu, + unsigned int intid, bool, void *); + int (*irqchip_inject_userspace_irq)(struct kvm *, unsigned int type, + unsigned int cpu, + unsigned int intid, bool); }; /* @@ -86,4 +91,10 @@ struct kvm_irqchip_flow { #define kvm_irqchip_vcpu_sync_hwstate(v) \ __vcpu_irqchip_action((v), vcpu_sync_hwstate, (v)) +#define kvm_irqchip_inject_irq(k, ...) \ + __kvm_irqchip_action_ret((k), inject_irq, (k), __VA_ARGS__) + +#define kvm_irqchip_inject_userspace_irq(k, ...) \ + __kvm_irqchip_action_ret((k), inject_userspace_irq, (k), __VA_ARGS__) + #endif diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 32ba6fbc3814..397bd7aea1f5 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -388,10 +388,10 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level, timer_ctx->irq.level); if (!userspace_irqchip(vcpu->kvm)) { - ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, - timer_ctx->irq.irq, - timer_ctx->irq.level, - timer_ctx); + ret = kvm_irqchip_inject_irq(vcpu->kvm, vcpu->vcpu_id, + timer_ctx->irq.irq, + timer_ctx->irq.level, + timer_ctx); WARN_ON(ret); } } diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 875e68514661..139f4154038b 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -870,18 +870,14 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, if (!vcpu) return -EINVAL; - if (irq_num < VGIC_NR_SGIS || irq_num >= VGIC_NR_PRIVATE_IRQS) - return -EINVAL; - - return kvm_vgic_inject_irq(kvm, vcpu->vcpu_id, irq_num, level, NULL); + return kvm_irqchip_inject_userspace_irq(kvm, irq_type, vcpu_idx, + irq_num, level); case KVM_ARM_IRQ_TYPE_SPI: if (!irqchip_in_kernel(kvm)) return -ENXIO; - if (irq_num < VGIC_NR_PRIVATE_IRQS) - return -EINVAL; - - return kvm_vgic_inject_irq(kvm, 0, irq_num, level, NULL); + return kvm_irqchip_inject_userspace_irq(kvm, irq_type, 0, + irq_num, level); } return -EINVAL; diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index f0d0312c0a55..f31ee6ad3444 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -378,8 +378,8 @@ static void kvm_pmu_update_state(struct kvm_vcpu *vcpu) pmu->irq_level = overflow; if (likely(irqchip_in_kernel(vcpu->kvm))) { - int ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, - pmu->irq_num, overflow, pmu); + int ret = kvm_irqchip_inject_irq(vcpu->kvm, vcpu->vcpu_id, + pmu->irq_num, overflow, pmu); WARN_ON(ret); } } diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 53fadbf4ca89..7a8504a5b634 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -27,6 +27,8 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_vcpu_first_run = kvm_vgic_vcpu_first_run, .irqchip_vcpu_flush_hwstate = kvm_vgic_flush_hwstate, .irqchip_vcpu_sync_hwstate = kvm_vgic_sync_hwstate, + .irqchip_inject_irq = kvm_vgic_inject_irq, + .irqchip_inject_userspace_irq = kvm_vgic_inject_userspace_irq, }; /* diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index f576273c5608..d676c010e45f 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -434,7 +434,7 @@ bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq, * level-sensitive interrupts. You can think of the level parameter as 1 * being HIGH and 0 being LOW and all devices being active-HIGH. */ -int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, +int kvm_vgic_inject_irq(struct kvm *kvm, unsigned int cpuid, unsigned int intid, bool level, void *owner) { struct kvm_vcpu *vcpu; @@ -476,6 +476,24 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, return 0; } +int kvm_vgic_inject_userspace_irq(struct kvm *kvm, unsigned int type, + unsigned int cpuid, unsigned int intid, + bool level) +{ + switch (type) { + case KVM_ARM_IRQ_TYPE_PPI: + if (intid < VGIC_NR_SGIS || intid >= VGIC_NR_PRIVATE_IRQS) + return -EINVAL; + return kvm_vgic_inject_irq(kvm, cpuid, intid, level, NULL); + case KVM_ARM_IRQ_TYPE_SPI: + if (intid < VGIC_NR_PRIVATE_IRQS) + return -EINVAL; + return kvm_vgic_inject_irq(kvm, 0, intid, level, NULL); + default: + return -EINVAL; + } +} + /* @irq->irq_lock must be held */ static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq, unsigned int host_irq, diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index 48e9efda9d8b..cddbd9b951e4 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -232,6 +232,12 @@ void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu); void kvm_vgic_vcpu_blocking(struct kvm_vcpu *vcpu); void kvm_vgic_vcpu_unblocking(struct kvm_vcpu *vcpu); +int kvm_vgic_inject_irq(struct kvm *kvm, unsigned int cpuid, unsigned int intid, + bool level, void *owner); +int kvm_vgic_inject_userspace_irq(struct kvm *kvm, unsigned int type, + unsigned int cpuid, unsigned int intid, + bool level); + bool vgic_has_its(struct kvm *kvm); int kvm_vgic_register_its_device(void); void vgic_enable_lpis(struct kvm_vcpu *vcpu); diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 4b3a334185fa..fba68129337d 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -339,8 +339,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type); int kvm_vgic_hyp_init(void); void kvm_vgic_init_cpu_hardware(void); -int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, - bool level, void *owner); int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, u32 vintid, bool (*get_input_level)(int vindid)); int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); From patchwork Thu Sep 3 15:26:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754225 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4C2571575 for ; Thu, 3 Sep 2020 15:57:37 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 25A3E20775 for ; Thu, 3 Sep 2020 15:57:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="xobWjcQN"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="o0fS08Vm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 25A3E20775 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=8yjxKIUeIgHROw1yKikwjYwhFWMesXRjxHwUM9mwQ2M=; b=xobWjcQNGh2d7Pm0Wd+p5NTpw TmTO3DX2/dr7G82iZ/JPJF+J2IyRO4mB3PYPbd9vZu8fW+/9qc3kBGcYvF9N/+hlxw7PX/OBnlN1G P1RahWZYwmQfN4rHDhTvRRi8nZkxp2vSscVGKxT3fdpzPdwmyFxo8Oedgk4Hg9VjNCBa+AP7brQ+n e00x1n5lE3OHXoEJfQXzl+gcXbLT+yXbUyfzSqeF12a+tZGzUyaHWCnSlxNLtAm0B8X0nGl7fUJcw me3nSfbL8N3XB0BGpNeRydKrzg14xbJoZqov0OeUVfX2sqcN9D5ERRvNuVdzTh9FMDO0kIeLK+hx0 GpM5e4KyQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrbv-0001Mx-Pc; Thu, 03 Sep 2020 15:57:16 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDraw-0000t6-50 for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:15 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5DFE3208C7; Thu, 3 Sep 2020 15:56:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148573; bh=ixc6smJXqyfDNyAO1JLLkDueX6FgJ+DaRlFRfhqH6bI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o0fS08VmaCSc3sU0V226iALI31gEEJGuXoqjjAKIXVvcrH8vdNC4e77mAh8ejY11B dnc8Li1k8JlAhBELkVoyJ5Nnf+74Li7dsfrUMouoXvQqw6OpF28chxiub9PYHNb+8S QRkOJIst0b2txuTpdK4U3sZPqOLrnCuQPaJqNAWk= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8B-008vT9-9b; Thu, 03 Sep 2020 16:26:31 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 17/23] KVM: arm64: Move mapping of HW interrupts into irqchip_flow Date: Thu, 3 Sep 2020 16:26:04 +0100 Message-Id: <20200903152610.1078827-18-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115614_453095_4CAE740A X-CRM114-Status: GOOD ( 16.43 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org As we continue cutting a VGIC-shaped hole in KVM, let's indirect all of the handling of mapped interrupts into the bit irqchip_flow bucket. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 17 +++++++++++++++++ arch/arm64/kvm/arch_timer.c | 22 +++++++++++----------- arch/arm64/kvm/vgic/vgic-init.c | 4 ++++ arch/arm64/kvm/vgic/vgic.h | 6 ++++++ include/kvm/arm_vgic.h | 7 ------- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index f816d4814fcf..16556417bd4a 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -33,6 +33,11 @@ struct kvm_irqchip_flow { int (*irqchip_inject_userspace_irq)(struct kvm *, unsigned int type, unsigned int cpu, unsigned int intid, bool); + bool (*irqchip_map_is_active)(struct kvm_vcpu *, unsigned in); + void (*irqchip_reset_mapped_irq)(struct kvm_vcpu *, u32); + int (*irqchip_map_phys_irq)(struct kvm_vcpu *, unsigned int, + u32, bool (*)(int)); + int (*irqchip_unmap_phys_irq)(struct kvm_vcpu *, unsigned int); }; /* @@ -97,4 +102,16 @@ struct kvm_irqchip_flow { #define kvm_irqchip_inject_userspace_irq(k, ...) \ __kvm_irqchip_action_ret((k), inject_userspace_irq, (k), __VA_ARGS__) +#define kvm_irqchip_map_is_active(v, ...) \ + __vcpu_irqchip_action_ret((v), map_is_active, (v), __VA_ARGS__) + +#define kvm_irqchip_reset_mapped_irq(v, ...) \ + __vcpu_irqchip_action((v), reset_mapped_irq, (v), __VA_ARGS__) + +#define kvm_irqchip_map_phys_irq(v, ...) \ + __vcpu_irqchip_action_ret((v), map_phys_irq, (v), __VA_ARGS__) + +#define kvm_irqchip_unmap_phys_irq(v, ...) \ + __vcpu_irqchip_action_ret((v), unmap_phys_irq, (v), __VA_ARGS__) + #endif diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 397bd7aea1f5..16999de299a7 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -562,7 +562,7 @@ static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx) kvm_timer_update_irq(ctx->vcpu, kvm_timer_should_fire(ctx), ctx); if (irqchip_in_kernel(vcpu->kvm)) - phys_active = kvm_vgic_map_is_active(vcpu, ctx->irq.irq); + phys_active = kvm_irqchip_map_is_active(vcpu, ctx->irq.irq); phys_active |= ctx->irq.level; @@ -734,9 +734,9 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu) kvm_timer_update_irq(vcpu, false, vcpu_ptimer(vcpu)); if (irqchip_in_kernel(vcpu->kvm)) { - kvm_vgic_reset_mapped_irq(vcpu, map.direct_vtimer->irq.irq); + kvm_irqchip_reset_mapped_irq(vcpu, map.direct_vtimer->irq.irq); if (map.direct_ptimer) - kvm_vgic_reset_mapped_irq(vcpu, map.direct_ptimer->irq.irq); + kvm_irqchip_reset_mapped_irq(vcpu, map.direct_ptimer->irq.irq); } } @@ -1139,18 +1139,18 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) get_timer_map(vcpu, &map); - ret = kvm_vgic_map_phys_irq(vcpu, - map.direct_vtimer->host_timer_irq, - map.direct_vtimer->irq.irq, - kvm_arch_timer_get_input_level); + ret = kvm_irqchip_map_phys_irq(vcpu, + map.direct_vtimer->host_timer_irq, + map.direct_vtimer->irq.irq, + kvm_arch_timer_get_input_level); if (ret) return ret; if (map.direct_ptimer) { - ret = kvm_vgic_map_phys_irq(vcpu, - map.direct_ptimer->host_timer_irq, - map.direct_ptimer->irq.irq, - kvm_arch_timer_get_input_level); + ret = kvm_irqchip_map_phys_irq(vcpu, + map.direct_ptimer->host_timer_irq, + map.direct_ptimer->irq.irq, + kvm_arch_timer_get_input_level); } if (ret) diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 7a8504a5b634..ed62c0a27b53 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -29,6 +29,10 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_vcpu_sync_hwstate = kvm_vgic_sync_hwstate, .irqchip_inject_irq = kvm_vgic_inject_irq, .irqchip_inject_userspace_irq = kvm_vgic_inject_userspace_irq, + .irqchip_map_is_active = kvm_vgic_map_is_active, + .irqchip_reset_mapped_irq = kvm_vgic_reset_mapped_irq, + .irqchip_map_phys_irq = kvm_vgic_map_phys_irq, + .irqchip_unmap_phys_irq = kvm_vgic_unmap_phys_irq, }; /* diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index cddbd9b951e4..af4a0e5f31c1 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -329,6 +329,12 @@ int vgic_v4_init(struct kvm *kvm); void vgic_v4_teardown(struct kvm *kvm); void vgic_v4_configure_vsgis(struct kvm *kvm); +bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); +void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid); +int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, + u32 vintid, bool (*get_input_level)(int)); +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); + int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); void kvm_vgic_load(struct kvm_vcpu *vcpu); diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index fba68129337d..ff8c49c0ebbd 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -339,17 +339,10 @@ int kvm_vgic_create(struct kvm *kvm, u32 type); int kvm_vgic_hyp_init(void); void kvm_vgic_init_cpu_hardware(void); -int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, - u32 vintid, bool (*get_input_level)(int vindid)); -int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); -bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); - #define vgic_initialized(k) ((k)->arch.vgic.initialized) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) -void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid); - void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1); /** From patchwork Thu Sep 3 15:26:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754233 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5F046109B for ; Thu, 3 Sep 2020 15:58:08 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 388542072A for ; Thu, 3 Sep 2020 15:58:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="1kkUxiNd"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="1oJVtoOj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 388542072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=gic1wG3YyizCfiLjEDetWIBtGpeAzwQ+dGzIEoCQVyI=; b=1kkUxiNdTPVBuOMrEIOiszkJw 0mJY80A9IES1Rqh5wMhQfwGwIPqZjQFOjRIITBXj3H4nrinL66mCGznMORhkX/YkPmU+FT1RXyNGj GI7yPxZycYQA+JPm5BLDlkz17IgIT1CvYwoEmQ8s6j2f2pKeWdwr0vI+EM7glssgvDOp/E/qjjTP0 xapHWKMC+Fq+KJoLWfIkgz5rwEe3XdeHp8FEXpdho10SUW3dWnlQaf31z9y3r8IC77QiZ9hRV+r9N vhrEa+0dqM5Xvouk9MUBD8INwIPZ7IaLZXGyBHi3isdGBmIkv6YaCHsrSYiOzFU0BtLjg188jdNFX M/bvbXK9w==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrbD-00010G-0A; Thu, 03 Sep 2020 15:56:31 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrao-0000po-3B for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:07 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 54E4B20775; Thu, 3 Sep 2020 15:56:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148565; bh=BmshpFlV+n7bQmpjLopkOVFKcvTuVvSTl9VMzmtkbv4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1oJVtoOjR7FgrGeGiYdGO8mweovEh7c6U9WSv1EPU8Y17MkDVEfGpwTE4B7OXAuTO qJEFPHJAIhL+WJu3ISTXo6V4rnG8vYzSrKWlzEu9w07rXUw3lw7SWXQoxbWSByqjv7 1veGfPOUuITYAykVdRc3pU0BMNCEt2Vu/h6mcAhg= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8B-008vT9-SM; Thu, 03 Sep 2020 16:26:31 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 18/23] KVM: arm64: Move set_owner into irqchip_flow Date: Thu, 3 Sep 2020 16:26:05 +0100 Message-Id: <20200903152610.1078827-19-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115606_295305_3F649774 X-CRM114-Status: GOOD ( 17.80 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Move the set_owner callback into irqchip_flow. It's not that useful an API anyway, and we should consider getting rid of it. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 4 ++++ arch/arm64/kvm/arch_timer.c | 4 ++-- arch/arm64/kvm/pmu-emul.c | 4 ++-- arch/arm64/kvm/vgic/vgic-init.c | 1 + arch/arm64/kvm/vgic/vgic.h | 1 + include/kvm/arm_vgic.h | 2 -- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 16556417bd4a..d1fc86b54f2d 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -38,6 +38,7 @@ struct kvm_irqchip_flow { int (*irqchip_map_phys_irq)(struct kvm_vcpu *, unsigned int, u32, bool (*)(int)); int (*irqchip_unmap_phys_irq)(struct kvm_vcpu *, unsigned int); + int (*irqchip_set_owner)(struct kvm_vcpu *, unsigned int, void *); }; /* @@ -114,4 +115,7 @@ struct kvm_irqchip_flow { #define kvm_irqchip_unmap_phys_irq(v, ...) \ __vcpu_irqchip_action_ret((v), unmap_phys_irq, (v), __VA_ARGS__) +#define kvm_irqchip_set_owner(v, ...) \ + __vcpu_irqchip_action_ret((v), set_owner, (v), __VA_ARGS__) + #endif diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 16999de299a7..706fd0c63273 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -1083,12 +1083,12 @@ static bool timer_irqs_are_valid(struct kvm_vcpu *vcpu) int i, ret; vtimer_irq = vcpu_vtimer(vcpu)->irq.irq; - ret = kvm_vgic_set_owner(vcpu, vtimer_irq, vcpu_vtimer(vcpu)); + ret = kvm_irqchip_set_owner(vcpu, vtimer_irq, vcpu_vtimer(vcpu)); if (ret) return false; ptimer_irq = vcpu_ptimer(vcpu)->irq.irq; - ret = kvm_vgic_set_owner(vcpu, ptimer_irq, vcpu_ptimer(vcpu)); + ret = kvm_irqchip_set_owner(vcpu, ptimer_irq, vcpu_ptimer(vcpu)); if (ret) return false; diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index f31ee6ad3444..d87f71845a64 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -758,8 +758,8 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu) if (!kvm_arm_pmu_irq_initialized(vcpu)) return -ENXIO; - ret = kvm_vgic_set_owner(vcpu, vcpu->arch.pmu.irq_num, - &vcpu->arch.pmu); + ret = kvm_irqchip_set_owner(vcpu, vcpu->arch.pmu.irq_num, + &vcpu->arch.pmu); if (ret) return ret; } diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index ed62c0a27b53..6ace624b439d 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -33,6 +33,7 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_reset_mapped_irq = kvm_vgic_reset_mapped_irq, .irqchip_map_phys_irq = kvm_vgic_map_phys_irq, .irqchip_unmap_phys_irq = kvm_vgic_unmap_phys_irq, + .irqchip_set_owner = kvm_vgic_set_owner, }; /* diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index af4a0e5f31c1..c9e14a6cddf6 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -334,6 +334,7 @@ void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid); int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, u32 vintid, bool (*get_input_level)(int)); int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); +int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index ff8c49c0ebbd..f753110e24f9 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -362,8 +362,6 @@ static inline int kvm_vgic_get_max_vcpus(void) */ int kvm_vgic_setup_default_irq_routing(struct kvm *kvm); -int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner); - struct kvm_kernel_irq_routing_entry; int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int irq, From patchwork Thu Sep 3 15:26:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754187 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4BB5F1575 for ; Thu, 3 Sep 2020 15:56:15 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 126A62072A for ; Thu, 3 Sep 2020 15:56:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="rMTmy3r+"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZqpRcPQi" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 126A62072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=W3Es7v3Z7brZqZDVrG0w7VTK2C8PvolyUPYUmT/2xbY=; b=rMTmy3r+ilygH6e/gQsbxk69Z ueo+wumVY3G/zPSLh8VhNVCrFlai1UdGBL/HIwdjYiuM7X1gJIDfO2EoqJM+0XA81cnicafERj97X i/2aA/a4FdFCno5eCLXvlH0dy+L/Oxh7FnaaK5/xR8RJVTQ/5ZVBZPblji3ZBVySQWnYV2T6b6MzG 7Tqfpv1VwNOWC6wsqzvarjnG43da90OVe7Qo9x4UWOcDihqDVcoeDDwP0AU2tY7ybj52WtuuYpfcd o/pfdXQPNB6U/B5Vxib2AZ23QA9fcEqM416BcCm37fCJd47IWWOBLeMP3upB+y/J/u9OeRbb7nq+n ZvSDEDpxQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDraf-0000n3-O5; Thu, 03 Sep 2020 15:55:57 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrab-0000ld-Bv for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:55:55 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id B013F206EB; Thu, 3 Sep 2020 15:55:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148552; bh=aNvBX7+Jljmjdh+CHU7/hx7wbOBWDbXatqazXXJSvAM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZqpRcPQisoNKI0gVqOggjtNQmLynd8+tjfKG9uUADfE5tsq0FY9PQ13mwDM1cEwox 48Xij+eNzDjh0i4KLCPw9MVl0UVjHb+6VvBQZU2I6bj/rWr/md3j5mJeu3lTGfI2pT z64fSaN4FFDkMSc+ygwazOr3aaj65p+5Ow+nRSH8= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8C-008vT9-E5; Thu, 03 Sep 2020 16:26:32 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 19/23] KVM: arm64: Turn vgic_initialized into irqchip_finalized Date: Thu, 3 Sep 2020 16:26:06 +0100 Message-Id: <20200903152610.1078827-20-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115553_814795_3C97A1BC X-CRM114-Status: GOOD ( 25.06 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org As we aim to make the core KVM/arm64 code GIC-agnostic, let's turn vgic_initialized into something more generic, and move the corresponding flag outside of the vgic data structure. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/include/asm/kvm_irq.h | 2 ++ arch/arm64/kvm/arch_timer.c | 2 +- arch/arm64/kvm/arm.c | 4 ++-- arch/arm64/kvm/pmu-emul.c | 2 +- arch/arm64/kvm/vgic/vgic-debug.c | 2 +- arch/arm64/kvm/vgic/vgic-init.c | 10 +++++----- arch/arm64/kvm/vgic/vgic-irqfd.c | 2 +- arch/arm64/kvm/vgic/vgic-its.c | 2 +- arch/arm64/kvm/vgic/vgic-kvm-device.c | 2 +- arch/arm64/kvm/vgic/vgic-v3.c | 2 +- arch/arm64/kvm/vgic/vgic.c | 10 +++++----- include/kvm/arm_vgic.h | 2 -- 13 files changed, 22 insertions(+), 21 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 52b502f3076f..5dd92873d40f 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -100,6 +100,7 @@ struct kvm_arch { /* Interrupt controller */ enum kvm_irqchip_type irqchip_type; + bool irqchip_finalized; struct kvm_irqchip_flow irqchip_flow; struct vgic_dist vgic; diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index d1fc86b54f2d..649b7d4c7e9f 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -17,6 +17,8 @@ enum kvm_irqchip_type { #define irqchip_is_gic_v2(k) ((k)->arch.irqchip_type == IRQCHIP_GICv2) #define irqchip_is_gic_v3(k) ((k)->arch.irqchip_type == IRQCHIP_GICv3) +#define irqchip_finalized(k) ((k)->arch.irqchip_finalized) + struct kvm_irqchip_flow { void (*irqchip_destroy)(struct kvm *); int (*irqchip_vcpu_init)(struct kvm_vcpu *); diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 706fd0c63273..9b84eb145ccd 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -1129,7 +1129,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) if (!irqchip_in_kernel(vcpu->kvm)) goto no_vgic; - if (!vgic_initialized(vcpu->kvm)) + if (!irqchip_finalized(vcpu->kvm)) return -ENODEV; if (!timer_irqs_are_valid(vcpu)) { diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 139f4154038b..678533871cfa 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -235,7 +235,7 @@ void kvm_arch_free_vm(struct kvm *kvm) int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) { - if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) + if (irqchip_in_kernel(kvm) && irqchip_finalized(kvm)) return -EBUSY; if (id >= kvm->arch.max_vcpus) @@ -525,7 +525,7 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) bool kvm_arch_intc_initialized(struct kvm *kvm) { - return vgic_initialized(kvm); + return (irqchip_in_kernel(kvm) && irqchip_finalized(kvm)); } void kvm_arm_halt_guest(struct kvm *kvm) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index d87f71845a64..2ab3b5288503 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -752,7 +752,7 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu) * implementation, we require the GIC to be already * initialized when initializing the PMU. */ - if (!vgic_initialized(vcpu->kvm)) + if (!irqchip_finalized(vcpu->kvm)) return -ENODEV; if (!kvm_arm_pmu_irq_initialized(vcpu)) diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c index 2d19fd55fc7b..feaccf41e33a 100644 --- a/arch/arm64/kvm/vgic/vgic-debug.c +++ b/arch/arm64/kvm/vgic/vgic-debug.c @@ -241,7 +241,7 @@ static int vgic_debug_show(struct seq_file *s, void *v) return 0; } - if (!kvm->arch.vgic.initialized) + if (!irqchip_finalized(kvm)) return 0; if (iter->vcpu_id < iter->nr_cpus) diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 6ace624b439d..a3e0389617a3 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -278,7 +278,7 @@ static void kvm_vgic_vcpu_enable(struct kvm_vcpu *vcpu) * - the number of vcpus * The function is generally called when nr_spis has been explicitly set * by the guest through the KVM DEVICE API. If not nr_spis is set to 256. - * vgic_initialized() returns true when this function has succeeded. + * irqchip_finalized() returns true when this function has succeeded. * Must be called with kvm->lock held! */ int vgic_init(struct kvm *kvm) @@ -287,7 +287,7 @@ int vgic_init(struct kvm *kvm) struct kvm_vcpu *vcpu; int ret = 0, i, idx; - if (vgic_initialized(kvm)) + if (irqchip_finalized(kvm)) return 0; /* Are we also in the middle of creating a VCPU? */ @@ -348,7 +348,7 @@ int vgic_init(struct kvm *kvm) vgic_debug_init(kvm); dist->implementation_rev = 2; - dist->initialized = true; + kvm->arch.irqchip_finalized = true; out: return ret; @@ -359,8 +359,8 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm) struct vgic_dist *dist = &kvm->arch.vgic; struct vgic_redist_region *rdreg, *next; + kvm->arch.irqchip_finalized = false; dist->ready = false; - dist->initialized = false; kfree(dist->spis); dist->spis = NULL; @@ -425,7 +425,7 @@ int vgic_lazy_init(struct kvm *kvm) { int ret = 0; - if (unlikely(!vgic_initialized(kvm))) { + if (unlikely(!irqchip_finalized(kvm))) { /* * We only provide the automatic initialization of the VGIC * for the legacy case of a GICv2. Any other type must diff --git a/arch/arm64/kvm/vgic/vgic-irqfd.c b/arch/arm64/kvm/vgic/vgic-irqfd.c index 79f8899b234c..dbece60c8dc0 100644 --- a/arch/arm64/kvm/vgic/vgic-irqfd.c +++ b/arch/arm64/kvm/vgic/vgic-irqfd.c @@ -124,7 +124,7 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, * Injecting SPIs is always possible in atomic context * as long as the damn vgic is initialized. */ - if (unlikely(!vgic_initialized(kvm))) + if (unlikely(!irqchip_finalized(kvm))) break; return vgic_irqfd_set_irq(e, kvm, irq_source_id, 1, line_status); } diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c index 40cbaca81333..5e715f71991d 100644 --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -1892,7 +1892,7 @@ static int vgic_its_create(struct kvm_device *dev, u32 type) if (!its) return -ENOMEM; - if (vgic_initialized(dev->kvm)) { + if (irqchip_finalized(dev->kvm)) { int ret = vgic_v4_init(dev->kvm); if (ret < 0) { kfree(its); diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c index 928afb224540..20654f318646 100644 --- a/arch/arm64/kvm/vgic/vgic-kvm-device.c +++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c @@ -532,7 +532,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev, mutex_lock(&dev->kvm->lock); - if (unlikely(!vgic_initialized(dev->kvm))) { + if (unlikely(!irqchip_finalized(dev->kvm))) { ret = -EBUSY; goto out; } diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index d176ad9bab85..938b73f3f8bf 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -522,7 +522,7 @@ int vgic_v3_map_resources(struct kvm *kvm) * For a VGICv3 we require the userland to explicitly initialize * the VGIC before we need to use it. */ - if (!vgic_initialized(kvm)) { + if (!irqchip_finalized(kvm)) { ret = -EBUSY; goto out; } diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index d676c010e45f..9cbbc24f8a95 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -577,7 +577,7 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid) struct vgic_irq *irq; unsigned long flags; - if (!vgic_initialized(vcpu->kvm)) + if (!irqchip_finalized(vcpu->kvm)) return -EAGAIN; irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); @@ -607,7 +607,7 @@ int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner) unsigned long flags; int ret = 0; - if (!vgic_initialized(vcpu->kvm)) + if (!irqchip_finalized(vcpu->kvm)) return -EAGAIN; /* SGIs and LPIs cannot be wired up to any device */ @@ -937,7 +937,7 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) void kvm_vgic_load(struct kvm_vcpu *vcpu) { - if (unlikely(!vgic_initialized(vcpu->kvm))) + if (unlikely(!irqchip_finalized(vcpu->kvm))) return; if (kvm_vgic_global_state.type == VGIC_V2) @@ -948,7 +948,7 @@ void kvm_vgic_load(struct kvm_vcpu *vcpu) void kvm_vgic_put(struct kvm_vcpu *vcpu) { - if (unlikely(!vgic_initialized(vcpu->kvm))) + if (unlikely(!irqchip_finalized(vcpu->kvm))) return; if (kvm_vgic_global_state.type == VGIC_V2) @@ -1044,7 +1044,7 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid) bool map_is_active; unsigned long flags; - if (!vgic_initialized(vcpu->kvm)) + if (!irqchip_finalized(vcpu->kvm)) return false; irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index f753110e24f9..cb1f66d373a4 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -202,7 +202,6 @@ struct vgic_redist_region { struct vgic_dist { bool ready; - bool initialized; /* Implementation revision as reported in the GICD_IIDR */ u32 implementation_rev; @@ -339,7 +338,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type); int kvm_vgic_hyp_init(void); void kvm_vgic_init_cpu_hardware(void); -#define vgic_initialized(k) ((k)->arch.vgic.initialized) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) From patchwork Thu Sep 3 15:26:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754229 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 473601575 for ; Thu, 3 Sep 2020 15:57:52 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0DC322072A for ; Thu, 3 Sep 2020 15:57:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="xtaDkxvW"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="eSB2VzPA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0DC322072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=yhXP7DLwMPnZbTqi6Cy3wtKRF8XblKp8M/z+a2orbd0=; b=xtaDkxvWzc1DduZsE1ZYMwSqc gm7jmCd/dCZX1B+ecyZ2cmiWrO0cqFJFuujaf/YD6tFg4hKoE/xY3Tl5my05x2B0W1vhav/rW61yp +mvcUEiC0SHVrQVcQW+4Pp0cwccYCuTvfdtQbFOGfew7RxslONloynZItnyLUcQS4AXK/3yUB9RNo uI7Rwdj/IWXBw2roLJ+HOADWoyswSKwUXDHw9JXd/bd8cj/onlYaz5Nz6DVmTIhRv8/4lHLIFNyCF A8pJ8B73YR8invBa9vG9e7WSomDdZrmzyEoYhU1JgSk4NJqYjwMEh5gV/pVkRQDuNCPxyyEtxdEPu XplOsi6hg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrai-0000nz-Td; Thu, 03 Sep 2020 15:56:00 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrad-0000m8-7W for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:55:56 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8549E206EF; Thu, 3 Sep 2020 15:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148554; bh=mIcx7QKvrQ/3Pi34zcPE1Rc2LMl3kMD/YYZYDG3ZIls=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eSB2VzPA6iOu/YGp9mhI8cNyyqD/69JylHkOAzB+6F7f3j+oG3n6brBMUZozKIaSM yBQJbhWeDbic3pVIsFfIIdY0rbln7bXRVFL1lbzqPNUAvT01ji+iaAMHk2cA2z/gUq Y9fE9rSGWPMvhdaGcqD2blX6Ja9fAMMKAeSsz1p0= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8D-008vT9-2Q; Thu, 03 Sep 2020 16:26:33 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 20/23] KVM: arm64: Move irqfd routing to irqchip_flow Date: Thu, 3 Sep 2020 16:26:07 +0100 Message-Id: <20200903152610.1078827-21-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115555_395431_8723CB0D X-CRM114-Status: GOOD ( 24.37 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org irqfd handling is still hidden away in the vgic code. Let's extract it and move the generic part in the non-GIC code, with the now required abstraction in the irqchip_flow struct. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_irq.h | 11 +++++ arch/arm64/kvm/arm.c | 68 ++++++++++++++++++++++++++++++ arch/arm64/kvm/vgic/vgic-init.c | 3 ++ arch/arm64/kvm/vgic/vgic-irqfd.c | 72 ++++++-------------------------- arch/arm64/kvm/vgic/vgic.h | 10 +++++ 5 files changed, 104 insertions(+), 60 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 649b7d4c7e9f..05fbe5241642 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -19,6 +19,8 @@ enum kvm_irqchip_type { #define irqchip_finalized(k) ((k)->arch.irqchip_finalized) +struct kvm_kernel_irq_routing_entry; + struct kvm_irqchip_flow { void (*irqchip_destroy)(struct kvm *); int (*irqchip_vcpu_init)(struct kvm_vcpu *); @@ -41,6 +43,15 @@ struct kvm_irqchip_flow { u32, bool (*)(int)); int (*irqchip_unmap_phys_irq)(struct kvm_vcpu *, unsigned int); int (*irqchip_set_owner)(struct kvm_vcpu *, unsigned int, void *); + int (*irqchip_irqfd_set_irq)(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status); + int (*irqchip_set_msi)(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status); + int (*irqchip_set_irq_inatomic)(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status); }; /* diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 678533871cfa..d625904633c0 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1592,6 +1592,74 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons) kvm_arm_resume_guest(irqfd->kvm); } +/** + * kvm_set_routing_entry: populate a kvm routing entry + * from a user routing entry + * + * @kvm: the VM this entry is applied to + * @e: kvm kernel routing entry handle + * @ue: user api routing entry handle + * return 0 on success, -EINVAL on errors. + */ +int kvm_set_routing_entry(struct kvm *kvm, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue) +{ + int r = -EINVAL; + + switch (ue->type) { + case KVM_IRQ_ROUTING_IRQCHIP: + e->set = kvm->arch.irqchip_flow.irqchip_irqfd_set_irq; + e->irqchip.irqchip = ue->u.irqchip.irqchip; + e->irqchip.pin = ue->u.irqchip.pin; + if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) || + (e->irqchip.irqchip >= KVM_NR_IRQCHIPS)) + goto out; + break; + case KVM_IRQ_ROUTING_MSI: + e->set = kvm->arch.irqchip_flow.irqchip_set_msi; + e->msi.address_lo = ue->u.msi.address_lo; + e->msi.address_hi = ue->u.msi.address_hi; + e->msi.data = ue->u.msi.data; + e->msi.flags = ue->flags; + e->msi.devid = ue->u.msi.devid; + break; + default: + goto out; + } + + if (!e->set) + goto out; + + r = 0; +out: + return r; +} + +int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status) +{ + if (!kvm->arch.irqchip_flow.irqchip_set_msi) + return -ENODEV; + return kvm->arch.irqchip_flow.irqchip_set_msi(e, kvm, irq_source_id, + level, line_status); +} + +int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, int level, + bool line_status) +{ + if (!level || !irqchip_finalized(kvm) || + !kvm->arch.irqchip_flow.irqchip_set_irq_inatomic) + return -EWOULDBLOCK; + + return kvm->arch.irqchip_flow.irqchip_set_irq_inatomic(e, kvm, + irq_source_id, + level, + line_status); +} + /** * Initialize Hyp-mode and memory mappings on all CPUs. */ diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index a3e0389617a3..440b8c09c030 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -34,6 +34,9 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_map_phys_irq = kvm_vgic_map_phys_irq, .irqchip_unmap_phys_irq = kvm_vgic_unmap_phys_irq, .irqchip_set_owner = kvm_vgic_set_owner, + .irqchip_irqfd_set_irq = vgic_irqfd_set_irq, + .irqchip_set_msi = vgic_set_msi, + .irqchip_set_irq_inatomic = vgic_set_irq_inatomic, }; /* diff --git a/arch/arm64/kvm/vgic/vgic-irqfd.c b/arch/arm64/kvm/vgic/vgic-irqfd.c index dbece60c8dc0..5bbdfe982a00 100644 --- a/arch/arm64/kvm/vgic/vgic-irqfd.c +++ b/arch/arm64/kvm/vgic/vgic-irqfd.c @@ -15,9 +15,9 @@ * * This is the entry point for irqfd IRQ injection */ -static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e, - struct kvm *kvm, int irq_source_id, - int level, bool line_status) +int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status) { unsigned int spi_id = e->irqchip.pin + VGIC_NR_PRIVATE_IRQS; @@ -26,46 +26,6 @@ static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e, return kvm_vgic_inject_irq(kvm, 0, spi_id, level, NULL); } -/** - * kvm_set_routing_entry: populate a kvm routing entry - * from a user routing entry - * - * @kvm: the VM this entry is applied to - * @e: kvm kernel routing entry handle - * @ue: user api routing entry handle - * return 0 on success, -EINVAL on errors. - */ -int kvm_set_routing_entry(struct kvm *kvm, - struct kvm_kernel_irq_routing_entry *e, - const struct kvm_irq_routing_entry *ue) -{ - int r = -EINVAL; - - switch (ue->type) { - case KVM_IRQ_ROUTING_IRQCHIP: - e->set = vgic_irqfd_set_irq; - e->irqchip.irqchip = ue->u.irqchip.irqchip; - e->irqchip.pin = ue->u.irqchip.pin; - if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) || - (e->irqchip.irqchip >= KVM_NR_IRQCHIPS)) - goto out; - break; - case KVM_IRQ_ROUTING_MSI: - e->set = kvm_set_msi; - e->msi.address_lo = ue->u.msi.address_lo; - e->msi.address_hi = ue->u.msi.address_hi; - e->msi.data = ue->u.msi.data; - e->msi.flags = ue->flags; - e->msi.devid = ue->u.msi.devid; - break; - default: - goto out; - } - r = 0; -out: - return r; -} - static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm_msi *msi) { @@ -75,16 +35,17 @@ static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e, msi->flags = e->msi.flags; msi->devid = e->msi.devid; } + /** - * kvm_set_msi: inject the MSI corresponding to the + * vgic_set_msi: inject the MSI corresponding to the * MSI routing entry * * This is the entry point for irqfd MSI injection * and userspace MSI injection. */ -int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, - struct kvm *kvm, int irq_source_id, - int level, bool line_status) +int vgic_set_msi(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status) { struct kvm_msi msi; @@ -99,15 +60,12 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, } /** - * kvm_arch_set_irq_inatomic: fast-path for irqfd injection + * vgic_set_irq_inatomic: fast-path for irqfd injection */ -int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, - struct kvm *kvm, int irq_source_id, int level, - bool line_status) +int vgic_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, int level, + bool line_status) { - if (!level) - return -EWOULDBLOCK; - switch (e->type) { case KVM_IRQ_ROUTING_MSI: { struct kvm_msi msi; @@ -120,12 +78,6 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, } case KVM_IRQ_ROUTING_IRQCHIP: - /* - * Injecting SPIs is always possible in atomic context - * as long as the damn vgic is initialized. - */ - if (unlikely(!irqchip_finalized(kvm))) - break; return vgic_irqfd_set_irq(e, kvm, irq_source_id, 1, line_status); } diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index c9e14a6cddf6..db3b111ed611 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -324,6 +324,16 @@ void vgic_lpi_translation_cache_init(struct kvm *kvm); void vgic_lpi_translation_cache_destroy(struct kvm *kvm); void vgic_its_invalidate_cache(struct kvm *kvm); +int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status); +int vgic_set_msi(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status); +int vgic_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, int level, + bool line_status); + bool vgic_supports_direct_msis(struct kvm *kvm); int vgic_v4_init(struct kvm *kvm); void vgic_v4_teardown(struct kvm *kvm); From patchwork Thu Sep 3 15:26:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754193 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0F9C9109B for ; Thu, 3 Sep 2020 15:56:18 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D746F2072A for ; Thu, 3 Sep 2020 15:56:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="WpgmJr87"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="HMS0YyIG" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D746F2072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=lh7F+haHwAikkKvz9HI0l76CShT3zgvhZaASqavPkDY=; b=WpgmJr87vIvjP3oDYB588cY3Q CCTOficHwZBu2n0z+BpPCrMlv0eA7eCVSm50h8JOzXpsK+Hk/ngVrlpVzpITRBcLntTj4meYtzpbo C8u4zjhY0iNNnyCxet/sp+LNSX/iy6M5LTDRUCA1MzOifXWkI2m8kjJFAz5ieX2AlVehkqhOEqJLt mH6Ze3It3Dj+ZaC3PeP8RUvRFiSEl2MrNYKNf4S0xjku8lwECgkw8I5OEqvyXPUazPSgcX2im9hsF 5U8cRMtbXdX4vIOy8n5GaNzpPRlSZ44T7qikV++tGRIAn12/saKvDX1oeaNDS9iRJ1SMJiuWL0Dry gAF+e5W9w==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDram-0000pB-J3; Thu, 03 Sep 2020 15:56:04 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrag-0000nW-Oy for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:00 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1F8652072A; Thu, 3 Sep 2020 15:55:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148558; bh=UawhsvvU+Wr870f+1lUBnJMX3SK6C5mCIOxqnEgbrsU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HMS0YyIG5G3YiDZO/NbUPiMufx4BuhOSssh8LXtEPBuM1jXbQSIljZeMSSnTXPxqU FPdoKtUwXC0rUL0OBW/O5Ah/o/SVcl9FLxJZIbYCOXWtAnl8Rdo3t0Ilf3MVc8cwRH kvJFmO4usBmSn+6M7LmldEi46maewGvHBC1a1ztM= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8D-008vT9-MV; Thu, 03 Sep 2020 16:26:34 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 21/23] KVM: arm64: Tighten msis_require_devid reporting Date: Thu, 3 Sep 2020 16:26:08 +0100 Message-Id: <20200903152610.1078827-22-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115558_965963_77937260 X-CRM114-Status: GOOD ( 13.28 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Although it is safe for now, do condition the returning of a msis_require_devid capability on the irqchip being a GICv3. Signed-off-by: Marc Zyngier --- arch/arm64/kvm/arm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index d625904633c0..0d4c8de27d1e 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -195,7 +195,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) if (!kvm) r = -EINVAL; else - r = kvm->arch.vgic.msis_require_devid; + r = (irqchip_is_gic_v3(kvm) && + kvm->arch.vgic.msis_require_devid); break; case KVM_CAP_ARM_USER_IRQ: /* From patchwork Thu Sep 3 15:26:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754197 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8344D109B for ; Thu, 3 Sep 2020 15:56:21 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4DA1C2072A for ; Thu, 3 Sep 2020 15:56:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Y4kcG8/a"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="NibJbE4r" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4DA1C2072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=5YEU2aiJTX0MsEzIOLC+oms9rLjgNVBtcxRJ77VD8Jg=; b=Y4kcG8/afRPBI484xwfA0LN0O aIsvtkeg3SP7jyUK+uteYAlMIgKWhF5uTFQPBGP+uJ1nsVWTOCmN5oB9gip0ocMcBXeITkRRLJ52C izGs9SiaZBTgHLS2fPIaePJGvLZokSZzKVEauIpucGTNzRe4EqpNsXOg9ZikOlo249L3xkm03ve/P hJ/1uy68cXxkUdlJ76djVfkPCD77F0nMc+6y9Y8LUGNkMnn5Uo0oBBi8C/zatJRO6mhiBxQRo/Kc3 1UFKZwIcxMRcG1VyUS4BsHcdG1TcS2OXrpTjA63YbeAiOiXXNg1vaebPS8+prSezWbpU/2v/czzQg e8/AWiMpA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDraq-0000qI-3I; Thu, 03 Sep 2020 15:56:08 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDraf-0000mv-3d for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:01 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 40770206EB; Thu, 3 Sep 2020 15:55:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148556; bh=+d5yRirkWJi4nfpAdhWaHUqFaI6Y4YjU38BcHqu0mfY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NibJbE4rMMCsw7WnDGNJ9A9a5O2D/ExuaHLblGkEbYoUajxGDqQhRZSn6eWN4dqhG YC1C3jsSMsL76MGEwsEhkzshukhwU0avoYsjOMDDbcmCYGUDcOsDUFmfwUGX9DlXGy pGJPmgw+Zxq39B8YWY5rMG8uy5FhQvmkODlr9p08= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8F-008vT9-2t; Thu, 03 Sep 2020 16:26:36 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 22/23] KVM: arm64: Add a rVIC/rVID in-kernel implementation Date: Thu, 3 Sep 2020 16:26:09 +0100 Message-Id: <20200903152610.1078827-23-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115557_288402_DE4314C0 X-CRM114-Status: GOOD ( 32.27 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The rVIC (reduced Virtual Interrupt Controller), and its rVID (reduced Virtual Interrupt Distributor) companion are the two parts of a PV interrupt controller architecture, aiming at supporting VMs with minimal interrupt requirements. Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_host.h | 7 +- arch/arm64/include/asm/kvm_irq.h | 2 + arch/arm64/include/uapi/asm/kvm.h | 9 + arch/arm64/kvm/Makefile | 2 +- arch/arm64/kvm/arm.c | 3 + arch/arm64/kvm/hypercalls.c | 7 + arch/arm64/kvm/rvic-cpu.c | 1073 +++++++++++++++++++++++++++++ include/kvm/arm_rvic.h | 41 ++ include/linux/irqchip/irq-rvic.h | 4 + include/uapi/linux/kvm.h | 2 + 10 files changed, 1148 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/kvm/rvic-cpu.c create mode 100644 include/kvm/arm_rvic.h diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 5dd92873d40f..381d3ff6e0b7 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -35,6 +35,7 @@ #include #include #include +#include #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS @@ -102,6 +103,7 @@ struct kvm_arch { enum kvm_irqchip_type irqchip_type; bool irqchip_finalized; struct kvm_irqchip_flow irqchip_flow; + void *irqchip_data; struct vgic_dist vgic; /* Mandated version of PSCI */ @@ -324,7 +326,10 @@ struct kvm_vcpu_arch { } host_debug_state; /* VGIC state */ - struct vgic_cpu vgic_cpu; + union { + struct vgic_cpu vgic_cpu; + struct rvic rvic; + }; struct arch_timer_cpu timer_cpu; struct kvm_pmu pmu; diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 05fbe5241642..bb1666093f80 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -11,11 +11,13 @@ enum kvm_irqchip_type { IRQCHIP_USER, /* Implemented in userspace */ IRQCHIP_GICv2, /* v2 on v2, or v2 on v3 */ IRQCHIP_GICv3, /* v3 on v3 */ + IRQCHIP_RVIC, /* PV irqchip */ }; #define irqchip_in_kernel(k) ((k)->arch.irqchip_type != IRQCHIP_USER) #define irqchip_is_gic_v2(k) ((k)->arch.irqchip_type == IRQCHIP_GICv2) #define irqchip_is_gic_v3(k) ((k)->arch.irqchip_type == IRQCHIP_GICv3) +#define irqchip_is_rvic(k) ((k)->arch.irqchip_type == IRQCHIP_RVIC) #define irqchip_finalized(k) ((k)->arch.irqchip_finalized) diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index ba85bb23f060..9fc26c84903f 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -335,6 +335,15 @@ struct kvm_vcpu_events { #define KVM_ARM_VCPU_PVTIME_CTRL 2 #define KVM_ARM_VCPU_PVTIME_IPA 0 +/* + * Device Control API: ARM RVIC. We only use the group, not the group + * attributes. They must be set to 0 for now. + */ +#define KVM_DEV_ARM_RVIC_GRP_NR_IRQS 0 +#define KVM_DEV_ARM_RVIC_GRP_NR_TRUSTED_MASK 0xffff +#define KVM_DEV_ARM_RVIC_GRP_NR_TOTAL_MASK (0xffff << 16) +#define KVM_DEV_ARM_RVIC_GRP_INIT 1 + /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_VCPU2_SHIFT 28 #define KVM_ARM_IRQ_VCPU2_MASK 0xf diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 99977c1972cc..e378293ce99b 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -16,7 +16,7 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ inject_fault.o regmap.o va_layout.o hyp.o handle_exit.o \ guest.o debug.o reset.o sys_regs.o \ vgic-sys-reg-v3.o fpsimd.o pmu.o \ - aarch32.o arch_timer.o \ + aarch32.o arch_timer.o rvic-cpu.o \ vgic/vgic.o vgic/vgic-init.o \ vgic/vgic-irqfd.o vgic/vgic-v2.o \ vgic/vgic-v3.o vgic/vgic-v4.o \ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 0d4c8de27d1e..bf0b11bdce84 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef REQUIRES_VIRT __asm__(".arch_extension virt"); @@ -1402,6 +1403,8 @@ static int init_subsystems(void) switch (err) { case 0: vgic_present = true; + if (kvm_register_rvic_device()) + kvm_err("Failed to register rvic device type\n"); break; case -ENODEV: case -ENXIO: diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 550dfa3e53cd..f6620be74ce5 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -8,6 +8,9 @@ #include #include +#include + +#include int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) { @@ -62,6 +65,10 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) if (gpa != GPA_INVALID) val = gpa; break; + case SMC64_RVIC_BASE ... SMC64_RVIC_LAST: + return kvm_rvic_handle_hcall(vcpu); + case SMC64_RVID_BASE ... SMC64_RVID_LAST: + return kvm_rvid_handle_hcall(vcpu); default: return kvm_psci_call(vcpu); } diff --git a/arch/arm64/kvm/rvic-cpu.c b/arch/arm64/kvm/rvic-cpu.c new file mode 100644 index 000000000000..5fb200c637d9 --- /dev/null +++ b/arch/arm64/kvm/rvic-cpu.c @@ -0,0 +1,1073 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * rVIC/rVID PV interrupt controller implementation for KVM/arm64. + * + * Copyright 2020 Google LLC. + * Author: Marc Zyngier + */ + +#include +#include +#include +#include + +#include +#include + +#include + +/* FIXME: lock/unlock_all_vcpus */ +#include "vgic/vgic.h" + +#define kvm_vcpu_to_rvic(v) (&(v)->arch.rvic) +#define kvm_rvic_to_vcpu(r) (container_of((r), struct kvm_vcpu, arch.rvic)) + +#define rvic_nr_untrusted(r) ((r)->nr_total - (r)->nr_trusted) + +struct rvic_vm_data { + u16 nr_trusted; + u16 nr_total; + spinlock_t lock; + /* Map is a dynamically allocated array of (total-trusted) elements */ + struct { + u16 target_vcpu; + u16 intid; + } rvid_map[]; +}; + +/* + * rvic_irq state machine: + * + * idle <- S/C -> pending + * ^ / ^ + * | / | + * U/M A U/M + * | / | + * v v V + * masked <- S/C -> masked+pending + * + * [S]: Set Pending, [C]: Clear Pending + * [U]: Unmask, [M]: Mask + * [A]: Ack + */ + +static struct rvic_irq *rvic_get_irq(struct rvic *rvic, unsigned int intid) +{ + if (intid >= rvic->nr_total) + return NULL; + return &rvic->irqs[intid]; +} + +static bool rvic_irq_queued(struct rvic_irq *irq) +{ + return !list_empty(&irq->delivery_entry); +} + +/* RVIC primitives. They all imply that the RVIC lock is held */ +static void __rvic_enable(struct rvic *rvic) +{ + rvic->enabled = true; +} + +static void __rvic_disable(struct rvic *rvic) +{ + rvic->enabled = false; +} + +static bool __rvic_is_enabled(struct rvic *rvic) +{ + return rvic->enabled; +} + +static void __rvic_set_pending(struct rvic *rvic, unsigned int intid) +{ + struct rvic_irq *irq = rvic_get_irq(rvic, intid); + unsigned long flags; + + if (!__rvic_is_enabled(rvic)) { + pr_debug("dropping intid %u\n", intid); + return; + } + + spin_lock_irqsave(&irq->lock, flags); + + irq->pending = true; + if (!irq->masked && !rvic_irq_queued(irq)) + list_add_tail(&irq->delivery_entry, &rvic->delivery); + + spin_unlock_irqrestore(&irq->lock, flags); +} + +static void __rvic_clear_pending(struct rvic *rvic, unsigned int intid) +{ + struct rvic_irq *irq = rvic_get_irq(rvic, intid); + unsigned long flags; + + spin_lock_irqsave(&irq->lock, flags); + + irq->pending = false; + list_del_init(&irq->delivery_entry); + + spin_unlock_irqrestore(&irq->lock, flags); +} + +static bool __rvic_is_pending(struct rvic *rvic, unsigned int intid) +{ + struct rvic_irq *irq = rvic_get_irq(rvic, intid); + unsigned long flags; + bool pend; + + spin_lock_irqsave(&irq->lock, flags); + pend = irq->pending; + spin_unlock_irqrestore(&irq->lock, flags); + + return pend; +} + +static void __rvic_set_masked(struct rvic *rvic, unsigned int intid) +{ + struct rvic_irq *irq = rvic_get_irq(rvic, intid); + unsigned long flags; + + spin_lock_irqsave(&irq->lock, flags); + + irq->masked = true; + if (irq->pending) + list_del_init(&irq->delivery_entry); + + spin_unlock_irqrestore(&irq->lock, flags); +} + +static void __rvic_clear_masked(struct rvic *rvic, unsigned int intid) +{ + struct rvic_irq *irq = rvic_get_irq(rvic, intid); + unsigned long flags; + + spin_lock_irqsave(&irq->lock, flags); + + irq->masked = false; + if (__rvic_is_enabled(rvic) && irq->pending && !rvic_irq_queued(irq)) + list_add_tail(&irq->delivery_entry, &rvic->delivery); + + spin_unlock_irqrestore(&irq->lock, flags); +} + +static unsigned int __rvic_ack(struct rvic *rvic) +{ + unsigned int intid = ~0U; + struct rvic_irq *irq; + + if (!__rvic_is_enabled(rvic)) + return intid; + + irq = list_first_entry_or_null(&rvic->delivery, struct rvic_irq, + delivery_entry); + if (irq) { + intid = irq->intid; + __rvic_set_masked(rvic, intid); + __rvic_clear_pending(rvic, intid); + } + + return intid; +} + +static bool __rvic_can_signal(struct rvic *rvic) +{ + return __rvic_is_enabled(rvic) && !list_empty(&rvic->delivery); +} + +static void __rvic_resample(struct rvic *rvic, unsigned int intid) +{ + struct rvic_irq *irq = rvic_get_irq(rvic, intid); + unsigned long flags; + bool pending; + + spin_lock_irqsave(&irq->lock, flags); + if (irq->get_line_level) { + pending = irq->get_line_level(irq->intid); + + /* + * As part of the resampling, tickle the GIC so that + * new interrupts can trickle in. + */ + if (!pending && irq->host_irq) + irq_set_irqchip_state(irq->host_irq, + IRQCHIP_STATE_ACTIVE, false); + } else { + pending = irq->line_level; + } + + spin_unlock_irqrestore(&irq->lock, flags); + + if (pending) + __rvic_set_pending(rvic, intid); +} + +/* + * rVIC hypercall handling. All functions assume they are being called + * from the vcpu thread that triggers the hypercall. + */ +static void __rvic_kick_vcpu(struct kvm_vcpu *vcpu) +{ + kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); + kvm_vcpu_kick(vcpu); +} + +static void __rvic_sync_hcr(struct kvm_vcpu *vcpu, struct rvic *rvic, + bool was_signaling) +{ + struct kvm_vcpu *target = kvm_rvic_to_vcpu(rvic); + bool signal = __rvic_can_signal(rvic); + + /* We're hitting our own rVIC: update HCR_VI locally */ + if (vcpu == target) { + if (signal) + *vcpu_hcr(vcpu) |= HCR_VI; + else + *vcpu_hcr(vcpu) &= ~HCR_VI; + + return; + } + + /* + * Remote rVIC case: + * + * We kick even if the interrupt disappears, as ISR_EL1.I must + * always reflect the state of the rVIC. This forces a reload + * of the vcpu state, making it consistent. + * + * This avoids modifying the target's own copy of HCR_EL2, as + * we are in a cross-vcpu call, and changing it from under its + * feet is dodgy. + */ + if (was_signaling != signal) + __rvic_kick_vcpu(target); +} + +static void rvic_version(struct kvm_vcpu *vcpu) +{ + /* ALP0.3 is the name of the game */ + smccc_set_retval(vcpu, RVIC_STATUS_SUCCESS, RVIC_VERSION(0, 3), 0, 0); +} + +static void rvic_info(struct kvm_vcpu *vcpu) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + unsigned long what = smccc_get_arg1(vcpu); + unsigned long a0, a1; + + switch (what) { + case RVIC_INFO_KEY_NR_TRUSTED_INTERRUPTS: + a0 = RVIx_STATUS_PACK(RVIC_STATUS_SUCCESS, 0); + a1 = rvic->nr_trusted; + break; + case RVIC_INFO_KEY_NR_UNTRUSTED_INTERRUPTS: + a0 = RVIx_STATUS_PACK(RVIC_STATUS_SUCCESS, 0); + a1 = rvic_nr_untrusted(rvic); + break; + default: + a0 = RVIx_STATUS_PACK(RVIC_STATUS_ERROR_PARAMETER, 0); + a1 = 0; + break; + } + + smccc_set_retval(vcpu, a0, a1, 0, 0); +} + +static void rvic_enable(struct kvm_vcpu *vcpu) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + unsigned long flags; + bool was_signaling; + + spin_lock_irqsave(&rvic->lock, flags); + + was_signaling = __rvic_can_signal(rvic); + __rvic_enable(rvic); + __rvic_sync_hcr(vcpu, rvic, was_signaling); + + spin_unlock_irqrestore(&rvic->lock, flags); + + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVIC_STATUS_SUCCESS, 0), + 0, 0, 0); +} + +static void rvic_disable(struct kvm_vcpu *vcpu) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + unsigned long flags; + bool was_signaling; + + spin_lock_irqsave(&rvic->lock, flags); + + was_signaling = __rvic_can_signal(rvic); + __rvic_disable(rvic); + __rvic_sync_hcr(vcpu, rvic, was_signaling); + + spin_unlock_irqrestore(&rvic->lock, flags); + + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVIC_STATUS_SUCCESS, 0), + 0, 0, 0); +} + +typedef void (*rvic_action_fn_t)(struct rvic *, unsigned int); + +static int validate_rvic_call(struct kvm_vcpu *vcpu, struct rvic **rvicp, + unsigned int *intidp) +{ + unsigned long mpidr = smccc_get_arg1(vcpu); + unsigned int intid = smccc_get_arg2(vcpu); + struct kvm_vcpu *target; + struct rvic *rvic; + + /* FIXME: The spec distinguishes between invalid MPIDR and invalid CPU */ + + target = kvm_mpidr_to_vcpu(vcpu->kvm, mpidr); + if (!target) { + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVIC_STATUS_INVALID_CPU, 0), + 0, 0, 0); + return -1; + } + + rvic = kvm_vcpu_to_rvic(target); + if (intid >= rvic->nr_total) { + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVIC_STATUS_ERROR_PARAMETER, 1), + 0, 0, 0); + return -1; + } + + *rvicp = rvic; + *intidp = intid; + + return 0; +} + +static void __rvic_action(struct kvm_vcpu *vcpu, rvic_action_fn_t action, + bool check_enabled) +{ + struct rvic *rvic; + unsigned long a0; + unsigned long flags; + int intid; + + if (validate_rvic_call(vcpu, &rvic, &intid)) + return; + + spin_lock_irqsave(&rvic->lock, flags); + + if (unlikely(check_enabled && !__rvic_is_enabled(rvic))) { + a0 = RVIx_STATUS_PACK(RVIC_STATUS_DISABLED, 0); + } else { + bool was_signaling = __rvic_can_signal(rvic); + action(rvic, intid); + __rvic_sync_hcr(vcpu, rvic, was_signaling); + a0 = RVIx_STATUS_PACK(RVIC_STATUS_SUCCESS, 0); + } + + spin_unlock_irqrestore(&rvic->lock, flags); + + smccc_set_retval(vcpu, a0, 0, 0, 0); +} + +static void rvic_set_masked(struct kvm_vcpu *vcpu) +{ + __rvic_action(vcpu, __rvic_set_masked, false); +} + +static void rvic_clear_masked(struct kvm_vcpu *vcpu) +{ + __rvic_action(vcpu, __rvic_clear_masked, false); +} + +static void rvic_clear_pending(struct kvm_vcpu *vcpu) +{ + __rvic_action(vcpu, __rvic_clear_pending, false); +} + +static void rvic_signal(struct kvm_vcpu *vcpu) +{ + __rvic_action(vcpu, __rvic_set_pending, true); +} + +static void rvic_is_pending(struct kvm_vcpu *vcpu) +{ + unsigned long flags; + struct rvic *rvic; + int intid; + bool res; + + if (validate_rvic_call(vcpu, &rvic, &intid)) + return; + + spin_lock_irqsave(&rvic->lock, flags); + + res = __rvic_is_pending(rvic, intid); + + spin_unlock_irqrestore(&rvic->lock, flags); + + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVIC_STATUS_SUCCESS, 0), + res, 0, 0); +} + +/* + * Ack and Resample are the only "interesting" operations that are + * strictly per-CPU. + */ +static void rvic_acknowledge(struct kvm_vcpu *vcpu) +{ + unsigned long a0, a1; + unsigned long flags; + unsigned int intid; + struct rvic *rvic; + + rvic = kvm_vcpu_to_rvic(vcpu); + + spin_lock_irqsave(&rvic->lock, flags); + + if (unlikely(!__rvic_is_enabled(rvic))) { + a0 = RVIx_STATUS_PACK(RVIC_STATUS_DISABLED, 0); + a1 = 0; + } else { + intid = __rvic_ack(rvic); + __rvic_sync_hcr(vcpu, rvic, true); + if (unlikely(intid >= rvic->nr_total)) { + a0 = RVIx_STATUS_PACK(RVIC_STATUS_NO_INTERRUPTS, 0); + a1 = 0; + } else { + a0 = RVIx_STATUS_PACK(RVIC_STATUS_SUCCESS, 0); + a1 = intid; + } + } + + spin_unlock_irqrestore(&rvic->lock, flags); + + smccc_set_retval(vcpu, a0, a1, 0, 0); +} + +static void rvic_resample(struct kvm_vcpu *vcpu) +{ + unsigned int intid = smccc_get_arg1(vcpu); + unsigned long flags; + unsigned long a0; + struct rvic *rvic; + + rvic = kvm_vcpu_to_rvic(vcpu); + + spin_lock_irqsave(&rvic->lock, flags); + + if (unlikely(intid >= rvic->nr_trusted)) { + a0 = RVIx_STATUS_PACK(RVIC_STATUS_ERROR_PARAMETER, 0); + } else { + __rvic_resample(rvic, intid); + + /* + * Don't bother finding out if we were signalling, we + * will update HCR_EL2 anyway as we are guaranteed not + * to be in a cross-call. + */ + __rvic_sync_hcr(vcpu, rvic, true); + a0 = RVIx_STATUS_PACK(RVIC_STATUS_SUCCESS, 0); + } + + spin_unlock_irqrestore(&rvic->lock, flags); + + smccc_set_retval(vcpu, a0, 0, 0, 0); +} + +int kvm_rvic_handle_hcall(struct kvm_vcpu *vcpu) +{ + pr_debug("RVIC: HC %08x", (unsigned int)smccc_get_function(vcpu)); + switch (smccc_get_function(vcpu)) { + case SMC64_RVIC_VERSION: + rvic_version(vcpu); + break; + case SMC64_RVIC_INFO: + rvic_info(vcpu); + break; + case SMC64_RVIC_ENABLE: + rvic_enable(vcpu); + break; + case SMC64_RVIC_DISABLE: + rvic_disable(vcpu); + break; + case SMC64_RVIC_SET_MASKED: + rvic_set_masked(vcpu); + break; + case SMC64_RVIC_CLEAR_MASKED: + rvic_clear_masked(vcpu); + break; + case SMC64_RVIC_IS_PENDING: + rvic_is_pending(vcpu); + break; + case SMC64_RVIC_SIGNAL: + rvic_signal(vcpu); + break; + case SMC64_RVIC_CLEAR_PENDING: + rvic_clear_pending(vcpu); + break; + case SMC64_RVIC_ACKNOWLEDGE: + rvic_acknowledge(vcpu); + break; + case SMC64_RVIC_RESAMPLE: + rvic_resample(vcpu); + break; + default: + smccc_set_retval(vcpu, SMCCC_RET_NOT_SUPPORTED, 0, 0, 0); + break; + } + + return 1; +} + +static void rvid_version(struct kvm_vcpu *vcpu) +{ + /* ALP0.3 is the name of the game */ + smccc_set_retval(vcpu, RVID_STATUS_SUCCESS, RVID_VERSION(0, 3), 0, 0); +} + +static void rvid_map(struct kvm_vcpu *vcpu) +{ + unsigned long input = smccc_get_arg1(vcpu); + unsigned long mpidr = smccc_get_arg2(vcpu); + unsigned int intid = smccc_get_arg3(vcpu); + unsigned long flags; + struct rvic_vm_data *data; + struct kvm_vcpu *target; + + data = vcpu->kvm->arch.irqchip_data; + + if (input > rvic_nr_untrusted(data)) { + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVID_STATUS_ERROR_PARAMETER, 0), + 0, 0, 0); + return; + } + + /* FIXME: different error from RVIC. Why? */ + target = kvm_mpidr_to_vcpu(vcpu->kvm, mpidr); + if (!target) { + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVID_STATUS_ERROR_PARAMETER, 1), + 0, 0, 0); + return; + } + + if (intid < data->nr_trusted || intid >= data->nr_total) { + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVID_STATUS_ERROR_PARAMETER, 2), + 0, 0, 0); + return; + } + + spin_lock_irqsave(&data->lock, flags); + data->rvid_map[input].target_vcpu = target->vcpu_id; + data->rvid_map[input].intid = intid; + spin_unlock_irqrestore(&data->lock, flags); + + smccc_set_retval(vcpu, 0, 0, 0, 0); +} + +static void rvid_unmap(struct kvm_vcpu *vcpu) +{ + unsigned long input = smccc_get_arg1(vcpu); + unsigned long flags; + struct rvic_vm_data *data; + + data = vcpu->kvm->arch.irqchip_data; + + if (input > rvic_nr_untrusted(data)) { + smccc_set_retval(vcpu, RVIx_STATUS_PACK(RVID_STATUS_ERROR_PARAMETER, 0), + 0, 0, 0); + return; + } + + spin_lock_irqsave(&data->lock, flags); + data->rvid_map[input].target_vcpu = 0; + data->rvid_map[input].intid = 0; + spin_unlock_irqrestore(&data->lock, flags); + + smccc_set_retval(vcpu, 0, 0, 0, 0); +} + +int kvm_rvid_handle_hcall(struct kvm_vcpu *vcpu) +{ + pr_debug("RVID: HC %08x", (unsigned int)smccc_get_function(vcpu)); + switch (smccc_get_function(vcpu)) { + case SMC64_RVID_VERSION: + rvid_version(vcpu); + break; + case SMC64_RVID_MAP: + rvid_map(vcpu); + break; + case SMC64_RVID_UNMAP: + rvid_unmap(vcpu); + break; + default: + smccc_set_retval(vcpu, SMCCC_RET_NOT_SUPPORTED, 0, 0, 0); + break; + } + + return 1; +} + +/* + * KVM internal interface to the rVIC + */ + +/* This *must* be called from the vcpu thread */ +static void rvic_flush_signaling_state(struct kvm_vcpu *vcpu) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + unsigned long flags; + + spin_lock_irqsave(&rvic->lock, flags); + + __rvic_sync_hcr(vcpu, rvic, true); + + spin_unlock_irqrestore(&rvic->lock, flags); +} + +/* This can be called from any context */ +static void rvic_vcpu_inject_irq(struct kvm_vcpu *vcpu, unsigned int intid, + bool level) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + unsigned long flags; + bool prev; + + spin_lock_irqsave(&rvic->lock, flags); + + if (WARN_ON(intid >= rvic->nr_total)) + goto out; + + /* + * Although really ugly, this should be safe as we hold the + * rvic lock, and the only path that uses this information is + * resample, which takes this lock too. + */ + if (!rvic->irqs[intid].get_line_level) + rvic->irqs[intid].line_level = level; + + if (level) { + prev = __rvic_can_signal(rvic); + __rvic_set_pending(rvic, intid); + if (prev != __rvic_can_signal(rvic)) + __rvic_kick_vcpu(vcpu); + } +out: + spin_unlock_irqrestore(&rvic->lock, flags); +} + +static int rvic_inject_irq(struct kvm *kvm, unsigned int cpu, + unsigned int intid, bool level, void *owner) +{ + struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, cpu); + struct rvic *rvic; + + if (unlikely(!vcpu)) + return -EINVAL; + + rvic = kvm_vcpu_to_rvic(vcpu); + if (unlikely(intid >= rvic->nr_total)) + return -EINVAL; + + /* Ignore interrupt owner for now */ + rvic_vcpu_inject_irq(vcpu, intid, level); + return 0; +} + +static int rvic_inject_userspace_irq(struct kvm *kvm, unsigned int type, + unsigned int cpu, + unsigned int intid, bool level) +{ + struct rvic_vm_data *data = kvm->arch.irqchip_data; + unsigned long flags; + u16 output; + + switch (type) { + case KVM_ARM_IRQ_TYPE_SPI: + /* + * Userspace can only inject interrupts that are + * translated by the rvid, so the cpu parameter is + * irrelevant and we override it when resolving the + * translation. + */ + if (intid >= rvic_nr_untrusted(data)) + return -EINVAL; + + spin_lock_irqsave(&data->lock, flags); + output = data->rvid_map[intid].intid; + cpu = data->rvid_map[intid].target_vcpu; + spin_unlock_irqrestore(&data->lock, flags); + + /* Silently ignore unmapped interrupts */ + if (output < data->nr_trusted) + return 0; + + return rvic_inject_irq(kvm, cpu, output, level, NULL); + default: + return -EINVAL; + } +} + +static int rvic_vcpu_init(struct kvm_vcpu *vcpu) +{ + struct rvic_vm_data *data = vcpu->kvm->arch.irqchip_data; + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + int i; + + /* irqchip not ready yet, we will come back later */ + if (!data) + return 0; + + if (WARN_ON(rvic->irqs)) + return -EINVAL; + + spin_lock_init(&rvic->lock); + INIT_LIST_HEAD(&rvic->delivery); + rvic->nr_trusted = data->nr_trusted; + rvic->nr_total = data->nr_total; + rvic->enabled = false; + + rvic->irqs = kcalloc(rvic->nr_total, sizeof(*rvic->irqs), GFP_ATOMIC); + if (!rvic->irqs) + return -ENOMEM; + + for (i = 0; i < rvic->nr_total; i++) { + struct rvic_irq *irq = &rvic->irqs[i]; + + spin_lock_init(&irq->lock); + INIT_LIST_HEAD(&irq->delivery_entry); + irq->get_line_level = NULL; + irq->intid = i; + irq->host_irq = 0; + irq->pending = false; + irq->masked = true; + irq->line_level = false; + } + + return 0; +} + +static void rvic_destroy(struct kvm *kvm) +{ + struct kvm_vcpu *vcpu; + int i; + + mutex_lock(&kvm->lock); + + kvm_for_each_vcpu(i, vcpu, kvm) { + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + + INIT_LIST_HEAD(&rvic->delivery); + kfree(rvic->irqs); + rvic->irqs = NULL; + } + + mutex_unlock(&kvm->lock); +} + +static int rvic_pending_irq(struct kvm_vcpu *vcpu) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + unsigned long flags; + bool res; + + spin_lock_irqsave(&rvic->lock, flags); + res = __rvic_can_signal(rvic); + spin_unlock_irqrestore(&rvic->lock, flags); + + return res; +} + +static int rvic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, + u32 intid, bool (*get_line_level)(int)) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + struct rvic_irq *irq = rvic_get_irq(rvic, intid); + unsigned long flags; + + spin_lock_irqsave(&irq->lock, flags); + irq->host_irq = host_irq; + irq->get_line_level = get_line_level; + spin_unlock_irqrestore(&irq->lock, flags); + + return 0; +} + +static int rvic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int intid) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + struct rvic_irq *irq = rvic_get_irq(rvic, intid); + unsigned long flags; + + spin_lock_irqsave(&irq->lock, flags); + irq->host_irq = 0; + irq->get_line_level = NULL; + spin_unlock_irqrestore(&irq->lock, flags); + + return 0; +} + +static int rvic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status) +{ + /* Abuse the userspace interface to perform the routing*/ + return rvic_inject_userspace_irq(kvm, KVM_ARM_IRQ_TYPE_SPI, 0, + e->irqchip.pin, level); +} + +static int rvic_set_msi(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status) +{ + return -ENODEV; +} + +static int rvic_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, + int level, bool line_status) +{ + if (e->type != KVM_IRQ_ROUTING_IRQCHIP) + return -EWOULDBLOCK; + + return rvic_irqfd_set_irq(e, kvm, irq_source_id, level, line_status); +} + +static const struct kvm_irqchip_flow rvic_irqchip_flow = { + .irqchip_destroy = rvic_destroy, + .irqchip_vcpu_init = rvic_vcpu_init, + /* Nothing to do on block/unblock */ + /* Nothing to do on load/put */ + .irqchip_vcpu_pending_irq = rvic_pending_irq, + .irqchip_vcpu_flush_hwstate = rvic_flush_signaling_state, + /* Nothing tp do on sync_hwstate */ + .irqchip_inject_irq = rvic_inject_irq, + .irqchip_inject_userspace_irq = rvic_inject_userspace_irq, + /* No reset_mapped_irq as we allow spurious interrupts */ + .irqchip_map_phys_irq = rvic_map_phys_irq, + .irqchip_unmap_phys_irq = rvic_unmap_phys_irq, + .irqchip_irqfd_set_irq = rvic_irqfd_set_irq, + .irqchip_set_msi = rvic_set_msi, + .irqchip_set_irq_inatomic = rvic_set_irq_inatomic, +}; + +static int rvic_setup_default_irq_routing(struct kvm *kvm) +{ + struct rvic_vm_data *data = kvm->arch.irqchip_data; + unsigned int nr = rvic_nr_untrusted(data); + struct kvm_irq_routing_entry *entries; + int i, ret; + + entries = kcalloc(nr, sizeof(*entries), GFP_KERNEL); + if (!entries) + return -ENOMEM; + + for (i = 0; i < nr; i++) { + entries[i].gsi = i; + entries[i].type = KVM_IRQ_ROUTING_IRQCHIP; + entries[i].u.irqchip.irqchip = 0; + entries[i].u.irqchip.pin = i; + } + ret = kvm_set_irq_routing(kvm, entries, nr, 0); + kfree(entries); + return ret; +} + +/* Device management */ +static int rvic_device_create(struct kvm_device *dev, u32 type) +{ + struct kvm *kvm = dev->kvm; + struct kvm_vcpu *vcpu; + int i, ret; + + if (irqchip_in_kernel(kvm)) + return -EEXIST; + + ret = -EBUSY; + if (!lock_all_vcpus(kvm)) + return ret; + + kvm_for_each_vcpu(i, vcpu, kvm) { + if (vcpu->arch.has_run_once) + goto out_unlock; + } + + ret = 0; + + /* + * The good thing about not having any HW is that you don't + * get the limitations of the HW... + */ + kvm->arch.max_vcpus = KVM_MAX_VCPUS; + kvm->arch.irqchip_type = IRQCHIP_RVIC; + kvm->arch.irqchip_flow = rvic_irqchip_flow; + kvm->arch.irqchip_data = NULL; + +out_unlock: + unlock_all_vcpus(kvm); + return ret; +} + +static void rvic_device_destroy(struct kvm_device *dev) +{ + kfree(dev->kvm->arch.irqchip_data); + kfree(dev); +} + +static int rvic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) +{ + struct rvic_vm_data *data; + struct kvm_vcpu *vcpu; + u32 __user *uaddr, val; + u16 trusted, total; + int i, ret = -ENXIO; + + mutex_lock(&dev->kvm->lock); + + switch (attr->group) { + case KVM_DEV_ARM_RVIC_GRP_NR_IRQS: + if (attr->attr) + break; + + if (dev->kvm->arch.irqchip_data) { + ret = -EBUSY; + break; + } + + uaddr = (u32 __user *)(uintptr_t)attr->addr; + if (get_user(val, uaddr)) { + ret = -EFAULT; + break; + } + + trusted = FIELD_GET(KVM_DEV_ARM_RVIC_GRP_NR_TRUSTED_MASK, val); + total = FIELD_GET(KVM_DEV_ARM_RVIC_GRP_NR_TOTAL_MASK, val); + if (total < trusted || trusted < 32 || total < 64 || + trusted % 32 || total % 32 || total > 2048) { + ret = -EINVAL; + break; + } + + data = kzalloc(struct_size(data, rvid_map, (total - trusted)), + GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + break; + } + + data->nr_trusted = trusted; + data->nr_total = total; + spin_lock_init(&data->lock); + /* Default to no mapping */ + for (i = 0; i < (total - trusted); i++) { + /* + * an intid < nr_trusted is invalid as the + * result of a translation through the rvid, + * hence the input in unmapped. + */ + data->rvid_map[i].target_vcpu = 0; + data->rvid_map[i].intid = 0; + } + + dev->kvm->arch.irqchip_data = data; + + ret = 0; + break; + + case KVM_DEV_ARM_RVIC_GRP_INIT: + if (attr->attr) + break; + + if (!dev->kvm->arch.irqchip_data) + break; + + ret = 0; + + /* Init the rvic on any already created vcpu */ + kvm_for_each_vcpu(i, vcpu, dev->kvm) { + ret = rvic_vcpu_init(vcpu); + if (ret) + break; + } + + if (!ret) + ret = rvic_setup_default_irq_routing(dev->kvm); + if (!ret) + dev->kvm->arch.irqchip_finalized = true; + break; + + default: + break; + } + + mutex_unlock(&dev->kvm->lock); + + return ret; +} + +static int rvic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr) +{ + struct rvic_vm_data *data; + u32 __user *uaddr, val; + int ret = -ENXIO; + + mutex_lock(&dev->kvm->lock); + + switch (attr->group) { + case KVM_DEV_ARM_RVIC_GRP_NR_IRQS: + if (attr->attr) + break; + + data = dev->kvm->arch.irqchip_data; + if (!data) + break; + + val = FIELD_PREP(KVM_DEV_ARM_RVIC_GRP_NR_TRUSTED_MASK, + data->nr_trusted); + val |= FIELD_PREP(KVM_DEV_ARM_RVIC_GRP_NR_TOTAL_MASK, + data->nr_total); + + uaddr = (u32 __user *)(uintptr_t)attr->addr; + ret = put_user(val, uaddr); + break; + + default: + break; + } + + mutex_unlock(&dev->kvm->lock); + + return ret; +} + +static int rvic_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr) +{ + int ret = -ENXIO; + + switch (attr->group) { + case KVM_DEV_ARM_RVIC_GRP_NR_IRQS: + case KVM_DEV_ARM_RVIC_GRP_INIT: + if (attr->attr) + break; + ret = 0; + break; + + default: + break; + } + + return ret; +} + +static const struct kvm_device_ops rvic_dev_ops = { + .name = "kvm-arm-rvic", + .create = rvic_device_create, + .destroy = rvic_device_destroy, + .set_attr = rvic_set_attr, + .get_attr = rvic_get_attr, + .has_attr = rvic_has_attr, +}; + +int kvm_register_rvic_device(void) +{ + return kvm_register_device_ops(&rvic_dev_ops, KVM_DEV_TYPE_ARM_RVIC); +} diff --git a/include/kvm/arm_rvic.h b/include/kvm/arm_rvic.h new file mode 100644 index 000000000000..9e67a83fa384 --- /dev/null +++ b/include/kvm/arm_rvic.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * rVIC/rVID PV interrupt controller implementation for KVM/arm64. + * + * Copyright 2020 Google LLC. + * Author: Marc Zyngier + */ + +#ifndef __KVM_ARM_RVIC_H__ +#define __KVM_ARM_RVIC_H__ + +#include +#include + +struct kvm_vcpu; + +struct rvic_irq { + spinlock_t lock; + struct list_head delivery_entry; + bool (*get_line_level)(int intid); + unsigned int intid; + unsigned int host_irq; + bool pending; + bool masked; + bool line_level; /* If get_line_level == NULL */ +}; + +struct rvic { + spinlock_t lock; + struct list_head delivery; + struct rvic_irq *irqs; + unsigned int nr_trusted; + unsigned int nr_total; + bool enabled; +}; + +int kvm_rvic_handle_hcall(struct kvm_vcpu *vcpu); +int kvm_rvid_handle_hcall(struct kvm_vcpu *vcpu); +int kvm_register_rvic_device(void); + +#endif diff --git a/include/linux/irqchip/irq-rvic.h b/include/linux/irqchip/irq-rvic.h index 4545c1e89741..b188773729fb 100644 --- a/include/linux/irqchip/irq-rvic.h +++ b/include/linux/irqchip/irq-rvic.h @@ -57,6 +57,8 @@ #define SMC64_RVIC_ACKNOWLEDGE SMC64_RVIC_FN(9) #define SMC64_RVIC_RESAMPLE SMC64_RVIC_FN(10) +#define SMC64_RVIC_LAST SMC64_RVIC_RESAMPLE + #define RVIC_INFO_KEY_NR_TRUSTED_INTERRUPTS 0 #define RVIC_INFO_KEY_NR_UNTRUSTED_INTERRUPTS 1 @@ -82,6 +84,8 @@ #define SMC64_RVID_MAP SMC64_RVID_FN(1) #define SMC64_RVID_UNMAP SMC64_RVID_FN(2) +#define SMC64_RVID_LAST SMC64_RVID_UNMAP + #define RVID_VERSION(M, m) RVIx_VERSION((M), (m)) #define RVID_VERSION_MAJOR(v) RVIx_VERSION_MAJOR((v)) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index f6d86033c4fa..6d245d2dc9e6 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1264,6 +1264,8 @@ enum kvm_device_type { #define KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_ARM_PV_TIME, #define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME + KVM_DEV_TYPE_ARM_RVIC, +#define KVM_DEV_TYPE_ARM_RVIC KVM_DEV_TYPE_ARM_RVIC KVM_DEV_TYPE_MAX, }; From patchwork Thu Sep 3 15:26:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 11754227 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7210C109B for ; Thu, 3 Sep 2020 15:57:49 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 48D282072A for ; Thu, 3 Sep 2020 15:57:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="jpuELGGv"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="s/yMoN+W" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 48D282072A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=G/UTPThkmCuFvrv9OuAboi2FgMKemIJkd2AoA7TuliM=; b=jpuELGGveTagjP0H0xhhUnTB6 jwUiP++Gh8YuckwmGgoniaGVqiUWEN6bzrgpl7ZWIvdEZMS5Cf6kQ/csKdJetDelUPrzVEDtC15d/ JtCgbPcJC91QoCaRxqVSEwidLGvpPXl/2ZS9WREJCvsof1LhBy6dMODeiXrgHC/GNqpyZCuxN/GZW +koQVvkiIuWnvKmDvUK/PhMVImid6GAtykUuGBDfZdCCEAbhiHZJL8zic83uMeEH9Yy4PJ1KVYOKs yvz86GtmchwMwZgrLV9bnu14UmloCMN6vV7RTc1GlN78CHJSQu0aUQGMOnN1eVGqBFEhNu/r0qRsE 71Ae/3vNg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDrcC-0001Ze-PE; Thu, 03 Sep 2020 15:57:33 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kDray-0000tu-5Q for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2020 15:56:17 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 350A020775; Thu, 3 Sep 2020 15:56:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599148575; bh=EUAnw+lWQ+cQMNjPnrjGEu/3OgEkhBEkYZ7J3y/Lfa4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=s/yMoN+W2anQfzITjpc+JTuk6Xq6VnN3WDqBgtQAQZiT/Yphxl771Tpeg6fORHqPl vdhN46HuDry2tT0/F2jjip/4/e0eREqymzdJG7NrJPF2YnfG+cEd+zvXBre+fkR+mA PP5EGIM97bGGCgaQ1AzkIROOTrNkZVlMe2P7OtT0= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kDr8G-008vT9-JA; Thu, 03 Sep 2020 16:26:37 +0100 From: Marc Zyngier To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 23/23] KVM: arm64: Add debugfs files for the rVIC/rVID implementation Date: Thu, 3 Sep 2020 16:26:10 +0100 Message-Id: <20200903152610.1078827-24-maz@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903152610.1078827-1-maz@kernel.org> References: <20200903152610.1078827-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, Christoffer.Dall@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200903_115616_376188_5EE509FB X-CRM114-Status: GOOD ( 20.68 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lorenzo Pieralisi , Suzuki K Poulose , Christoffer Dall , James Morse , kernel-team@android.com, Julien Thierry Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org It turns out that having these debugfs information is really useful when trying to understand what is going wrong in a guest, or even in the host kernel... Signed-off-by: Marc Zyngier --- arch/arm64/kvm/rvic-cpu.c | 140 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/arch/arm64/kvm/rvic-cpu.c b/arch/arm64/kvm/rvic-cpu.c index 5fb200c637d9..0e91bf6633d5 100644 --- a/arch/arm64/kvm/rvic-cpu.c +++ b/arch/arm64/kvm/rvic-cpu.c @@ -6,6 +6,7 @@ * Author: Marc Zyngier */ +#include #include #include #include @@ -707,6 +708,8 @@ static int rvic_inject_userspace_irq(struct kvm *kvm, unsigned int type, } } +static void rvic_create_debugfs(struct kvm_vcpu *vcpu); + static int rvic_vcpu_init(struct kvm_vcpu *vcpu) { struct rvic_vm_data *data = vcpu->kvm->arch.irqchip_data; @@ -743,6 +746,8 @@ static int rvic_vcpu_init(struct kvm_vcpu *vcpu) irq->line_level = false; } + rvic_create_debugfs(vcpu); + return 0; } @@ -913,6 +918,8 @@ static void rvic_device_destroy(struct kvm_device *dev) kfree(dev); } +static void rvid_create_debugfs(struct kvm *kvm); + static int rvic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { struct rvic_vm_data *data; @@ -969,6 +976,7 @@ static int rvic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) } dev->kvm->arch.irqchip_data = data; + rvid_create_debugfs(dev->kvm); ret = 0; break; @@ -1071,3 +1079,135 @@ int kvm_register_rvic_device(void) { return kvm_register_device_ops(&rvic_dev_ops, KVM_DEV_TYPE_ARM_RVIC); } + +static void rvic_irq_debug_show_one(struct seq_file *s, struct rvic_irq *irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq->lock, flags); + + seq_printf(s, "%d: [%d] %c %c %ps %c %c\n", + irq->intid, irq->host_irq, + irq->pending ? 'P' : 'p', + irq->masked ? 'M' : 'm', + irq->get_line_level, + irq->get_line_level ? 'x' : (irq->line_level ? 'H' : 'L'), + rvic_irq_queued(irq) ? 'Q' : 'i'); + + spin_unlock_irqrestore(&irq->lock, flags); +} + +static int rvic_irq_debug_show(struct seq_file *s, void *p) +{ + rvic_irq_debug_show_one(s, s->private); + return 0; +} + +static int rvic_irq_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, rvic_irq_debug_show, inode->i_private); +} + +static const struct file_operations rvic_irq_debug_fops = { + .open = rvic_irq_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int rvic_debug_show(struct seq_file *s, void *p) +{ + struct kvm_vcpu *vcpu = s->private; + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + struct rvic_irq *irq; + unsigned long flags; + + spin_lock_irqsave(&rvic->lock, flags); + + seq_printf(s, "%s\n", rvic->enabled ? "Enabled" : "Disabled"); + seq_printf(s, "%d Trusted\n", rvic->nr_trusted); + seq_printf(s, "%d Total\n", rvic->nr_total); + list_for_each_entry(irq, &rvic->delivery, delivery_entry) + rvic_irq_debug_show_one(s, irq); + + spin_unlock_irqrestore(&rvic->lock, flags); + + return 0; +} + +static int rvic_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, rvic_debug_show, inode->i_private); +} + +static const struct file_operations rvic_debug_fops = { + .open = rvic_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void rvic_create_debugfs(struct kvm_vcpu *vcpu) +{ + struct rvic *rvic = kvm_vcpu_to_rvic(vcpu); + struct dentry *rvic_root; + char dname[128]; + int i; + + snprintf(dname, sizeof(dname), "rvic-%d", vcpu->vcpu_id); + rvic_root = debugfs_create_dir(dname, vcpu->kvm->debugfs_dentry); + if (!rvic_root) + return; + + debugfs_create_file("state", 0444, rvic_root, vcpu, &rvic_debug_fops); + for (i = 0; i < rvic->nr_total; i++) { + snprintf(dname, sizeof(dname), "%d", i); + debugfs_create_file(dname, 0444, rvic_root, + rvic_get_irq(rvic, i), + &rvic_irq_debug_fops); + } +} + +static int rvid_debug_show(struct seq_file *s, void *p) +{ + struct kvm *kvm = s->private; + struct rvic_vm_data *data = kvm->arch.irqchip_data; + unsigned long flags; + int i; + + spin_lock_irqsave(&data->lock, flags); + + seq_printf(s, "%d Trusted\n", data->nr_trusted); + seq_printf(s, "%d Total\n", data->nr_total); + + for (i = 0; i < rvic_nr_untrusted(data); i++) { + if (data->rvid_map[i].intid < data->nr_trusted) + continue; + + seq_printf(s, "%4u: vcpu-%u %u\n", + i, data->rvid_map[i].target_vcpu, + data->rvid_map[i].intid); + } + + spin_unlock_irqrestore(&data->lock, flags); + + return 0; +} + +static int rvid_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, rvid_debug_show, inode->i_private); +} + +static const struct file_operations rvid_debug_fops = { + .open = rvid_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void rvid_create_debugfs(struct kvm *kvm) +{ + debugfs_create_file("rvid", 0444, kvm->debugfs_dentry, + kvm, &rvid_debug_fops); +}