*
*/
-#include <sys/types.h>
+#include "qemu/osdep.h"
#include <sys/ioctl.h>
#include <sys/mman.h>
-#include <stdarg.h>
#include <linux/kvm.h>
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing *irq_routes;
int nr_allocated_irq_routes;
- uint32_t *used_gsi_bitmap;
+ unsigned long *used_gsi_bitmap;
unsigned int gsi_count;
QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
#endif
KVMState *kvm_state;
bool kvm_kernel_irqchip;
+bool kvm_split_irqchip;
bool kvm_async_interrupts_allowed;
bool kvm_halt_in_kernel_allowed;
bool kvm_eventfds_allowed;
static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
unsigned long *bitmap)
{
- ram_addr_t start = section->offset_within_region + section->mr->ram_addr;
+ ram_addr_t start = section->offset_within_region +
+ memory_region_get_ram_addr(section->mr);
ram_addr_t pages = int128_get64(section->size) / getpagesize();
cpu_physical_memory_set_dirty_lebitmap(bitmap, start, pages);
static void set_gsi(KVMState *s, unsigned int gsi)
{
- s->used_gsi_bitmap[gsi / 32] |= 1U << (gsi % 32);
+ set_bit(gsi, s->used_gsi_bitmap);
}
static void clear_gsi(KVMState *s, unsigned int gsi)
{
- s->used_gsi_bitmap[gsi / 32] &= ~(1U << (gsi % 32));
+ clear_bit(gsi, s->used_gsi_bitmap);
}
void kvm_init_irq_routing(KVMState *s)
gsi_count = kvm_check_extension(s, KVM_CAP_IRQ_ROUTING) - 1;
if (gsi_count > 0) {
- unsigned int gsi_bits, i;
-
/* Round up so we can search ints using ffs */
- gsi_bits = ALIGN(gsi_count, 32);
- s->used_gsi_bitmap = g_malloc0(gsi_bits / 8);
+ s->used_gsi_bitmap = bitmap_new(gsi_count);
s->gsi_count = gsi_count;
-
- /* Mark any over-allocated bits as already in use */
- for (i = gsi_count; i < gsi_bits; i++) {
- set_gsi(s, i);
- }
}
s->irq_routes = g_malloc0(sizeof(*s->irq_routes));
static int kvm_irqchip_get_virq(KVMState *s)
{
- uint32_t *word = s->used_gsi_bitmap;
- int max_words = ALIGN(s->gsi_count, 32) / 32;
- int i, zeroes;
+ int next_virq;
/*
* PIC and IOAPIC share the first 16 GSI numbers, thus the available
}
/* Return the lowest unused GSI in the bitmap */
- for (i = 0; i < max_words; i++) {
- zeroes = ctz32(~word[i]);
- if (zeroes == 32) {
- continue;
- }
-
- return zeroes + i * 32;
+ next_virq = find_first_zero_bit(s->used_gsi_bitmap, s->gsi_count);
+ if (next_virq >= s->gsi_count) {
+ return -ENOSPC;
+ } else {
+ return next_virq;
}
- return -ENOSPC;
-
}
static KVMMSIRoute *kvm_lookup_msi_route(KVMState *s, MSIMessage msg)
/* First probe and see if there's a arch-specific hook to create the
* in-kernel irqchip for us */
- ret = kvm_arch_irqchip_create(s);
+ ret = kvm_arch_irqchip_create(machine, s);
if (ret == 0) {
- ret = kvm_vm_ioctl(s, KVM_CREATE_IRQCHIP);
+ if (machine_kernel_irqchip_split(machine)) {
+ perror("Split IRQ chip mode not supported.");
+ exit(1);
+ } else {
+ ret = kvm_vm_ioctl(s, KVM_CREATE_IRQCHIP);
+ }
}
if (ret < 0) {
fprintf(stderr, "Create kernel irqchip failed: %s\n", strerror(-ret));
write ? KVM_SET_DEVICE_ATTR : KVM_GET_DEVICE_ATTR,
&kvmattr);
if (err < 0) {
- error_report("KVM_%s_DEVICE_ATTR failed: %s\n"
- "Group %d attr 0x%016" PRIx64, write ? "SET" : "GET",
- strerror(-err), group, attr);
+ error_report("KVM_%s_DEVICE_ATTR failed: %s",
+ write ? "SET" : "GET", strerror(-err));
+ error_printf("Group %d attr 0x%016" PRIx64, group, attr);
abort();
}
}
reg.addr = (uintptr_t) source;
r = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
if (r) {
- trace_kvm_failed_reg_set(id, strerror(r));
+ trace_kvm_failed_reg_set(id, strerror(-r));
}
return r;
}
reg.addr = (uintptr_t) target;
r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
if (r) {
- trace_kvm_failed_reg_get(id, strerror(r));
+ trace_kvm_failed_reg_get(id, strerror(-r));
}
return r;
}