Skip to content

ras-mce-handler: store 64-bit MCE registers as INT64 - #264

Closed
agenticode wants to merge 1 commit into
mchehab:masterfrom
agenticode:mce-int64-registers
Closed

agenticode wants to merge 1 commit into
mchehab:masterfrom
agenticode:mce-int64-registers

Conversation

@agenticode

Copy link
Copy Markdown

struct mce_event has mcgcap, mcgstatus and ppin as uint64_t, but mce_record_fields[] declares those columns as DB_TYPE_INT32. sqlite3 binds them with sqlite3_bind_int(), so the top 32 bits are dropped on INSERT and the value is sign-extended on read.

ppin is the one that matters: it is a 64-bit processor serial, so two CPUs sharing the low 32 bits collide.

Injecting ppin 0x123456789abcdef0 and 0x000000009abcdef0 through ras_event_publish():

before

1|wide MCA_STATUS (VAL set)    |-1698898192|ffffffff9abcdef0
2|narrow MCA_STATUS (VAL clear)|-1698898192|ffffffff9abcdef0

after

1|wide MCA_STATUS (VAL set)    |1311768467463790320|123456789abcdef0
2|narrow MCA_STATUS (VAL clear)|2596069104         |000000009abcdef0

These three are the only columns in the tree where the bound value is wider than the column type.

No migration needed: db_sqlite3_get_sql_type() returns INTEGER for both INT32 and INT64, and the generated schema is identical before and after. MySQL/PostgreSQL get BIGINT instead of INT on new tables; existing tables are untouched since db_alter_table() only adds columns.

This is not DB_TYPE_UINT32/DB_TYPE_UINT64 from TODO item 4 - that needs a representation decision and a migration path. Fields with bit 63 set (status always has MCI_STATUS_VAL) still read back negative, but the bits are kept.

Tested on Ubuntu 26.04 (gcc 15.2) and Fedora 44 (clang 22.1):

  • meson test: 9/9 OK with both compilers, no build warnings
  • python3 tests/run.py: 140 tests, rc=0
  • scripts/checkpatch.pl --no-tree --strict: 0 errors, 0 warnings, 0 checks
  • reverting only the ras-mce-handler.c hunk fails the new check: [ ERROR ] --- -1698898192 != 1311768467463790320

mcgcap, mcgstatus and ppin are uint64_t in struct mce_event, but
mce_record_fields[] declares them as DB_TYPE_INT32. The sqlite3 backend
binds those with sqlite3_bind_int(), so the upper 32 bits are dropped on
INSERT and the value is sign-extended on read.

ppin is the one that matters: it is a 64-bit processor serial, so two
CPUs sharing the low 32 bits end up with the same value. 0x123456789abcdef0
and 0x000000009abcdef0 both read back as -1698898192.

Use DB_TYPE_INT64 for the three fields. sqlite3 maps INT32 and INT64 to
the same column type (INTEGER), so existing databases keep working with
no migration. On MySQL and PostgreSQL new tables get BIGINT instead of
INT; existing tables are untouched, as db_alter_table() only adds columns.

Extend test_mc_event_recording() to check that the MSR-backed fields
survive a round trip.

Signed-off-by: Jongwon Lee <ai@linux.com>
@mchehab

mchehab commented Sep 29, 2026

Copy link
Copy Markdown
Owner

Applied, thanks!

@mchehab mchehab closed this Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants