mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
e683014c21
Historically a lot of these existed because we did not have a distinction between what was modular code and what was providing support to modules via EXPORT_SYMBOL and friends. That changed when we forked out support for the latter into the export.h file. This means we should be able to reduce the usage of module.h in code that is obj-y Makefile or bool Kconfig. The advantage in doing so is that module.h itself sources about 15 other headers; adding significantly to what we feed cpp, and it can obscure what headers we are effectively using. Since module.h was the source for init.h (for __init) and for export.h (for EXPORT_SYMBOL) we consider each obj-y/bool instance for the presence of either and replace as needed. Build testing revealed a couple implicit header usage issues that were fixed. Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20160714001901.31603-5-paul.gortmaker@windriver.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
138 lines
2.3 KiB
C
138 lines
2.3 KiB
C
#include <linux/export.h>
|
|
#include <linux/percpu.h>
|
|
#include <linux/preempt.h>
|
|
#include <asm/msr.h>
|
|
#define CREATE_TRACE_POINTS
|
|
#include <asm/msr-trace.h>
|
|
|
|
struct msr *msrs_alloc(void)
|
|
{
|
|
struct msr *msrs = NULL;
|
|
|
|
msrs = alloc_percpu(struct msr);
|
|
if (!msrs) {
|
|
pr_warn("%s: error allocating msrs\n", __func__);
|
|
return NULL;
|
|
}
|
|
|
|
return msrs;
|
|
}
|
|
EXPORT_SYMBOL(msrs_alloc);
|
|
|
|
void msrs_free(struct msr *msrs)
|
|
{
|
|
free_percpu(msrs);
|
|
}
|
|
EXPORT_SYMBOL(msrs_free);
|
|
|
|
/**
|
|
* Read an MSR with error handling
|
|
*
|
|
* @msr: MSR to read
|
|
* @m: value to read into
|
|
*
|
|
* It returns read data only on success, otherwise it doesn't change the output
|
|
* argument @m.
|
|
*
|
|
*/
|
|
int msr_read(u32 msr, struct msr *m)
|
|
{
|
|
int err;
|
|
u64 val;
|
|
|
|
err = rdmsrl_safe(msr, &val);
|
|
if (!err)
|
|
m->q = val;
|
|
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Write an MSR with error handling
|
|
*
|
|
* @msr: MSR to write
|
|
* @m: value to write
|
|
*/
|
|
int msr_write(u32 msr, struct msr *m)
|
|
{
|
|
return wrmsrl_safe(msr, m->q);
|
|
}
|
|
|
|
static inline int __flip_bit(u32 msr, u8 bit, bool set)
|
|
{
|
|
struct msr m, m1;
|
|
int err = -EINVAL;
|
|
|
|
if (bit > 63)
|
|
return err;
|
|
|
|
err = msr_read(msr, &m);
|
|
if (err)
|
|
return err;
|
|
|
|
m1 = m;
|
|
if (set)
|
|
m1.q |= BIT_64(bit);
|
|
else
|
|
m1.q &= ~BIT_64(bit);
|
|
|
|
if (m1.q == m.q)
|
|
return 0;
|
|
|
|
err = msr_write(msr, &m1);
|
|
if (err)
|
|
return err;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Set @bit in a MSR @msr.
|
|
*
|
|
* Retval:
|
|
* < 0: An error was encountered.
|
|
* = 0: Bit was already set.
|
|
* > 0: Hardware accepted the MSR write.
|
|
*/
|
|
int msr_set_bit(u32 msr, u8 bit)
|
|
{
|
|
return __flip_bit(msr, bit, true);
|
|
}
|
|
|
|
/**
|
|
* Clear @bit in a MSR @msr.
|
|
*
|
|
* Retval:
|
|
* < 0: An error was encountered.
|
|
* = 0: Bit was already cleared.
|
|
* > 0: Hardware accepted the MSR write.
|
|
*/
|
|
int msr_clear_bit(u32 msr, u8 bit)
|
|
{
|
|
return __flip_bit(msr, bit, false);
|
|
}
|
|
|
|
#ifdef CONFIG_TRACEPOINTS
|
|
void do_trace_write_msr(unsigned msr, u64 val, int failed)
|
|
{
|
|
trace_write_msr(msr, val, failed);
|
|
}
|
|
EXPORT_SYMBOL(do_trace_write_msr);
|
|
EXPORT_TRACEPOINT_SYMBOL(write_msr);
|
|
|
|
void do_trace_read_msr(unsigned msr, u64 val, int failed)
|
|
{
|
|
trace_read_msr(msr, val, failed);
|
|
}
|
|
EXPORT_SYMBOL(do_trace_read_msr);
|
|
EXPORT_TRACEPOINT_SYMBOL(read_msr);
|
|
|
|
void do_trace_rdpmc(unsigned counter, u64 val, int failed)
|
|
{
|
|
trace_rdpmc(counter, val, failed);
|
|
}
|
|
EXPORT_SYMBOL(do_trace_rdpmc);
|
|
EXPORT_TRACEPOINT_SYMBOL(rdpmc);
|
|
|
|
#endif
|