mirror of https://github.com/torvalds/linux.git
kernel.h: move PTR_IF() and u64_to_user_ptr() to util_macros.h
While the natural choice of PTR_IF() is kconfig.h, the latter is too broad to include C code and actually the macro was moved out from there in the past. But kernel.h is neither a good choice for that. Move it to util_macros.h. Do the same for u64_to_user_ptr(). While moving, add necessary documentation. Link: https://lkml.kernel.org/r/20250324105228.775784-3-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Alexandru Ardelean <aardelean@baylibre.com> Cc: Ingo Molnar <mingo@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
4ef5211ee6
commit
029c896c41
|
|
@ -33,6 +33,7 @@
|
||||||
#include <linux/sprintf.h>
|
#include <linux/sprintf.h>
|
||||||
#include <linux/static_call_types.h>
|
#include <linux/static_call_types.h>
|
||||||
#include <linux/instruction_pointer.h>
|
#include <linux/instruction_pointer.h>
|
||||||
|
#include <linux/util_macros.h>
|
||||||
#include <linux/wordpart.h>
|
#include <linux/wordpart.h>
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
@ -41,15 +42,6 @@
|
||||||
|
|
||||||
#define STACK_MAGIC 0xdeadbeef
|
#define STACK_MAGIC 0xdeadbeef
|
||||||
|
|
||||||
#define PTR_IF(cond, ptr) ((cond) ? (ptr) : NULL)
|
|
||||||
|
|
||||||
#define u64_to_user_ptr(x) ( \
|
|
||||||
{ \
|
|
||||||
typecheck(u64, (x)); \
|
|
||||||
(void __user *)(uintptr_t)(x); \
|
|
||||||
} \
|
|
||||||
)
|
|
||||||
|
|
||||||
struct completion;
|
struct completion;
|
||||||
struct user;
|
struct user;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,72 @@
|
||||||
(__fc_i); \
|
(__fc_i); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PTR_IF - evaluate to @ptr if @cond is true, or to NULL otherwise.
|
||||||
|
* @cond: A conditional, usually in a form of IS_ENABLED(CONFIG_FOO)
|
||||||
|
* @ptr: A pointer to assign if @cond is true.
|
||||||
|
*
|
||||||
|
* PTR_IF(IS_ENABLED(CONFIG_FOO), ptr) evaluates to @ptr if CONFIG_FOO is set
|
||||||
|
* to 'y' or 'm', or to NULL otherwise. The (ptr) argument must be a pointer.
|
||||||
|
*
|
||||||
|
* The macro can be very useful to help compiler dropping dead code.
|
||||||
|
*
|
||||||
|
* For instance, consider the following::
|
||||||
|
*
|
||||||
|
* #ifdef CONFIG_FOO_SUSPEND
|
||||||
|
* static int foo_suspend(struct device *dev)
|
||||||
|
* {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* #endif
|
||||||
|
*
|
||||||
|
* static struct pm_ops foo_ops = {
|
||||||
|
* #ifdef CONFIG_FOO_SUSPEND
|
||||||
|
* .suspend = foo_suspend,
|
||||||
|
* #endif
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* While this works, the foo_suspend() macro is compiled conditionally,
|
||||||
|
* only when CONFIG_FOO_SUSPEND is set. This is problematic, as there could
|
||||||
|
* be a build bug in this function, we wouldn't have a way to know unless
|
||||||
|
* the configuration option is set.
|
||||||
|
*
|
||||||
|
* An alternative is to declare foo_suspend() always, but mark it
|
||||||
|
* as __maybe_unused. This works, but the __maybe_unused attribute
|
||||||
|
* is required to instruct the compiler that the function may not
|
||||||
|
* be referenced anywhere, and is safe to remove without making
|
||||||
|
* a fuss about it. This makes the programmer responsible for tagging
|
||||||
|
* the functions that can be garbage-collected.
|
||||||
|
*
|
||||||
|
* With the macro it is possible to write the following:
|
||||||
|
*
|
||||||
|
* static int foo_suspend(struct device *dev)
|
||||||
|
* {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static struct pm_ops foo_ops = {
|
||||||
|
* .suspend = PTR_IF(IS_ENABLED(CONFIG_FOO_SUSPEND), foo_suspend),
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* The foo_suspend() function will now be automatically dropped by the
|
||||||
|
* compiler, and it does not require any specific attribute.
|
||||||
|
*/
|
||||||
|
#define PTR_IF(cond, ptr) ((cond) ? (ptr) : NULL)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* to_user_ptr - cast a pointer passed as u64 from user space to void __user *
|
||||||
|
* @x: The u64 value from user space, usually via IOCTL
|
||||||
|
*
|
||||||
|
* to_user_ptr() simply casts a pointer passed as u64 from user space to void
|
||||||
|
* __user * correctly. Using this lets us get rid of all the tiresome casts.
|
||||||
|
*/
|
||||||
|
#define u64_to_user_ptr(x) \
|
||||||
|
({ \
|
||||||
|
typecheck(u64, (x)); \
|
||||||
|
(void __user *)(uintptr_t)(x); \
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* is_insidevar - check if the @ptr points inside the @var memory range.
|
* is_insidevar - check if the @ptr points inside the @var memory range.
|
||||||
* @ptr: the pointer to a memory address.
|
* @ptr: the pointer to a memory address.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue