From patchwork Sat May 21 08:51:51 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 805512 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p4L8qHej032147 for ; Sat, 21 May 2011 08:52:18 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753615Ab1EUIwJ (ORCPT ); Sat, 21 May 2011 04:52:09 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:43680 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753074Ab1EUIwG (ORCPT ); Sat, 21 May 2011 04:52:06 -0400 Received: by wwa36 with SMTP id 36so4709702wwa.1 for ; Sat, 21 May 2011 01:52:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=S5JSqdZOs3Cb+ga0GnC+fZWZM4McRyNKBlK0yoae9B0=; b=TAuYxxIy0lUULB4buBN+wtQxQigLcIPy5cZloZ48BNrMQ1n8FFyU5ZylX222lm7imN 5ckrBlLAZzz9pbQsviZC1oW5ZH8z/XT9vvbt8mQcbtrKs2nd7wkMwAC09wD5Y9hsV5ru ujOMysXuUXULbW6R4wL0lTgduPUYAUgNwYCqk= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=QsU1NTJ6jR/t/VDpCUWRpMQehpRWkNNjY5bxykI90y37yvFmEkiMvFvMhmyRc5sZ8J Zyqxg5JU97+04C4Gpfdt4RQgJugc/K+q1iXT9KweGXMUNFrthjx5/sKo9fm4AzGhwBK4 t5j09CyobKk+grMgo1ZGiif7FgF9R92oyBzXk= Received: by 10.227.209.9 with SMTP id ge9mr415291wbb.110.1305967924989; Sat, 21 May 2011 01:52:04 -0700 (PDT) Received: from localhost.localdomain (bzq-79-179-206-38.red.bezeqint.net [79.179.206.38]) by mx.google.com with ESMTPS id ca12sm2765187wbb.19.2011.05.21.01.52.03 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 21 May 2011 01:52:04 -0700 (PDT) From: Sasha Levin To: penberg@kernel.org Cc: mingo@elte.hu, asias.hejun@gmail.com, gorcunov@gmail.com, prasadjoshi124@gmail.com, kvm@vger.kernel.org, Sasha Levin Subject: [PATCH 2/2] kvm tools: Modify ioport to use interval rbtree Date: Sat, 21 May 2011 11:51:51 +0300 Message-Id: <1305967911-30045-2-git-send-email-levinsasha928@gmail.com> X-Mailer: git-send-email 1.7.5.rc3 In-Reply-To: <1305967911-30045-1-git-send-email-levinsasha928@gmail.com> References: <1305967911-30045-1-git-send-email-levinsasha928@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sat, 21 May 2011 08:52:18 +0000 (UTC) Currently the ioport implementation is based on a USHRT_MAX length array of ptrs to ioport_operations. Instead, use an interval rbtree to map the ioports to ioport_operations. Signed-off-by: Sasha Levin --- tools/kvm/ioport.c | 54 +++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 47 insertions(+), 7 deletions(-) diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c index 2f6c06c..ea19f2b 100644 --- a/tools/kvm/ioport.c +++ b/tools/kvm/ioport.c @@ -1,6 +1,8 @@ #include "kvm/ioport.h" #include "kvm/kvm.h" +#include "kvm/util.h" +#include "kvm/rbtree-interval.h" #include /* for KVM_EXIT_* */ #include @@ -11,8 +13,32 @@ #include #include +#define ioport_node(n) rb_entry(n, struct ioport_entry, node) + +struct ioport_entry { + struct rb_int_node node; + struct ioport_operations *ops; +}; + +static struct rb_root ioport_tree = RB_ROOT; bool ioport_debug; +static struct ioport_entry *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_entry *data) +{ + return rb_int_insert(root, &data->node); +} + static bool debug_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count) { exit(EXIT_SUCCESS); @@ -41,14 +67,24 @@ static struct ioport_operations dummy_write_only_ioport_ops = { .io_out = dummy_io_out, }; -static struct ioport_operations *ioport_ops[USHRT_MAX]; - void ioport__register(u16 port, struct ioport_operations *ops, int count) { - int i; + struct ioport_entry *entry; - for (i = 0; i < count; i++) - ioport_ops[port + i] = ops; + entry = ioport_search(&ioport_tree, port); + if (entry) + rb_int_erase(&ioport_tree, &entry->node); + + entry = malloc(sizeof(*entry)); + if (entry == NULL) + die("Failed allocating new ioport entry"); + + *entry = (struct ioport_entry) { + .node = RB_INT_INIT(port, port + count), + .ops = ops, + }; + + ioport_insert(&ioport_tree, entry); } static const char *to_direction(int direction) @@ -66,12 +102,16 @@ static void ioport_error(u16 port, void *data, int direction, int size, u32 coun bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count) { - struct ioport_operations *ops = ioport_ops[port]; + struct ioport_operations *ops; bool ret; + struct ioport_entry *entry; - if (!ops) + entry = ioport_search(&ioport_tree, port); + if (!entry) goto error; + ops = entry->ops; + if (direction == KVM_EXIT_IO_IN) { if (!ops->io_in) goto error;