Commit b0f891d1 authored by Yonghong Song's avatar Yonghong Song

Force udst ctx->#reg load to be volatile

This is related to issue #1133. Compiler sometimes
generates code patterns likes:
     r1 = ctx + 96
     goto next
   here:
     r1 = ctx + 48
   next:
     r3 = load (r1 + 0)
Verifier will fail for such cases as r1 is marked
as "unknown" at the time of load.

The previous workaround is to add volatile attribute
to the store like
   *(volatile u64 *)&dest = ctx->bx
The hope is to force ctx related load in-place since
its value is needed for store.

Unfortunately, this does not always work and compiler
still has freedom to merge different ctx loads at the
same time honoring the volatile &dest. In USDT generated
code, different branches of &dest are the same.

This patch directly make ctx->bx itself as a volatile load:
  *(volatile u64 *)&ctx->bx
This seems working as compiler stops playing around
the address pointing to a volatile data.
Signed-off-by: default avatarYonghong Song <yhs@fb.com>
parent e7b0ab2d
......@@ -152,7 +152,7 @@ bool Probe::usdt_getarg(std::ostream &stream) {
for (size_t arg_n = 0; arg_n < arg_count; ++arg_n) {
std::string ctype = largest_arg_type(arg_n);
std::string cptr = tfm::format("*((volatile %s *)dest)", ctype);
std::string cptr("dest");
tfm::format(stream,
"static __always_inline int _bpf_readarg_%s_%d("
......
......@@ -67,17 +67,17 @@ bool Argument::assign_to_local(std::ostream &stream,
}
if (!deref_offset_) {
tfm::format(stream, "%s = (%s)ctx->%s;", local_name, ctype(),
tfm::format(stream, "%s = *(volatile %s *)&ctx->%s;", local_name, ctype(),
*base_register_name_);
return true;
}
if (deref_offset_ && !deref_ident_) {
tfm::format(stream, "{ u64 __addr = ctx->%s + (%d)",
tfm::format(stream, "{ u64 __addr = (*(volatile u64 *)&ctx->%s) + (%d)",
*base_register_name_, *deref_offset_);
if (index_register_name_) {
int scale = scale_.value_or(1);
tfm::format(stream, " + (ctx->%s * %d);", *index_register_name_, scale);
tfm::format(stream, " + ((*(volatile u64 *)&ctx->%s) * %d);", *index_register_name_, scale);
} else {
tfm::format(stream, ";");
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment