On 13.02.19 05:48, Peng Fan wrote:
When compiling code using poky gcc 8.2, met the warning:
"
CC hypervisor/printk.o
/tmp/cclKpFV2.s: Assembler messages:
/tmp/cclKpFV2.s:1306: Warning: unpredictable: identical transfer and status
registers --`stxr w4,x5,[x4]'
"
According to DDI0487D_a_armv8_arm, section "C6.2.285 STXR",
"
if s == n && n != 31 then
Constraint c = ConstrainUnpredictable();
assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF,
Constraint_NOP};
case c of
when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN
when Constraint_NONE rn_unknown = FALSE; // address is original base
when Constraint_UNDEF UNDEFINED;
when Constraint_NOP EndOfInstruction();
"
And ConstrainUnpredictable means:
"
shared/functions/unpredictable/ConstrainUnpredictable
// Return the appropriate Constraint result to control the caller's behavior.
The return value
// is IMPLEMENTATION DEFINED within a permitted list for each UNPREDICTABLE
case.
// (The permitted list is determined by an assert or case statement at the call
site.)
"
So we need to avoid the situation that s == n returns true.
Without this patch, the asm code as following in panic_prink
ffffc0207ac0: 91006024 add x4, x1, #0x18
ffffc0207ac4: c85f7c85 ldxr x5, [x4]
ffffc0207ac8: ea0200a3 ands x3, x5, x2
ffffc0207acc: 54000041 b.ne ffffc0207ad4
<panic_printk+0x40> // b.any
ffffc0207ad0: aa0200a5 orr x5, x5, x2
ffffc0207ad4: c8047c85 stxr w4, x5, [x4]
ffffc0207ad8: d5033bbf dmb ish
ffffc0207adc: 35ffff24 cbnz w4, ffffc0207ac0
<panic_printk+0x2c>
With this patch, the asm code as following:
ffffc0207a10: c85f7c44 ldxr x4, [x2]
ffffc0207a14: ea010083 ands x3, x4, x1
ffffc0207a18: 54000041 b.ne ffffc0207a20
<panic_printk+0x40> // b.any
ffffc0207a1c: aa010084 orr x4, x4, x1
ffffc0207a20: c8017c44 stxr w1, x4, [x2]
ffffc0207a24: d5033bbf dmb ish
ffffc0207a28: 35ffff41 cbnz w1, ffffc0207a10
<panic_printk+0x30>
Note: not sure this is gcc bug or not, but arm64 poky gcc also generated
same code, but no warning.
Probably worth to ask gcc folks at least.
Signed-off-by: Peng Fan <[email protected]>
---
hypervisor/arch/arm64/include/asm/bitops.h | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/hypervisor/arch/arm64/include/asm/bitops.h
b/hypervisor/arch/arm64/include/asm/bitops.h
index c4b1ea46..aa53a6f9 100644
--- a/hypervisor/arch/arm64/include/asm/bitops.h
+++ b/hypervisor/arch/arm64/include/asm/bitops.h
@@ -83,21 +83,21 @@ static inline int test_and_set_bit(int nr, volatile
unsigned long *addr)
/* AARCH64_TODO: using Inner Shareable DMB at the moment,
* revisit when we will deal with shareability domains */
+ asm volatile (
+ "1:\n\t"
+ "ldxr %3, %2\n\t"
+ "ands %1, %3, %4\n\t"
+ "b.ne 2f\n\t"
+ "orr %3, %3, %4\n\t"
+ "2:\n\t"
+ "stxr %w0, %3, %2\n\t"
+ "dmb ish\n\t"
+ "cbnz %w0, 1b\n\t"
+ : "=r" (ret), "=&r" (test),
+ "+Q" (*(volatile unsigned long *)addr),
+ "=r" (tmp)
+ : "r" (1ul << nr));
I supposes this folding of the loop into assembly simple shakes the register
allocator a bit to come up with a different assignment that happens to not
trigger the issue. Or is there some other trick in this?
Jan
- do {
- asm volatile (
- "ldxr %3, %2\n\t"
- "ands %1, %3, %4\n\t"
- "b.ne 1f\n\t"
- "orr %3, %3, %4\n\t"
- "1:\n\t"
- "stxr %w0, %3, %2\n\t"
- "dmb ish\n\t"
- : "=r" (ret), "=&r" (test),
- "+Q" (*(volatile unsigned long *)addr),
- "=r" (tmp)
- : "r" (1ul << nr));
- } while (ret);
return !!(test);
}
--
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux
--
You received this message because you are subscribed to the Google Groups
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.