From patchwork Fri Jul 3 15:11:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 50637 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 8270E22916 for ; Fri, 3 Jul 2015 15:11:48 +0000 (UTC) Received: by widjy10 with SMTP id jy10sf33553603wid.3 for ; Fri, 03 Jul 2015 08:11:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=ii4V/0p3rW4uAsNAJfASF07EdRunt1LCtb/AV7/6g4c=; b=QqQXM23Ng8qq/mPUbCmVoKgP8cdS+yyYnGOQ7erQLIrHfDiwKiUXAzLBH70LEL0MXf vDZBjP18idZwQdLu2w3+M4F0sGon0apllg6SNyuJmOa7PiTcFGhCr4D9QjAj9K655k/3 5TJbwYvHW05BJDuhQ0BPfeATEXR6fn1mUJGI7r5Seh6xFW3Xo14gZN0AckFxy28YqkeJ t+3i/CQwEd/LGjYx+4rjPfn0wKvpLDZgsBtiq2iZn8/L/daXk5fwtsRDy25fyez0QPS9 Yo5xxHwMBvMGmmzEXZh2vx073CzAlg50sN7JETC4Jc6E02uJ+dtRvUZ+ct044DlPn3YQ m5Dw== X-Gm-Message-State: ALoCoQlrTG3GaP4w/E20oVk4Of7tSNpXA9nKyeGB7i4gkBdYsYEhgMsd2ISOE7FqCHzlTgf2c+N8 X-Received: by 10.152.88.70 with SMTP id be6mr22877905lab.9.1435936307788; Fri, 03 Jul 2015 08:11:47 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.20.67 with SMTP id l3ls497854lae.73.gmail; Fri, 03 Jul 2015 08:11:47 -0700 (PDT) X-Received: by 10.112.167.202 with SMTP id zq10mr35524309lbb.118.1435936307519; Fri, 03 Jul 2015 08:11:47 -0700 (PDT) Received: from mail-la0-f47.google.com (mail-la0-f47.google.com. [209.85.215.47]) by mx.google.com with ESMTPS id w5si7440301lal.105.2015.07.03.08.11.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Jul 2015 08:11:47 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.47 as permitted sender) client-ip=209.85.215.47; Received: by lagh6 with SMTP id h6so88670680lag.2 for ; Fri, 03 Jul 2015 08:11:47 -0700 (PDT) X-Received: by 10.112.166.2 with SMTP id zc2mr16569599lbb.29.1435936307371; Fri, 03 Jul 2015 08:11:47 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp94176lbb; Fri, 3 Jul 2015 08:11:46 -0700 (PDT) X-Received: by 10.180.75.4 with SMTP id y4mr27652142wiv.1.1435936306527; Fri, 03 Jul 2015 08:11:46 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id q10si15663056wiw.121.2015.07.03.08.11.46 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 03 Jul 2015 08:11:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::1 as permitted sender) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1ZB2cx-0003zz-E4; Fri, 03 Jul 2015 16:11:43 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Paolo Bonzini , "Edgar E. Iglesias" Subject: [PATCH 3/3] exec.c: Collect AddressSpace related fields into a CPUAddressSpace struct Date: Fri, 3 Jul 2015 16:11:43 +0100 Message-Id: <1435936303-15335-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1435936303-15335-1-git-send-email-peter.maydell@linaro.org> References: <1435936303-15335-1-git-send-email-peter.maydell@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.47 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Gather up all the fields currently in CPUState which deal with the CPU's AddressSpace into a separate CPUAddressSpace struct. This paves the way for allowing the CPU to know about more than one AddressSpace. The rearrangement also allows us to make the MemoryListener a directly embedded object in the CPUAddressSpace (it could not be embedded in CPUState because 'struct MemoryListener' isn't defined for the user-only builds). This allows us to resolve the FIXME in tcg_commit() by going directly from the MemoryListener to the CPUAddressSpace. This patch extracts the actual update of the cached dispatch pointer from cpu_reload_memory_map() (which is renamed accordingly to cpu_reloading_memory_map() as it is only responsible for breaking cpu-exec.c's RCU critical section now). This lets us keep the definition of the CPUAddressSpace struct private to exec.c. Signed-off-by: Peter Maydell --- cpu-exec.c | 13 +++--------- exec.c | 56 +++++++++++++++++++++++++++++++++---------------- include/exec/exec-all.h | 2 +- include/qemu/typedefs.h | 1 + include/qom/cpu.h | 7 +++++-- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index d84c2cd..cdfb0de 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -145,10 +145,8 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc) siglongjmp(cpu->jmp_env, 1); } -void cpu_reload_memory_map(CPUState *cpu) +void cpu_reloading_memory_map(void) { - AddressSpaceDispatch *d; - if (qemu_in_vcpu_thread()) { /* The guest can in theory prolong the RCU critical section as long * as it feels like. The major problem with this is that because it @@ -167,17 +165,12 @@ void cpu_reload_memory_map(CPUState *cpu) * part of this callback might become unnecessary.) * * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which - * only protects cpu->as->dispatch. Since we reload it below, we can - * split the critical section. + * only protects cpuas->dispatch. Since we know our caller is about + * to reload it, it's safe to split the critical section. */ rcu_read_unlock(); rcu_read_lock(); } - - /* The CPU and TLB are protected by the iothread lock. */ - d = atomic_rcu_read(&cpu->as->dispatch); - cpu->memory_dispatch = d; - tlb_flush(cpu, 1); } #endif diff --git a/exec.c b/exec.c index 2616394..ecefd18 100644 --- a/exec.c +++ b/exec.c @@ -158,6 +158,21 @@ static void memory_map_init(void); static void tcg_commit(MemoryListener *listener); static MemoryRegion io_mem_watch; + +/** + * CPUAddressSpace: all the information a CPU needs about an AddressSpace + * @cpu: the CPU whose AddressSpace this is + * @as: the AddressSpace itself + * @memory_dispatch: its dispatch pointer (cached, RCU protected) + * @tcg_as_listener: listener for tracking changes to the AddressSpace + */ +struct CPUAddressSpace { + CPUState *cpu; + AddressSpace *as; + struct AddressSpaceDispatch *memory_dispatch; + MemoryListener tcg_as_listener; +}; + #endif #if !defined(CONFIG_USER_ONLY) @@ -416,7 +431,7 @@ address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat, hwaddr *plen) { MemoryRegionSection *section; - section = address_space_translate_internal(cpu->memory_dispatch, + section = address_space_translate_internal(cpu->cpu_ases[0].memory_dispatch, addr, xlat, plen, false); assert(!section->mr->iommu_ops); @@ -503,13 +518,16 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) /* We only support one address space per cpu at the moment. */ assert(cpu->as == as); - if (cpu->tcg_as_listener) { - memory_listener_unregister(cpu->tcg_as_listener); - } else { - cpu->tcg_as_listener = g_new0(MemoryListener, 1); + if (cpu->cpu_ases) { + /* We've already registered the listener for our only AS */ + return; } - cpu->tcg_as_listener->commit = tcg_commit; - memory_listener_register(cpu->tcg_as_listener, as); + + cpu->cpu_ases = g_new0(CPUAddressSpace, 1); + cpu->cpu_ases[0].cpu = cpu; + cpu->cpu_ases[0].as = as; + cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit; + memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as); } #endif @@ -2097,7 +2115,8 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as, MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index) { - AddressSpaceDispatch *d = atomic_rcu_read(&cpu->memory_dispatch); + CPUAddressSpace *cpuas = &cpu->cpu_ases[0]; + AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch); MemoryRegionSection *sections = d->map.sections; return sections[index & ~TARGET_PAGE_MASK].mr; @@ -2156,19 +2175,20 @@ static void mem_commit(MemoryListener *listener) static void tcg_commit(MemoryListener *listener) { - CPUState *cpu; + CPUAddressSpace *cpuas; + AddressSpaceDispatch *d; /* since each CPU stores ram addresses in its TLB cache, we must reset the modified entries */ - /* XXX: slow ! */ - CPU_FOREACH(cpu) { - /* FIXME: Disentangle the cpu.h circular files deps so we can - directly get the right CPU from listener. */ - if (cpu->tcg_as_listener != listener) { - continue; - } - cpu_reload_memory_map(cpu); - } + cpuas = container_of(listener, CPUAddressSpace, tcg_as_listener); + cpu_reloading_memory_map(); + /* The CPU and TLB are protected by the iothread lock. + * We reload the dispatch pointer now because cpu_reloading_memory_map() + * may have split the RCU critical section. + */ + d = atomic_rcu_read(&cpuas->as->dispatch); + cpuas->memory_dispatch = d; + tlb_flush(cpuas->cpu, 1); } void address_space_init_dispatch(AddressSpace *as) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 2573e8c..53445a1 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -93,7 +93,7 @@ void QEMU_NORETURN cpu_loop_exit(CPUState *cpu); #if !defined(CONFIG_USER_ONLY) bool qemu_in_vcpu_thread(void); -void cpu_reload_memory_map(CPUState *cpu); +void cpu_reloading_memory_map(void); void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as); /* cputlb.c */ void tlb_flush_page(CPUState *cpu, target_ulong addr); diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 6fdcbcd..df39eba 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -16,6 +16,7 @@ typedef struct BusClass BusClass; typedef struct BusState BusState; typedef struct CharDriverState CharDriverState; typedef struct CompatProperty CompatProperty; +typedef struct CPUAddressSpace CPUAddressSpace; typedef struct DeviceState DeviceState; typedef struct DeviceListener DeviceListener; typedef struct DisplayChangeListener DisplayChangeListener; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 39f0f19..ca18e49 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -228,6 +228,10 @@ struct kvm_run; * This allows a single read-compare-cbranch-write sequence to test * for both decrementer underflow and exceptions. * @can_do_io: Nonzero if memory-mapped IO is safe. + * @cpu_ases: Pointer to array of CPUAddressSpaces (which define the + * AddressSpaces this CPU has) + * @as: Pointer to the first AddressSpace, for the convenience of targets which + * only have a single AddressSpace * @env_ptr: Pointer to subclass-specific CPUArchState field. * @current_tb: Currently executing TB. * @gdb_regs: Additional GDB registers. @@ -269,9 +273,8 @@ struct CPUState { int64_t icount_extra; sigjmp_buf jmp_env; + CPUAddressSpace *cpu_ases; AddressSpace *as; - struct AddressSpaceDispatch *memory_dispatch; - MemoryListener *tcg_as_listener; void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb;