Index: qemu-2.6.2/exec.c
===================================================================
--- qemu-2.6.2.orig/exec.c
+++ qemu-2.6.2/exec.c
@@ -36,6 +36,7 @@
 #include "qemu/timer.h"
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
+#include "qemu/log.h"
 #include "exec/memory.h"
 #include "sysemu/dma.h"
 #include "exec/address-spaces.h"
@@ -2654,6 +2655,33 @@ static bool prepare_mmio_access(MemoryRe
     return release_lock;
 }
 
+/**
+ * address_space_access_allowed
+ * @mr: #MemoryRegion to be accessed
+ * @attrs: memory transaction attributes
+ * @addr: address within that memory region
+ * @len: the number of bytes to access
+ *
+ * Check if a memory transaction is allowed.
+ *
+ * Returns: true if transaction is allowed, false if denied.
+ */
+static bool address_space_access_allowed(MemoryRegion *mr, MemTxAttrs attrs,
+                                         hwaddr addr, hwaddr len)
+{
+    if (likely(!attrs.memory)) {
+        return true;
+    }
+    if (memory_region_is_ram(mr)) {
+        return true;
+    }
+    qemu_log_mask(LOG_GUEST_ERROR,
+                  "Invalid access to non-RAM device at "
+                  "addr 0x%" HWADDR_PRIX ", size %" HWADDR_PRIu ", "
+                  "region '%s'\n", addr, len, memory_region_name(mr));
+    return false;
+}
+
 /* Called within RCU critical section.  */
 static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
                                                 MemTxAttrs attrs,
@@ -2667,7 +2695,10 @@ static MemTxResult address_space_write_c
     bool release_lock = false;
 
     for (;;) {
-        if (!memory_access_is_direct(mr, true)) {
+        if (!address_space_access_allowed(mr, attrs, addr1, l)) {
+            result |= MEMTX_ACCESS_ERROR;
+            /* Keep going. */
+        } else if (!memory_access_is_direct(mr, true)) {
             release_lock |= prepare_mmio_access(mr);
             l = memory_access_size(mr, l, addr1);
             /* XXX: could force current_cpu to NULL to avoid
@@ -2740,8 +2771,12 @@ MemTxResult address_space_write(AddressS
         rcu_read_lock();
         l = len;
         mr = address_space_translate(as, addr, &addr1, &l, true);
-        result = address_space_write_continue(as, addr, attrs, buf, len,
-                                              addr1, l, mr);
+        if (!address_space_access_allowed(mr, attrs, addr, len)) {
+            result = MEMTX_ACCESS_ERROR;
+        } else {
+            result = address_space_write_continue(as, addr, attrs, buf, len,
+                                                  addr1, l, mr);
+        }
         rcu_read_unlock();
     }
 
@@ -2760,7 +2795,10 @@ MemTxResult address_space_read_continue(
     bool release_lock = false;
 
     for (;;) {
-        if (!memory_access_is_direct(mr, false)) {
+        if (!address_space_access_allowed(mr, attrs, addr1, l)) {
+            result |= MEMTX_ACCESS_ERROR;
+            /* Keep going. */
+        } else if (!memory_access_is_direct(mr, false)) {
             /* I/O case */
             release_lock |= prepare_mmio_access(mr);
             l = memory_access_size(mr, l, addr1);
@@ -2832,8 +2870,12 @@ MemTxResult address_space_read_full(Addr
         rcu_read_lock();
         l = len;
         mr = address_space_translate(as, addr, &addr1, &l, false);
-        result = address_space_read_continue(as, addr, attrs, buf, len,
-                                             addr1, l, mr);
+        if (!address_space_access_allowed(mr, attrs, addr, len)) {
+            result = MEMTX_ACCESS_ERROR;
+        } else {
+            result = address_space_read_continue(as, addr, attrs, buf, len,
+                                                 addr1, l, mr);
+        }
         rcu_read_unlock();
     }
 
Index: qemu-2.6.2/include/exec/memattrs.h
===================================================================
--- qemu-2.6.2.orig/include/exec/memattrs.h
+++ qemu-2.6.2/include/exec/memattrs.h
@@ -35,6 +35,14 @@ typedef struct MemTxAttrs {
     unsigned int secure:1;
     /* Memory access is usermode (unprivileged) */
     unsigned int user:1;
+    /*
+     * Bus interconnect and peripherals can access anything (memories,
+     * devices) by default. By setting the 'memory' bit, bus transaction
+     * are restricted to "normal" memories (per the AMBA documentation)
+     * versus devices. Access to devices will be logged and rejected
+     * (see MEMTX_ACCESS_ERROR).
+     */
+    unsigned int memory:1;
     /* Requester ID (for MSI for example) */
     unsigned int requester_id:16;
 } MemTxAttrs;
Index: qemu-2.6.2/include/exec/memory.h
===================================================================
--- qemu-2.6.2.orig/include/exec/memory.h
+++ qemu-2.6.2/include/exec/memory.h
@@ -73,6 +73,7 @@ struct IOMMUTLBEntry {
 #define MEMTX_OK 0
 #define MEMTX_ERROR             (1U << 0) /* device returned an error */
 #define MEMTX_DECODE_ERROR      (1U << 1) /* nothing at that address */
+#define MEMTX_ACCESS_ERROR      (1U << 2) /* access denied */
 typedef uint32_t MemTxResult;
 
 /*
