@@ -9,6 +9,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 */
@@ -22,6 +25,8 @@
#define IOPORT_VIRTIO_RNG 0xf200 /* Virtio network device */
#define IOPORT_VIRTIO_RNG_SIZE 256
+#define IOPORT_EMPTY USHRT_MAX
+
struct kvm;
struct ioport {
@@ -37,7 +42,7 @@ struct ioport_operations {
void ioport__setup_legacy(void);
-void ioport__register(u16 port, struct ioport_operations *ops, int count, void *param);
+u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param);
static inline u8 ioport__read8(u8 *data)
{
@@ -3,6 +3,9 @@
#include "kvm/kvm.h"
#include "kvm/util.h"
+#include "kvm/rbtree-interval.h"
+#include "kvm/mutex.h"
+
#include <linux/kvm.h> /* for KVM_EXIT_* */
#include <linux/types.h>
@@ -14,9 +17,23 @@
#define ioport_node(n) rb_entry(n, struct ioport, node)
+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 *ioport_search(struct rb_root *root, u64 addr)
{
struct rb_int_node *node;
@@ -61,10 +78,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, void *param)
+u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param)
{
struct ioport *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);
@@ -82,6 +102,8 @@ void ioport__register(u16 port, struct ioport_operations *ops, int count, void *
};
ioport_insert(&ioport_tree, entry);
+
+ return port;
}
static const char *to_direction(int direction)
Add a very simple allocation of ioports. This prevents the need to coordinate ioports between different modules. Signed-off-by: Sasha Levin <levinsasha928@gmail.com> --- tools/kvm/include/kvm/ioport.h | 7 ++++++- tools/kvm/ioport.c | 24 +++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-)