mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
x86, msr: Add support for non-contiguous cpumasks
The current rd/wrmsr_on_cpus helpers assume that the supplied cpumasks are contiguous. However, there are machines out there like some K8 multinode Opterons which have a non-contiguous core enumeration on each node (e.g. cores 0,2 on node 0 instead of 0,1), see http://www.gossamer-threads.com/lists/linux/kernel/1160268. This patch fixes out-of-bounds writes (see URL above) by adding per-CPU msr structs which are used on the respective cores. Additionally, two helpers, msrs_{alloc,free}, are provided for use by the callers of the MSR accessors. Cc: H. Peter Anvin <hpa@zytor.com> Cc: Mauro Carvalho Chehab <mchehab@redhat.com> Cc: Aristeu Rozanski <aris@redhat.com> Cc: Randy Dunlap <randy.dunlap@oracle.com> Cc: Doug Thompson <dougthompson@xmission.com> Signed-off-by: Borislav Petkov <borislav.petkov@amd.com> LKML-Reference: <20091211171440.GD31998@aftab> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
committed by
H. Peter Anvin
parent
5c6baba84e
commit
505422517d
@@ -7,7 +7,6 @@ struct msr_info {
|
||||
u32 msr_no;
|
||||
struct msr reg;
|
||||
struct msr *msrs;
|
||||
int off;
|
||||
int err;
|
||||
};
|
||||
|
||||
@@ -18,7 +17,7 @@ static void __rdmsr_on_cpu(void *info)
|
||||
int this_cpu = raw_smp_processor_id();
|
||||
|
||||
if (rv->msrs)
|
||||
reg = &rv->msrs[this_cpu - rv->off];
|
||||
reg = per_cpu_ptr(rv->msrs, this_cpu);
|
||||
else
|
||||
reg = &rv->reg;
|
||||
|
||||
@@ -32,7 +31,7 @@ static void __wrmsr_on_cpu(void *info)
|
||||
int this_cpu = raw_smp_processor_id();
|
||||
|
||||
if (rv->msrs)
|
||||
reg = &rv->msrs[this_cpu - rv->off];
|
||||
reg = per_cpu_ptr(rv->msrs, this_cpu);
|
||||
else
|
||||
reg = &rv->reg;
|
||||
|
||||
@@ -80,7 +79,6 @@ static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
|
||||
|
||||
memset(&rv, 0, sizeof(rv));
|
||||
|
||||
rv.off = cpumask_first(mask);
|
||||
rv.msrs = msrs;
|
||||
rv.msr_no = msr_no;
|
||||
|
||||
@@ -120,6 +118,26 @@ void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
|
||||
}
|
||||
EXPORT_SYMBOL(wrmsr_on_cpus);
|
||||
|
||||
struct msr *msrs_alloc(void)
|
||||
{
|
||||
struct msr *msrs = NULL;
|
||||
|
||||
msrs = alloc_percpu(struct msr);
|
||||
if (!msrs) {
|
||||
pr_warning("%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);
|
||||
|
||||
/* These "safe" variants are slower and should be used when the target MSR
|
||||
may not actually exist. */
|
||||
static void __rdmsr_safe_on_cpu(void *info)
|
||||
|
Reference in New Issue
Block a user