Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

acpi_tables: Fix VIOT endpoint_id remapping #34

Merged
merged 1 commit into from
Mar 26, 2024

Conversation

tjeznach
Copy link
Contributor

Summary of the PR

For non-zero segment remappings defined in ACPI VIOT data structures it's very likely that target endpoint namespace will start at 0, without requester segment number encoded in the translation request.
This change updates default VIOT endpoint_id generation - starting point of the translated identifiers, to ignore requester segment number.

@@ -188,7 +188,7 @@ impl Aml for PciRange {
sink.byte(ViotEntryType::PciRange as u8);
sink.byte(0); // reserved
sink.word(Self::len() as u16);
sink.dword(self.first.as_endpoint());
sink.dword(self.first.as_bdf() as u32);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Based on the ACPI spec, and particularly the section about the PCI range node structure here, the Endpoint Start is the first Endpoint ID, and an Endpoint ID is described as follows:

The corresponding endpoint ID is obtained by combining segment and BDF:
Endpoint ID = ((segment - Segment Start) << 16) + BDF - BDF Start + Endpoint Start

I'm a bit confused because what does Endpoint Start stand for in this formula? And if we substract both the Segment Start and BDF Start, does that mean we end up with the endpoint ID being a simple index corresponding to Endpoint Start?

My point is, I think you're patching this in the right direction but we're still missing the BDF substraction. Should we simply always hardcode the Endpoint Start as 0?

/cc @timw-rivos @rbradford

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think 99% of the time Endpoint Start will likely be 0, but the "correct" thing to do is to probably use the corresponding formula from the spec

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For most simple mappings Endpoint Start this will be 0, however for more complex mappings in the IOMMU range assuming the most common case (unity mapping in the segment) Endpoint Start should represent First BDF in the range. This change will provide simple unity mapping for non-contiguous PCI ranges, without adding segment number.
Eg. Mapping example for single IOMMU handle:

0001:00:01.0 - 0000:01.7  --> 0x008
0001:00:06.0 - 0000:06.7  --> 0x030

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for clarifying @tjeznach
It's a bit of a shame the ACPI spec isn't clear on that aspect, but I believe you've looked into the Linux implementation of the VIOT table, which is the "actual" spec :)

sboeuf
sboeuf previously approved these changes Mar 26, 2024
@sboeuf
Copy link
Collaborator

sboeuf commented Mar 26, 2024

@rbradford CI is failing on clippy, is that something you want to fix or should we merge anyway?

For non-zero segment remappings it's very likely that target
endpoint identifiers namespace will start at 0, without requester
segment number encoded in the translation request.

Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
@rbradford
Copy link
Collaborator

It's only failing on beta - we can fix this in a separate PR.

@rbradford rbradford merged commit ca1a473 into rust-vmm:main Mar 26, 2024
10 of 14 checks passed
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.

4 participants