xen/arch/x86: add TPR (TXT Protected Range) DMA protection support#29
xen/arch/x86: add TPR (TXT Protected Range) DMA protection support#29accek-itl wants to merge 1 commit into
Conversation
Assisted-by: Claude:claude-opus-4-6
| * 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) |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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 ) |
There was a problem hiding this comment.
| if ( tpr_req->count >= 2 ) | |
| if ( tpr_req->count == 2 ) |
or
| 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. |
There was a problem hiding this comment.
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 ) |
There was a problem hiding this comment.
| if ( tpr_req->count >= 2 ) | |
| if ( tpr_req->count == 2 ) |
or
| 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 ) |
There was a problem hiding this comment.
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.
| .long 0x42b651cb /* UUID3 */ | ||
| .long (.Lmle_header_end - mle_header) /* MLE header size */ | ||
| .long 0x00020002 /* MLE version 2.2 */ | ||
| .long 0x00020003 /* MLE version 2.3 */ |
There was a problem hiding this comment.
I hope this won't cause older SINITs to refuse processing this MLE.
| if ( tpr_req->ranges[1].base + tpr_req->ranges[1].size <= | ||
| 0x100000000ULL ) |
There was a problem hiding this comment.
/* 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. */ |
There was a problem hiding this comment.
| /* Lo range must not exceed 4G. */ | |
| /* Low range must not exceed 4G. */ |
Assisted-by: Claude:claude-opus-4-6