From patchwork Mon Feb 16 18:17:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 440329 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id CD02E1401F0 for ; Tue, 17 Feb 2015 05:25:27 +1100 (AEDT) Received: from localhost ([::1]:41363 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNQMH-0005W2-Tr for incoming@patchwork.ozlabs.org; Mon, 16 Feb 2015 13:25:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60129) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNQFj-0001VK-Bs for qemu-devel@nongnu.org; Mon, 16 Feb 2015 13:18:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YNQFi-0001RL-4J for qemu-devel@nongnu.org; Mon, 16 Feb 2015 13:18:39 -0500 Received: from mail-wi0-x229.google.com ([2a00:1450:400c:c05::229]:62977) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNQFh-0001R9-RS for qemu-devel@nongnu.org; Mon, 16 Feb 2015 13:18:38 -0500 Received: by mail-wi0-f169.google.com with SMTP id em10so26869813wid.0 for ; Mon, 16 Feb 2015 10:18:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=OBPAGVElt6mJPXPEzd9eSCYu07FvZh+fW8+J472EtVY=; b=prxsFeK1Z9XEPLhTVrVZqENkeq6PQtTxj/d2GSSWz2PqX6KNZKSb8OJ6hi/CMoMUDf QzyPDgXBpnXREvDJy7sTSANrFbrC7vWps6ZjomDre7T5xrGwLeNRe8iX69mwURf5cD12 AQMD0SoIuRZrPJ81OZ56LKLrOkZz3dUfh+G4f0LNzdXefLgom4VHyavOlDHaB2GupOU+ oDVH3A852D4w88gYbufg3cohjYi5gf/gJuyF5RCFFkGrEr6Lh0hoI5FesnizZaA/kvzf W1PaVnGudIDuMW+LR2UarpEKZMA1IhxXxTd4IAJys1J0DfukkyMnKU8q1BIxE5nQQSQf wq0g== X-Received: by 10.180.74.206 with SMTP id w14mr39830637wiv.71.1424110717299; Mon, 16 Feb 2015 10:18:37 -0800 (PST) Received: from playground.station (net-93-66-73-217.cust.vodafonedsl.it. [93.66.73.217]) by mx.google.com with ESMTPSA id p6sm20746248wia.14.2015.02.16.10.18.35 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Feb 2015 10:18:36 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 16 Feb 2015 19:17:55 +0100 Message-Id: <1424110682-14334-15-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 2.3.0 In-Reply-To: <1424110682-14334-1-git-send-email-pbonzini@redhat.com> References: <1424110682-14334-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::229 Subject: [Qemu-devel] [PULL 14/21] exec: make iotlb RCU-friendly X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org After the previous patch, TLBs will be flushed on every change to the memory mapping. This patch augments that with synchronization of the MemoryRegionSections referred to in the iotlb array. With this change, it is guaranteed that iotlb_to_region will access the correct memory map, even once the TLB will be accessed outside the BQL. Reviewed-by: Fam Zheng Signed-off-by: Paolo Bonzini --- cpu-exec.c | 6 +++++- cputlb.c | 5 ++--- exec.c | 13 ++++++++----- include/exec/cputlb.h | 2 +- include/exec/exec-all.h | 3 ++- include/qom/cpu.h | 1 + softmmu_template.h | 4 ++-- 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 78fe382..98f968d 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -24,6 +24,8 @@ #include "qemu/atomic.h" #include "sysemu/qtest.h" #include "qemu/timer.h" +#include "exec/address-spaces.h" +#include "exec/memory-internal.h" /* -icount align implementation. */ @@ -144,7 +146,9 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc) void cpu_reload_memory_map(CPUState *cpu) { - /* The TLB is protected by the iothread lock. */ + /* The CPU and TLB are protected by the iothread lock. */ + AddressSpaceDispatch *d = cpu->as->dispatch; + cpu->memory_dispatch = d; tlb_flush(cpu, 1); } #endif diff --git a/cputlb.c b/cputlb.c index 3b271d4..f92db5e 100644 --- a/cputlb.c +++ b/cputlb.c @@ -265,8 +265,7 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr, } sz = size; - section = address_space_translate_for_iotlb(cpu->as, paddr, - &xlat, &sz); + section = address_space_translate_for_iotlb(cpu, paddr, &xlat, &sz); assert(sz >= TARGET_PAGE_SIZE); #if defined(DEBUG_TLB) @@ -347,7 +346,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr) cpu_ldub_code(env1, addr); } pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK; - mr = iotlb_to_region(cpu->as, pd); + mr = iotlb_to_region(cpu, pd); if (memory_region_is_unassigned(mr)) { CPUClass *cc = CPU_GET_CLASS(cpu); diff --git a/exec.c b/exec.c index 2bfb4d3..fe1e60a 100644 --- a/exec.c +++ b/exec.c @@ -401,11 +401,12 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, } MemoryRegionSection * -address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat, - hwaddr *plen) +address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, + hwaddr *xlat, hwaddr *plen) { MemoryRegionSection *section; - section = address_space_translate_internal(as->dispatch, addr, xlat, plen, false); + section = address_space_translate_internal(cpu->memory_dispatch, + addr, xlat, plen, false); assert(!section->mr->iommu_ops); return section; @@ -1961,9 +1962,11 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as, return phys_section_add(map, §ion); } -MemoryRegion *iotlb_to_region(AddressSpace *as, hwaddr index) +MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index) { - return as->dispatch->map.sections[index & ~TARGET_PAGE_MASK].mr; + MemoryRegionSection *sections = cpu->memory_dispatch->map.sections; + + return sections[index & ~TARGET_PAGE_MASK].mr; } static void io_mem_init(void) diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index b8ecd6f..e0da9d7 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -34,7 +34,7 @@ extern int tlb_flush_count; void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr); MemoryRegionSection * -address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat, +address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat, hwaddr *plen); hwaddr memory_region_section_get_iotlb(CPUState *cpu, MemoryRegionSection *section, diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 1b30813..bb3fd37 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -338,7 +338,8 @@ extern uintptr_t tci_tb_ptr; void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align)); -struct MemoryRegion *iotlb_to_region(AddressSpace *as, hwaddr index); +struct MemoryRegion *iotlb_to_region(CPUState *cpu, + hwaddr index); bool io_mem_read(struct MemoryRegion *mr, hwaddr addr, uint64_t *pvalue, unsigned size); bool io_mem_write(struct MemoryRegion *mr, hwaddr addr, diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 2098f1c..48fd6fb 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -256,6 +256,7 @@ struct CPUState { sigjmp_buf jmp_env; AddressSpace *as; + struct AddressSpaceDispatch *memory_dispatch; MemoryListener *tcg_as_listener; void *env_ptr; /* CPUArchState */ diff --git a/softmmu_template.h b/softmmu_template.h index 6b4e615..0e3dd35 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -149,7 +149,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, { uint64_t val; CPUState *cpu = ENV_GET_CPU(env); - MemoryRegion *mr = iotlb_to_region(cpu->as, physaddr); + MemoryRegion *mr = iotlb_to_region(cpu, physaddr); physaddr = (physaddr & TARGET_PAGE_MASK) + addr; cpu->mem_io_pc = retaddr; @@ -369,7 +369,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env, uintptr_t retaddr) { CPUState *cpu = ENV_GET_CPU(env); - MemoryRegion *mr = iotlb_to_region(cpu->as, physaddr); + MemoryRegion *mr = iotlb_to_region(cpu, physaddr); physaddr = (physaddr & TARGET_PAGE_MASK) + addr; if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu_can_do_io(cpu)) {