[SPARSE] noderef & ASM statements

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm investigating some sparse's "warning: unknown expression (4 0)"
on the current kernel. They are a few distinct cases but all of them
are caused by some __builtin_types_compatible_p() not being expanded.

In some of these cases the statement is not expanded because of an
earlier error, for example in compatible_assignment_types(), but
this statement is then linearized anyway. This needs to be be fixed
but is not really a problem.

Another case, much more annoying, is because input & output operands
of ASM statements are not expanded. This is very easy to fix (see
patch here below) but once fixed and used on the kernel, sparse then
issues many thousands of "warning: dereference of noderef expression"
(in fact, more than one million on defconfig + allyesconfig).
These warnings are perfectly correct: a lot of ASM operands are
indeed noderef variables or expressions (most warnings seem to come
from put_user(), get_user() or one of the percpu operations).

I'm quite reluctant to commit a patch that will add so much warnings.
On the other hand, properly silenting these warnings in the kernel
is a non-obvious job, especially given the fact that __force can't
simply be used to 'ignore' __noderef (because the dereferencing
kinda happens before the cast), you need to act via a pointer with
something like:
	*(typeof(X) __kernel __force *) &(X);


The only simple temporary 'solution' is see for the moment would be
to disable 'noderef' warnings while expanding ASM.

-- Luc Van Oostenryck


>From 89e3ba40948c9c98ada673f3451be0b11b5740c3 Mon Sep 17 00:00:00 2001
From: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
Date: Mon, 14 Jan 2019 16:02:06 +0100
Subject: [PATCH] fix expansion of asm statements

---
 expand.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/expand.c b/expand.c
index e8e50b080..fa410f39f 100644
--- a/expand.c
+++ b/expand.c
@@ -1155,6 +1155,22 @@ static int expand_if_statement(struct statement *stmt)
 	return SIDE_EFFECTS;
 }
 
+static int expand_asm_statement(struct statement *stmt)
+{
+	struct expression *op;
+	int cost = 0;
+
+	FOR_EACH_PTR(stmt->asm_outputs, op) {
+		cost += expand_expression(op->expr);
+	} END_FOR_EACH_PTR(op);
+
+	FOR_EACH_PTR(stmt->asm_inputs, op) {
+		cost += expand_expression(op->expr);
+	} END_FOR_EACH_PTR(op);
+
+	return cost;
+}
+
 /*
  * Expanding a compound statement is really just
  * about adding up the costs of each individual
@@ -1245,7 +1261,7 @@ static int expand_statement(struct statement *stmt)
 	case STMT_NONE:
 		break;
 	case STMT_ASM:
-		/* FIXME! Do the asm parameter evaluation! */
+		expand_asm_statement(stmt);
 		break;
 	case STMT_CONTEXT:
 		expand_expression(stmt->expression);
-- 
2.20.0





[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux