Commit 870836a9 authored by Julien Thierry's avatar Julien Thierry Committed by Alexandru Elisei
Browse files

ioport: pci: Move port allocations to PCI devices



The dynamic ioport allocation with IOPORT_EMPTY is currently only used
by PCI devices. Other devices use fixed ports for which they request
registration to the ioport API.

PCI ports need to be in the PCI IO space and there is no reason ioport
API should know a PCI port is being allocated and needs to be placed in
PCI IO space. This currently just happens to be the case.

Move the responsability of dynamic allocation of ioports from the ioport
API to PCI.

In the future, if other types of devices also need dynamic ioport
allocation, they'll have to figure out the range of ports they are
allowed to use.
Signed-off-by: default avatarJulien Thierry <julien.thierry@arm.com>
[Renamed functions for clarity]
Signed-off-by: Alexandru Elisei's avatarAlexandru Elisei <alexandru.elisei@arm.com>
parent c2a8c2a7
......@@ -62,8 +62,8 @@ struct framebuffer *vesa__init(struct kvm *kvm)
if (!kvm->cfg.vnc && !kvm->cfg.sdl && !kvm->cfg.gtk)
return NULL;
r = ioport__register(kvm, IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
r = pci_get_io_port_block(IOPORT_SIZE);
r = ioport__register(kvm, r, &vesa_io_ops, IOPORT_SIZE, NULL);
if (r < 0)
return ERR_PTR(r);
......
......@@ -14,11 +14,8 @@
/* some ports we reserve for own use */
#define IOPORT_DBG 0xe0
#define IOPORT_START 0x6200
#define IOPORT_SIZE 0x400
#define IOPORT_EMPTY USHRT_MAX
struct kvm;
struct ioport {
......
......@@ -19,6 +19,7 @@
#define PCI_CONFIG_DATA 0xcfc
#define PCI_CONFIG_BUS_FORWARD 0xcfa
#define PCI_IO_SIZE 0x100
#define PCI_IOPORT_START 0x6200
#define PCI_CFG_SIZE (1ULL << 24)
struct kvm;
......@@ -152,7 +153,8 @@ struct pci_device_header {
int pci__init(struct kvm *kvm);
int pci__exit(struct kvm *kvm);
struct pci_device_header *pci__find_dev(u8 dev_num);
u32 pci_get_io_space_block(u32 size);
u32 pci_get_mmio_block(u32 size);
u16 pci_get_io_port_block(u32 size);
void pci__assign_irq(struct device_header *dev_hdr);
void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size);
void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size);
......
......@@ -16,24 +16,8 @@
#define ioport_node(n) rb_entry(n, struct ioport, node)
DEFINE_MUTEX(ioport_mutex);
static u16 free_io_port_idx; /* protected by ioport_mutex */
static struct rb_root ioport_tree = RB_ROOT;
static u16 ioport__find_free_port(void)
{
u16 free_port;
mutex_lock(&ioport_mutex);
free_port = IOPORT_START + free_io_port_idx * IOPORT_SIZE;
free_io_port_idx++;
mutex_unlock(&ioport_mutex);
return free_port;
}
static struct ioport *ioport_search(struct rb_root *root, u64 addr)
{
struct rb_int_node *node;
......@@ -85,8 +69,6 @@ int ioport__register(struct kvm *kvm, u16 port, struct ioport_operations *ops, i
int r;
br_write_lock(kvm);
if (port == IOPORT_EMPTY)
port = ioport__find_free_port();
entry = ioport_search(&ioport_tree, port);
if (entry) {
......
......@@ -15,15 +15,24 @@ static u32 pci_config_address_bits;
* (That's why it can still 32bit even with 64bit guests-- 64bit
* PCI isn't currently supported.)
*/
static u32 io_space_blocks = KVM_PCI_MMIO_AREA;
static u32 mmio_blocks = KVM_PCI_MMIO_AREA;
static u16 io_port_blocks = PCI_IOPORT_START;
u16 pci_get_io_port_block(u32 size)
{
u16 port = ALIGN(io_port_blocks, IOPORT_SIZE);
io_port_blocks = port + size;
return port;
}
/*
* BARs must be naturally aligned, so enforce this in the allocator.
*/
u32 pci_get_io_space_block(u32 size)
u32 pci_get_mmio_block(u32 size)
{
u32 block = ALIGN(io_space_blocks, size);
io_space_blocks = block + size;
u32 block = ALIGN(mmio_blocks, size);
mmio_blocks = block + size;
return block;
}
......
......@@ -34,7 +34,7 @@
#define KVM_MMIO_START PPC_MMIO_START
/*
* This is the address that pci_get_io_space_block() starts allocating
* This is the address that pci_get_io_port_block() starts allocating
* from. Note that this is a PCI bus address.
*/
#define KVM_IOPORT_AREA 0x0
......
......@@ -202,8 +202,10 @@ 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, IOPORT_EMPTY, &vfio_ioport_ops,
region->info.size, region);
int port = pci_get_io_port_block(region->info.size);
port = ioport__register(kvm, port, &vfio_ioport_ops,
region->info.size, region);
if (port < 0)
return port;
......
......@@ -750,7 +750,7 @@ static int vfio_pci_create_msix_table(struct kvm *kvm,
* powers of two.
*/
mmio_size = roundup_pow_of_two(table->size + pba->size);
table->guest_phys_addr = pci_get_io_space_block(mmio_size);
table->guest_phys_addr = pci_get_mmio_block(mmio_size);
if (!table->guest_phys_addr) {
pr_err("cannot allocate IO space");
ret = -ENOMEM;
......@@ -851,7 +851,7 @@ static int vfio_pci_configure_bar(struct kvm *kvm, struct vfio_device *vdev,
if (!region->is_ioport) {
/* Grab some MMIO space in the guest */
map_size = ALIGN(region->info.size, PAGE_SIZE);
region->guest_phys_addr = pci_get_io_space_block(map_size);
region->guest_phys_addr = pci_get_mmio_block(map_size);
}
/* Map the BARs into the guest or setup a trap region. */
......
......@@ -438,18 +438,19 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
BUILD_BUG_ON(!is_power_of_two(IOPORT_SIZE));
BUILD_BUG_ON(!is_power_of_two(PCI_IO_SIZE));
r = ioport__register(kvm, IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vdev);
r = pci_get_io_port_block(IOPORT_SIZE);
r = ioport__register(kvm, r, &virtio_pci__io_ops, IOPORT_SIZE, vdev);
if (r < 0)
return r;
vpci->port_addr = (u16)r;
vpci->mmio_addr = pci_get_io_space_block(IOPORT_SIZE);
vpci->mmio_addr = pci_get_mmio_block(IOPORT_SIZE);
r = kvm__register_mmio(kvm, vpci->mmio_addr, IOPORT_SIZE, false,
virtio_pci__io_mmio_callback, vpci);
if (r < 0)
goto free_ioport;
vpci->msix_io_block = pci_get_io_space_block(PCI_IO_SIZE * 2);
vpci->msix_io_block = pci_get_mmio_block(PCI_IO_SIZE * 2);
r = kvm__register_mmio(kvm, vpci->msix_io_block, PCI_IO_SIZE * 2, false,
virtio_pci__msix_mmio_callback, vpci);
if (r < 0)
......
......@@ -16,7 +16,7 @@
#define KVM_MMIO_START KVM_32BIT_GAP_START
/* This is the address that pci_get_io_space_block() starts allocating
/* This is the address that pci_get_io_port_block() starts allocating
* from. Note that this is a PCI bus address (though same on x86).
*/
#define KVM_IOPORT_AREA 0x0
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment