Skip to content

Commit dd575a7

Browse files
authored
Add support for reading CCEL EventLogs from devmem (#288)
* Add support for reading CCEL EventLogs from devmem "ACPI sysfs support for CCEL records" [1] is merged in linux kernel since v6.4, and some old kernels may not have the sysfs feature. Parse the CCEL EventLogs' physics address and length from the raw ACPI table and read the EventLog from /dev/mem to faclitate old kernels. Signed-off-by: GuoRui.Yu <[email protected]> [1] torvalds/linux@4f855dc * Make tdx_{eventlogs,extend_rtmr,tdreport,verify_rtmr} executable Signed-off-by: GuoRui.Yu <[email protected]> --------- Signed-off-by: GuoRui.Yu <[email protected]> Co-authored-by: GuoRui.Yu <[email protected]>
1 parent 4aca092 commit dd575a7

File tree

5 files changed

+58
-2
lines changed

5 files changed

+58
-2
lines changed

utilities/tdx/pytdxmeasure/pytdxmeasure/actor.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import os
66
import logging
7+
import struct
78
from typing import Dict, List
89
from hashlib import sha384
910

@@ -89,8 +90,7 @@ def __init__(self, base, length):
8990
self._event_logs = []
9091
self._rtmrs = {}
9192

92-
def _read(self, ccel_file="/sys/firmware/acpi/tables/data/CCEL"):
93-
assert os.path.exists(ccel_file), f"Could not find the CCEL file {ccel_file}"
93+
def _read_direct(self, ccel_file):
9494
try:
9595
with open(ccel_file, "rb") as fobj:
9696
self._data = fobj.read()
@@ -100,6 +100,62 @@ def _read(self, ccel_file="/sys/firmware/acpi/tables/data/CCEL"):
100100
LOG.error("Need root permission to open file %s", ccel_file)
101101
return None
102102

103+
def _read_from_devmem(self, acpi_file):
104+
try:
105+
with open(acpi_file, "rb") as fobj:
106+
acpi_data = fobj.read()
107+
assert len(acpi_data) > 0
108+
109+
# typedef struct {
110+
# UINT32 Signature;
111+
# UINT32 Length;
112+
# UINT8 Revision;
113+
# UINT8 Checksum;
114+
# UINT8 OemId[6];
115+
# UINT64 OemTableId;
116+
# UINT32 OemRevision;
117+
# UINT32 CreatorId;
118+
# UINT32 CreatorRevision;
119+
# } EFI_ACPI_DESCRIPTION_HEADER;
120+
121+
# typedef struct {
122+
# EFI_ACPI_DESCRIPTION_HEADER Header;
123+
# UINT32 Rsv; // default to 0
124+
# UINT64 Laml; // Optional
125+
# UINT64 Lasa;
126+
# } TDX_Event_Log_ACPI_Table;
127+
128+
# Read the CCEL table from the /sys/firmware/acpi/tables/CCEL
129+
struct_fmt = "<4sI2B6sQ4IQQ"
130+
ccel_acpi_table = struct.unpack(struct_fmt, acpi_data[:struct.calcsize(struct_fmt)])
131+
(
132+
signature, length, revision, checksum, oem_id, oem_table_id, oem_revision,
133+
creator_id, creator_revision,
134+
rsv, laml, lasa
135+
) = ccel_acpi_table
136+
137+
assert signature == b'CCEL', "Invalid CCEL ACPI table"
138+
assert length == len(acpi_data), "Invalid CCEL ACPI table"
139+
assert rsv == 0, "Invalid CCEL ACPI table"
140+
141+
with open("/dev/mem", "rb") as fobj:
142+
fobj.seek(lasa)
143+
self._data = fobj.read(laml)
144+
assert len(self._data) > 0
145+
return self._data
146+
147+
except (PermissionError, OSError):
148+
LOG.error("Need root permission to open file %s", acpi_file)
149+
return None
150+
151+
def _read(self, ccel_file="/sys/firmware/acpi/tables/data/CCEL", acpi_file="/sys/firmware/acpi/tables/CCEL"):
152+
assert os.path.exists(ccel_file) or os.path.exists(acpi_file), f"Could not find the CCEL file and CCEL ACPI table"
153+
154+
if os.path.exists(ccel_file):
155+
return self._read_direct(ccel_file)
156+
else:
157+
return self._read_from_devmem(acpi_file)
158+
103159
@staticmethod
104160
def _replay_single_rtmr(event_logs: List[TDEventLogEntry]) -> RTMR:
105161
rtmr = bytearray(RTMR.RTMR_LENGTH_BY_BYTES)

utilities/tdx/pytdxmeasure/tdx_eventlogs

100644100755
File mode changed.

utilities/tdx/pytdxmeasure/tdx_extend_rtmr

100644100755
File mode changed.

utilities/tdx/pytdxmeasure/tdx_tdreport

100644100755
File mode changed.

utilities/tdx/pytdxmeasure/tdx_verify_rtmr

100644100755
File mode changed.

0 commit comments

Comments
 (0)