struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
bool coalesced_flush_in_progress;
int broken_set_mem_region;
- int migration_log;
int vcpu_events;
int robust_singlestep;
int debugregs;
mem.guest_phys_addr = slot->start_addr;
mem.userspace_addr = (unsigned long)slot->ram;
mem.flags = slot->flags;
- if (s->migration_log) {
- mem.flags |= KVM_MEM_LOG_DIRTY_PAGES;
- }
if (slot->memory_size && mem.flags & KVM_MEM_READONLY) {
/* Set the slot size to 0 before setting the slot to the desired
mem->flags = flags;
/* If nothing changed effectively, no need to issue ioctl */
- if (s->migration_log) {
- flags |= KVM_MEM_LOG_DIRTY_PAGES;
- }
-
if (flags == old_flags) {
return 0;
}
KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size);
if (mem == NULL) {
- fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-"
- TARGET_FMT_plx "\n", __func__, phys_addr,
- (hwaddr)(phys_addr + size - 1));
- return -EINVAL;
+ return 0;
+ } else {
+ return kvm_slot_dirty_pages_log_change(mem, log_dirty);
}
- return kvm_slot_dirty_pages_log_change(mem, log_dirty);
}
static void kvm_log_start(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
int r;
+ if (old != 0) {
+ return;
+ }
+
r = kvm_dirty_pages_log_change(section->offset_within_address_space,
int128_get64(section->size), true);
if (r < 0) {
}
static void kvm_log_stop(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
int r;
+ if (new != 0) {
+ return;
+ }
+
r = kvm_dirty_pages_log_change(section->offset_within_address_space,
int128_get64(section->size), false);
if (r < 0) {
}
}
-static int kvm_set_migration_log(bool enable)
-{
- KVMState *s = kvm_state;
- KVMSlot *mem;
- int i, err;
-
- s->migration_log = enable;
-
- for (i = 0; i < s->nr_slots; i++) {
- mem = &s->slots[i];
-
- if (!mem->memory_size) {
- continue;
- }
- if (!!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES) == enable) {
- continue;
- }
- err = kvm_set_user_memory_region(s, mem);
- if (err) {
- return err;
- }
- }
- return 0;
-}
-
/* get kvm's dirty pages bitmap and update qemu's */
static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
unsigned long *bitmap)
bool assign, uint32_t size, bool datamatch)
{
int ret;
- struct kvm_ioeventfd iofd;
-
- iofd.datamatch = datamatch ? adjust_ioeventfd_endianness(val, size) : 0;
- iofd.addr = addr;
- iofd.len = size;
- iofd.flags = 0;
- iofd.fd = fd;
+ struct kvm_ioeventfd iofd = {
+ .datamatch = datamatch ? adjust_ioeventfd_endianness(val, size) : 0,
+ .addr = addr,
+ .len = size,
+ .flags = 0,
+ .fd = fd,
+ };
if (!kvm_enabled()) {
return -ENOSYS;
KVMSlot *mem, old;
int err;
MemoryRegion *mr = section->mr;
- bool log_dirty = memory_region_is_logging(mr);
+ bool log_dirty = memory_region_get_dirty_log_mask(mr) != 0;
bool writeable = !mr->readonly && !mr->rom_device;
bool readonly_flag = mr->readonly || memory_region_is_romd(mr);
hwaddr start_addr = section->offset_within_address_space;
old = *mem;
- if ((mem->flags & KVM_MEM_LOG_DIRTY_PAGES) || s->migration_log) {
+ if (mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
kvm_physical_sync_dirty_bitmap(section);
}
}
}
-static void kvm_log_global_start(struct MemoryListener *listener)
-{
- int r;
-
- r = kvm_set_migration_log(1);
- assert(r >= 0);
-}
-
-static void kvm_log_global_stop(struct MemoryListener *listener)
-{
- int r;
-
- r = kvm_set_migration_log(0);
- assert(r >= 0);
-}
-
static void kvm_mem_ioeventfd_add(MemoryListener *listener,
MemoryRegionSection *section,
bool match_data, uint64_t data,
.log_start = kvm_log_start,
.log_stop = kvm_log_stop,
.log_sync = kvm_log_sync,
- .log_global_start = kvm_log_global_start,
- .log_global_stop = kvm_log_global_stop,
.eventfd_add = kvm_mem_ioeventfd_add,
.eventfd_del = kvm_mem_ioeventfd_del,
.coalesced_mmio_add = kvm_coalesce_mmio_region,
uint32_t *word = s->used_gsi_bitmap;
int max_words = ALIGN(s->gsi_count, 32) / 32;
int i, zeroes;
- bool retry = true;
-again:
+ /*
+ * PIC and IOAPIC share the first 16 GSI numbers, thus the available
+ * GSI numbers are more than the number of IRQ route. Allocating a GSI
+ * number can succeed even though a new route entry cannot be added.
+ * When this happens, flush dynamic MSI entries to free IRQ route entries.
+ */
+ if (!s->direct_msi && s->irq_routes->nr == s->gsi_count) {
+ kvm_flush_dynamic_msi_routes(s);
+ }
+
/* Return the lowest unused GSI in the bitmap */
for (i = 0; i < max_words; i++) {
zeroes = ctz32(~word[i]);
return zeroes + i * 32;
}
- if (!s->direct_msi && retry) {
- retry = false;
- kvm_flush_dynamic_msi_routes(s);
- goto again;
- }
return -ENOSPC;
}
int virq;
if (kvm_gsi_direct_mapping()) {
- return msg.data & 0xffff;
+ return kvm_arch_msi_data_to_gsi(msg.data);
}
if (!kvm_gsi_routing_enabled()) {
s->sigmask_len = sigmask_len;
}
-static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
- uint32_t count)
+static void kvm_handle_io(uint16_t port, MemTxAttrs attrs, void *data, int direction,
+ int size, uint32_t count)
{
int i;
uint8_t *ptr = data;
for (i = 0; i < count; i++) {
- address_space_rw(&address_space_io, port, MEMTXATTRS_UNSPECIFIED,
+ address_space_rw(&address_space_io, port, attrs,
ptr, size,
direction == KVM_EXIT_IO_OUT);
ptr += size;
}
do {
+ MemTxAttrs attrs;
+
if (cpu->kvm_vcpu_dirty) {
kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
cpu->kvm_vcpu_dirty = false;
run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);
qemu_mutex_lock_iothread();
- kvm_arch_post_run(cpu, run);
+ attrs = kvm_arch_post_run(cpu, run);
if (run_ret < 0) {
if (run_ret == -EINTR || run_ret == -EAGAIN) {
}
fprintf(stderr, "error: kvm run failed %s\n",
strerror(-run_ret));
+#ifdef TARGET_PPC
+ if (run_ret == -EBUSY) {
+ fprintf(stderr,
+ "This is probably because your SMT is enabled.\n"
+ "VCPU can only run on primary threads with all "
+ "secondary threads offline.\n");
+ }
+#endif
ret = -1;
break;
}
switch (run->exit_reason) {
case KVM_EXIT_IO:
DPRINTF("handle_io\n");
- kvm_handle_io(run->io.port,
+ kvm_handle_io(run->io.port, attrs,
(uint8_t *)run + run->io.data_offset,
run->io.direction,
run->io.size,
break;
case KVM_EXIT_MMIO:
DPRINTF("handle_mmio\n");
- cpu_physical_memory_rw(run->mmio.phys_addr,
- run->mmio.data,
- run->mmio.len,
- run->mmio.is_write);
+ address_space_rw(&address_space_memory,
+ run->mmio.phys_addr, attrs,
+ run->mmio.data,
+ run->mmio.len,
+ run->mmio.is_write);
ret = 0;
break;
case KVM_EXIT_IRQ_WINDOW_OPEN: