From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sasha Levin Subject: [PATCH v2 2/8] kvm tools: Add basic ioport dynamic allocation Date: Thu, 26 May 2011 09:42:09 +0300 Message-ID: <1306392135-16993-2-git-send-email-levinsasha928@gmail.com> References: <1306392135-16993-1-git-send-email-levinsasha928@gmail.com> Cc: john@jfloren.net, kvm@vger.kernel.org, mingo@elte.hu, asias.hejun@gmail.com, gorcunov@gmail.com, prasadjoshi124@gmail.com, Sasha Levin To: penberg@kernel.org Return-path: Received: from mail-ww0-f42.google.com ([74.125.82.42]:45636 "EHLO mail-ww0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753770Ab1EZGms (ORCPT ); Thu, 26 May 2011 02:42:48 -0400 Received: by wwk4 with SMTP id 4so4127985wwk.1 for ; Wed, 25 May 2011 23:42:47 -0700 (PDT) In-Reply-To: <1306392135-16993-1-git-send-email-levinsasha928@gmail.com> Sender: kvm-owner@vger.kernel.org List-ID: Add a very simple allocation of ioports. This prevents the need to coordinate ioports between different modules. Signed-off-by: Sasha Levin --- tools/kvm/include/kvm/ioport.h | 11 +++++++++-- tools/kvm/ioport.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h index 2a8d74d..c500f1e 100644 --- a/tools/kvm/include/kvm/ioport.h +++ b/tools/kvm/include/kvm/ioport.h @@ -7,6 +7,9 @@ /* some ports we reserve for own use */ #define IOPORT_DBG 0xe0 +#define IOPORT_START 0x6200 +#define IOPORT_SIZE 0x400 + #define IOPORT_VESA 0xa200 #define IOPORT_VESA_SIZE 256 #define IOPORT_VIRTIO_P9 0xb200 /* Virtio 9P device */ @@ -20,6 +23,8 @@ #define IOPORT_VIRTIO_RNG 0xf200 /* Virtio network device */ #define IOPORT_VIRTIO_RNG_SIZE 256 +#define IOPORT_EMPTY USHRT_MAX + struct kvm; struct ioport_operations { @@ -31,8 +36,10 @@ struct ioport_operations { void ioport__setup_legacy(void); -void ioport__register(u16 port, struct ioport_operations *ops, int count); -void ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param); +u16 ioport__register(u16 port, struct ioport_operations *ops, int count); +u16 ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param); + +u16 ioport__find_free_range(void); static inline u8 ioport__read8(u8 *data) { diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c index 159d089..b2a3272 100644 --- a/tools/kvm/ioport.c +++ b/tools/kvm/ioport.c @@ -3,6 +3,7 @@ #include "kvm/kvm.h" #include "kvm/util.h" #include "kvm/rbtree-interval.h" +#include "kvm/mutex.h" #include /* for KVM_EXIT_* */ #include @@ -21,9 +22,23 @@ struct ioport_entry { void *param; }; +static u16 free_io_port_idx; +DEFINE_MUTEX(free_io_port_idx_lock); static struct rb_root ioport_tree = RB_ROOT; bool ioport_debug; +static u16 ioport__find_free_port(void) +{ + u16 free_port; + + mutex_lock(&free_io_port_idx_lock); + free_port = IOPORT_START + free_io_port_idx * IOPORT_SIZE; + free_io_port_idx++; + mutex_unlock(&free_io_port_idx_lock); + + return free_port; +} + static struct ioport_entry *ioport_search(struct rb_root *root, u64 addr) { struct rb_int_node *node; @@ -68,10 +83,13 @@ static struct ioport_operations dummy_write_only_ioport_ops = { .io_out = dummy_io_out, }; -void ioport__register(u16 port, struct ioport_operations *ops, int count) +u16 ioport__register(u16 port, struct ioport_operations *ops, int count) { struct ioport_entry *entry; + if (port == IOPORT_EMPTY) + port = ioport__find_free_port(); + entry = ioport_search(&ioport_tree, port); if (entry) { pr_warning("ioport re-registered: %x", port); @@ -88,12 +106,17 @@ void ioport__register(u16 port, struct ioport_operations *ops, int count) }; ioport_insert(&ioport_tree, entry); + + return port; } -void ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param) +u16 ioport__register_param(u16 port, struct ioport_operations *ops, int count, void *param) { struct ioport_entry *entry; + if (port == IOPORT_EMPTY) + port = ioport__find_free_port(); + entry = ioport_search(&ioport_tree, port); if (entry) { pr_warning("ioport re-registered: %x", port); @@ -111,6 +134,8 @@ void ioport__register_param(u16 port, struct ioport_operations *ops, int count, }; ioport_insert(&ioport_tree, entry); + + return port; } static const char *to_direction(int direction) @@ -126,6 +151,13 @@ static void ioport_error(u16 port, void *data, int direction, int size, u32 coun fprintf(stderr, "IO error: %s port=%x, size=%d, count=%u\n", to_direction(direction), port, size, count); } +u16 ioport__find_free_range(void) +{ + static u16 cur_loc; + + return IOPORT_START + (cur_loc++ * IOPORT_SIZE); +} + bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count) { struct ioport_operations *ops; -- 1.7.5.rc3