Bug 199740 - syscall __clear_cache (ARM_SYNC_ICACHE) does not achieve icache consistency
Summary: syscall __clear_cache (ARM_SYNC_ICACHE) does not achieve icache consistency
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-arm (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-04-27 19:47 UTC by weiss
Modified: 2015-05-05 01:24 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description weiss 2015-04-27 19:47:55 UTC
function does not round to cache line boundaries as all other functions in this file do

diff --git a/sys/arm/arm/cpufunc_asm_armv7.S b/sys/arm/arm/cpufunc_asm_armv7.S
index 25f052f..6a9b3e0 100644
--- a/sys/arm/arm/cpufunc_asm_armv7.S
+++ b/sys/arm/arm/cpufunc_asm_armv7.S
@@ -264,8 +272,14 @@ ENTRY_NP(armv7_icache_sync_all)
 END(armv7_icache_sync_all)
 
 ENTRY_NP(armv7_icache_sync_range)
        ldr     ip, .Larmv7_icache_line_size
        ldr     ip, [ip]
+       sub     r3, ip, #1
+       and     r2, r0, r3
+       add     r1, r1, r2
+       bic     r0, r0, r3
 .Larmv7_sync_next:
        mcr     CP15_DCCMVAC(r0)
        mcr     CP15_ICIMVAU(r0)
Comment 1 Ian Lepore freebsd_committer freebsd_triage 2015-05-03 20:11:11 UTC
The ARM ARM, in a rare example of lucidity, describes the register parameter for cp15 cache operations thusly: "When the data is stated to be an MVA, it does not have to be cache line aligned.

If these changes lead to something working that doesn't work without the changes, I guess we need to figure out why.  It may imply that the caller to the function is incorrectly converting a start/end tulple to start/len or something along those lines.
Comment 2 weiss 2015-05-03 21:49:38 UTC
sorry, my bug report was a bit brief.

assume a cache line size of 32 bytes and a call with offset 16 and length 24.
It should sync 2 cache lines but does actually sync only one. The last
8 bytes would not be synced.

So one does not have to round the va to a boundary, but one has to adjust
the length.

So the following change would probably be sufficient (untested)

ENTRY_NP(armv7_icache_sync_range)
        ldr     ip, .Larmv7_icache_line_size
        ldr     ip, [ip]
+       sub     r3, ip, #1
+       and     r2, r0, r3
+       add     r1, r1, r2
 .Larmv7_sync_next:
        mcr     CP15_DCCMVAC(r0)
        mcr     CP15_ICIMVAU(r0)
Comment 3 commit-hook freebsd_committer freebsd_triage 2015-05-04 14:55:48 UTC
A commit references this bug:

Author: ian
Date: Mon May  4 14:55:22 UTC 2015
New revision: 282418
URL: https://svnweb.freebsd.org/changeset/base/282418

Log:
  On an icache sync by address/len, round the length up if the operation spans
  a cacheline boundary.

  PR:		199740
  Submitted by:	Juergen Weiss <weiss@uni-mainz.de>

Changes:
  head/sys/arm/arm/cpufunc_asm_armv7.S