mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2026-04-01 12:47:07 +02:00
fix: rework read_msr for values > INT32_MAX (#507)
This commit is contained in:
@@ -155,7 +155,7 @@ readonly READ_MSR_RET_KO=1
|
|||||||
readonly READ_MSR_RET_ERR=2
|
readonly READ_MSR_RET_ERR=2
|
||||||
# Read an MSR register value across one or all cores
|
# Read an MSR register value across one or all cores
|
||||||
# Args: $1=msr_address $2=cpu_index(optional, default 0)
|
# Args: $1=msr_address $2=cpu_index(optional, default 0)
|
||||||
# Sets: ret_read_msr_value, ret_read_msr_msg
|
# Sets: ret_read_msr_value, ret_read_msr_value_hi, ret_read_msr_value_lo, ret_read_msr_msg
|
||||||
# Returns: READ_MSR_RET_OK | READ_MSR_RET_KO | READ_MSR_RET_ERR
|
# Returns: READ_MSR_RET_OK | READ_MSR_RET_KO | READ_MSR_RET_ERR
|
||||||
read_msr() {
|
read_msr() {
|
||||||
local ret core first_core_ret first_core_value
|
local ret core first_core_ret first_core_value
|
||||||
@@ -187,21 +187,31 @@ read_msr() {
|
|||||||
|
|
||||||
# Read an MSR register value from a single CPU core
|
# Read an MSR register value from a single CPU core
|
||||||
# Args: $1=core $2=msr_address
|
# Args: $1=core $2=msr_address
|
||||||
# Sets: ret_read_msr_value, ret_read_msr_msg
|
# Sets: ret_read_msr_value, ret_read_msr_value_hi, ret_read_msr_value_lo, ret_read_msr_msg
|
||||||
# Returns: READ_MSR_RET_OK | READ_MSR_RET_KO | READ_MSR_RET_ERR
|
# Returns: READ_MSR_RET_OK | READ_MSR_RET_KO | READ_MSR_RET_ERR
|
||||||
read_msr_one_core() {
|
read_msr_one_core() {
|
||||||
local ret core msr msr_dec mockvarname msr_h msr_l
|
local ret core msr msr_dec mockvarname msr_h msr_l mockval
|
||||||
core="$1"
|
core="$1"
|
||||||
msr_dec=$(($2))
|
msr_dec=$(($2))
|
||||||
msr=$(printf "0x%x" "$msr_dec")
|
msr=$(printf "0x%x" "$msr_dec")
|
||||||
|
|
||||||
ret_read_msr_value=''
|
ret_read_msr_value=''
|
||||||
|
ret_read_msr_value_hi=''
|
||||||
|
ret_read_msr_value_lo=''
|
||||||
ret_read_msr_msg='unknown error'
|
ret_read_msr_msg='unknown error'
|
||||||
|
|
||||||
mockvarname="SMC_MOCK_RDMSR_${msr}"
|
mockvarname="SMC_MOCK_RDMSR_${msr}"
|
||||||
# shellcheck disable=SC2086,SC1083
|
# shellcheck disable=SC2086,SC1083
|
||||||
if [ -n "$(eval echo \${$mockvarname:-})" ]; then
|
if [ -n "$(eval echo \${$mockvarname:-})" ]; then
|
||||||
ret_read_msr_value="$(eval echo \$$mockvarname)"
|
mockval="$(eval echo \$$mockvarname)"
|
||||||
|
# accept both legacy decimal (small values) and new 16-char hex format
|
||||||
|
if [ "${#mockval}" -eq 16 ]; then
|
||||||
|
ret_read_msr_value="$mockval"
|
||||||
|
else
|
||||||
|
ret_read_msr_value=$(printf '%016x' "$mockval")
|
||||||
|
fi
|
||||||
|
ret_read_msr_value_hi=$((0x${ret_read_msr_value%????????}))
|
||||||
|
ret_read_msr_value_lo=$((0x${ret_read_msr_value#????????}))
|
||||||
pr_debug "read_msr: MOCKING enabled for msr $msr, returning $ret_read_msr_value"
|
pr_debug "read_msr: MOCKING enabled for msr $msr, returning $ret_read_msr_value"
|
||||||
g_mocked=1
|
g_mocked=1
|
||||||
return $READ_MSR_RET_OK
|
return $READ_MSR_RET_OK
|
||||||
@@ -235,7 +245,7 @@ read_msr_one_core() {
|
|||||||
# MSR 0x10: 0x000003e1 0xb106dded
|
# MSR 0x10: 0x000003e1 0xb106dded
|
||||||
msr_h=$(echo "$msr" | awk '{print $3}')
|
msr_h=$(echo "$msr" | awk '{print $3}')
|
||||||
msr_l=$(echo "$msr" | awk '{print $4}')
|
msr_l=$(echo "$msr" | awk '{print $4}')
|
||||||
ret_read_msr_value=$((msr_h << 32 | msr_l))
|
ret_read_msr_value=$(printf '%08x%08x' "$((msr_h))" "$((msr_l))")
|
||||||
else
|
else
|
||||||
# for Linux
|
# for Linux
|
||||||
if [ ! -r $CPU_DEV_BASE/"$core"/msr ]; then
|
if [ ! -r $CPU_DEV_BASE/"$core"/msr ]; then
|
||||||
@@ -245,15 +255,15 @@ read_msr_one_core() {
|
|||||||
# if rdmsr is available, use it
|
# if rdmsr is available, use it
|
||||||
elif command -v rdmsr >/dev/null 2>&1 && [ "${SMC_NO_RDMSR:-}" != 1 ]; then
|
elif command -v rdmsr >/dev/null 2>&1 && [ "${SMC_NO_RDMSR:-}" != 1 ]; then
|
||||||
pr_debug "read_msr: using rdmsr on $msr"
|
pr_debug "read_msr: using rdmsr on $msr"
|
||||||
ret_read_msr_value=$(rdmsr -r $msr_dec 2>/dev/null | od -t u8 -A n)
|
ret_read_msr_value=$(rdmsr -r $msr_dec 2>/dev/null | od -A n -t x8)
|
||||||
# or if we have perl, use it, any 5.x version will work
|
# or if we have perl, use it, any 5.x version will work
|
||||||
elif command -v perl >/dev/null 2>&1 && [ "${SMC_NO_PERL:-}" != 1 ]; then
|
elif command -v perl >/dev/null 2>&1 && [ "${SMC_NO_PERL:-}" != 1 ]; then
|
||||||
pr_debug "read_msr: using perl on $msr"
|
pr_debug "read_msr: using perl on $msr"
|
||||||
ret_read_msr_value=$(perl -e "open(M,'<','$CPU_DEV_BASE/$core/msr') and seek(M,$msr_dec,0) and read(M,\$_,8) and print" | od -t u8 -A n)
|
ret_read_msr_value=$(perl -e "open(M,'<','$CPU_DEV_BASE/$core/msr') and seek(M,$msr_dec,0) and read(M,\$_,8) and print" | od -A n -t x8)
|
||||||
# fallback to dd if it supports skip_bytes
|
# fallback to dd if it supports skip_bytes
|
||||||
elif dd if=/dev/null of=/dev/null bs=8 count=1 skip="$msr_dec" iflag=skip_bytes 2>/dev/null; then
|
elif dd if=/dev/null of=/dev/null bs=8 count=1 skip="$msr_dec" iflag=skip_bytes 2>/dev/null; then
|
||||||
pr_debug "read_msr: using dd on $msr"
|
pr_debug "read_msr: using dd on $msr"
|
||||||
ret_read_msr_value=$(dd if=$CPU_DEV_BASE/"$core"/msr bs=8 count=1 skip="$msr_dec" iflag=skip_bytes 2>/dev/null | od -t u8 -A n)
|
ret_read_msr_value=$(dd if=$CPU_DEV_BASE/"$core"/msr bs=8 count=1 skip="$msr_dec" iflag=skip_bytes 2>/dev/null | od -A n -t x8)
|
||||||
else
|
else
|
||||||
pr_debug "read_msr: got no rdmsr, perl or recent enough dd!"
|
pr_debug "read_msr: got no rdmsr, perl or recent enough dd!"
|
||||||
g_mockme=$(printf "%b\n%b" "$g_mockme" "SMC_MOCK_RDMSR_${msr}_RET=$READ_MSR_RET_ERR")
|
g_mockme=$(printf "%b\n%b" "$g_mockme" "SMC_MOCK_RDMSR_${msr}_RET=$READ_MSR_RET_ERR")
|
||||||
@@ -266,8 +276,10 @@ read_msr_one_core() {
|
|||||||
return $READ_MSR_RET_KO
|
return $READ_MSR_RET_KO
|
||||||
fi
|
fi
|
||||||
# remove sparse spaces od might give us
|
# remove sparse spaces od might give us
|
||||||
ret_read_msr_value=$((ret_read_msr_value))
|
ret_read_msr_value=$(printf '%s' "$ret_read_msr_value" | tr -d ' \t\n' | tr '[:upper:]' '[:lower:]')
|
||||||
fi
|
fi
|
||||||
|
ret_read_msr_value_hi=$((0x${ret_read_msr_value%????????}))
|
||||||
|
ret_read_msr_value_lo=$((0x${ret_read_msr_value#????????}))
|
||||||
g_mockme=$(printf "%b\n%b" "$g_mockme" "SMC_MOCK_RDMSR_${msr}='$ret_read_msr_value'")
|
g_mockme=$(printf "%b\n%b" "$g_mockme" "SMC_MOCK_RDMSR_${msr}='$ret_read_msr_value'")
|
||||||
pr_debug "read_msr: MSR=$msr value is $ret_read_msr_value"
|
pr_debug "read_msr: MSR=$msr value is $ret_read_msr_value"
|
||||||
return $READ_MSR_RET_OK
|
return $READ_MSR_RET_OK
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ parse_cpu_details() {
|
|||||||
read_msr 0x17
|
read_msr 0x17
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ $ret = $READ_MSR_RET_OK ]; then
|
if [ $ret = $READ_MSR_RET_OK ]; then
|
||||||
cpu_platformid=$((1 << ((ret_read_msr_value >> 18) & 7)))
|
# platform ID (bits 52:50) = bits 18:20 of the upper 32-bit word
|
||||||
|
cpu_platformid=$((1 << ((ret_read_msr_value_hi >> 18) & 7)))
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -768,18 +768,18 @@ check_cpu() {
|
|||||||
if [ $ret = $READ_MSR_RET_OK ]; then
|
if [ $ret = $READ_MSR_RET_OK ]; then
|
||||||
capabilities=$ret_read_msr_value
|
capabilities=$ret_read_msr_value
|
||||||
# https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/x86/include/asm/msr-index.h#n82
|
# https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/x86/include/asm/msr-index.h#n82
|
||||||
pr_debug "capabilities MSR is $capabilities (decimal)"
|
pr_debug "capabilities MSR is $capabilities (hex)"
|
||||||
[ $((capabilities >> 0 & 1)) -eq 1 ] && cap_rdcl_no=1
|
[ $(( ret_read_msr_value_lo >> 0 & 1 )) -eq 1 ] && cap_rdcl_no=1
|
||||||
[ $((capabilities >> 1 & 1)) -eq 1 ] && cap_ibrs_all=1
|
[ $(( ret_read_msr_value_lo >> 1 & 1 )) -eq 1 ] && cap_ibrs_all=1
|
||||||
[ $((capabilities >> 2 & 1)) -eq 1 ] && cap_rsba=1
|
[ $(( ret_read_msr_value_lo >> 2 & 1 )) -eq 1 ] && cap_rsba=1
|
||||||
[ $((capabilities >> 3 & 1)) -eq 1 ] && cap_l1dflush_no=1
|
[ $(( ret_read_msr_value_lo >> 3 & 1 )) -eq 1 ] && cap_l1dflush_no=1
|
||||||
[ $((capabilities >> 4 & 1)) -eq 1 ] && cap_ssb_no=1
|
[ $(( ret_read_msr_value_lo >> 4 & 1 )) -eq 1 ] && cap_ssb_no=1
|
||||||
[ $((capabilities >> 5 & 1)) -eq 1 ] && cap_mds_no=1
|
[ $(( ret_read_msr_value_lo >> 5 & 1 )) -eq 1 ] && cap_mds_no=1
|
||||||
[ $((capabilities >> 6 & 1)) -eq 1 ] && cap_pschange_msc_no=1
|
[ $(( ret_read_msr_value_lo >> 6 & 1 )) -eq 1 ] && cap_pschange_msc_no=1
|
||||||
[ $((capabilities >> 7 & 1)) -eq 1 ] && cap_tsx_ctrl_msr=1
|
[ $(( ret_read_msr_value_lo >> 7 & 1 )) -eq 1 ] && cap_tsx_ctrl_msr=1
|
||||||
[ $((capabilities >> 8 & 1)) -eq 1 ] && cap_taa_no=1
|
[ $(( ret_read_msr_value_lo >> 8 & 1 )) -eq 1 ] && cap_taa_no=1
|
||||||
[ $((capabilities >> 25 & 1)) -eq 1 ] && cap_gds_ctrl=1
|
[ $(( ret_read_msr_value_lo >> 25 & 1 )) -eq 1 ] && cap_gds_ctrl=1
|
||||||
[ $((capabilities >> 26 & 1)) -eq 1 ] && cap_gds_no=1
|
[ $(( ret_read_msr_value_lo >> 26 & 1 )) -eq 1 ] && cap_gds_no=1
|
||||||
pr_debug "capabilities says rdcl_no=$cap_rdcl_no ibrs_all=$cap_ibrs_all rsba=$cap_rsba l1dflush_no=$cap_l1dflush_no ssb_no=$cap_ssb_no mds_no=$cap_mds_no taa_no=$cap_taa_no pschange_msc_no=$cap_pschange_msc_no"
|
pr_debug "capabilities says rdcl_no=$cap_rdcl_no ibrs_all=$cap_ibrs_all rsba=$cap_rsba l1dflush_no=$cap_l1dflush_no ssb_no=$cap_ssb_no mds_no=$cap_mds_no taa_no=$cap_taa_no pschange_msc_no=$cap_pschange_msc_no"
|
||||||
if [ "$cap_ibrs_all" = 1 ]; then
|
if [ "$cap_ibrs_all" = 1 ]; then
|
||||||
pstatus green YES
|
pstatus green YES
|
||||||
@@ -869,9 +869,8 @@ check_cpu() {
|
|||||||
read_msr 0x122
|
read_msr 0x122
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ "$ret" = $READ_MSR_RET_OK ]; then
|
if [ "$ret" = $READ_MSR_RET_OK ]; then
|
||||||
g_tsx_ctrl_msr=$ret_read_msr_value
|
cap_tsx_ctrl_rtm_disable=$(( ret_read_msr_value_lo >> 0 & 1 ))
|
||||||
cap_tsx_ctrl_rtm_disable=$((g_tsx_ctrl_msr >> 0 & 1))
|
cap_tsx_ctrl_cpuid_clear=$(( ret_read_msr_value_lo >> 1 & 1 ))
|
||||||
cap_tsx_ctrl_cpuid_clear=$((g_tsx_ctrl_msr >> 1 & 1))
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pr_info_nol " * TSX_CTRL MSR indicates TSX RTM is disabled: "
|
pr_info_nol " * TSX_CTRL MSR indicates TSX RTM is disabled: "
|
||||||
@@ -909,9 +908,8 @@ check_cpu() {
|
|||||||
read_msr 0x123
|
read_msr 0x123
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ "$ret" = $READ_MSR_RET_OK ]; then
|
if [ "$ret" = $READ_MSR_RET_OK ]; then
|
||||||
g_mcu_opt_ctrl=$ret_read_msr_value
|
cap_gds_mitg_dis=$(( ret_read_msr_value_lo >> 4 & 1 ))
|
||||||
cap_gds_mitg_dis=$((g_mcu_opt_ctrl >> 4 & 1))
|
cap_gds_mitg_lock=$(( ret_read_msr_value_lo >> 5 & 1 ))
|
||||||
cap_gds_mitg_lock=$((g_mcu_opt_ctrl >> 5 & 1))
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pr_info_nol " * GDS microcode mitigation is disabled (GDS_MITG_DIS): "
|
pr_info_nol " * GDS microcode mitigation is disabled (GDS_MITG_DIS): "
|
||||||
@@ -1018,7 +1016,7 @@ check_cpu() {
|
|||||||
read_msr 0x123
|
read_msr 0x123
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ $ret = $READ_MSR_RET_OK ]; then
|
if [ $ret = $READ_MSR_RET_OK ]; then
|
||||||
if [ "$ret_read_msr_value" = 0 ]; then
|
if [ "$ret_read_msr_value" = "0000000000000000" ]; then
|
||||||
#SRBDS mitigation control exists and is enabled via microcode
|
#SRBDS mitigation control exists and is enabled via microcode
|
||||||
cap_srbds_on=1
|
cap_srbds_on=1
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ check_CVE_2023_20593_linux() {
|
|||||||
read_msr 0xc0011029
|
read_msr 0xc0011029
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ "$ret" = "$READ_MSR_RET_OK" ]; then
|
if [ "$ret" = "$READ_MSR_RET_OK" ]; then
|
||||||
if [ $((ret_read_msr_value >> 9 & 1)) -eq 1 ]; then
|
if [ $(( ret_read_msr_value_lo >> 9 & 1 )) -eq 1 ]; then
|
||||||
pstatus green YES "FP_BACKUP_FIX bit set in DE_CFG"
|
pstatus green YES "FP_BACKUP_FIX bit set in DE_CFG"
|
||||||
fp_backup_fix=1
|
fp_backup_fix=1
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user