mirror of
https://github.com/speed47/spectre-meltdown-checker
synced 2024-12-22 20:33:56 +01:00
Check MSR in each CPU/Thread (#136)
This commit is contained in:
parent
12ea49fe0c
commit
ecdc448531
@ -1059,6 +1059,38 @@ sys_interface_check()
|
||||
return 0
|
||||
}
|
||||
|
||||
number_of_cpus()
|
||||
{
|
||||
n=$(grep -c ^processor /proc/cpuinfo)
|
||||
return "$n"
|
||||
}
|
||||
|
||||
# $1 - msr number
|
||||
# $2 - cpu index
|
||||
check_msr_enable()
|
||||
{
|
||||
dd if=/dev/cpu/"$2"/msr of=/dev/null bs=8 count=1 skip="$1" iflag=skip_bytes 2>/dev/null; ret=$?
|
||||
return $ret
|
||||
}
|
||||
|
||||
# $1 - msr number
|
||||
# $2 - cpu index
|
||||
# $3 - value
|
||||
write_to_msr()
|
||||
{
|
||||
$echo_cmd -ne "$3" | dd of=/dev/cpu/"$2"/msr bs=8 count=1 seek="$1" oflag=seek_bytes 2>/dev/null; ret=$?
|
||||
return $ret
|
||||
}
|
||||
|
||||
# $1 - msr number
|
||||
# $2 - cpu index
|
||||
read_msr()
|
||||
{
|
||||
msr=$(dd if=/dev/cpu/"$2"/msr bs=8 count=1 skip="$1" iflag=skip_bytes 2>/dev/null | od -t u1 -A n | awk '{print $8}');
|
||||
return "$msr"
|
||||
}
|
||||
|
||||
|
||||
check_cpu()
|
||||
{
|
||||
_info "\033[1;34mHardware check\033[0m"
|
||||
@ -1066,6 +1098,9 @@ check_cpu()
|
||||
_info "* Hardware support (CPU microcode) for mitigation techniques"
|
||||
_info " * Indirect Branch Restricted Speculation (IBRS)"
|
||||
_info_nol " * SPEC_CTRL MSR is available: "
|
||||
number_of_cpus
|
||||
ncpus=$?
|
||||
idx_max_cpu=$((ncpus-1))
|
||||
if [ ! -e /dev/cpu/0/msr ]; then
|
||||
# try to load the module ourselves (and remember it so we can rmmod it afterwards)
|
||||
load_msr
|
||||
@ -1078,10 +1113,30 @@ check_cpu()
|
||||
# here we use dd, it's the same as using 'rdmsr 0x48' but without needing the rdmsr tool
|
||||
# if we get a read error, the MSR is not there. bs has to be 8 for msr
|
||||
# skip=9 because 8*9=72=0x48
|
||||
dd if=/dev/cpu/0/msr of=/dev/null bs=8 count=1 skip=9 2>/dev/null; ret=$?
|
||||
if [ $ret -eq 0 ]; then
|
||||
val=0
|
||||
cpu_mismatch=0
|
||||
for i in $(seq 0 "$idx_max_cpu")
|
||||
do
|
||||
check_msr_enable 72 "$i"
|
||||
ret=$?
|
||||
if [ "$i" -eq 0 ]; then
|
||||
val=$ret
|
||||
else
|
||||
if [ "$ret" -eq $val ]; then
|
||||
continue
|
||||
else
|
||||
cpu_mismatch=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ $val -eq 0 ]; then
|
||||
if [ $cpu_mismatch -eq 0 ]; then
|
||||
spec_ctrl_msr=1
|
||||
pstatus green YES
|
||||
else
|
||||
spec_ctrl_msr=1
|
||||
pstatus green YES "But not in all CPUs"
|
||||
fi
|
||||
else
|
||||
spec_ctrl_msr=0
|
||||
pstatus red NO
|
||||
@ -1126,15 +1181,34 @@ check_cpu()
|
||||
# the new MSR 'PRED_CTRL' is at offset 0x49, write-only
|
||||
# here we use dd, it's the same as using 'wrmsr 0x49 0' but without needing the wrmsr tool
|
||||
# if we get a write error, the MSR is not there
|
||||
$echo_cmd -ne "\0\0\0\0\0\0\0\0" | dd of=/dev/cpu/0/msr bs=8 count=1 seek=73 oflag=seek_bytes 2>/dev/null; ret=$?
|
||||
if [ $ret -eq 0 ]; then
|
||||
val=0
|
||||
cpu_mismatch=0
|
||||
for i in $(seq 0 "$idx_max_cpu")
|
||||
do
|
||||
write_to_msr 73 "$i" "\0\0\0\0\0\0\0\0"
|
||||
ret=$?
|
||||
if [ "$i" -eq 0 ]; then
|
||||
val=$ret
|
||||
else
|
||||
if [ "$ret" -eq $val ]; then
|
||||
continue
|
||||
else
|
||||
cpu_mismatch=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $val -eq 0 ]; then
|
||||
if [ $cpu_mismatch -eq 0 ]; then
|
||||
pstatus green YES
|
||||
else
|
||||
pstatus green YES "But not in all CPUs"
|
||||
fi
|
||||
else
|
||||
pstatus red NO
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
_info_nol " * CPU indicates IBPB capability: "
|
||||
# CPUID EAX=0x80000008, ECX=0x00 return EBX[12] indicates support for just IBPB.
|
||||
read_cpuid 2147483656 5 16; ret=$?
|
||||
@ -1201,16 +1275,40 @@ check_cpu()
|
||||
# the new MSR 'ARCH_CAPABILITIES' is at offset 0x10a
|
||||
# here we use dd, it's the same as using 'rdmsr 0x10a' but without needing the rdmsr tool
|
||||
# if we get a read error, the MSR is not there. bs has to be 8 for msr
|
||||
capabilities=$(dd if=/dev/cpu/0/msr bs=8 count=1 skip=266 iflag=skip_bytes 2>/dev/null | od -t u1 -A n | awk '{print $8}'); ret=$?
|
||||
val=0
|
||||
val_cap_msr=0
|
||||
cpu_mismatch=0
|
||||
for i in $(seq 0 "$idx_max_cpu")
|
||||
do
|
||||
check_msr_enable 266 "$i"
|
||||
ret=$?
|
||||
read_msr 266 "$i"
|
||||
capabilities=$?
|
||||
if [ "$i" -eq 0 ]; then
|
||||
val=$ret
|
||||
val_cap_msr=$capabilities
|
||||
else
|
||||
if [ "$ret" -eq "$val" -a "$capabilities" -eq "$val_cap_msr" ]; then
|
||||
continue
|
||||
else
|
||||
cpu_mismatch=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
capabilities=$val_cap_msr
|
||||
capabilities_rdcl_no=0
|
||||
capabilities_ibrs_all=0
|
||||
if [ $ret -eq 0 ]; then
|
||||
if [ $val -eq 0 ]; then
|
||||
_debug "capabilities MSR lower byte is $capabilities (decimal)"
|
||||
[ $(( capabilities & 1 )) -eq 1 ] && capabilities_rdcl_no=1
|
||||
[ $(( capabilities & 2 )) -eq 2 ] && capabilities_ibrs_all=1
|
||||
_debug "capabilities says rdcl_no=$capabilities_rdcl_no ibrs_all=$capabilities_ibrs_all"
|
||||
if [ "$capabilities_ibrs_all" = 1 ]; then
|
||||
if [ $cpu_mismatch -eq 0 ]; then
|
||||
pstatus green YES
|
||||
else:
|
||||
pstatus green YES "But not in all CPUs"
|
||||
fi
|
||||
else
|
||||
pstatus red NO
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user