Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8897452d
Commit
8897452d
authored
Apr 02, 2002
by
Dave Jones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] x86 microcode driver update
From Tigran via 2.4
parent
7e7a44c1
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
68 additions
and
37 deletions
+68
-37
arch/i386/kernel/microcode.c
arch/i386/kernel/microcode.c
+68
-37
No files found.
arch/i386/kernel/microcode.c
View file @
8897452d
...
@@ -51,6 +51,12 @@
...
@@ -51,6 +51,12 @@
* Bugfix for HT (Hyper-Threading) enabled processors
* Bugfix for HT (Hyper-Threading) enabled processors
* whereby processor resources are shared by all logical processors
* whereby processor resources are shared by all logical processors
* in a single CPU package.
* in a single CPU package.
* 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and
* Tigran Aivazian <tigran@veritas.com>,
* Serialize updates as required on HT processors due to speculative
* nature of implementation.
* 1.11 22 Mar 2001 Tigran Aivazian <tigran@veritas.com>
* Fix the panic when writing zero-length microcode chunk.
*/
*/
#include <linux/init.h>
#include <linux/init.h>
...
@@ -60,12 +66,16 @@
...
@@ -60,12 +66,16 @@
#include <linux/vmalloc.h>
#include <linux/vmalloc.h>
#include <linux/miscdevice.h>
#include <linux/miscdevice.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/spinlock.h>
#include <asm/msr.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/processor.h>
#define MICROCODE_VERSION "1.09"
static
spinlock_t
microcode_update_lock
=
SPIN_LOCK_UNLOCKED
;
#define MICROCODE_VERSION "1.11"
MODULE_DESCRIPTION
(
"Intel CPU (IA-32) microcode update driver"
);
MODULE_DESCRIPTION
(
"Intel CPU (IA-32) microcode update driver"
);
MODULE_AUTHOR
(
"Tigran Aivazian <tigran@veritas.com>"
);
MODULE_AUTHOR
(
"Tigran Aivazian <tigran@veritas.com>"
);
...
@@ -195,7 +205,8 @@ static void do_update_one(void *unused)
...
@@ -195,7 +205,8 @@ static void do_update_one(void *unused)
struct
cpuinfo_x86
*
c
=
cpu_data
+
cpu_num
;
struct
cpuinfo_x86
*
c
=
cpu_data
+
cpu_num
;
struct
update_req
*
req
=
update_req
+
cpu_num
;
struct
update_req
*
req
=
update_req
+
cpu_num
;
unsigned
int
pf
=
0
,
val
[
2
],
rev
,
sig
;
unsigned
int
pf
=
0
,
val
[
2
],
rev
,
sig
;
int
i
,
found
=
0
;
unsigned
long
flags
;
int
i
;
req
->
err
=
1
;
/* assume update will fail on this cpu */
req
->
err
=
1
;
/* assume update will fail on this cpu */
...
@@ -216,8 +227,9 @@ static void do_update_one(void *unused)
...
@@ -216,8 +227,9 @@ static void do_update_one(void *unused)
for
(
i
=
0
;
i
<
microcode_num
;
i
++
)
for
(
i
=
0
;
i
<
microcode_num
;
i
++
)
if
(
microcode
[
i
].
sig
==
sig
&&
microcode
[
i
].
pf
==
pf
&&
if
(
microcode
[
i
].
sig
==
sig
&&
microcode
[
i
].
pf
==
pf
&&
microcode
[
i
].
ldrver
==
1
&&
microcode
[
i
].
hdrver
==
1
)
{
microcode
[
i
].
ldrver
==
1
&&
microcode
[
i
].
hdrver
==
1
)
{
int
sum
=
0
;
found
=
1
;
struct
microcode
*
m
=
&
microcode
[
i
];
unsigned
int
*
sump
=
(
unsigned
int
*
)(
m
+
1
);
printf
(
"Microcode
\n
"
);
printf
(
"Microcode
\n
"
);
printf
(
" Header Revision %d
\n
"
,
microcode
[
i
].
hdrver
);
printf
(
" Header Revision %d
\n
"
,
microcode
[
i
].
hdrver
);
...
@@ -234,27 +246,43 @@ static void do_update_one(void *unused)
...
@@ -234,27 +246,43 @@ static void do_update_one(void *unused)
printf
(
" Loader Revision %x
\n
"
,
microcode
[
i
].
ldrver
);
printf
(
" Loader Revision %x
\n
"
,
microcode
[
i
].
ldrver
);
printf
(
" Processor Flags %x
\n\n
"
,
microcode
[
i
].
pf
);
printf
(
" Processor Flags %x
\n\n
"
,
microcode
[
i
].
pf
);
req
->
slot
=
i
;
/* serialize access to update decision */
spin_lock_irqsave
(
&
microcode_update_lock
,
flags
);
/* trick, to work even if there was no prior update by the BIOS */
/* trick, to work even if there was no prior update by the BIOS */
wrmsr
(
MSR_IA32_UCODE_REV
,
0
,
0
);
wrmsr
(
MSR_IA32_UCODE_REV
,
0
,
0
);
__asm__
__volatile__
(
"cpuid"
:
:
:
"ax"
,
"bx"
,
"cx"
,
"dx"
);
__asm__
__volatile__
(
"cpuid"
:
:
:
"ax"
,
"bx"
,
"cx"
,
"dx"
);
/* get current (on-cpu) revision into rev (ignore val[0]) */
/* get current (on-cpu) revision into rev (ignore val[0]) */
rdmsr
(
MSR_IA32_UCODE_REV
,
val
[
0
],
rev
);
rdmsr
(
MSR_IA32_UCODE_REV
,
val
[
0
],
rev
);
if
(
microcode
[
i
].
rev
<
rev
)
{
if
(
microcode
[
i
].
rev
<
rev
)
{
spin_unlock_irqrestore
(
&
microcode_update_lock
,
flags
);
printk
(
KERN_ERR
printk
(
KERN_ERR
"microcode: CPU%d not 'upgrading' to earlier revision"
"microcode: CPU%d not 'upgrading' to earlier revision"
" %d (current=%d)
\n
"
,
cpu_num
,
microcode
[
i
].
rev
,
rev
);
" %d (current=%d)
\n
"
,
cpu_num
,
microcode
[
i
].
rev
,
rev
);
}
else
{
return
;
int
sum
=
0
;
}
else
if
(
microcode
[
i
].
rev
==
rev
)
{
struct
microcode
*
m
=
&
microcode
[
i
];
/* notify the caller of success on this cpu */
unsigned
int
*
sump
=
(
unsigned
int
*
)(
m
+
1
);
req
->
err
=
0
;
spin_unlock_irqrestore
(
&
microcode_update_lock
,
flags
);
printk
(
KERN_ERR
"microcode: CPU%d already at revision"
" %d (current=%d)
\n
"
,
cpu_num
,
microcode
[
i
].
rev
,
rev
);
return
;
}
/* Verify the checksum */
while
(
--
sump
>=
(
unsigned
int
*
)
m
)
while
(
--
sump
>=
(
unsigned
int
*
)
m
)
sum
+=
*
sump
;
sum
+=
*
sump
;
if
(
sum
!=
0
)
{
if
(
sum
!=
0
)
{
req
->
err
=
1
;
spin_unlock_irqrestore
(
&
microcode_update_lock
,
flags
);
printk
(
KERN_ERR
"microcode: CPU%d aborting, "
printk
(
KERN_ERR
"microcode: CPU%d aborting, "
"bad checksum
\n
"
,
cpu_num
);
"bad checksum
\n
"
,
cpu_num
);
break
;
return
;
}
}
/* write microcode via MSR 0x79 */
/* write microcode via MSR 0x79 */
...
@@ -268,20 +296,19 @@ static void do_update_one(void *unused)
...
@@ -268,20 +296,19 @@ static void do_update_one(void *unused)
/* notify the caller of success on this cpu */
/* notify the caller of success on this cpu */
req
->
err
=
0
;
req
->
err
=
0
;
req
->
slot
=
i
;
spin_unlock_irqrestore
(
&
microcode_update_lock
,
flags
);
printk
(
KERN_INFO
"microcode: CPU%d updated from revision "
printk
(
KERN_INFO
"microcode: CPU%d updated from revision "
"%d to %d, date=%08x
\n
"
,
"%d to %d, date=%08x
\n
"
,
cpu_num
,
rev
,
val
[
1
],
m
->
date
);
cpu_num
,
rev
,
val
[
1
],
microcode
[
i
].
date
);
}
return
;
break
;
}
}
if
(
!
found
)
printk
(
KERN_ERR
printk
(
KERN_ERR
"microcode: CPU%d no microcode found! (sig=%x, pflags=%d)
\n
"
,
"microcode: CPU%d no microcode found! (sig=%x, pflags=%d)
\n
"
,
cpu_num
,
sig
,
pf
);
cpu_num
,
sig
,
pf
);
}
}
static
ssize_t
microcode_read
(
struct
file
*
file
,
char
*
buf
,
size_t
len
,
loff_t
*
ppos
)
static
ssize_t
microcode_read
(
struct
file
*
file
,
char
*
buf
,
size_t
len
,
loff_t
*
ppos
)
{
{
ssize_t
ret
=
0
;
ssize_t
ret
=
0
;
...
@@ -305,11 +332,15 @@ static ssize_t microcode_write(struct file *file, const char *buf, size_t len, l
...
@@ -305,11 +332,15 @@ static ssize_t microcode_write(struct file *file, const char *buf, size_t len, l
{
{
ssize_t
ret
;
ssize_t
ret
;
if
(
len
%
sizeof
(
struct
microcode
)
!=
0
)
{
if
(
!
len
||
len
%
sizeof
(
struct
microcode
)
!=
0
)
{
printk
(
KERN_ERR
"microcode: can only write in N*%d bytes units
\n
"
,
printk
(
KERN_ERR
"microcode: can only write in N*%d bytes units
\n
"
,
sizeof
(
struct
microcode
));
sizeof
(
struct
microcode
));
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
((
len
>>
PAGE_SHIFT
)
>
num_physpages
)
{
printk
(
KERN_ERR
"microcode: too much data (max %d pages)
\n
"
,
num_physpages
);
return
-
EINVAL
;
}
down_write
(
&
microcode_rwsem
);
down_write
(
&
microcode_rwsem
);
if
(
!
mc_applied
)
{
if
(
!
mc_applied
)
{
mc_applied
=
kmalloc
(
smp_num_cpus
*
sizeof
(
struct
microcode
),
mc_applied
=
kmalloc
(
smp_num_cpus
*
sizeof
(
struct
microcode
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment