accel/tcg: Remove prot argument to atomic_mmu_lookup
Now that load/store are gone, we're always passing PAGE_READ | PAGE_WRITE for RMW atomic operations. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
ec4a9629a1
commit
7bedee3243
@ -73,8 +73,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
|||||||
ABI_TYPE cmpv, ABI_TYPE newv,
|
ABI_TYPE cmpv, ABI_TYPE newv,
|
||||||
MemOpIdx oi, uintptr_t retaddr)
|
MemOpIdx oi, uintptr_t retaddr)
|
||||||
{
|
{
|
||||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
|
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
|
||||||
PAGE_READ | PAGE_WRITE, retaddr);
|
|
||||||
DATA_TYPE ret;
|
DATA_TYPE ret;
|
||||||
|
|
||||||
#if DATA_SIZE == 16
|
#if DATA_SIZE == 16
|
||||||
@ -91,8 +90,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
|||||||
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
||||||
MemOpIdx oi, uintptr_t retaddr)
|
MemOpIdx oi, uintptr_t retaddr)
|
||||||
{
|
{
|
||||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
|
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
|
||||||
PAGE_READ | PAGE_WRITE, retaddr);
|
|
||||||
DATA_TYPE ret;
|
DATA_TYPE ret;
|
||||||
|
|
||||||
ret = qatomic_xchg__nocheck(haddr, val);
|
ret = qatomic_xchg__nocheck(haddr, val);
|
||||||
@ -105,9 +103,8 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
|||||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
|
ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
|
||||||
{ \
|
{ \
|
||||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
|
DATA_TYPE *haddr, ret; \
|
||||||
PAGE_READ | PAGE_WRITE, retaddr); \
|
haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr); \
|
||||||
DATA_TYPE ret; \
|
|
||||||
ret = qatomic_##X(haddr, val); \
|
ret = qatomic_##X(haddr, val); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
atomic_trace_rmw_post(env, addr, oi); \
|
atomic_trace_rmw_post(env, addr, oi); \
|
||||||
@ -137,9 +134,8 @@ GEN_ATOMIC_HELPER(xor_fetch)
|
|||||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
|
ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
|
||||||
{ \
|
{ \
|
||||||
XDATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
|
XDATA_TYPE *haddr, cmp, old, new, val = xval; \
|
||||||
PAGE_READ | PAGE_WRITE, retaddr); \
|
haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr); \
|
||||||
XDATA_TYPE cmp, old, new, val = xval; \
|
|
||||||
smp_mb(); \
|
smp_mb(); \
|
||||||
cmp = qatomic_read__nocheck(haddr); \
|
cmp = qatomic_read__nocheck(haddr); \
|
||||||
do { \
|
do { \
|
||||||
@ -180,8 +176,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
|||||||
ABI_TYPE cmpv, ABI_TYPE newv,
|
ABI_TYPE cmpv, ABI_TYPE newv,
|
||||||
MemOpIdx oi, uintptr_t retaddr)
|
MemOpIdx oi, uintptr_t retaddr)
|
||||||
{
|
{
|
||||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
|
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
|
||||||
PAGE_READ | PAGE_WRITE, retaddr);
|
|
||||||
DATA_TYPE ret;
|
DATA_TYPE ret;
|
||||||
|
|
||||||
#if DATA_SIZE == 16
|
#if DATA_SIZE == 16
|
||||||
@ -198,8 +193,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
|||||||
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
||||||
MemOpIdx oi, uintptr_t retaddr)
|
MemOpIdx oi, uintptr_t retaddr)
|
||||||
{
|
{
|
||||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
|
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
|
||||||
PAGE_READ | PAGE_WRITE, retaddr);
|
|
||||||
ABI_TYPE ret;
|
ABI_TYPE ret;
|
||||||
|
|
||||||
ret = qatomic_xchg__nocheck(haddr, BSWAP(val));
|
ret = qatomic_xchg__nocheck(haddr, BSWAP(val));
|
||||||
@ -212,9 +206,8 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
|||||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
|
ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
|
||||||
{ \
|
{ \
|
||||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
|
DATA_TYPE *haddr, ret; \
|
||||||
PAGE_READ | PAGE_WRITE, retaddr); \
|
haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr); \
|
||||||
DATA_TYPE ret; \
|
|
||||||
ret = qatomic_##X(haddr, BSWAP(val)); \
|
ret = qatomic_##X(haddr, BSWAP(val)); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
atomic_trace_rmw_post(env, addr, oi); \
|
atomic_trace_rmw_post(env, addr, oi); \
|
||||||
@ -241,9 +234,8 @@ GEN_ATOMIC_HELPER(xor_fetch)
|
|||||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
|
ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
|
||||||
{ \
|
{ \
|
||||||
XDATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
|
XDATA_TYPE *haddr, ldo, ldn, old, new, val = xval; \
|
||||||
PAGE_READ | PAGE_WRITE, retaddr); \
|
haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr); \
|
||||||
XDATA_TYPE ldo, ldn, old, new, val = xval; \
|
|
||||||
smp_mb(); \
|
smp_mb(); \
|
||||||
ldn = qatomic_read__nocheck(haddr); \
|
ldn = qatomic_read__nocheck(haddr); \
|
||||||
do { \
|
do { \
|
||||||
|
@ -1896,12 +1896,9 @@ static bool mmu_lookup(CPUArchState *env, target_ulong addr, MemOpIdx oi,
|
|||||||
/*
|
/*
|
||||||
* Probe for an atomic operation. Do not allow unaligned operations,
|
* Probe for an atomic operation. Do not allow unaligned operations,
|
||||||
* or io operations to proceed. Return the host address.
|
* or io operations to proceed. Return the host address.
|
||||||
*
|
|
||||||
* @prot may be PAGE_READ, PAGE_WRITE, or PAGE_READ|PAGE_WRITE.
|
|
||||||
*/
|
*/
|
||||||
static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
||||||
MemOpIdx oi, int size, int prot,
|
MemOpIdx oi, int size, uintptr_t retaddr)
|
||||||
uintptr_t retaddr)
|
|
||||||
{
|
{
|
||||||
uintptr_t mmu_idx = get_mmuidx(oi);
|
uintptr_t mmu_idx = get_mmuidx(oi);
|
||||||
MemOp mop = get_memop(oi);
|
MemOp mop = get_memop(oi);
|
||||||
@ -1937,54 +1934,37 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
|||||||
tlbe = tlb_entry(env, mmu_idx, addr);
|
tlbe = tlb_entry(env, mmu_idx, addr);
|
||||||
|
|
||||||
/* Check TLB entry and enforce page permissions. */
|
/* Check TLB entry and enforce page permissions. */
|
||||||
if (prot & PAGE_WRITE) {
|
tlb_addr = tlb_addr_write(tlbe);
|
||||||
tlb_addr = tlb_addr_write(tlbe);
|
if (!tlb_hit(tlb_addr, addr)) {
|
||||||
if (!tlb_hit(tlb_addr, addr)) {
|
if (!victim_tlb_hit(env, mmu_idx, index, MMU_DATA_STORE,
|
||||||
if (!victim_tlb_hit(env, mmu_idx, index, MMU_DATA_STORE,
|
addr & TARGET_PAGE_MASK)) {
|
||||||
addr & TARGET_PAGE_MASK)) {
|
tlb_fill(env_cpu(env), addr, size,
|
||||||
tlb_fill(env_cpu(env), addr, size,
|
MMU_DATA_STORE, mmu_idx, retaddr);
|
||||||
MMU_DATA_STORE, mmu_idx, retaddr);
|
index = tlb_index(env, mmu_idx, addr);
|
||||||
index = tlb_index(env, mmu_idx, addr);
|
tlbe = tlb_entry(env, mmu_idx, addr);
|
||||||
tlbe = tlb_entry(env, mmu_idx, addr);
|
|
||||||
}
|
|
||||||
tlb_addr = tlb_addr_write(tlbe) & ~TLB_INVALID_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prot & PAGE_READ) {
|
|
||||||
/*
|
|
||||||
* Let the guest notice RMW on a write-only page.
|
|
||||||
* We have just verified that the page is writable.
|
|
||||||
* Subpage lookups may have left TLB_INVALID_MASK set,
|
|
||||||
* but addr_read will only be -1 if PAGE_READ was unset.
|
|
||||||
*/
|
|
||||||
if (unlikely(tlbe->addr_read == -1)) {
|
|
||||||
tlb_fill(env_cpu(env), addr, size,
|
|
||||||
MMU_DATA_LOAD, mmu_idx, retaddr);
|
|
||||||
/*
|
|
||||||
* Since we don't support reads and writes to different
|
|
||||||
* addresses, and we do have the proper page loaded for
|
|
||||||
* write, this shouldn't ever return. But just in case,
|
|
||||||
* handle via stop-the-world.
|
|
||||||
*/
|
|
||||||
goto stop_the_world;
|
|
||||||
}
|
|
||||||
/* Collect TLB_WATCHPOINT for read. */
|
|
||||||
tlb_addr |= tlbe->addr_read;
|
|
||||||
}
|
|
||||||
} else /* if (prot & PAGE_READ) */ {
|
|
||||||
tlb_addr = tlbe->addr_read;
|
|
||||||
if (!tlb_hit(tlb_addr, addr)) {
|
|
||||||
if (!victim_tlb_hit(env, mmu_idx, index, MMU_DATA_LOAD,
|
|
||||||
addr & TARGET_PAGE_MASK)) {
|
|
||||||
tlb_fill(env_cpu(env), addr, size,
|
|
||||||
MMU_DATA_LOAD, mmu_idx, retaddr);
|
|
||||||
index = tlb_index(env, mmu_idx, addr);
|
|
||||||
tlbe = tlb_entry(env, mmu_idx, addr);
|
|
||||||
}
|
|
||||||
tlb_addr = tlbe->addr_read & ~TLB_INVALID_MASK;
|
|
||||||
}
|
}
|
||||||
|
tlb_addr = tlb_addr_write(tlbe) & ~TLB_INVALID_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let the guest notice RMW on a write-only page.
|
||||||
|
* We have just verified that the page is writable.
|
||||||
|
* Subpage lookups may have left TLB_INVALID_MASK set,
|
||||||
|
* but addr_read will only be -1 if PAGE_READ was unset.
|
||||||
|
*/
|
||||||
|
if (unlikely(tlbe->addr_read == -1)) {
|
||||||
|
tlb_fill(env_cpu(env), addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
|
||||||
|
/*
|
||||||
|
* Since we don't support reads and writes to different
|
||||||
|
* addresses, and we do have the proper page loaded for
|
||||||
|
* write, this shouldn't ever return. But just in case,
|
||||||
|
* handle via stop-the-world.
|
||||||
|
*/
|
||||||
|
goto stop_the_world;
|
||||||
|
}
|
||||||
|
/* Collect TLB_WATCHPOINT for read. */
|
||||||
|
tlb_addr |= tlbe->addr_read;
|
||||||
|
|
||||||
/* Notice an IO access or a needs-MMU-lookup access */
|
/* Notice an IO access or a needs-MMU-lookup access */
|
||||||
if (unlikely(tlb_addr & (TLB_MMIO | TLB_DISCARD_WRITE))) {
|
if (unlikely(tlb_addr & (TLB_MMIO | TLB_DISCARD_WRITE))) {
|
||||||
/* There's really nothing that can be done to
|
/* There's really nothing that can be done to
|
||||||
@ -2000,11 +1980,8 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(tlb_addr & TLB_WATCHPOINT)) {
|
if (unlikely(tlb_addr & TLB_WATCHPOINT)) {
|
||||||
QEMU_BUILD_BUG_ON(PAGE_READ != BP_MEM_READ);
|
cpu_check_watchpoint(env_cpu(env), addr, size, full->attrs,
|
||||||
QEMU_BUILD_BUG_ON(PAGE_WRITE != BP_MEM_WRITE);
|
BP_MEM_READ | BP_MEM_WRITE, retaddr);
|
||||||
/* therefore prot == watchpoint bits */
|
|
||||||
cpu_check_watchpoint(env_cpu(env), addr, size,
|
|
||||||
full->attrs, prot, retaddr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hostaddr;
|
return hostaddr;
|
||||||
|
@ -1323,12 +1323,9 @@ uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not allow unaligned operations to proceed. Return the host address.
|
* Do not allow unaligned operations to proceed. Return the host address.
|
||||||
*
|
|
||||||
* @prot may be PAGE_READ, PAGE_WRITE, or PAGE_READ|PAGE_WRITE.
|
|
||||||
*/
|
*/
|
||||||
static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
||||||
MemOpIdx oi, int size, int prot,
|
MemOpIdx oi, int size, uintptr_t retaddr)
|
||||||
uintptr_t retaddr)
|
|
||||||
{
|
{
|
||||||
MemOp mop = get_memop(oi);
|
MemOp mop = get_memop(oi);
|
||||||
int a_bits = get_alignment_bits(mop);
|
int a_bits = get_alignment_bits(mop);
|
||||||
@ -1336,8 +1333,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
|||||||
|
|
||||||
/* Enforce guest required alignment. */
|
/* Enforce guest required alignment. */
|
||||||
if (unlikely(addr & ((1 << a_bits) - 1))) {
|
if (unlikely(addr & ((1 << a_bits) - 1))) {
|
||||||
MMUAccessType t = prot == PAGE_READ ? MMU_DATA_LOAD : MMU_DATA_STORE;
|
cpu_loop_exit_sigbus(env_cpu(env), addr, MMU_DATA_STORE, retaddr);
|
||||||
cpu_loop_exit_sigbus(env_cpu(env), addr, t, retaddr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enforce qemu required alignment. */
|
/* Enforce qemu required alignment. */
|
||||||
|
Loading…
Reference in New Issue
Block a user