Commit 88209c10 authored by Ricardo Koller's avatar Ricardo Koller Committed by Marc Zyngier
Browse files

KVM: selftests: Add IRQ GSI routing library functions



Add an architecture independent wrapper function for creating and
writing IRQ GSI routing tables. Also add a function to add irqchip
entries.

Signed-off-by: default avatarRicardo Koller <ricarkol@google.com>
Acked-by: default avatarAndrew Jones <drjones@redhat.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20211109023906.1091208-15-ricarkol@google.com
parent 90f50aca
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -252,6 +252,14 @@ int _vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
			 uint64_t attr, void *val, bool write);

#define KVM_MAX_IRQ_ROUTES		4096

struct kvm_irq_routing *kvm_gsi_routing_create(void);
void kvm_gsi_routing_irqchip_add(struct kvm_irq_routing *routing,
		uint32_t gsi, uint32_t pin);
int _kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);
void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);

const char *exit_reason_str(unsigned int exit_reason);

void virt_pgd_alloc(struct kvm_vm *vm);
+51 −0
Original line number Diff line number Diff line
@@ -2107,6 +2107,57 @@ void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level)
	TEST_ASSERT(ret >= 0, "KVM_IRQ_LINE failed, rc: %i errno: %i", ret, errno);
}

struct kvm_irq_routing *kvm_gsi_routing_create(void)
{
	struct kvm_irq_routing *routing;
	size_t size;

	size = sizeof(struct kvm_irq_routing);
	/* Allocate space for the max number of entries: this wastes 196 KBs. */
	size += KVM_MAX_IRQ_ROUTES * sizeof(struct kvm_irq_routing_entry);
	routing = calloc(1, size);
	assert(routing);

	return routing;
}

void kvm_gsi_routing_irqchip_add(struct kvm_irq_routing *routing,
		uint32_t gsi, uint32_t pin)
{
	int i;

	assert(routing);
	assert(routing->nr < KVM_MAX_IRQ_ROUTES);

	i = routing->nr;
	routing->entries[i].gsi = gsi;
	routing->entries[i].type = KVM_IRQ_ROUTING_IRQCHIP;
	routing->entries[i].flags = 0;
	routing->entries[i].u.irqchip.irqchip = 0;
	routing->entries[i].u.irqchip.pin = pin;
	routing->nr++;
}

int _kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing)
{
	int ret;

	assert(routing);
	ret = ioctl(vm_get_fd(vm), KVM_SET_GSI_ROUTING, routing);
	free(routing);

	return ret;
}

void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing)
{
	int ret;

	ret = _kvm_gsi_routing_write(vm, routing);
	TEST_ASSERT(ret == 0, "KVM_SET_GSI_ROUTING failed, rc: %i errno: %i",
				ret, errno);
}

/*
 * VM Dump
 *