From patchwork Thu Feb 25 00:58:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC718C433DB for ; Thu, 25 Feb 2021 01:01:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7C51364EC4 for ; Thu, 25 Feb 2021 01:01:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235673AbhBYBBW (ORCPT ); Wed, 24 Feb 2021 20:01:22 -0500 Received: from foss.arm.com ([217.140.110.172]:58248 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233299AbhBYBBN (ORCPT ); Wed, 24 Feb 2021 20:01:13 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AFAF1101E; Wed, 24 Feb 2021 17:00:27 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 650B13F73B; Wed, 24 Feb 2021 17:00:26 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 01/22] ioport: Remove ioport__setup_arch() Date: Thu, 25 Feb 2021 00:58:54 +0000 Message-Id: <20210225005915.26423-2-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Since x86 had a special need for registering tons of special I/O ports, we had an ioport__setup_arch() callback, to allow each architecture to do the same. As it turns out no one uses it beside x86, so we remove that unnecessary abstraction. The generic function was registered via a device_base_init() call, so we just do the same for the x86 specific function only, and can remove the unneeded ioport__setup_arch(). Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- arm/ioport.c | 5 ----- include/kvm/ioport.h | 1 - ioport.c | 6 ------ mips/kvm.c | 5 ----- powerpc/ioport.c | 6 ------ x86/ioport.c | 3 ++- 6 files changed, 2 insertions(+), 24 deletions(-) diff --git a/arm/ioport.c b/arm/ioport.c index 2f0feb9a..24092c9d 100644 --- a/arm/ioport.c +++ b/arm/ioport.c @@ -1,11 +1,6 @@ #include "kvm/ioport.h" #include "kvm/irq.h" -int ioport__setup_arch(struct kvm *kvm) -{ - return 0; -} - void ioport__map_irq(u8 *irq) { *irq = irq__alloc_line(); diff --git a/include/kvm/ioport.h b/include/kvm/ioport.h index 039633f7..d0213541 100644 --- a/include/kvm/ioport.h +++ b/include/kvm/ioport.h @@ -35,7 +35,6 @@ struct ioport_operations { enum irq_type)); }; -int ioport__setup_arch(struct kvm *kvm); void ioport__map_irq(u8 *irq); int __must_check ioport__register(struct kvm *kvm, u16 port, struct ioport_operations *ops, diff --git a/ioport.c b/ioport.c index 844a832d..a6972179 100644 --- a/ioport.c +++ b/ioport.c @@ -221,12 +221,6 @@ out: return !kvm->cfg.ioport_debug; } -int ioport__init(struct kvm *kvm) -{ - return ioport__setup_arch(kvm); -} -dev_base_init(ioport__init); - int ioport__exit(struct kvm *kvm) { ioport__unregister_all(); diff --git a/mips/kvm.c b/mips/kvm.c index 26355930..e110e5d5 100644 --- a/mips/kvm.c +++ b/mips/kvm.c @@ -100,11 +100,6 @@ void kvm__irq_trigger(struct kvm *kvm, int irq) die_perror("KVM_IRQ_LINE ioctl"); } -int ioport__setup_arch(struct kvm *kvm) -{ - return 0; -} - bool kvm__arch_cpu_supports_vm(void) { return true; diff --git a/powerpc/ioport.c b/powerpc/ioport.c index 0c188b61..a5cff4ee 100644 --- a/powerpc/ioport.c +++ b/powerpc/ioport.c @@ -12,12 +12,6 @@ #include -int ioport__setup_arch(struct kvm *kvm) -{ - /* PPC has no legacy ioports to set up */ - return 0; -} - void ioport__map_irq(u8 *irq) { } diff --git a/x86/ioport.c b/x86/ioport.c index 7ad7b8f3..a8d2bb1a 100644 --- a/x86/ioport.c +++ b/x86/ioport.c @@ -69,7 +69,7 @@ void ioport__map_irq(u8 *irq) { } -int ioport__setup_arch(struct kvm *kvm) +static int ioport__setup_arch(struct kvm *kvm) { int r; @@ -150,3 +150,4 @@ int ioport__setup_arch(struct kvm *kvm) return 0; } +dev_base_init(ioport__setup_arch); From patchwork Thu Feb 25 00:58:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103019 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 40C86C433E0 for ; Thu, 25 Feb 2021 01:01:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ED8CC64EF1 for ; Thu, 25 Feb 2021 01:01:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234586AbhBYBB1 (ORCPT ); Wed, 24 Feb 2021 20:01:27 -0500 Received: from foss.arm.com ([217.140.110.172]:58258 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236161AbhBYBBP (ORCPT ); Wed, 24 Feb 2021 20:01:15 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 411471063; Wed, 24 Feb 2021 17:00:29 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EA5DD3F73B; Wed, 24 Feb 2021 17:00:27 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 02/22] hw/serial: Use device abstraction for FDT generator function Date: Thu, 25 Feb 2021 00:58:55 +0000 Message-Id: <20210225005915.26423-3-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org At the moment we use the .generate_fdt_node member of the ioport ops structure to store the function pointer for the FDT node generator function. ioport__register() will then put a wrapper and this pointer into the device header. The serial device is the only device making use of this special ioport feature, so let's move this over to using the device header directly. This will allow us to get rid of this .generate_fdt_node member in the ops and simplify the code. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- hw/serial.c | 49 +++++++++++++++++++++++++++++++++++++---------- include/kvm/kvm.h | 2 ++ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/hw/serial.c b/hw/serial.c index 13c4663e..b0465d99 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -23,6 +23,7 @@ #define UART_IIR_TYPE_BITS 0xc0 struct serial8250_device { + struct device_header dev_hdr; struct mutex mutex; u8 id; @@ -53,9 +54,20 @@ struct serial8250_device { .msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS, \ .mcr = UART_MCR_OUT2, +#ifdef CONFIG_HAS_LIBFDT +static +void serial8250_generate_fdt_node(void *fdt, struct device_header *dev_hdr, + fdt_irq_fn irq_fn); +#else +#define serial8250_generate_fdt_node NULL +#endif static struct serial8250_device devices[] = { /* ttyS0 */ [0] = { + .dev_hdr = { + .bus_type = DEVICE_BUS_IOPORT, + .data = serial8250_generate_fdt_node, + }, .mutex = MUTEX_INITIALIZER, .id = 0, @@ -66,6 +78,10 @@ static struct serial8250_device devices[] = { }, /* ttyS1 */ [1] = { + .dev_hdr = { + .bus_type = DEVICE_BUS_IOPORT, + .data = serial8250_generate_fdt_node, + }, .mutex = MUTEX_INITIALIZER, .id = 1, @@ -76,6 +92,10 @@ static struct serial8250_device devices[] = { }, /* ttyS2 */ [2] = { + .dev_hdr = { + .bus_type = DEVICE_BUS_IOPORT, + .data = serial8250_generate_fdt_node, + }, .mutex = MUTEX_INITIALIZER, .id = 2, @@ -86,6 +106,10 @@ static struct serial8250_device devices[] = { }, /* ttyS3 */ [3] = { + .dev_hdr = { + .bus_type = DEVICE_BUS_IOPORT, + .data = serial8250_generate_fdt_node, + }, .mutex = MUTEX_INITIALIZER, .id = 3, @@ -371,13 +395,14 @@ char *fdt_stdout_path = NULL; #define DEVICE_NAME_MAX_LEN 32 static -void serial8250_generate_fdt_node(struct ioport *ioport, void *fdt, - void (*generate_irq_prop)(void *fdt, - u8 irq, - enum irq_type)) +void serial8250_generate_fdt_node(void *fdt, struct device_header *dev_hdr, + fdt_irq_fn irq_fn) { char dev_name[DEVICE_NAME_MAX_LEN]; - struct serial8250_device *dev = ioport->priv; + struct serial8250_device *dev = container_of(dev_hdr, + struct serial8250_device, + dev_hdr); + u64 addr = KVM_IOPORT_AREA + dev->iobase; u64 reg_prop[] = { cpu_to_fdt64(addr), @@ -395,24 +420,26 @@ void serial8250_generate_fdt_node(struct ioport *ioport, void *fdt, _FDT(fdt_begin_node(fdt, dev_name)); _FDT(fdt_property_string(fdt, "compatible", "ns16550a")); _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop))); - generate_irq_prop(fdt, dev->irq, IRQ_TYPE_LEVEL_HIGH); + irq_fn(fdt, dev->irq, IRQ_TYPE_LEVEL_HIGH); _FDT(fdt_property_cell(fdt, "clock-frequency", 1843200)); _FDT(fdt_end_node(fdt)); } -#else -#define serial8250_generate_fdt_node NULL #endif static struct ioport_operations serial8250_ops = { .io_in = serial8250_in, .io_out = serial8250_out, - .generate_fdt_node = serial8250_generate_fdt_node, }; -static int serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev) +static int serial8250__device_init(struct kvm *kvm, + struct serial8250_device *dev) { int r; + r = device__register(&dev->dev_hdr); + if (r < 0) + return r; + ioport__map_irq(&dev->irq); r = ioport__register(kvm, dev->iobase, &serial8250_ops, 8, dev); @@ -438,6 +465,7 @@ cleanup: struct serial8250_device *dev = &devices[j]; ioport__unregister(kvm, dev->iobase); + device__unregister(&dev->dev_hdr); } return r; @@ -455,6 +483,7 @@ int serial8250__exit(struct kvm *kvm) r = ioport__unregister(kvm, dev->iobase); if (r < 0) return r; + device__unregister(&dev->dev_hdr); } return 0; diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h index 53373b08..f1f0afd7 100644 --- a/include/kvm/kvm.h +++ b/include/kvm/kvm.h @@ -31,6 +31,8 @@ .name = #ext, \ .code = ext +typedef void (*fdt_irq_fn)(void *fdt, u8 irq, enum irq_type irq_type); + enum { KVM_VMSTATE_RUNNING, KVM_VMSTATE_PAUSED, From patchwork Thu Feb 25 00:58:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103021 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6766CC433E6 for ; Thu, 25 Feb 2021 01:01:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1B46264F0C for ; Thu, 25 Feb 2021 01:01:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235642AbhBYBBj (ORCPT ); Wed, 24 Feb 2021 20:01:39 -0500 Received: from foss.arm.com ([217.140.110.172]:58270 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236574AbhBYBBR (ORCPT ); Wed, 24 Feb 2021 20:01:17 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id CA100113E; Wed, 24 Feb 2021 17:00:30 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7B99A3F73B; Wed, 24 Feb 2021 17:00:29 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 03/22] ioport: Retire .generate_fdt_node functionality Date: Thu, 25 Feb 2021 00:58:56 +0000 Message-Id: <20210225005915.26423-4-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The ioport routines support a special way of registering FDT node generator functions. There is no reason to have this separate from the already existing way via the device header. Now that the only user of this special ioport variety has been transferred, we can retire this code, to simplify ioport handling. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- include/kvm/ioport.h | 4 ---- ioport.c | 34 ---------------------------------- 2 files changed, 38 deletions(-) diff --git a/include/kvm/ioport.h b/include/kvm/ioport.h index d0213541..a61038e2 100644 --- a/include/kvm/ioport.h +++ b/include/kvm/ioport.h @@ -29,10 +29,6 @@ struct ioport { struct ioport_operations { bool (*io_in)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size); bool (*io_out)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size); - void (*generate_fdt_node)(struct ioport *ioport, void *fdt, - void (*generate_irq_prop)(void *fdt, - u8 irq, - enum irq_type)); }; void ioport__map_irq(u8 *irq); diff --git a/ioport.c b/ioport.c index a6972179..e0123f27 100644 --- a/ioport.c +++ b/ioport.c @@ -56,7 +56,6 @@ static struct ioport *ioport_get(struct rb_root *root, u64 addr) /* Called with ioport_lock held. */ static void ioport_unregister(struct rb_root *root, struct ioport *data) { - device__unregister(&data->dev_hdr); ioport_remove(root, data); free(data); } @@ -70,30 +69,6 @@ static void ioport_put(struct rb_root *root, struct ioport *data) mutex_unlock(&ioport_lock); } -#ifdef CONFIG_HAS_LIBFDT -static void generate_ioport_fdt_node(void *fdt, - struct device_header *dev_hdr, - void (*generate_irq_prop)(void *fdt, - u8 irq, - enum irq_type)) -{ - struct ioport *ioport = container_of(dev_hdr, struct ioport, dev_hdr); - struct ioport_operations *ops = ioport->ops; - - if (ops->generate_fdt_node) - ops->generate_fdt_node(ioport, fdt, generate_irq_prop); -} -#else -static void generate_ioport_fdt_node(void *fdt, - struct device_header *dev_hdr, - void (*generate_irq_prop)(void *fdt, - u8 irq, - enum irq_type)) -{ - die("Unable to generate device tree nodes without libfdt\n"); -} -#endif - int ioport__register(struct kvm *kvm, u16 port, struct ioport_operations *ops, int count, void *param) { struct ioport *entry; @@ -107,10 +82,6 @@ int ioport__register(struct kvm *kvm, u16 port, struct ioport_operations *ops, i .node = RB_INT_INIT(port, port + count), .ops = ops, .priv = param, - .dev_hdr = (struct device_header) { - .bus_type = DEVICE_BUS_IOPORT, - .data = generate_ioport_fdt_node, - }, /* * Start from 0 because ioport__unregister() doesn't decrement * the reference count. @@ -123,15 +94,10 @@ int ioport__register(struct kvm *kvm, u16 port, struct ioport_operations *ops, i r = ioport_insert(&ioport_tree, entry); if (r < 0) goto out_free; - r = device__register(&entry->dev_hdr); - if (r < 0) - goto out_remove; mutex_unlock(&ioport_lock); return port; -out_remove: - ioport_remove(&ioport_tree, entry); out_free: free(entry); mutex_unlock(&ioport_lock); From patchwork Thu Feb 25 00:58:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103023 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8B3BC433E9 for ; Thu, 25 Feb 2021 01:01:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8FE7564EF1 for ; Thu, 25 Feb 2021 01:01:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235334AbhBYBBo (ORCPT ); Wed, 24 Feb 2021 20:01:44 -0500 Received: from foss.arm.com ([217.140.110.172]:58286 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236592AbhBYBBT (ORCPT ); Wed, 24 Feb 2021 20:01:19 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 651AE11D4; Wed, 24 Feb 2021 17:00:32 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0E8C13F800; Wed, 24 Feb 2021 17:00:30 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 04/22] mmio: Extend handling to include ioport emulation Date: Thu, 25 Feb 2021 00:58:57 +0000 Message-Id: <20210225005915.26423-5-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org In their core functionality MMIO and I/O port traps are not really different, yet we still have two totally separate code paths for handling them. Devices need to decide on one conduit or need to provide different handler functions for each of them. Extend the existing MMIO emulation to also cover ioport handlers. This just adds another RB tree root for holding the I/O port handlers, but otherwise uses the same tree population and lookup code. "ioport" or "mmio" just become a flag in the registration function. Provide wrappers to not break existing users, and allow an easy transition for the existing ioport handlers. This also means that ioport handlers now can use the same emulation callback prototype as MMIO handlers, which means we have to migrate them over. To allow a smooth transition, we hook up the new I/O emulate function to the end of the existing ioport emulation code. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- include/kvm/kvm.h | 49 ++++++++++++++++++++++++++++++++--- ioport.c | 4 +-- mmio.c | 65 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 102 insertions(+), 16 deletions(-) diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h index f1f0afd7..306b258a 100644 --- a/include/kvm/kvm.h +++ b/include/kvm/kvm.h @@ -27,10 +27,23 @@ #define PAGE_SIZE (sysconf(_SC_PAGE_SIZE)) #endif +/* + * We are reusing the existing DEVICE_BUS_MMIO and DEVICE_BUS_IOPORT constants + * from kvm/devices.h to differentiate between registering an I/O port and an + * MMIO region. + * To avoid collisions with future additions of more bus types, we reserve + * a generous 4 bits for the bus mask here. + */ +#define IOTRAP_BUS_MASK 0xf +#define IOTRAP_COALESCE (1U << 4) + #define DEFINE_KVM_EXT(ext) \ .name = #ext, \ .code = ext +struct kvm_cpu; +typedef void (*mmio_handler_fn)(struct kvm_cpu *vcpu, u64 addr, u8 *data, + u32 len, u8 is_write, void *ptr); typedef void (*fdt_irq_fn)(void *fdt, u8 irq, enum irq_type irq_type); enum { @@ -113,6 +126,8 @@ void kvm__irq_line(struct kvm *kvm, int irq, int level); void kvm__irq_trigger(struct kvm *kvm, int irq); bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count); bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write); +bool kvm__emulate_pio(struct kvm_cpu *vcpu, u16 port, void *data, + int direction, int size, u32 count); int kvm__destroy_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr); int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr, enum kvm_mem_type type); @@ -136,10 +151,36 @@ static inline int kvm__reserve_mem(struct kvm *kvm, u64 guest_phys, u64 size) KVM_MEM_TYPE_RESERVED); } -int __must_check kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool coalesce, - void (*mmio_fn)(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr), - void *ptr); -bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr); +int __must_check kvm__register_iotrap(struct kvm *kvm, u64 phys_addr, u64 len, + mmio_handler_fn mmio_fn, void *ptr, + unsigned int flags); + +static inline +int __must_check kvm__register_mmio(struct kvm *kvm, u64 phys_addr, + u64 phys_addr_len, bool coalesce, + mmio_handler_fn mmio_fn, void *ptr) +{ + return kvm__register_iotrap(kvm, phys_addr, phys_addr_len, mmio_fn, ptr, + DEVICE_BUS_MMIO | (coalesce ? IOTRAP_COALESCE : 0)); +} +static inline +int __must_check kvm__register_pio(struct kvm *kvm, u16 port, u16 len, + mmio_handler_fn mmio_fn, void *ptr) +{ + return kvm__register_iotrap(kvm, port, len, mmio_fn, ptr, + DEVICE_BUS_IOPORT); +} + +bool kvm__deregister_iotrap(struct kvm *kvm, u64 phys_addr, unsigned int flags); +static inline bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr) +{ + return kvm__deregister_iotrap(kvm, phys_addr, DEVICE_BUS_MMIO); +} +static inline bool kvm__deregister_pio(struct kvm *kvm, u16 port) +{ + return kvm__deregister_iotrap(kvm, port, DEVICE_BUS_IOPORT); +} + void kvm__reboot(struct kvm *kvm); void kvm__pause(struct kvm *kvm); void kvm__continue(struct kvm *kvm); diff --git a/ioport.c b/ioport.c index e0123f27..ce29e7e7 100644 --- a/ioport.c +++ b/ioport.c @@ -162,7 +162,8 @@ bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, entry = ioport_get(&ioport_tree, port); if (!entry) - goto out; + return kvm__emulate_pio(vcpu, port, data, direction, + size, count); ops = entry->ops; @@ -177,7 +178,6 @@ bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, ioport_put(&ioport_tree, entry); -out: if (ret) return true; diff --git a/mmio.c b/mmio.c index cd141cd3..75de04ad 100644 --- a/mmio.c +++ b/mmio.c @@ -19,13 +19,14 @@ static DEFINE_MUTEX(mmio_lock); struct mmio_mapping { struct rb_int_node node; - void (*mmio_fn)(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr); + mmio_handler_fn mmio_fn; void *ptr; u32 refcount; bool remove; }; static struct rb_root mmio_tree = RB_ROOT; +static struct rb_root pio_tree = RB_ROOT; static struct mmio_mapping *mmio_search(struct rb_root *root, u64 addr, u64 len) { @@ -103,9 +104,14 @@ static void mmio_put(struct kvm *kvm, struct rb_root *root, struct mmio_mapping mutex_unlock(&mmio_lock); } -int kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool coalesce, - void (*mmio_fn)(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr), - void *ptr) +static bool trap_is_mmio(unsigned int flags) +{ + return (flags & IOTRAP_BUS_MASK) == DEVICE_BUS_MMIO; +} + +int kvm__register_iotrap(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, + mmio_handler_fn mmio_fn, void *ptr, + unsigned int flags) { struct mmio_mapping *mmio; struct kvm_coalesced_mmio_zone zone; @@ -127,7 +133,7 @@ int kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool c .remove = false, }; - if (coalesce) { + if (trap_is_mmio(flags) && (flags & IOTRAP_COALESCE)) { zone = (struct kvm_coalesced_mmio_zone) { .addr = phys_addr, .size = phys_addr_len, @@ -138,19 +144,29 @@ int kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool c return -errno; } } + mutex_lock(&mmio_lock); - ret = mmio_insert(&mmio_tree, mmio); + if (trap_is_mmio(flags)) + ret = mmio_insert(&mmio_tree, mmio); + else + ret = mmio_insert(&pio_tree, mmio); mutex_unlock(&mmio_lock); return ret; } -bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr) +bool kvm__deregister_iotrap(struct kvm *kvm, u64 phys_addr, unsigned int flags) { struct mmio_mapping *mmio; + struct rb_root *tree; + + if ((flags & IOTRAP_BUS_MASK) == DEVICE_BUS_IOPORT) + tree = &pio_tree; + else + tree = &mmio_tree; mutex_lock(&mmio_lock); - mmio = mmio_search_single(&mmio_tree, phys_addr); + mmio = mmio_search_single(tree, phys_addr); if (mmio == NULL) { mutex_unlock(&mmio_lock); return false; @@ -167,7 +183,7 @@ bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr) * called mmio_put(). This will trigger use-after-free errors on VCPU0. */ if (mmio->refcount == 0) - mmio_deregister(kvm, &mmio_tree, mmio); + mmio_deregister(kvm, tree, mmio); else mmio->remove = true; mutex_unlock(&mmio_lock); @@ -175,7 +191,8 @@ bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr) return true; } -bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write) +bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, + u32 len, u8 is_write) { struct mmio_mapping *mmio; @@ -194,3 +211,31 @@ bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u out: return true; } + +bool kvm__emulate_pio(struct kvm_cpu *vcpu, u16 port, void *data, + int direction, int size, u32 count) +{ + struct mmio_mapping *mmio; + bool is_write = direction == KVM_EXIT_IO_OUT; + + mmio = mmio_get(&pio_tree, port, size); + if (!mmio) { + if (vcpu->kvm->cfg.ioport_debug) { + fprintf(stderr, "IO error: %s port=%x, size=%d, count=%u\n", + to_direction(direction), port, size, count); + + return false; + } + return true; + } + + while (count--) { + mmio->mmio_fn(vcpu, port, data, size, is_write, mmio->ptr); + + data += size; + } + + mmio_put(vcpu->kvm, &pio_tree, mmio); + + return true; +} From patchwork Thu Feb 25 00:58:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103027 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA2E5C433DB for ; Thu, 25 Feb 2021 01:02:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6280764F0C for ; Thu, 25 Feb 2021 01:02:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233148AbhBYBCK (ORCPT ); Wed, 24 Feb 2021 20:02:10 -0500 Received: from foss.arm.com ([217.140.110.172]:58502 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233162AbhBYBB6 (ORCPT ); Wed, 24 Feb 2021 20:01:58 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EA47A11FB; Wed, 24 Feb 2021 17:00:33 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9FA163F73B; Wed, 24 Feb 2021 17:00:32 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 05/22] hw/i8042: Clean up data types Date: Thu, 25 Feb 2021 00:58:58 +0000 Message-Id: <20210225005915.26423-6-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The i8042 is clearly an 8-bit era device, so there is little room for 32-bit registers. Clean up the data types used. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- hw/i8042.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hw/i8042.c b/hw/i8042.c index 37a99a2d..7d1f9772 100644 --- a/hw/i8042.c +++ b/hw/i8042.c @@ -64,11 +64,11 @@ struct kbd_state { struct kvm *kvm; - char kq[QUEUE_SIZE]; /* Keyboard queue */ + u8 kq[QUEUE_SIZE]; /* Keyboard queue */ int kread, kwrite; /* Indexes into the queue */ int kcount; /* number of elements in queue */ - char mq[QUEUE_SIZE]; + u8 mq[QUEUE_SIZE]; int mread, mwrite; int mcount; @@ -82,7 +82,7 @@ struct kbd_state { * Some commands (on port 0x64) have arguments; * we store the command here while we wait for the argument */ - u32 write_cmd; + u8 write_cmd; }; static struct kbd_state state; @@ -173,9 +173,9 @@ static void kbd_write_command(struct kvm *kvm, u8 val) /* * Called when the OS reads from port 0x60 (PS/2 data) */ -static u32 kbd_read_data(void) +static u8 kbd_read_data(void) { - u32 ret; + u8 ret; int i; if (state.kcount != 0) { @@ -202,9 +202,9 @@ static u32 kbd_read_data(void) /* * Called when the OS read from port 0x64, the command port */ -static u32 kbd_read_status(void) +static u8 kbd_read_status(void) { - return (u32)state.status; + return state.status; } /* @@ -212,7 +212,7 @@ static u32 kbd_read_status(void) * Things written here are generally arguments to commands previously * written to port 0x64 and stored in state.write_cmd */ -static void kbd_write_data(u32 val) +static void kbd_write_data(u8 val) { switch (state.write_cmd) { case I8042_CMD_CTL_WCTR: @@ -266,8 +266,8 @@ static void kbd_write_data(u32 val) break; default: break; - } - break; + } + break; case 0: /* Just send the ID */ kbd_queue(RESPONSE_ACK); @@ -304,8 +304,8 @@ static bool kbd_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void * break; } case I8042_DATA_REG: { - u32 value = kbd_read_data(); - ioport__write32(data, value); + u8 value = kbd_read_data(); + ioport__write8(data, value); break; } case I8042_PORT_B_REG: { @@ -328,7 +328,7 @@ static bool kbd_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void break; } case I8042_DATA_REG: { - u32 value = ioport__read32(data); + u8 value = ioport__read8(data); kbd_write_data(value); break; } From patchwork Thu Feb 25 00:58:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C958C433E0 for ; Thu, 25 Feb 2021 01:02:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5AF3064EF1 for ; Thu, 25 Feb 2021 01:02:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234136AbhBYBCC (ORCPT ); Wed, 24 Feb 2021 20:02:02 -0500 Received: from foss.arm.com ([217.140.110.172]:58500 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232588AbhBYBB6 (ORCPT ); Wed, 24 Feb 2021 20:01:58 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7B18E12FC; Wed, 24 Feb 2021 17:00:35 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 30AE83F73B; Wed, 24 Feb 2021 17:00:34 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 06/22] hw/i8042: Refactor trap handler Date: Thu, 25 Feb 2021 00:58:59 +0000 Message-Id: <20210225005915.26423-7-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With the planned retirement of the special ioport emulation code, we need to provide an emulation function compatible with the MMIO prototype. Adjust the trap handler to use that new function, and provide shims to implement the old ioport interface, for now. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- hw/i8042.c | 68 +++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/hw/i8042.c b/hw/i8042.c index 7d1f9772..ab866662 100644 --- a/hw/i8042.c +++ b/hw/i8042.c @@ -292,52 +292,52 @@ static void kbd_reset(void) }; } -/* - * Called when the OS has written to one of the keyboard's ports (0x60 or 0x64) - */ -static bool kbd_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static void kbd_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, + u8 is_write, void *ptr) { - switch (port) { - case I8042_COMMAND_REG: { - u8 value = kbd_read_status(); - ioport__write8(data, value); + u8 value; + + if (is_write) + value = ioport__read8(data); + + switch (addr) { + case I8042_COMMAND_REG: + if (is_write) + kbd_write_command(vcpu->kvm, value); + else + value = kbd_read_status(); break; - } - case I8042_DATA_REG: { - u8 value = kbd_read_data(); - ioport__write8(data, value); + case I8042_DATA_REG: + if (is_write) + kbd_write_data(value); + else + value = kbd_read_data(); break; - } - case I8042_PORT_B_REG: { - ioport__write8(data, 0x20); + case I8042_PORT_B_REG: + if (!is_write) + value = 0x20; break; - } default: - return false; + return; } + if (!is_write) + ioport__write8(data, value); +} + +/* + * Called when the OS has written to one of the keyboard's ports (0x60 or 0x64) + */ +static bool kbd_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +{ + kbd_io(vcpu, port, data, size, 0, NULL); + return true; } static bool kbd_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) { - switch (port) { - case I8042_COMMAND_REG: { - u8 value = ioport__read8(data); - kbd_write_command(vcpu->kvm, value); - break; - } - case I8042_DATA_REG: { - u8 value = ioport__read8(data); - kbd_write_data(value); - break; - } - case I8042_PORT_B_REG: { - break; - } - default: - return false; - } + kbd_io(vcpu, port, data, size, 1, NULL); return true; } From patchwork Thu Feb 25 00:59:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103031 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 633C2C433E0 for ; Thu, 25 Feb 2021 01:02:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2174E64F0C for ; Thu, 25 Feb 2021 01:02:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231786AbhBYBCS (ORCPT ); Wed, 24 Feb 2021 20:02:18 -0500 Received: from foss.arm.com ([217.140.110.172]:58508 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234064AbhBYBCC (ORCPT ); Wed, 24 Feb 2021 20:02:02 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0E429139F; Wed, 24 Feb 2021 17:00:37 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B577D3F73B; Wed, 24 Feb 2021 17:00:35 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 07/22] hw/i8042: Switch to new trap handlers Date: Thu, 25 Feb 2021 00:59:00 +0000 Message-Id: <20210225005915.26423-8-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Now that the PC keyboard has a trap handler adhering to the MMIO fault handler prototype, let's switch over to the joint registration routine. This allows us to get rid of the ioport shim routines. Make the kbd_init() function static on the way. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- hw/i8042.c | 30 ++++-------------------------- include/kvm/i8042.h | 1 - 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/hw/i8042.c b/hw/i8042.c index ab866662..20be36c4 100644 --- a/hw/i8042.c +++ b/hw/i8042.c @@ -325,40 +325,18 @@ static void kbd_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, ioport__write8(data, value); } -/* - * Called when the OS has written to one of the keyboard's ports (0x60 or 0x64) - */ -static bool kbd_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - kbd_io(vcpu, port, data, size, false, NULL); - - return true; -} - -static bool kbd_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - kbd_io(vcpu, port, data, size, true, NULL); - - return true; -} - -static struct ioport_operations kbd_ops = { - .io_in = kbd_in, - .io_out = kbd_out, -}; - -int kbd__init(struct kvm *kvm) +static int kbd__init(struct kvm *kvm) { int r; kbd_reset(); state.kvm = kvm; - r = ioport__register(kvm, I8042_DATA_REG, &kbd_ops, 2, NULL); + r = kvm__register_pio(kvm, I8042_DATA_REG, 2, kbd_io, NULL); if (r < 0) return r; - r = ioport__register(kvm, I8042_COMMAND_REG, &kbd_ops, 2, NULL); + r = kvm__register_pio(kvm, I8042_COMMAND_REG, 2, kbd_io, NULL); if (r < 0) { - ioport__unregister(kvm, I8042_DATA_REG); + kvm__deregister_pio(kvm, I8042_DATA_REG); return r; } diff --git a/include/kvm/i8042.h b/include/kvm/i8042.h index 3b4ab688..cd4ae6bb 100644 --- a/include/kvm/i8042.h +++ b/include/kvm/i8042.h @@ -7,6 +7,5 @@ struct kvm; void mouse_queue(u8 c); void kbd_queue(u8 c); -int kbd__init(struct kvm *kvm); #endif From patchwork Thu Feb 25 00:59:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103029 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA8FCC433DB for ; Thu, 25 Feb 2021 01:02:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7BA4464F0C for ; Thu, 25 Feb 2021 01:02:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233267AbhBYBCO (ORCPT ); Wed, 24 Feb 2021 20:02:14 -0500 Received: from foss.arm.com ([217.140.110.172]:58510 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232770AbhBYBCC (ORCPT ); Wed, 24 Feb 2021 20:02:02 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 933DF13A1; Wed, 24 Feb 2021 17:00:38 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 48E003F73B; Wed, 24 Feb 2021 17:00:37 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 08/22] x86/ioport: Refactor trap handlers Date: Thu, 25 Feb 2021 00:59:01 +0000 Message-Id: <20210225005915.26423-9-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With the planned retirement of the special ioport emulation code, we need to provide emulation functions compatible with the MMIO prototype. Adjust the trap handlers to use that new function, and provide shims to implement the old ioport interface, for now. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- x86/ioport.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/x86/ioport.c b/x86/ioport.c index a8d2bb1a..78f9a863 100644 --- a/x86/ioport.c +++ b/x86/ioport.c @@ -3,8 +3,14 @@ #include #include +static void dummy_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, + u8 is_write, void *ptr) +{ +} + static bool debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) { + dummy_mmio(vcpu, port, data, size, true, NULL); return 0; } @@ -12,15 +18,23 @@ static struct ioport_operations debug_ops = { .io_out = debug_io_out, }; -static bool seabios_debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static void seabios_debug_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, + u32 len, u8 is_write, void *ptr) { char ch; + if (!is_write) + return; + ch = ioport__read8(data); putchar(ch); +} - return true; +static bool seabios_debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +{ + seabios_debug_mmio(vcpu, port, data, size, true, NULL); + return 0; } static struct ioport_operations seabios_debug_ops = { @@ -29,11 +43,13 @@ static struct ioport_operations seabios_debug_ops = { static bool dummy_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) { + dummy_mmio(vcpu, port, data, size, false, NULL); return true; } static bool dummy_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) { + dummy_mmio(vcpu, port, data, size, true, NULL); return true; } @@ -50,13 +66,19 @@ static struct ioport_operations dummy_write_only_ioport_ops = { * The "fast A20 gate" */ -static bool ps2_control_a_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static void ps2_control_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, + u8 is_write, void *ptr) { /* * A20 is always enabled. */ - ioport__write8(data, 0x02); + if (!is_write) + ioport__write8(data, 0x02); +} +static bool ps2_control_a_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +{ + ps2_control_mmio(vcpu, port, data, size, false, NULL); return true; } From patchwork Thu Feb 25 00:59:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103035 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5163AC433DB for ; Thu, 25 Feb 2021 01:02:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EB7D164EF1 for ; Thu, 25 Feb 2021 01:02:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236605AbhBYBCc (ORCPT ); Wed, 24 Feb 2021 20:02:32 -0500 Received: from foss.arm.com ([217.140.110.172]:58512 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235061AbhBYBCG (ORCPT ); Wed, 24 Feb 2021 20:02:06 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2410B1424; Wed, 24 Feb 2021 17:00:40 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CDC933F73B; Wed, 24 Feb 2021 17:00:38 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 09/22] x86/ioport: Switch to new trap handlers Date: Thu, 25 Feb 2021 00:59:02 +0000 Message-Id: <20210225005915.26423-10-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Now that the x86 I/O ports have trap handlers adhering to the MMIO fault handler prototype, let's switch over to the joint registration routine. This allows us to get rid of the ioport shim routines. Since the debug output was done in ioport.c, we would lose this functionality when moving over to the MMIO handlers. So bring this back here explicitly, by introducing debug_mmio(). Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- x86/ioport.c | 102 +++++++++++++++++++-------------------------------- 1 file changed, 37 insertions(+), 65 deletions(-) diff --git a/x86/ioport.c b/x86/ioport.c index 78f9a863..9fcbb6c9 100644 --- a/x86/ioport.c +++ b/x86/ioport.c @@ -3,21 +3,35 @@ #include #include -static void dummy_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, +static void debug_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) { + if (!vcpu->kvm->cfg.ioport_debug) + return; + + fprintf(stderr, "debug port %s from VCPU%lu: port=0x%lx, size=%u", + is_write ? "write" : "read", vcpu->cpu_id, + (unsigned long)addr, len); + if (is_write) { + u32 value; + + switch (len) { + case 1: value = ioport__read8(data); break; + case 2: value = ioport__read16((u16*)data); break; + case 4: value = ioport__read32((u32*)data); break; + default: value = 0; break; + } + fprintf(stderr, ", data: 0x%x\n", value); + } else { + fprintf(stderr, "\n"); + } } -static bool debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static void dummy_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, + u8 is_write, void *ptr) { - dummy_mmio(vcpu, port, data, size, true, NULL); - return 0; } -static struct ioport_operations debug_ops = { - .io_out = debug_io_out, -}; - static void seabios_debug_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) { @@ -31,37 +45,6 @@ static void seabios_debug_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, putchar(ch); } -static bool seabios_debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - seabios_debug_mmio(vcpu, port, data, size, true, NULL); - return 0; -} - -static struct ioport_operations seabios_debug_ops = { - .io_out = seabios_debug_io_out, -}; - -static bool dummy_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - dummy_mmio(vcpu, port, data, size, false, NULL); - return true; -} - -static bool dummy_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - dummy_mmio(vcpu, port, data, size, true, NULL); - return true; -} - -static struct ioport_operations dummy_read_write_ioport_ops = { - .io_in = dummy_io_in, - .io_out = dummy_io_out, -}; - -static struct ioport_operations dummy_write_only_ioport_ops = { - .io_out = dummy_io_out, -}; - /* * The "fast A20 gate" */ @@ -76,17 +59,6 @@ static void ps2_control_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, ioport__write8(data, 0x02); } -static bool ps2_control_a_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - ps2_control_mmio(vcpu, port, data, size, false, NULL); - return true; -} - -static struct ioport_operations ps2_control_a_ops = { - .io_in = ps2_control_a_io_in, - .io_out = dummy_io_out, -}; - void ioport__map_irq(u8 *irq) { } @@ -98,75 +70,75 @@ static int ioport__setup_arch(struct kvm *kvm) /* Legacy ioport setup */ /* 0000 - 001F - DMA1 controller */ - r = ioport__register(kvm, 0x0000, &dummy_read_write_ioport_ops, 32, NULL); + r = kvm__register_pio(kvm, 0x0000, 32, dummy_mmio, NULL); if (r < 0) return r; /* 0x0020 - 0x003F - 8259A PIC 1 */ - r = ioport__register(kvm, 0x0020, &dummy_read_write_ioport_ops, 2, NULL); + r = kvm__register_pio(kvm, 0x0020, 2, dummy_mmio, NULL); if (r < 0) return r; /* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */ - r = ioport__register(kvm, 0x0040, &dummy_read_write_ioport_ops, 4, NULL); + r = kvm__register_pio(kvm, 0x0040, 4, dummy_mmio, NULL); if (r < 0) return r; /* 0092 - PS/2 system control port A */ - r = ioport__register(kvm, 0x0092, &ps2_control_a_ops, 1, NULL); + r = kvm__register_pio(kvm, 0x0092, 1, ps2_control_mmio, NULL); if (r < 0) return r; /* 0x00A0 - 0x00AF - 8259A PIC 2 */ - r = ioport__register(kvm, 0x00A0, &dummy_read_write_ioport_ops, 2, NULL); + r = kvm__register_pio(kvm, 0x00A0, 2, dummy_mmio, NULL); if (r < 0) return r; /* 00C0 - 001F - DMA2 controller */ - r = ioport__register(kvm, 0x00C0, &dummy_read_write_ioport_ops, 32, NULL); + r = kvm__register_pio(kvm, 0x00c0, 32, dummy_mmio, NULL); if (r < 0) return r; /* PORT 00E0-00EF are 'motherboard specific' so we use them for our internal debugging purposes. */ - r = ioport__register(kvm, IOPORT_DBG, &debug_ops, 1, NULL); + r = kvm__register_pio(kvm, IOPORT_DBG, 1, debug_mmio, NULL); if (r < 0) return r; /* PORT 00ED - DUMMY PORT FOR DELAY??? */ - r = ioport__register(kvm, 0x00ED, &dummy_write_only_ioport_ops, 1, NULL); + r = kvm__register_pio(kvm, 0x00ed, 1, dummy_mmio, NULL); if (r < 0) return r; /* 0x00F0 - 0x00FF - Math co-processor */ - r = ioport__register(kvm, 0x00F0, &dummy_write_only_ioport_ops, 2, NULL); + r = kvm__register_pio(kvm, 0x00f0, 2, dummy_mmio, NULL); if (r < 0) return r; /* PORT 0278-027A - PARALLEL PRINTER PORT (usually LPT1, sometimes LPT2) */ - r = ioport__register(kvm, 0x0278, &dummy_read_write_ioport_ops, 3, NULL); + r = kvm__register_pio(kvm, 0x0278, 3, dummy_mmio, NULL); if (r < 0) return r; /* PORT 0378-037A - PARALLEL PRINTER PORT (usually LPT2, sometimes LPT3) */ - r = ioport__register(kvm, 0x0378, &dummy_read_write_ioport_ops, 3, NULL); + r = kvm__register_pio(kvm, 0x0378, 3, dummy_mmio, NULL); if (r < 0) return r; /* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */ - r = ioport__register(kvm, 0x03D4, &dummy_read_write_ioport_ops, 1, NULL); + r = kvm__register_pio(kvm, 0x03d4, 1, dummy_mmio, NULL); if (r < 0) return r; - r = ioport__register(kvm, 0x03D5, &dummy_write_only_ioport_ops, 1, NULL); + r = kvm__register_pio(kvm, 0x03d5, 1, dummy_mmio, NULL); if (r < 0) return r; - r = ioport__register(kvm, 0x402, &seabios_debug_ops, 1, NULL); + r = kvm__register_pio(kvm, 0x0402, 1, seabios_debug_mmio, NULL); if (r < 0) return r; /* 0510 - QEMU BIOS configuration register */ - r = ioport__register(kvm, 0x510, &dummy_read_write_ioport_ops, 2, NULL); + r = kvm__register_pio(kvm, 0x0510, 2, dummy_mmio, NULL); if (r < 0) return r; From patchwork Thu Feb 25 00:59:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103033 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6F7AC433DB for ; Thu, 25 Feb 2021 01:02:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BFBAB64EF1 for ; Thu, 25 Feb 2021 01:02:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236161AbhBYBCX (ORCPT ); Wed, 24 Feb 2021 20:02:23 -0500 Received: from foss.arm.com ([217.140.110.172]:58514 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234587AbhBYBCG (ORCPT ); Wed, 24 Feb 2021 20:02:06 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A9165142F; Wed, 24 Feb 2021 17:00:41 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5EA973F73B; Wed, 24 Feb 2021 17:00:40 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 10/22] hw/rtc: Refactor trap handlers Date: Thu, 25 Feb 2021 00:59:03 +0000 Message-Id: <20210225005915.26423-11-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With the planned retirement of the special ioport emulation code, we need to provide emulation functions compatible with the MMIO prototype. Merge the two different trap handlers into one function, checking for read/write and data/index register inside. Adjust the trap handlers to use that new function, and provide shims to implement the old ioport interface, for now. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- hw/rtc.c | 70 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/hw/rtc.c b/hw/rtc.c index 5483879f..664d4cb0 100644 --- a/hw/rtc.c +++ b/hw/rtc.c @@ -42,11 +42,37 @@ static inline unsigned char bin2bcd(unsigned val) return ((val / 10) << 4) + val % 10; } -static bool cmos_ram_data_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static void cmos_ram_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, + u32 len, u8 is_write, void *ptr) { struct tm *tm; time_t ti; + if (is_write) { + if (addr == 0x70) { /* index register */ + u8 value = ioport__read8(data); + + vcpu->kvm->nmi_disabled = value & (1UL << 7); + rtc.cmos_idx = value & ~(1UL << 7); + + return; + } + + switch (rtc.cmos_idx) { + case RTC_REG_C: + case RTC_REG_D: + /* Read-only */ + break; + default: + rtc.cmos_data[rtc.cmos_idx] = ioport__read8(data); + break; + } + return; + } + + if (addr == 0x70) + return; + time(&ti); tm = gmtime(&ti); @@ -92,42 +118,23 @@ static bool cmos_ram_data_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 po ioport__write8(data, rtc.cmos_data[rtc.cmos_idx]); break; } - - return true; } -static bool cmos_ram_data_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static bool cmos_ram_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) { - switch (rtc.cmos_idx) { - case RTC_REG_C: - case RTC_REG_D: - /* Read-only */ - break; - default: - rtc.cmos_data[rtc.cmos_idx] = ioport__read8(data); - break; - } - + cmos_ram_io(vcpu, port, data, size, false, NULL); return true; } -static struct ioport_operations cmos_ram_data_ioport_ops = { - .io_out = cmos_ram_data_out, - .io_in = cmos_ram_data_in, -}; - -static bool cmos_ram_index_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static bool cmos_ram_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) { - u8 value = ioport__read8(data); - - vcpu->kvm->nmi_disabled = value & (1UL << 7); - rtc.cmos_idx = value & ~(1UL << 7); - + cmos_ram_io(vcpu, port, data, size, true, NULL); return true; } -static struct ioport_operations cmos_ram_index_ioport_ops = { - .io_out = cmos_ram_index_out, +static struct ioport_operations cmos_ram_ioport_ops = { + .io_out = cmos_ram_out, + .io_in = cmos_ram_in, }; #ifdef CONFIG_HAS_LIBFDT @@ -162,21 +169,15 @@ int rtc__init(struct kvm *kvm) return r; /* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */ - r = ioport__register(kvm, 0x0070, &cmos_ram_index_ioport_ops, 1, NULL); + r = ioport__register(kvm, 0x0070, &cmos_ram_ioport_ops, 2, NULL); if (r < 0) goto out_device; - r = ioport__register(kvm, 0x0071, &cmos_ram_data_ioport_ops, 1, NULL); - if (r < 0) - goto out_ioport; - /* Set the VRT bit in Register D to indicate valid RAM and time */ rtc.cmos_data[RTC_REG_D] = RTC_REG_D_VRT; return r; -out_ioport: - ioport__unregister(kvm, 0x0070); out_device: device__unregister(&rtc_dev_hdr); @@ -188,7 +189,6 @@ int rtc__exit(struct kvm *kvm) { /* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */ ioport__unregister(kvm, 0x0070); - ioport__unregister(kvm, 0x0071); return 0; } From patchwork Thu Feb 25 00:59:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103039 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 04CEDC433E0 for ; Thu, 25 Feb 2021 01:03:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A596264F03 for ; Thu, 25 Feb 2021 01:03:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236717AbhBYBCz (ORCPT ); Wed, 24 Feb 2021 20:02:55 -0500 Received: from foss.arm.com ([217.140.110.172]:58516 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234943AbhBYBCJ (ORCPT ); Wed, 24 Feb 2021 20:02:09 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4489F1435; Wed, 24 Feb 2021 17:00:43 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EEA643F73B; Wed, 24 Feb 2021 17:00:41 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 11/22] hw/rtc: Switch to new trap handler Date: Thu, 25 Feb 2021 00:59:04 +0000 Message-Id: <20210225005915.26423-12-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Now that the RTC device has a trap handler adhering to the MMIO fault handler prototype, let's switch over to the joint registration routine. This allows us to get rid of the ioport shim routines. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- hw/rtc.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/hw/rtc.c b/hw/rtc.c index 664d4cb0..ee4c9102 100644 --- a/hw/rtc.c +++ b/hw/rtc.c @@ -120,23 +120,6 @@ static void cmos_ram_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, } } -static bool cmos_ram_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - cmos_ram_io(vcpu, port, data, size, false, NULL); - return true; -} - -static bool cmos_ram_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - cmos_ram_io(vcpu, port, data, size, true, NULL); - return true; -} - -static struct ioport_operations cmos_ram_ioport_ops = { - .io_out = cmos_ram_out, - .io_in = cmos_ram_in, -}; - #ifdef CONFIG_HAS_LIBFDT static void generate_rtc_fdt_node(void *fdt, struct device_header *dev_hdr, @@ -169,7 +152,7 @@ int rtc__init(struct kvm *kvm) return r; /* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */ - r = ioport__register(kvm, 0x0070, &cmos_ram_ioport_ops, 2, NULL); + r = kvm__register_pio(kvm, 0x0070, 2, cmos_ram_io, NULL); if (r < 0) goto out_device; @@ -188,7 +171,7 @@ dev_init(rtc__init); int rtc__exit(struct kvm *kvm) { /* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */ - ioport__unregister(kvm, 0x0070); + kvm__deregister_pio(kvm, 0x0070); return 0; } From patchwork Thu Feb 25 00:59:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103037 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B672C433DB for ; Thu, 25 Feb 2021 01:02:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3C0AB64F03 for ; Thu, 25 Feb 2021 01:02:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236689AbhBYBCs (ORCPT ); Wed, 24 Feb 2021 20:02:48 -0500 Received: from foss.arm.com ([217.140.110.172]:58518 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234928AbhBYBCJ (ORCPT ); Wed, 24 Feb 2021 20:02:09 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C99A3143B; Wed, 24 Feb 2021 17:00:44 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7F2593F73B; Wed, 24 Feb 2021 17:00:43 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 12/22] hw/vesa: Switch trap handling to use MMIO handler Date: Thu, 25 Feb 2021 00:59:05 +0000 Message-Id: <20210225005915.26423-13-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org To be able to use the VESA device with the new generic I/O trap handler, we need to use the different MMIO handler callback routine. Replace the existing dummy in and out handlers with a joint dummy MMIO handler, and register this using the new registration function. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- hw/vesa.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/hw/vesa.c b/hw/vesa.c index 8659a002..7f82cdb4 100644 --- a/hw/vesa.c +++ b/hw/vesa.c @@ -43,21 +43,11 @@ static struct framebuffer vesafb = { .mem_size = VESA_MEM_SIZE, }; -static bool vesa_pci_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static void vesa_pci_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, + u8 is_write, void *ptr) { - return true; } -static bool vesa_pci_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - return true; -} - -static struct ioport_operations vesa_io_ops = { - .io_in = vesa_pci_io_in, - .io_out = vesa_pci_io_out, -}; - static int vesa__bar_activate(struct kvm *kvm, struct pci_device_header *pci_hdr, int bar_num, void *data) { @@ -82,7 +72,8 @@ struct framebuffer *vesa__init(struct kvm *kvm) BUILD_BUG_ON(VESA_MEM_SIZE < VESA_BPP/8 * VESA_WIDTH * VESA_HEIGHT); vesa_base_addr = pci_get_io_port_block(PCI_IO_SIZE); - r = ioport__register(kvm, vesa_base_addr, &vesa_io_ops, PCI_IO_SIZE, NULL); + r = kvm__register_pio(kvm, vesa_base_addr, PCI_IO_SIZE, vesa_pci_io, + NULL); if (r < 0) goto out_error; @@ -116,7 +107,7 @@ unmap_dev: unregister_device: device__unregister(&vesa_device); unregister_ioport: - ioport__unregister(kvm, vesa_base_addr); + kvm__deregister_pio(kvm, vesa_base_addr); out_error: return ERR_PTR(r); } From patchwork Thu Feb 25 00:59:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103043 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E38E7C433DB for ; Thu, 25 Feb 2021 01:03:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9C0F064EC4 for ; Thu, 25 Feb 2021 01:03:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236651AbhBYBDP (ORCPT ); Wed, 24 Feb 2021 20:03:15 -0500 Received: from foss.arm.com ([217.140.110.172]:58520 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235515AbhBYBCN (ORCPT ); Wed, 24 Feb 2021 20:02:13 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5AFEC143D; Wed, 24 Feb 2021 17:00:46 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 101DC3F73B; Wed, 24 Feb 2021 17:00:44 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 13/22] hw/serial: Refactor trap handler Date: Thu, 25 Feb 2021 00:59:06 +0000 Message-Id: <20210225005915.26423-14-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With the planned retirement of the special ioport emulation code, we need to provide an emulation function compatible with the MMIO prototype. Adjust the trap handler to use that new function, and provide shims to implement the old ioport interface, for now. We drop the usage of ioport__read8/write8 entirely, as this would only be applicable for I/O port accesses, and does nothing for 8-bit wide accesses anyway. Signed-off-by: Andre Przywara --- hw/serial.c | 93 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/hw/serial.c b/hw/serial.c index b0465d99..c495eac1 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -242,36 +242,31 @@ void serial8250__inject_sysrq(struct kvm *kvm, char sysrq) sysrq_pending = sysrq; } -static bool serial8250_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, - void *data, int size) +static bool serial8250_out(struct serial8250_device *dev, struct kvm_cpu *vcpu, + u16 offset, u8 data) { - struct serial8250_device *dev = ioport->priv; - u16 offset; bool ret = true; - char *addr = data; mutex_lock(&dev->mutex); - offset = port - dev->iobase; - switch (offset) { case UART_TX: if (dev->lcr & UART_LCR_DLAB) { - dev->dll = ioport__read8(data); + dev->dll = data; break; } /* Loopback mode */ if (dev->mcr & UART_MCR_LOOP) { if (dev->rxcnt < FIFO_LEN) { - dev->rxbuf[dev->rxcnt++] = *addr; + dev->rxbuf[dev->rxcnt++] = data; dev->lsr |= UART_LSR_DR; } break; } if (dev->txcnt < FIFO_LEN) { - dev->txbuf[dev->txcnt++] = *addr; + dev->txbuf[dev->txcnt++] = data; dev->lsr &= ~UART_LSR_TEMT; if (dev->txcnt == FIFO_LEN / 2) dev->lsr &= ~UART_LSR_THRE; @@ -283,18 +278,18 @@ static bool serial8250_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port break; case UART_IER: if (!(dev->lcr & UART_LCR_DLAB)) - dev->ier = ioport__read8(data) & 0x0f; + dev->ier = data & 0x0f; else - dev->dlm = ioport__read8(data); + dev->dlm = data; break; case UART_FCR: - dev->fcr = ioport__read8(data); + dev->fcr = data; break; case UART_LCR: - dev->lcr = ioport__read8(data); + dev->lcr = data; break; case UART_MCR: - dev->mcr = ioport__read8(data); + dev->mcr = data; break; case UART_LSR: /* Factory test */ @@ -303,7 +298,7 @@ static bool serial8250_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port /* Not used */ break; case UART_SCR: - dev->scr = ioport__read8(data); + dev->scr = data; break; default: ret = false; @@ -317,7 +312,7 @@ static bool serial8250_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port return ret; } -static void serial8250_rx(struct serial8250_device *dev, void *data) +static void serial8250_rx(struct serial8250_device *dev, u8 *data) { if (dev->rxdone == dev->rxcnt) return; @@ -325,57 +320,54 @@ static void serial8250_rx(struct serial8250_device *dev, void *data) /* Break issued ? */ if (dev->lsr & UART_LSR_BI) { dev->lsr &= ~UART_LSR_BI; - ioport__write8(data, 0); + *data = 0; return; } - ioport__write8(data, dev->rxbuf[dev->rxdone++]); + *data = dev->rxbuf[dev->rxdone++]; if (dev->rxcnt == dev->rxdone) { dev->lsr &= ~UART_LSR_DR; dev->rxcnt = dev->rxdone = 0; } } -static bool serial8250_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static bool serial8250_in(struct serial8250_device *dev, struct kvm_cpu *vcpu, + u16 offset, u8 *data) { - struct serial8250_device *dev = ioport->priv; - u16 offset; bool ret = true; mutex_lock(&dev->mutex); - offset = port - dev->iobase; - switch (offset) { case UART_RX: if (dev->lcr & UART_LCR_DLAB) - ioport__write8(data, dev->dll); + *data = dev->dll; else serial8250_rx(dev, data); break; case UART_IER: if (dev->lcr & UART_LCR_DLAB) - ioport__write8(data, dev->dlm); + *data = dev->dlm; else - ioport__write8(data, dev->ier); + *data = dev->ier; break; case UART_IIR: - ioport__write8(data, dev->iir | UART_IIR_TYPE_BITS); + *data = dev->iir | UART_IIR_TYPE_BITS; break; case UART_LCR: - ioport__write8(data, dev->lcr); + *data = dev->lcr; break; case UART_MCR: - ioport__write8(data, dev->mcr); + *data = dev->mcr; break; case UART_LSR: - ioport__write8(data, dev->lsr); + *data = dev->lsr; break; case UART_MSR: - ioport__write8(data, dev->msr); + *data = dev->msr; break; case UART_SCR: - ioport__write8(data, dev->scr); + *data = dev->scr; break; default: ret = false; @@ -389,6 +381,37 @@ static bool serial8250_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, return ret; } +static void serial8250_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, + u8 is_write, void *ptr) +{ + struct serial8250_device *dev = ptr; + + if (is_write) + serial8250_out(dev, vcpu, addr - dev->iobase, *data); + else + serial8250_in(dev, vcpu, addr - dev->iobase, data); +} + +static bool serial8250_ioport_out(struct ioport *ioport, struct kvm_cpu *vcpu, + u16 port, void *data, int size) +{ + struct serial8250_device *dev = ioport->priv; + + serial8250_mmio(vcpu, port, data, 1, true, dev); + + return true; +} + +static bool serial8250_ioport_in(struct ioport *ioport, struct kvm_cpu *vcpu, + u16 port, void *data, int size) +{ + struct serial8250_device *dev = ioport->priv; + + serial8250_mmio(vcpu, port, data, 1, false, dev); + + return true; +} + #ifdef CONFIG_HAS_LIBFDT char *fdt_stdout_path = NULL; @@ -427,8 +450,8 @@ void serial8250_generate_fdt_node(void *fdt, struct device_header *dev_hdr, #endif static struct ioport_operations serial8250_ops = { - .io_in = serial8250_in, - .io_out = serial8250_out, + .io_in = serial8250_ioport_in, + .io_out = serial8250_ioport_out, }; static int serial8250__device_init(struct kvm *kvm, From patchwork Thu Feb 25 00:59:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103041 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 611CBC433DB for ; Thu, 25 Feb 2021 01:03:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1331C64EF1 for ; Thu, 25 Feb 2021 01:03:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235701AbhBYBDH (ORCPT ); Wed, 24 Feb 2021 20:03:07 -0500 Received: from foss.arm.com ([217.140.110.172]:58522 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235508AbhBYBCN (ORCPT ); Wed, 24 Feb 2021 20:02:13 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E0C661474; Wed, 24 Feb 2021 17:00:47 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 96A2A3F73B; Wed, 24 Feb 2021 17:00:46 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 14/22] hw/serial: Switch to new trap handlers Date: Thu, 25 Feb 2021 00:59:07 +0000 Message-Id: <20210225005915.26423-15-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Now that the serial device has a trap handler adhering to the MMIO fault handler prototype, let's switch over to the joint registration routine. This allows us to get rid of the ioport shim routines. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- hw/serial.c | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/hw/serial.c b/hw/serial.c index c495eac1..4be188a1 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -392,26 +392,6 @@ static void serial8250_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, serial8250_in(dev, vcpu, addr - dev->iobase, data); } -static bool serial8250_ioport_out(struct ioport *ioport, struct kvm_cpu *vcpu, - u16 port, void *data, int size) -{ - struct serial8250_device *dev = ioport->priv; - - serial8250_mmio(vcpu, port, data, 1, true, dev); - - return true; -} - -static bool serial8250_ioport_in(struct ioport *ioport, struct kvm_cpu *vcpu, - u16 port, void *data, int size) -{ - struct serial8250_device *dev = ioport->priv; - - serial8250_mmio(vcpu, port, data, 1, false, dev); - - return true; -} - #ifdef CONFIG_HAS_LIBFDT char *fdt_stdout_path = NULL; @@ -449,11 +429,6 @@ void serial8250_generate_fdt_node(void *fdt, struct device_header *dev_hdr, } #endif -static struct ioport_operations serial8250_ops = { - .io_in = serial8250_ioport_in, - .io_out = serial8250_ioport_out, -}; - static int serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev) { @@ -464,7 +439,7 @@ static int serial8250__device_init(struct kvm *kvm, return r; ioport__map_irq(&dev->irq); - r = ioport__register(kvm, dev->iobase, &serial8250_ops, 8, dev); + r = kvm__register_pio(kvm, dev->iobase, 8, serial8250_mmio, dev); return r; } @@ -487,7 +462,7 @@ cleanup: for (j = 0; j <= i; j++) { struct serial8250_device *dev = &devices[j]; - ioport__unregister(kvm, dev->iobase); + kvm__deregister_pio(kvm, dev->iobase); device__unregister(&dev->dev_hdr); } @@ -503,7 +478,7 @@ int serial8250__exit(struct kvm *kvm) for (i = 0; i < ARRAY_SIZE(devices); i++) { struct serial8250_device *dev = &devices[i]; - r = ioport__unregister(kvm, dev->iobase); + r = kvm__deregister_pio(kvm, dev->iobase); if (r < 0) return r; device__unregister(&dev->dev_hdr); From patchwork Thu Feb 25 00:59:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103045 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCC1CC433E0 for ; Thu, 25 Feb 2021 01:03:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 811BE64EC4 for ; Thu, 25 Feb 2021 01:03:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236690AbhBYBDZ (ORCPT ); Wed, 24 Feb 2021 20:03:25 -0500 Received: from foss.arm.com ([217.140.110.172]:58500 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235452AbhBYBCU (ORCPT ); Wed, 24 Feb 2021 20:02:20 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 72CF31476; Wed, 24 Feb 2021 17:00:49 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2755E3F73B; Wed, 24 Feb 2021 17:00:48 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 15/22] vfio: Refactor ioport trap handler Date: Thu, 25 Feb 2021 00:59:08 +0000 Message-Id: <20210225005915.26423-16-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With the planned retirement of the special ioport emulation code, we need to provide an emulation function compatible with the MMIO prototype. Adjust the I/O port trap handler to use that new function, and provide shims to implement the old ioport interface, for now. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- vfio/core.c | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/vfio/core.c b/vfio/core.c index 0b45e78b..ddd3c2c7 100644 --- a/vfio/core.c +++ b/vfio/core.c @@ -81,15 +81,12 @@ out_free_buf: return ret; } -static bool vfio_ioport_in(struct ioport *ioport, struct kvm_cpu *vcpu, - u16 port, void *data, int len) +static bool _vfio_ioport_in(struct vfio_region *region, u32 offset, + void *data, int len) { - u32 val; - ssize_t nr; - struct vfio_region *region = ioport->priv; struct vfio_device *vdev = region->vdev; - - u32 offset = port - region->port_base; + ssize_t nr; + u32 val; if (!(region->info.flags & VFIO_REGION_INFO_FLAG_READ)) return false; @@ -97,7 +94,7 @@ static bool vfio_ioport_in(struct ioport *ioport, struct kvm_cpu *vcpu, nr = pread(vdev->fd, &val, len, region->info.offset + offset); if (nr != len) { vfio_dev_err(vdev, "could not read %d bytes from I/O port 0x%x\n", - len, port); + len, offset + region->port_base); return false; } @@ -118,15 +115,13 @@ static bool vfio_ioport_in(struct ioport *ioport, struct kvm_cpu *vcpu, return true; } -static bool vfio_ioport_out(struct ioport *ioport, struct kvm_cpu *vcpu, - u16 port, void *data, int len) +static bool _vfio_ioport_out(struct vfio_region *region, u32 offset, + void *data, int len) { - u32 val; - ssize_t nr; - struct vfio_region *region = ioport->priv; struct vfio_device *vdev = region->vdev; + ssize_t nr; + u32 val; - u32 offset = port - region->port_base; if (!(region->info.flags & VFIO_REGION_INFO_FLAG_WRITE)) return false; @@ -148,11 +143,37 @@ static bool vfio_ioport_out(struct ioport *ioport, struct kvm_cpu *vcpu, nr = pwrite(vdev->fd, &val, len, region->info.offset + offset); if (nr != len) vfio_dev_err(vdev, "could not write %d bytes to I/O port 0x%x", - len, port); + len, offset + region->port_base); return nr == len; } +static void vfio_ioport_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, + u8 is_write, void *ptr) +{ + struct vfio_region *region = ptr; + u32 offset = addr - region->port_base; + + if (is_write) + _vfio_ioport_out(region, offset, data, len); + else + _vfio_ioport_in(region, offset, data, len); +} + +static bool vfio_ioport_out(struct ioport *ioport, struct kvm_cpu *vcpu, + u16 port, void *data, int len) +{ + vfio_ioport_mmio(vcpu, port, data, len, true, ioport->priv); + return true; +} + +static bool vfio_ioport_in(struct ioport *ioport, struct kvm_cpu *vcpu, + u16 port, void *data, int len) +{ + vfio_ioport_mmio(vcpu, port, data, len, false, ioport->priv); + return true; +} + static struct ioport_operations vfio_ioport_ops = { .io_in = vfio_ioport_in, .io_out = vfio_ioport_out, From patchwork Thu Feb 25 00:59:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103053 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C659C433DB for ; Thu, 25 Feb 2021 01:04:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 101D364EC4 for ; Thu, 25 Feb 2021 01:04:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236744AbhBYBD6 (ORCPT ); Wed, 24 Feb 2021 20:03:58 -0500 Received: from foss.arm.com ([217.140.110.172]:58540 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236653AbhBYBCr (ORCPT ); Wed, 24 Feb 2021 20:02:47 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 06C591477; Wed, 24 Feb 2021 17:00:51 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id AD6EF3F73B; Wed, 24 Feb 2021 17:00:49 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 16/22] vfio: Switch to new ioport trap handlers Date: Thu, 25 Feb 2021 00:59:09 +0000 Message-Id: <20210225005915.26423-17-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Now that the vfio device has a trap handler adhering to the MMIO fault handler prototype, let's switch over to the joint registration routine. This allows us to get rid of the ioport shim routines. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- vfio/core.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/vfio/core.c b/vfio/core.c index ddd3c2c7..3ff2c0b0 100644 --- a/vfio/core.c +++ b/vfio/core.c @@ -81,7 +81,7 @@ out_free_buf: return ret; } -static bool _vfio_ioport_in(struct vfio_region *region, u32 offset, +static bool vfio_ioport_in(struct vfio_region *region, u32 offset, void *data, int len) { struct vfio_device *vdev = region->vdev; @@ -115,7 +115,7 @@ static bool _vfio_ioport_in(struct vfio_region *region, u32 offset, return true; } -static bool _vfio_ioport_out(struct vfio_region *region, u32 offset, +static bool vfio_ioport_out(struct vfio_region *region, u32 offset, void *data, int len) { struct vfio_device *vdev = region->vdev; @@ -155,30 +155,11 @@ static void vfio_ioport_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u32 offset = addr - region->port_base; if (is_write) - _vfio_ioport_out(region, offset, data, len); + vfio_ioport_out(region, offset, data, len); else - _vfio_ioport_in(region, offset, data, len); + vfio_ioport_in(region, offset, data, len); } -static bool vfio_ioport_out(struct ioport *ioport, struct kvm_cpu *vcpu, - u16 port, void *data, int len) -{ - vfio_ioport_mmio(vcpu, port, data, len, true, ioport->priv); - return true; -} - -static bool vfio_ioport_in(struct ioport *ioport, struct kvm_cpu *vcpu, - u16 port, void *data, int len) -{ - vfio_ioport_mmio(vcpu, port, data, len, false, ioport->priv); - return true; -} - -static struct ioport_operations vfio_ioport_ops = { - .io_in = vfio_ioport_in, - .io_out = vfio_ioport_out, -}; - static void vfio_mmio_access(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) { @@ -223,9 +204,11 @@ static int vfio_setup_trap_region(struct kvm *kvm, struct vfio_device *vdev, struct vfio_region *region) { if (region->is_ioport) { - int port = ioport__register(kvm, region->port_base, - &vfio_ioport_ops, region->info.size, - region); + int port; + + port = kvm__register_pio(kvm, region->port_base, + region->info.size, vfio_ioport_mmio, + region); if (port < 0) return port; return 0; @@ -292,7 +275,7 @@ void vfio_unmap_region(struct kvm *kvm, struct vfio_region *region) munmap(region->host_addr, region->info.size); region->host_addr = NULL; } else if (region->is_ioport) { - ioport__unregister(kvm, region->port_base); + kvm__deregister_pio(kvm, region->port_base); } else { kvm__deregister_mmio(kvm, region->guest_phys_addr); } From patchwork Thu Feb 25 00:59:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103047 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08ABDC433E0 for ; Thu, 25 Feb 2021 01:03:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B36C664EC4 for ; Thu, 25 Feb 2021 01:03:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236720AbhBYBDb (ORCPT ); Wed, 24 Feb 2021 20:03:31 -0500 Received: from foss.arm.com ([217.140.110.172]:58502 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235735AbhBYBCW (ORCPT ); Wed, 24 Feb 2021 20:02:22 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 898CA1480; Wed, 24 Feb 2021 17:00:52 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3F6F63F73B; Wed, 24 Feb 2021 17:00:51 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 17/22] virtio: Switch trap handling to use MMIO handler Date: Thu, 25 Feb 2021 00:59:10 +0000 Message-Id: <20210225005915.26423-18-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With the planned retirement of the special ioport emulation code, we need to provide an emulation function compatible with the MMIO prototype. Adjust the existing MMIO callback routine to automatically determine the region this trap came through, and call the existing I/O handlers. Register the ioport region using the new registration function. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- virtio/pci.c | 46 ++++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/virtio/pci.c b/virtio/pci.c index 6eea6c68..eb91f512 100644 --- a/virtio/pci.c +++ b/virtio/pci.c @@ -178,15 +178,6 @@ static bool virtio_pci__data_in(struct kvm_cpu *vcpu, struct virtio_device *vdev return ret; } -static bool virtio_pci__io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - struct virtio_device *vdev = ioport->priv; - struct virtio_pci *vpci = vdev->virtio; - unsigned long offset = port - virtio_pci__port_addr(vpci); - - return virtio_pci__data_in(vcpu, vdev, offset, data, size); -} - static void update_msix_map(struct virtio_pci *vpci, struct msix_table *msix_entry, u32 vecnum) { @@ -334,20 +325,6 @@ static bool virtio_pci__data_out(struct kvm_cpu *vcpu, struct virtio_device *vde return ret; } -static bool virtio_pci__io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - struct virtio_device *vdev = ioport->priv; - struct virtio_pci *vpci = vdev->virtio; - unsigned long offset = port - virtio_pci__port_addr(vpci); - - return virtio_pci__data_out(vcpu, vdev, offset, data, size); -} - -static struct ioport_operations virtio_pci__io_ops = { - .io_in = virtio_pci__io_in, - .io_out = virtio_pci__io_out, -}; - static void virtio_pci__msix_mmio_callback(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) @@ -455,12 +432,19 @@ static void virtio_pci__io_mmio_callback(struct kvm_cpu *vcpu, { struct virtio_device *vdev = ptr; struct virtio_pci *vpci = vdev->virtio; - u32 mmio_addr = virtio_pci__mmio_addr(vpci); + u32 ioport_addr = virtio_pci__port_addr(vpci); + u32 base_addr; + + if (addr >= ioport_addr && + addr < ioport_addr + pci__bar_size(&vpci->pci_hdr, 0)) + base_addr = ioport_addr; + else + base_addr = virtio_pci__mmio_addr(vpci); if (!is_write) - virtio_pci__data_in(vcpu, vdev, addr - mmio_addr, data, len); + virtio_pci__data_in(vcpu, vdev, addr - base_addr, data, len); else - virtio_pci__data_out(vcpu, vdev, addr - mmio_addr, data, len); + virtio_pci__data_out(vcpu, vdev, addr - base_addr, data, len); } static int virtio_pci__bar_activate(struct kvm *kvm, @@ -478,10 +462,8 @@ static int virtio_pci__bar_activate(struct kvm *kvm, switch (bar_num) { case 0: - r = ioport__register(kvm, bar_addr, &virtio_pci__io_ops, - bar_size, vdev); - if (r > 0) - r = 0; + r = kvm__register_pio(kvm, bar_addr, bar_size, + virtio_pci__io_mmio_callback, vdev); break; case 1: r = kvm__register_mmio(kvm, bar_addr, bar_size, false, @@ -510,7 +492,7 @@ static int virtio_pci__bar_deactivate(struct kvm *kvm, switch (bar_num) { case 0: - r = ioport__unregister(kvm, bar_addr); + r = kvm__deregister_pio(kvm, bar_addr); break; case 1: case 2: @@ -625,7 +607,7 @@ int virtio_pci__exit(struct kvm *kvm, struct virtio_device *vdev) virtio_pci__reset(kvm, vdev); kvm__deregister_mmio(kvm, virtio_pci__mmio_addr(vpci)); kvm__deregister_mmio(kvm, virtio_pci__msix_io_addr(vpci)); - ioport__unregister(kvm, virtio_pci__port_addr(vpci)); + kvm__deregister_pio(kvm, virtio_pci__port_addr(vpci)); return 0; } From patchwork Thu Feb 25 00:59:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103055 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2169C433DB for ; Thu, 25 Feb 2021 01:04:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 592F664EC4 for ; Thu, 25 Feb 2021 01:04:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236807AbhBYBEW (ORCPT ); Wed, 24 Feb 2021 20:04:22 -0500 Received: from foss.arm.com ([217.140.110.172]:58544 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236667AbhBYBCt (ORCPT ); Wed, 24 Feb 2021 20:02:49 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1A9381478; Wed, 24 Feb 2021 17:00:54 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id C44993F73B; Wed, 24 Feb 2021 17:00:52 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 18/22] pci: Switch trap handling to use MMIO handler Date: Thu, 25 Feb 2021 00:59:11 +0000 Message-Id: <20210225005915.26423-19-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With the planned retirement of the special ioport emulation code, we need to provide an emulation function compatible with the MMIO prototype. Merge the existing _in and _out handlers to adhere to that MMIO interface, and register these using the new registration function. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- pci.c | 82 +++++++++++++++++------------------------------------------ 1 file changed, 24 insertions(+), 58 deletions(-) diff --git a/pci.c b/pci.c index 2e2c0270..d6da79e0 100644 --- a/pci.c +++ b/pci.c @@ -87,29 +87,16 @@ static void *pci_config_address_ptr(u16 port) return base + offset; } -static bool pci_config_address_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static void pci_config_address_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, + u32 len, u8 is_write, void *ptr) { - void *p = pci_config_address_ptr(port); + void *p = pci_config_address_ptr(addr); - memcpy(p, data, size); - - return true; -} - -static bool pci_config_address_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - void *p = pci_config_address_ptr(port); - - memcpy(data, p, size); - - return true; + if (is_write) + memcpy(p, data, len); + else + memcpy(data, p, len); } - -static struct ioport_operations pci_config_address_ops = { - .io_in = pci_config_address_in, - .io_out = pci_config_address_out, -}; - static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_number) { union pci_config_address pci_config_address; @@ -125,49 +112,27 @@ static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_numbe return !IS_ERR_OR_NULL(device__find_dev(DEVICE_BUS_PCI, device_number)); } -static bool pci_config_data_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) -{ - union pci_config_address pci_config_address; - - if (size > 4) - size = 4; - - pci_config_address.w = ioport__read32(&pci_config_address_bits); - /* - * If someone accesses PCI configuration space offsets that are not - * aligned to 4 bytes, it uses ioports to signify that. - */ - pci_config_address.reg_offset = port - PCI_CONFIG_DATA; - - pci__config_wr(vcpu->kvm, pci_config_address, data, size); - - return true; -} - -static bool pci_config_data_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) +static void pci_config_data_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data, + u32 len, u8 is_write, void *kvm) { union pci_config_address pci_config_address; - if (size > 4) - size = 4; + if (len > 4) + len = 4; pci_config_address.w = ioport__read32(&pci_config_address_bits); /* * If someone accesses PCI configuration space offsets that are not * aligned to 4 bytes, it uses ioports to signify that. */ - pci_config_address.reg_offset = port - PCI_CONFIG_DATA; + pci_config_address.reg_offset = addr - PCI_CONFIG_DATA; - pci__config_rd(vcpu->kvm, pci_config_address, data, size); - - return true; + if (is_write) + pci__config_wr(vcpu->kvm, pci_config_address, data, len); + else + pci__config_rd(vcpu->kvm, pci_config_address, data, len); } -static struct ioport_operations pci_config_data_ops = { - .io_in = pci_config_data_in, - .io_out = pci_config_data_out, -}; - static int pci_activate_bar(struct kvm *kvm, struct pci_device_header *pci_hdr, int bar_num) { @@ -512,11 +477,12 @@ int pci__init(struct kvm *kvm) { int r; - r = ioport__register(kvm, PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL); + r = kvm__register_pio(kvm, PCI_CONFIG_DATA, 4, + pci_config_data_mmio, NULL); if (r < 0) return r; - - r = ioport__register(kvm, PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL); + r = kvm__register_pio(kvm, PCI_CONFIG_ADDRESS, 4, + pci_config_address_mmio, NULL); if (r < 0) goto err_unregister_data; @@ -528,17 +494,17 @@ int pci__init(struct kvm *kvm) return 0; err_unregister_addr: - ioport__unregister(kvm, PCI_CONFIG_ADDRESS); + kvm__deregister_pio(kvm, PCI_CONFIG_ADDRESS); err_unregister_data: - ioport__unregister(kvm, PCI_CONFIG_DATA); + kvm__deregister_pio(kvm, PCI_CONFIG_DATA); return r; } dev_base_init(pci__init); int pci__exit(struct kvm *kvm) { - ioport__unregister(kvm, PCI_CONFIG_DATA); - ioport__unregister(kvm, PCI_CONFIG_ADDRESS); + kvm__deregister_pio(kvm, PCI_CONFIG_DATA); + kvm__deregister_pio(kvm, PCI_CONFIG_ADDRESS); return 0; } From patchwork Thu Feb 25 00:59:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103049 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8D40C433E0 for ; Thu, 25 Feb 2021 01:03:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A672664F03 for ; Thu, 25 Feb 2021 01:03:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232806AbhBYBDg (ORCPT ); Wed, 24 Feb 2021 20:03:36 -0500 Received: from foss.arm.com ([217.140.110.172]:58510 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236319AbhBYBC0 (ORCPT ); Wed, 24 Feb 2021 20:02:26 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A35BF14BF; Wed, 24 Feb 2021 17:00:55 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 54FFA3F73B; Wed, 24 Feb 2021 17:00:54 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 19/22] Remove ioport specific routines Date: Thu, 25 Feb 2021 00:59:12 +0000 Message-Id: <20210225005915.26423-20-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Now that all users of the dedicated ioport trap handler interface are gone, we can retire the code associated with it. This removes ioport.c and ioport.h, along with removing prototypes from other header files. This also transfers the responsibility for port I/O trap handling entirely into the new routine in mmio.c. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- Makefile | 1 - include/kvm/ioport.h | 27 ------ include/kvm/kvm.h | 2 - ioport.c | 195 ------------------------------------------- mmio.c | 2 +- 5 files changed, 1 insertion(+), 226 deletions(-) delete mode 100644 ioport.c diff --git a/Makefile b/Makefile index 35bb1182..94ff5da6 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,6 @@ OBJS += framebuffer.o OBJS += guest_compat.o OBJS += hw/rtc.o OBJS += hw/serial.o -OBJS += ioport.o OBJS += irq.o OBJS += kvm-cpu.o OBJS += kvm.o diff --git a/include/kvm/ioport.h b/include/kvm/ioport.h index a61038e2..b6f579cb 100644 --- a/include/kvm/ioport.h +++ b/include/kvm/ioport.h @@ -1,13 +1,8 @@ #ifndef KVM__IOPORT_H #define KVM__IOPORT_H -#include "kvm/devices.h" #include "kvm/kvm-cpu.h" -#include "kvm/rbtree-interval.h" -#include "kvm/fdt.h" -#include -#include #include #include #include @@ -15,30 +10,8 @@ /* some ports we reserve for own use */ #define IOPORT_DBG 0xe0 -struct kvm; - -struct ioport { - struct rb_int_node node; - struct ioport_operations *ops; - void *priv; - struct device_header dev_hdr; - u32 refcount; - bool remove; -}; - -struct ioport_operations { - bool (*io_in)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size); - bool (*io_out)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size); -}; - void ioport__map_irq(u8 *irq); -int __must_check ioport__register(struct kvm *kvm, u16 port, struct ioport_operations *ops, - int count, void *param); -int ioport__unregister(struct kvm *kvm, u16 port); -int ioport__init(struct kvm *kvm); -int ioport__exit(struct kvm *kvm); - static inline u8 ioport__read8(u8 *data) { return *data; diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h index 306b258a..6c28afa3 100644 --- a/include/kvm/kvm.h +++ b/include/kvm/kvm.h @@ -126,8 +126,6 @@ void kvm__irq_line(struct kvm *kvm, int irq, int level); void kvm__irq_trigger(struct kvm *kvm, int irq); bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count); bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write); -bool kvm__emulate_pio(struct kvm_cpu *vcpu, u16 port, void *data, - int direction, int size, u32 count); int kvm__destroy_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr); int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr, enum kvm_mem_type type); diff --git a/ioport.c b/ioport.c deleted file mode 100644 index ce29e7e7..00000000 --- a/ioport.c +++ /dev/null @@ -1,195 +0,0 @@ -#include "kvm/ioport.h" - -#include "kvm/kvm.h" -#include "kvm/util.h" -#include "kvm/rbtree-interval.h" -#include "kvm/mutex.h" - -#include /* for KVM_EXIT_* */ -#include - -#include -#include -#include -#include - -#define ioport_node(n) rb_entry(n, struct ioport, node) - -static DEFINE_MUTEX(ioport_lock); - -static struct rb_root ioport_tree = RB_ROOT; - -static struct ioport *ioport_search(struct rb_root *root, u64 addr) -{ - struct rb_int_node *node; - - node = rb_int_search_single(root, addr); - if (node == NULL) - return NULL; - - return ioport_node(node); -} - -static int ioport_insert(struct rb_root *root, struct ioport *data) -{ - return rb_int_insert(root, &data->node); -} - -static void ioport_remove(struct rb_root *root, struct ioport *data) -{ - rb_int_erase(root, &data->node); -} - -static struct ioport *ioport_get(struct rb_root *root, u64 addr) -{ - struct ioport *ioport; - - mutex_lock(&ioport_lock); - ioport = ioport_search(root, addr); - if (ioport) - ioport->refcount++; - mutex_unlock(&ioport_lock); - - return ioport; -} - -/* Called with ioport_lock held. */ -static void ioport_unregister(struct rb_root *root, struct ioport *data) -{ - ioport_remove(root, data); - free(data); -} - -static void ioport_put(struct rb_root *root, struct ioport *data) -{ - mutex_lock(&ioport_lock); - data->refcount--; - if (data->remove && data->refcount == 0) - ioport_unregister(root, data); - mutex_unlock(&ioport_lock); -} - -int ioport__register(struct kvm *kvm, u16 port, struct ioport_operations *ops, int count, void *param) -{ - struct ioport *entry; - int r; - - entry = malloc(sizeof(*entry)); - if (entry == NULL) - return -ENOMEM; - - *entry = (struct ioport) { - .node = RB_INT_INIT(port, port + count), - .ops = ops, - .priv = param, - /* - * Start from 0 because ioport__unregister() doesn't decrement - * the reference count. - */ - .refcount = 0, - .remove = false, - }; - - mutex_lock(&ioport_lock); - r = ioport_insert(&ioport_tree, entry); - if (r < 0) - goto out_free; - mutex_unlock(&ioport_lock); - - return port; - -out_free: - free(entry); - mutex_unlock(&ioport_lock); - return r; -} - -int ioport__unregister(struct kvm *kvm, u16 port) -{ - struct ioport *entry; - - mutex_lock(&ioport_lock); - entry = ioport_search(&ioport_tree, port); - if (!entry) { - mutex_unlock(&ioport_lock); - return -ENOENT; - } - /* The same reasoning from kvm__deregister_mmio() applies. */ - if (entry->refcount == 0) - ioport_unregister(&ioport_tree, entry); - else - entry->remove = true; - mutex_unlock(&ioport_lock); - - return 0; -} - -static void ioport__unregister_all(void) -{ - struct ioport *entry; - struct rb_node *rb; - struct rb_int_node *rb_node; - - rb = rb_first(&ioport_tree); - while (rb) { - rb_node = rb_int(rb); - entry = ioport_node(rb_node); - ioport_unregister(&ioport_tree, entry); - rb = rb_first(&ioport_tree); - } -} - -static const char *to_direction(int direction) -{ - if (direction == KVM_EXIT_IO_IN) - return "IN"; - else - return "OUT"; -} - -static void ioport_error(u16 port, void *data, int direction, int size, u32 count) -{ - fprintf(stderr, "IO error: %s port=%x, size=%d, count=%u\n", to_direction(direction), port, size, count); -} - -bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count) -{ - struct ioport_operations *ops; - bool ret = false; - struct ioport *entry; - void *ptr = data; - struct kvm *kvm = vcpu->kvm; - - entry = ioport_get(&ioport_tree, port); - if (!entry) - return kvm__emulate_pio(vcpu, port, data, direction, - size, count); - - ops = entry->ops; - - while (count--) { - if (direction == KVM_EXIT_IO_IN && ops->io_in) - ret = ops->io_in(entry, vcpu, port, ptr, size); - else if (direction == KVM_EXIT_IO_OUT && ops->io_out) - ret = ops->io_out(entry, vcpu, port, ptr, size); - - ptr += size; - } - - ioport_put(&ioport_tree, entry); - - if (ret) - return true; - - if (kvm->cfg.ioport_debug) - ioport_error(port, data, direction, size, count); - - return !kvm->cfg.ioport_debug; -} - -int ioport__exit(struct kvm *kvm) -{ - ioport__unregister_all(); - return 0; -} -dev_base_exit(ioport__exit); diff --git a/mmio.c b/mmio.c index 75de04ad..9f731dcf 100644 --- a/mmio.c +++ b/mmio.c @@ -212,7 +212,7 @@ out: return true; } -bool kvm__emulate_pio(struct kvm_cpu *vcpu, u16 port, void *data, +bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count) { struct mmio_mapping *mmio; From patchwork Thu Feb 25 00:59:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103057 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF9B3C433E0 for ; Thu, 25 Feb 2021 01:04:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C752164EC4 for ; Thu, 25 Feb 2021 01:04:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234024AbhBYBE3 (ORCPT ); Wed, 24 Feb 2021 20:04:29 -0500 Received: from foss.arm.com ([217.140.110.172]:58550 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235094AbhBYBCw (ORCPT ); Wed, 24 Feb 2021 20:02:52 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 36C5A14FF; Wed, 24 Feb 2021 17:00:57 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DE02D3F73B; Wed, 24 Feb 2021 17:00:55 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 20/22] arm: Reorganise and document memory map Date: Thu, 25 Feb 2021 00:59:13 +0000 Message-Id: <20210225005915.26423-21-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The hardcoded memory map we expose to a guest is currently described using a series of partially interconnected preprocessor constants, which is hard to read and follow. In preparation for moving the UART and RTC to some different MMIO region, document the current map with some ASCII art, and clean up the definition of the sections. No functional change. Signed-off-by: Andre Przywara --- arm/include/arm-common/kvm-arch.h | 41 ++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h index d84e50cd..b12255b0 100644 --- a/arm/include/arm-common/kvm-arch.h +++ b/arm/include/arm-common/kvm-arch.h @@ -7,14 +7,33 @@ #include "arm-common/gic.h" +/* + * The memory map used for ARM guests (not to scale): + * + * 0 64K 16M 32M 48M 1GB 2GB + * +-------+-..-+-------+-------+--....--+-----+--.....--+---...... + * | (PCI) |////| int. | | | | | + * | I/O |////| MMIO: | Flash | virtio | GIC | PCI | DRAM + * | ports |////| UART, | | MMIO | | (AXI) | + * | |////| RTC | | | | | + * +-------+-..-+-------+-------+--....--+-----+--.....--+---...... + */ + #define ARM_IOPORT_AREA _AC(0x0000000000000000, UL) -#define ARM_FLASH_AREA _AC(0x0000000002000000, UL) -#define ARM_MMIO_AREA _AC(0x0000000003000000, UL) +#define ARM_MMIO_AREA _AC(0x0000000001000000, UL) #define ARM_AXI_AREA _AC(0x0000000040000000, UL) #define ARM_MEMORY_AREA _AC(0x0000000080000000, UL) -#define ARM_LOMAP_MAX_MEMORY ((1ULL << 32) - ARM_MEMORY_AREA) -#define ARM_HIMAP_MAX_MEMORY ((1ULL << 40) - ARM_MEMORY_AREA) +#define KVM_IOPORT_AREA ARM_IOPORT_AREA +#define ARM_IOPORT_SIZE (1U << 16) + + +#define KVM_FLASH_MMIO_BASE (ARM_MMIO_AREA + 0x1000000) +#define KVM_FLASH_MAX_SIZE 0x1000000 + +#define KVM_VIRTIO_MMIO_AREA (KVM_FLASH_MMIO_BASE + KVM_FLASH_MAX_SIZE) +#define ARM_VIRTIO_MMIO_SIZE (ARM_AXI_AREA - \ + (KVM_VIRTIO_MMIO_AREA + ARM_GIC_SIZE)) #define ARM_GIC_DIST_BASE (ARM_AXI_AREA - ARM_GIC_DIST_SIZE) #define ARM_GIC_CPUI_BASE (ARM_GIC_DIST_BASE - ARM_GIC_CPUI_SIZE) @@ -22,19 +41,17 @@ #define ARM_GIC_DIST_SIZE 0x10000 #define ARM_GIC_CPUI_SIZE 0x20000 -#define KVM_FLASH_MMIO_BASE ARM_FLASH_AREA -#define KVM_FLASH_MAX_SIZE (ARM_MMIO_AREA - ARM_FLASH_AREA) -#define ARM_IOPORT_SIZE (1U << 16) -#define ARM_VIRTIO_MMIO_SIZE (ARM_AXI_AREA - (ARM_MMIO_AREA + ARM_GIC_SIZE)) +#define KVM_PCI_CFG_AREA ARM_AXI_AREA #define ARM_PCI_CFG_SIZE (1ULL << 24) +#define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE) #define ARM_PCI_MMIO_SIZE (ARM_MEMORY_AREA - \ (ARM_AXI_AREA + ARM_PCI_CFG_SIZE)) -#define KVM_IOPORT_AREA ARM_IOPORT_AREA -#define KVM_PCI_CFG_AREA ARM_AXI_AREA -#define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE) -#define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA + +#define ARM_LOMAP_MAX_MEMORY ((1ULL << 32) - ARM_MEMORY_AREA) +#define ARM_HIMAP_MAX_MEMORY ((1ULL << 40) - ARM_MEMORY_AREA) + #define KVM_IOEVENTFD_HAS_PIO 0 From patchwork Thu Feb 25 00:59:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103051 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B232C433E9 for ; Thu, 25 Feb 2021 01:03:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CC66C64EC4 for ; Thu, 25 Feb 2021 01:03:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235508AbhBYBDn (ORCPT ); Wed, 24 Feb 2021 20:03:43 -0500 Received: from foss.arm.com ([217.140.110.172]:58508 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236589AbhBYBCd (ORCPT ); Wed, 24 Feb 2021 20:02:33 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BCA3C1509; Wed, 24 Feb 2021 17:00:58 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 714B23F73B; Wed, 24 Feb 2021 17:00:57 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 21/22] hw/serial: ARM/arm64: Use MMIO at higher addresses Date: Thu, 25 Feb 2021 00:59:14 +0000 Message-Id: <20210225005915.26423-22-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Using the UART devices at their legacy I/O addresses as set by IBM in 1981 was a kludge we used for simplicity on ARM platforms as well. However this imposes problems due to their missing alignment and overlap with the PCI I/O address space. Now that we can switch a device easily between using ioports and MMIO, let's move the UARTs out of the first 4K of memory on ARM platforms. That should be transparent for well behaved guests, since the change is naturally reflected in the device tree. Even "earlycon" keeps working, as the stdout-path property is adjusted automatically. People providing direct earlycon parameters via the command line need to adjust it to: "earlycon=uart,mmio,0x1000000". Signed-off-by: Andre Przywara --- arm/include/arm-common/kvm-arch.h | 3 +++ hw/serial.c | 45 ++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h index b12255b0..633ea8fa 100644 --- a/arm/include/arm-common/kvm-arch.h +++ b/arm/include/arm-common/kvm-arch.h @@ -28,6 +28,9 @@ #define ARM_IOPORT_SIZE (1U << 16) +#define ARM_UART_MMIO_BASE ARM_MMIO_AREA +#define ARM_UART_MMIO_SIZE 0x10000 + #define KVM_FLASH_MMIO_BASE (ARM_MMIO_AREA + 0x1000000) #define KVM_FLASH_MAX_SIZE 0x1000000 diff --git a/hw/serial.c b/hw/serial.c index 4be188a1..1854add2 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -13,6 +13,17 @@ #include +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +#define serial_iobase(nr) (ARM_UART_MMIO_BASE + (nr) * 0x1000) +#define serial_irq(nr) (32 + (nr)) +#define SERIAL8250_BUS_TYPE DEVICE_BUS_MMIO +#else +#define serial_iobase(nr) ((((nr) & 1) ? 0x200 : 0x300) + \ + ((nr) >= 2 ? 0xe8 : 0xf8)) +#define serial_irq(nr) (((nr) & 1) ? 3 : 4) +#define SERIAL8250_BUS_TYPE DEVICE_BUS_IOPORT +#endif + /* * This fakes a U6_16550A. The fifo len needs to be 64 as the kernel * expects that for autodetection. @@ -27,7 +38,7 @@ struct serial8250_device { struct mutex mutex; u8 id; - u16 iobase; + u32 iobase; u8 irq; u8 irq_state; int txcnt; @@ -65,56 +76,56 @@ static struct serial8250_device devices[] = { /* ttyS0 */ [0] = { .dev_hdr = { - .bus_type = DEVICE_BUS_IOPORT, + .bus_type = SERIAL8250_BUS_TYPE, .data = serial8250_generate_fdt_node, }, .mutex = MUTEX_INITIALIZER, .id = 0, - .iobase = 0x3f8, - .irq = 4, + .iobase = serial_iobase(0), + .irq = serial_irq(0), SERIAL_REGS_SETTING }, /* ttyS1 */ [1] = { .dev_hdr = { - .bus_type = DEVICE_BUS_IOPORT, + .bus_type = SERIAL8250_BUS_TYPE, .data = serial8250_generate_fdt_node, }, .mutex = MUTEX_INITIALIZER, .id = 1, - .iobase = 0x2f8, - .irq = 3, + .iobase = serial_iobase(1), + .irq = serial_irq(1), SERIAL_REGS_SETTING }, /* ttyS2 */ [2] = { .dev_hdr = { - .bus_type = DEVICE_BUS_IOPORT, + .bus_type = SERIAL8250_BUS_TYPE, .data = serial8250_generate_fdt_node, }, .mutex = MUTEX_INITIALIZER, .id = 2, - .iobase = 0x3e8, - .irq = 4, + .iobase = serial_iobase(2), + .irq = serial_irq(2), SERIAL_REGS_SETTING }, /* ttyS3 */ [3] = { .dev_hdr = { - .bus_type = DEVICE_BUS_IOPORT, + .bus_type = SERIAL8250_BUS_TYPE, .data = serial8250_generate_fdt_node, }, .mutex = MUTEX_INITIALIZER, .id = 3, - .iobase = 0x2e8, - .irq = 3, + .iobase = serial_iobase(3), + .irq = serial_irq(3), SERIAL_REGS_SETTING }, @@ -439,7 +450,8 @@ static int serial8250__device_init(struct kvm *kvm, return r; ioport__map_irq(&dev->irq); - r = kvm__register_pio(kvm, dev->iobase, 8, serial8250_mmio, dev); + r = kvm__register_iotrap(kvm, dev->iobase, 8, serial8250_mmio, dev, + SERIAL8250_BUS_TYPE); return r; } @@ -462,7 +474,7 @@ cleanup: for (j = 0; j <= i; j++) { struct serial8250_device *dev = &devices[j]; - kvm__deregister_pio(kvm, dev->iobase); + kvm__deregister_iotrap(kvm, dev->iobase, SERIAL8250_BUS_TYPE); device__unregister(&dev->dev_hdr); } @@ -478,7 +490,8 @@ int serial8250__exit(struct kvm *kvm) for (i = 0; i < ARRAY_SIZE(devices); i++) { struct serial8250_device *dev = &devices[i]; - r = kvm__deregister_pio(kvm, dev->iobase); + r = kvm__deregister_iotrap(kvm, dev->iobase, + SERIAL8250_BUS_TYPE); if (r < 0) return r; device__unregister(&dev->dev_hdr); From patchwork Thu Feb 25 00:59:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 12103059 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 831CEC433E6 for ; Thu, 25 Feb 2021 01:04:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4B96664F03 for ; Thu, 25 Feb 2021 01:04:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236691AbhBYBEd (ORCPT ); Wed, 24 Feb 2021 20:04:33 -0500 Received: from foss.arm.com ([217.140.110.172]:58554 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236715AbhBYBCz (ORCPT ); Wed, 24 Feb 2021 20:02:55 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4DF771515; Wed, 24 Feb 2021 17:01:00 -0800 (PST) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 02F613F73B; Wed, 24 Feb 2021 17:00:58 -0800 (PST) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: Alexandru Elisei , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, Marc Zyngier , Sami Mujawar Subject: [PATCH kvmtool v2 22/22] hw/rtc: ARM/arm64: Use MMIO at higher addresses Date: Thu, 25 Feb 2021 00:59:15 +0000 Message-Id: <20210225005915.26423-23-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210225005915.26423-1-andre.przywara@arm.com> References: <20210225005915.26423-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Using the RTC device at its legacy I/O address as set by IBM in 1981 was a kludge we used for simplicity on ARM platforms as well. However this imposes problems due to their missing alignment and overlap with the PCI I/O address space. Now that we can switch a device easily between using ioports and MMIO, let's move the RTC out of the first 4K of memory on ARM platforms. That should be transparent for well behaved guests, since the change is naturally reflected in the device tree. Signed-off-by: Andre Przywara Reviewed-by: Alexandru Elisei --- arm/include/arm-common/kvm-arch.h | 3 +++ hw/rtc.c | 24 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h index 633ea8fa..02100c48 100644 --- a/arm/include/arm-common/kvm-arch.h +++ b/arm/include/arm-common/kvm-arch.h @@ -31,6 +31,9 @@ #define ARM_UART_MMIO_BASE ARM_MMIO_AREA #define ARM_UART_MMIO_SIZE 0x10000 +#define ARM_RTC_MMIO_BASE (ARM_UART_MMIO_BASE + ARM_UART_MMIO_SIZE) +#define ARM_RTC_MMIO_SIZE 0x10000 + #define KVM_FLASH_MMIO_BASE (ARM_MMIO_AREA + 0x1000000) #define KVM_FLASH_MAX_SIZE 0x1000000 diff --git a/hw/rtc.c b/hw/rtc.c index ee4c9102..aec31c52 100644 --- a/hw/rtc.c +++ b/hw/rtc.c @@ -5,6 +5,15 @@ #include +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +#define RTC_BUS_TYPE DEVICE_BUS_MMIO +#define RTC_BASE_ADDRESS ARM_RTC_MMIO_BASE +#else +/* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */ +#define RTC_BUS_TYPE DEVICE_BUS_IOPORT +#define RTC_BASE_ADDRESS 0x70 +#endif + /* * MC146818 RTC registers */ @@ -49,7 +58,7 @@ static void cmos_ram_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, time_t ti; if (is_write) { - if (addr == 0x70) { /* index register */ + if (addr == RTC_BASE_ADDRESS) { /* index register */ u8 value = ioport__read8(data); vcpu->kvm->nmi_disabled = value & (1UL << 7); @@ -70,7 +79,7 @@ static void cmos_ram_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, return; } - if (addr == 0x70) + if (addr == RTC_BASE_ADDRESS) /* index register is write-only */ return; time(&ti); @@ -127,7 +136,7 @@ static void generate_rtc_fdt_node(void *fdt, u8 irq, enum irq_type)) { - u64 reg_prop[2] = { cpu_to_fdt64(0x70), cpu_to_fdt64(2) }; + u64 reg_prop[2] = { cpu_to_fdt64(RTC_BASE_ADDRESS), cpu_to_fdt64(2) }; _FDT(fdt_begin_node(fdt, "rtc")); _FDT(fdt_property_string(fdt, "compatible", "motorola,mc146818")); @@ -139,7 +148,7 @@ static void generate_rtc_fdt_node(void *fdt, #endif struct device_header rtc_dev_hdr = { - .bus_type = DEVICE_BUS_IOPORT, + .bus_type = RTC_BUS_TYPE, .data = generate_rtc_fdt_node, }; @@ -151,8 +160,8 @@ int rtc__init(struct kvm *kvm) if (r < 0) return r; - /* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */ - r = kvm__register_pio(kvm, 0x0070, 2, cmos_ram_io, NULL); + r = kvm__register_iotrap(kvm, RTC_BASE_ADDRESS, 2, cmos_ram_io, NULL, + RTC_BUS_TYPE); if (r < 0) goto out_device; @@ -170,8 +179,7 @@ dev_init(rtc__init); int rtc__exit(struct kvm *kvm) { - /* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */ - kvm__deregister_pio(kvm, 0x0070); + kvm__deregister_iotrap(kvm, RTC_BASE_ADDRESS, RTC_BUS_TYPE); return 0; }