Skip to content

xen/arch/x86: add TPR (TXT Protected Range) DMA protection support#29

Open
accek-itl wants to merge 1 commit into
TrenchBoot:aem-staging-2026-03-13from
accek-itl:txt-tpr
Open

xen/arch/x86: add TPR (TXT Protected Range) DMA protection support#29
accek-itl wants to merge 1 commit into
TrenchBoot:aem-staging-2026-03-13from
accek-itl:txt-tpr

Conversation

@accek-itl
Copy link
Copy Markdown

Assisted-by: Claude:claude-opus-4-6

@macpijan macpijan requested a review from SergiiDmytruk April 30, 2026 09:39
* Find the TPR request element in the TXT heap extended data.
*/
static inline const struct txt_heap_tpr_req_element *
txt_find_tpr_req_element(const struct txt_os_sinit_data *os_sinit)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you'll make this function take data element type as a parameter, it will be possible to reuse the function in tpm.c which is the only other place that searches for a data element.

P.S. Looks like tpm.c is actually doing it wrong: it interprets size relative to the data field which matches the comment on txt_ext_data_element in this file but contradicts the SDM. So it shouldn't actually work there and likely doesn't.

{
const struct txt_heap_tpr_req_element *tpr_req;

tpr_req = txt_find_tpr_req_element(os_sinit);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment that txt_verify_dma_protection() has already validated presence and contents of the element.


tpr_req = txt_find_tpr_req_element(os_sinit);
lo_size = tpr_req->ranges[0].base + tpr_req->ranges[0].size;
if ( tpr_req->count >= 2 )
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ( tpr_req->count >= 2 )
if ( tpr_req->count == 2 )

or

Suggested change
if ( tpr_req->count >= 2 )
if ( tpr_req->count > 1 )

* txt_verify_pmr_ranges() makes sure the low range always starts at 0, so
* its size is also end address.
* txt_verify_dma_protection() makes sure the low range always starts at
* 0, so its size is also end address.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should be in the else-branch above and the variable name should be lo_end instead of lo_size to make sense for both branches.

0x100000000ULL )
txt_reset(SLAUNCH_ERROR_TPR_INVALID);

if ( tpr_req->count >= 2 )
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ( tpr_req->count >= 2 )
if ( tpr_req->count == 2 )

or

Suggested change
if ( tpr_req->count >= 2 )
if ( tpr_req->count > 1 )

* 0, so its size is also end address.
*/
if ( base + size <= os_sinit->vtd_pmr_lo_size )
if ( base + size <= lo_size )
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check makes sense only if lo_base is guaranteed to be zero. But it can't be with TPR due to overlaps with MMIO or something else, right? Then need to check lower bound too.

Comment thread xen/arch/x86/boot/head.S
.long 0x42b651cb /* UUID3 */
.long (.Lmle_header_end - mle_header) /* MLE header size */
.long 0x00020002 /* MLE version 2.2 */
.long 0x00020003 /* MLE version 2.3 */
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope this won't cause older SINITs to refuse processing this MLE.

Comment on lines +460 to +461
if ( tpr_req->ranges[1].base + tpr_req->ranges[1].size <=
0x100000000ULL )
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/* Hi range must start at or above 4G. */ check above leaves no chance for this condition to be true unless an integer overflow occurs.

Speaking of integer overflows, PMR code checks for them.

if ( tpr_req->count > 2 )
txt_reset(SLAUNCH_ERROR_TPR_UNSUPPORTED);

/* Lo range must not exceed 4G. */
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* Lo range must not exceed 4G. */
/* Low range must not exceed 4G. */

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.

3 participants