diff options
-rw-r--r-- | hw/net/e1000.c | 1 | ||||
-rw-r--r-- | hw/net/vhost_net.c | 10 | ||||
-rw-r--r-- | hw/virtio/virtio.c | 5 | ||||
-rw-r--r-- | include/hw/virtio/virtio.h | 1 | ||||
-rw-r--r-- | net/colo-compare.c | 3 | ||||
-rw-r--r-- | net/slirp.c | 3 | ||||
-rw-r--r-- | target/m68k/cpu.c | 2 | ||||
-rw-r--r-- | target/m68k/cpu.h | 7 | ||||
-rw-r--r-- | target/m68k/helper.c | 84 | ||||
-rw-r--r-- | target/m68k/op_helper.c | 20 | ||||
-rw-r--r-- | target/m68k/translate.c | 9 |
11 files changed, 103 insertions, 42 deletions
diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 9b39bccfb2..121452d508 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -901,7 +901,6 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) if (size < sizeof(min_buf)) { iov_to_buf(iov, iovcnt, 0, min_buf, size); memset(&min_buf[size], 0, sizeof(min_buf) - size); - e1000x_inc_reg_if_not_full(s->mac_reg, RUC); min_iov.iov_base = filter_buf = min_buf; min_iov.iov_len = size = sizeof(min_buf); iovcnt = 1; diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index be3cc88370..a6b719035c 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -244,6 +244,11 @@ static int vhost_net_start_one(struct vhost_net *net, qemu_set_fd_handler(net->backend, NULL, NULL, NULL); file.fd = net->backend; for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { + if (!virtio_queue_enabled(dev, net->dev.vq_index + + file.index)) { + /* Queue might not be ready for start */ + continue; + } r = vhost_net_set_backend(&net->dev, &file); if (r < 0) { r = -errno; @@ -256,6 +261,11 @@ fail: file.fd = -1; if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) { while (file.index-- > 0) { + if (!virtio_queue_enabled(dev, net->dev.vq_index + + file.index)) { + /* Queue might not be ready for start */ + continue; + } int r = vhost_net_set_backend(&net->dev, &file); assert(r >= 0); } diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 2626a895cb..28056a7ef7 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2318,6 +2318,11 @@ hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n) return vdev->vq[n].vring.desc; } +bool virtio_queue_enabled(VirtIODevice *vdev, int n) +{ + return virtio_queue_get_desc_addr(vdev, n) != 0; +} + hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n) { return vdev->vq[n].vring.avail; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index ce9516236a..7140381e3a 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -282,6 +282,7 @@ typedef struct VirtIORNGConf VirtIORNGConf; VIRTIO_F_IOMMU_PLATFORM, false) hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); +bool virtio_queue_enabled(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n); diff --git a/net/colo-compare.c b/net/colo-compare.c index bf10526f05..fcb491121b 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -813,9 +813,8 @@ static void colo_compare_handle_event(void *opaque) break; } - assert(event_unhandled_count > 0); - qemu_mutex_lock(&event_mtx); + assert(event_unhandled_count > 0); event_unhandled_count--; qemu_cond_broadcast(&event_complete_cond); qemu_mutex_unlock(&event_mtx); diff --git a/net/slirp.c b/net/slirp.c index 95934fb36d..b34cb29276 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -498,7 +498,8 @@ static int net_slirp_init(NetClientState *peer, const char *model, } if (vprefix6_len < 0 || vprefix6_len > 126) { error_setg(errp, - "Invalid prefix provided (prefix len must be in range 0-126"); + "Invalid IPv6 prefix provided " + "(IPv6 prefix length must be between 0 and 126)"); return -1; } diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index 6f441bc973..b16957934a 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -271,7 +271,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->gdb_write_register = m68k_cpu_gdb_write_register; cc->tlb_fill = m68k_cpu_tlb_fill; #if defined(CONFIG_SOFTMMU) - cc->do_unassigned_access = m68k_cpu_unassigned_access; + cc->do_transaction_failed = m68k_cpu_transaction_failed; cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; #endif cc->disas_set_info = m68k_cpu_disas_set_info; diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 683d3e2f79..9deff9e234 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -545,9 +545,10 @@ static inline int cpu_mmu_index (CPUM68KState *env, bool ifetch) bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); -void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, - bool is_write, bool is_exec, int is_asi, - unsigned size); +void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, + unsigned size, MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr); #include "exec/cpu-all.h" diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 9fc9e646ff..6db93bdd81 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -390,6 +390,7 @@ static void dump_address_map(CPUM68KState *env, uint32_t root_pointer) int last_attr = -1, attr = -1; M68kCPU *cpu = m68k_env_get_cpu(env); CPUState *cs = CPU(cpu); + MemTxResult txres; if (env->mmu.tcr & M68K_TCR_PAGE_8K) { /* 8k page */ @@ -403,22 +404,29 @@ static void dump_address_map(CPUM68KState *env, uint32_t root_pointer) tib_mask = M68K_4K_PAGE_MASK; } for (i = 0; i < M68K_ROOT_POINTER_ENTRIES; i++) { - tia = ldl_phys(cs->as, M68K_POINTER_BASE(root_pointer) + i * 4); - if (!M68K_UDT_VALID(tia)) { + tia = address_space_ldl(cs->as, M68K_POINTER_BASE(root_pointer) + i * 4, + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK || !M68K_UDT_VALID(tia)) { continue; } for (j = 0; j < M68K_ROOT_POINTER_ENTRIES; j++) { - tib = ldl_phys(cs->as, M68K_POINTER_BASE(tia) + j * 4); - if (!M68K_UDT_VALID(tib)) { + tib = address_space_ldl(cs->as, M68K_POINTER_BASE(tia) + j * 4, + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK || !M68K_UDT_VALID(tib)) { continue; } for (k = 0; k < tic_size; k++) { - tic = ldl_phys(cs->as, (tib & tib_mask) + k * 4); - if (!M68K_PDT_VALID(tic)) { + tic = address_space_ldl(cs->as, (tib & tib_mask) + k * 4, + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK || !M68K_PDT_VALID(tic)) { continue; } if (M68K_PDT_INDIRECT(tic)) { - tic = ldl_phys(cs->as, M68K_INDIRECT_POINTER(tic)); + tic = address_space_ldl(cs->as, M68K_INDIRECT_POINTER(tic), + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + continue; + } } last_logical = logical; @@ -630,6 +638,7 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, bool debug = access_type & ACCESS_DEBUG; int page_bits; int i; + MemTxResult txres; /* Transparent Translation (physical = logical) */ for (i = 0; i < M68K_MAX_TTR; i++) { @@ -659,12 +668,19 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, /* Root Index */ entry = M68K_POINTER_BASE(next) | M68K_ROOT_INDEX(address); - next = ldl_phys(cs->as, entry); + next = address_space_ldl(cs->as, entry, MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } if (!M68K_UDT_VALID(next)) { return -1; } if (!(next & M68K_DESC_USED) && !debug) { - stl_phys(cs->as, entry, next | M68K_DESC_USED); + address_space_stl(cs->as, entry, next | M68K_DESC_USED, + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } } if (next & M68K_DESC_WRITEPROT) { if (access_type & ACCESS_PTEST) { @@ -679,12 +695,19 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, /* Pointer Index */ entry = M68K_POINTER_BASE(next) | M68K_POINTER_INDEX(address); - next = ldl_phys(cs->as, entry); + next = address_space_ldl(cs->as, entry, MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } if (!M68K_UDT_VALID(next)) { return -1; } if (!(next & M68K_DESC_USED) && !debug) { - stl_phys(cs->as, entry, next | M68K_DESC_USED); + address_space_stl(cs->as, entry, next | M68K_DESC_USED, + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } } if (next & M68K_DESC_WRITEPROT) { if (access_type & ACCESS_PTEST) { @@ -703,27 +726,46 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, entry = M68K_4K_PAGE_BASE(next) | M68K_4K_PAGE_INDEX(address); } - next = ldl_phys(cs->as, entry); + next = address_space_ldl(cs->as, entry, MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } if (!M68K_PDT_VALID(next)) { return -1; } if (M68K_PDT_INDIRECT(next)) { - next = ldl_phys(cs->as, M68K_INDIRECT_POINTER(next)); + next = address_space_ldl(cs->as, M68K_INDIRECT_POINTER(next), + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } } if (access_type & ACCESS_STORE) { if (next & M68K_DESC_WRITEPROT) { if (!(next & M68K_DESC_USED) && !debug) { - stl_phys(cs->as, entry, next | M68K_DESC_USED); + address_space_stl(cs->as, entry, next | M68K_DESC_USED, + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } } } else if ((next & (M68K_DESC_MODIFIED | M68K_DESC_USED)) != (M68K_DESC_MODIFIED | M68K_DESC_USED) && !debug) { - stl_phys(cs->as, entry, - next | (M68K_DESC_MODIFIED | M68K_DESC_USED)); + address_space_stl(cs->as, entry, + next | (M68K_DESC_MODIFIED | M68K_DESC_USED), + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } } } else { if (!(next & M68K_DESC_USED) && !debug) { - stl_phys(cs->as, entry, next | M68K_DESC_USED); + address_space_stl(cs->as, entry, next | M68K_DESC_USED, + MEMTXATTRS_UNSPECIFIED, &txres); + if (txres != MEMTX_OK) { + goto txfail; + } } } @@ -755,6 +797,14 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, } return 0; + +txfail: + /* + * A page table load/store failed. TODO: we should really raise a + * suitable guest fault here if this is not a debug access. + * For now just return that the translation failed. + */ + return -1; } hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index d421614727..1ecc772b5c 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -439,19 +439,15 @@ static inline void do_interrupt_m68k_hardirq(CPUM68KState *env) do_interrupt_all(env, 1); } -void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write, - bool is_exec, int is_asi, unsigned size) +void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, + unsigned size, MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr) { M68kCPU *cpu = M68K_CPU(cs); CPUM68KState *env = &cpu->env; -#ifdef DEBUG_UNASSIGNED - qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n", - addr, is_write, is_exec); -#endif - if (env == NULL) { - /* when called from gdb, env is NULL */ - return; - } + + cpu_restore_state(cs, retaddr, true); if (m68k_feature(env, M68K_FEATURE_M68040)) { env->mmu.mmusr = 0; @@ -461,7 +457,7 @@ void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write, if (env->sr & SR_S) { /* SUPERVISOR */ env->mmu.ssw |= M68K_TM_040_SUPER; } - if (is_exec) { /* instruction or data */ + if (access_type == MMU_INST_FETCH) { /* instruction or data */ env->mmu.ssw |= M68K_TM_040_CODE; } else { env->mmu.ssw |= M68K_TM_040_DATA; @@ -479,7 +475,7 @@ void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write, break; } - if (!is_write) { + if (access_type != MMU_DATA_STORE) { env->mmu.ssw |= M68K_RW_040; } diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 58596278c2..f0534a4ba0 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -2227,6 +2227,7 @@ static TCGv gen_get_sr(DisasContext *s) sr = tcg_temp_new(); tcg_gen_andi_i32(sr, QREG_SR, 0xffe0); tcg_gen_or_i32(sr, sr, ccr); + tcg_temp_free(ccr); return sr; } @@ -3020,7 +3021,6 @@ DISAS_INSN(branch) int32_t offset; uint32_t base; int op; - TCGLabel *l1; base = s->pc; op = (insn >> 8) & 0xf; @@ -3036,7 +3036,7 @@ DISAS_INSN(branch) } if (op > 1) { /* Bcc */ - l1 = gen_new_label(); + TCGLabel *l1 = gen_new_label(); gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1); gen_jmp_tb(s, 1, base + offset); gen_set_label(l1); @@ -3693,6 +3693,7 @@ static TCGv rotate_x(TCGv reg, TCGv shift, int left, int size) tcg_gen_sub_i32(shl, shl, shift); /* shl = size + 1 - shift */ tcg_gen_sub_i32(shx, sz, shift); /* shx = size - shift */ } + tcg_temp_free_i32(sz); /* reg = (reg << shl) | (reg >> shr) | (x << shx); */ @@ -3708,9 +3709,7 @@ static TCGv rotate_x(TCGv reg, TCGv shift, int left, int size) /* X = (reg >> size) & 1 */ X = tcg_temp_new(); - tcg_gen_shr_i32(X, reg, sz); - tcg_gen_andi_i32(X, X, 1); - tcg_temp_free(sz); + tcg_gen_extract_i32(X, reg, size, 1); return X; } |