From patchwork Tue Apr 7 20:09:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 458790 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 77F771401E7 for ; Wed, 8 Apr 2015 06:15:39 +1000 (AEST) Received: from localhost ([::1]:48710 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YfZuL-0000nT-1a for incoming@patchwork.ozlabs.org; Tue, 07 Apr 2015 16:15:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37636) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YfZpV-0001Hd-NS for qemu-devel@nongnu.org; Tue, 07 Apr 2015 16:10:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YfZpU-0008Os-Jp for qemu-devel@nongnu.org; Tue, 07 Apr 2015 16:10:37 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:33323) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YfZpU-00084l-9A for qemu-devel@nongnu.org; Tue, 07 Apr 2015 16:10:36 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1YfZov-0002Dj-3n; Tue, 07 Apr 2015 21:10:01 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 7 Apr 2015 21:09:55 +0100 Message-Id: <1428437400-8474-10-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1428437400-8474-1-git-send-email-peter.maydell@linaro.org> References: <1428437400-8474-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Cc: Peter Crosthwaite , patches@linaro.org, "Edgar E. Iglesias" , Greg Bellows , Paolo Bonzini , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson Subject: [Qemu-devel] [PATCH 09/14] exec.c: Capture the memory attributes for a watchpoint hit 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 Capture the memory attributes for the transaction which triggered a watchpoint; this allows CPU specific code to implement features like ARM's "user-mode only WPs also hit for LDRT/STRT accesses made from privileged code". Signed-off-by: Peter Maydell --- exec.c | 52 +++++++++++++++++++++++++++++++--------------------- include/qom/cpu.h | 2 ++ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/exec.c b/exec.c index a0d18ee..b6a11c0 100644 --- a/exec.c +++ b/exec.c @@ -1858,7 +1858,7 @@ static const MemoryRegionOps notdirty_mem_ops = { }; /* Generate a debug exception if a watchpoint has been hit. */ -static void check_watchpoint(int offset, int len, int flags) +static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags) { CPUState *cpu = current_cpu; CPUArchState *env = cpu->env_ptr; @@ -1884,6 +1884,7 @@ static void check_watchpoint(int offset, int len, int flags) wp->flags |= BP_WATCHPOINT_HIT_WRITE; } wp->hitaddr = vaddr; + wp->hitattrs = attrs; if (!cpu->watchpoint_hit) { cpu->watchpoint_hit = wp; tb_check_watchpoint(cpu); @@ -1905,45 +1906,54 @@ static void check_watchpoint(int offset, int len, int flags) /* Watchpoint access routines. Watchpoints are inserted using TLB tricks, so these check for a hit then pass through to the normal out-of-line phys routines. */ -static uint64_t watch_mem_read(void *opaque, hwaddr addr, - unsigned size) +static MemTxResult watch_mem_read(void *opaque, hwaddr addr, uint64_t *pdata, + unsigned size, MemTxAttrs attrs) { - check_watchpoint(addr & ~TARGET_PAGE_MASK, size, BP_MEM_READ); + MemTxResult res; + uint64_t data; + + check_watchpoint(addr & ~TARGET_PAGE_MASK, size, attrs, BP_MEM_READ); switch (size) { - case 1: return address_space_ldub(&address_space_memory, addr, - MEMTXATTRS_UNSPECIFIED, NULL); - case 2: return address_space_lduw(&address_space_memory, addr, - MEMTXATTRS_UNSPECIFIED, NULL); - case 4: return address_space_ldl(&address_space_memory, addr, - MEMTXATTRS_UNSPECIFIED, NULL); + case 1: + data = address_space_ldub(&address_space_memory, addr, attrs, &res); + break; + case 2: + data = address_space_lduw(&address_space_memory, addr, attrs, &res); + break; + case 4: + data = address_space_ldl(&address_space_memory, addr, attrs, &res); + break; default: abort(); } + *pdata = data; + return res; } -static void watch_mem_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) +static MemTxResult watch_mem_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size, + MemTxAttrs attrs) { - check_watchpoint(addr & ~TARGET_PAGE_MASK, size, BP_MEM_WRITE); + MemTxResult res; + + check_watchpoint(addr & ~TARGET_PAGE_MASK, size, attrs, BP_MEM_WRITE); switch (size) { case 1: - address_space_stb(&address_space_memory, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); + address_space_stb(&address_space_memory, addr, val, attrs, &res); break; case 2: - address_space_stw(&address_space_memory, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); + address_space_stw(&address_space_memory, addr, val, attrs, &res); break; case 4: - address_space_stl(&address_space_memory, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); + address_space_stl(&address_space_memory, addr, val, attrs, &res); break; default: abort(); } + return res; } static const MemoryRegionOps watch_mem_ops = { - .read = watch_mem_read, - .write = watch_mem_write, + .read_with_attrs = watch_mem_read, + .write_with_attrs = watch_mem_write, .endianness = DEVICE_NATIVE_ENDIAN, }; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 9dafb48..39f0f19 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -24,6 +24,7 @@ #include #include "hw/qdev-core.h" #include "exec/hwaddr.h" +#include "exec/memattrs.h" #include "qemu/queue.h" #include "qemu/thread.h" #include "qemu/tls.h" @@ -195,6 +196,7 @@ typedef struct CPUWatchpoint { vaddr vaddr; vaddr len; vaddr hitaddr; + MemTxAttrs hitattrs; int flags; /* BP_* */ QTAILQ_ENTRY(CPUWatchpoint) entry; } CPUWatchpoint;