Implement memory management and mapping functions for PCI Root bridge io protocols#1724
Implement memory management and mapping functions for PCI Root bridge io protocols#1724tmvkrpxl0 wants to merge 3 commits intorust-osdev:mainfrom
Conversation
|
|
||
| impl Drop for PciMappedRegion<'_, '_> { | ||
| fn drop(&mut self) { | ||
| let status = unsafe { (self.proto.unmap)(self.proto, self.key) }; |
There was a problem hiding this comment.
Would it make sense to add a fn unmap(self) -> Result method, so that callers can choose to handle errors from unmapping? The Drop trait doesn't really allow that. I think the drop implementation should probably not panic on errors, and that we should remove the unreachable; UEFI implementations sometimes return additional errors beyond what the spec includes.
Ditto for the PciPage implementation.
There was a problem hiding this comment.
True, I initially put unreachable macro there to indicate that "errors that may happen according to spec are all handled and no other error can occur"
But yeah second thought we can never be sure
There was a problem hiding this comment.
Tho, what else should it do when an error occurs? Should I make it undroppable(assuming it's possible) so that users must use functions like unmap?
There was a problem hiding this comment.
There's no way to make something undroppable in Rust, unfortunately. There are two options:
- A 'drop bomb', i.e. panic unconditionally in
dropifunmapwasn't called. The documentation should strongly remind the user thatunmapmust be called. - Handle errors in drop by ignoring them (or log them and otherwise ignore). The documentation can encourage users to call
unmapfor better error handling, but it's not required. This is whatFiledoes, for example; it suggests callingsync_allbeforedropif you want to handle errors.
In cases where errors are unlikely (which I think is the case here), I prefer the 2nd option; log errors in drop but otherwise ignore them.
There was a problem hiding this comment.
There's no way to make something undroppable in Rust
What about ManuallyDrop::new(val)?
There was a problem hiding this comment.
Hello, I'm back. Sorry for this long black period. Anyway, for ManuallyDrop, that's not feasible here because the intention was to make drop calls explicit so that error occurred during clean-up can be handled, and ManuallyDrop doesn't fit for that purpose.
|
Well test fails on windows because it can't use new pci memory device |
Might need to just skip this test on Windows. Take a look at https://github.com/rust-osdev/uefi-rs/blob/main/xtask/src/main.rs#L149 for examples of how we control test features. |
3a85c72 to
556049b
Compare
| cmd.arg("-device"); | ||
| cmd.arg("ivshmem-plain,memdev=hostmem,id=hostmem"); | ||
| cmd.arg("-object"); | ||
| cmd.arg("memory-backend-file,size=1M,share,mem-path=/dev/shm/ivshmem,id=hostmem"); |
There was a problem hiding this comment.
well I think if this tests runs under windows, we instead need something like ...mem-path=C:\\temp\\ivshmem,size=1M,share=on here
|
Please
Then we can get this merged. |
fc77f22 to
4f6eadd
Compare
|
@phip1611 I rebased my current branch and updated testing code. I don't have windows machine to locally test it out, but since the file path is now local instead of trying to look it up in |
could you please have another look? CI is still failing |
? |
4f6eadd to
6d51948
Compare
6d51948 to
754a3d1
Compare
The interesting error is the line above: Please either fix your CI test for windows or exclude it on Windows so that we can proceed here |
|
I am working on git history. Sorry for working on this so slowly. |
19e5754 to
7bdd369
Compare
|
It took a while because I installed windows 10 VM and tried to look for alternatives but I couldn't find any. I ended up just excluding the test on windows. |
aaff544 to
c9a37f1
Compare
|
I decided to implement just two protocol seeing that PR only added structs, not functionality |
0783864 to
c6fbe33
Compare
|
Question, should parts of memory management feature gated behind "alloc"? It doesn't use alloc crate but it does allocate memory, by using UEFI implementation. |
520653b to
c6f7d66
Compare
no that's fine. Currently, feature |
|
I think it's ready for review now. I removed all panic paths from drop as requested and all github ci actions pass |
There was a problem hiding this comment.
Generally, I think it is good to have this. A few remarks and opens:
- Please add a motivation to the PR (why you need this, where it is useful)
- One-two sentences are enough, but reviewers should see the value-proposition
- Please clean up your git commit history. We do not accept
do A, do B, fix A, fix B, fix A even morecommits. - The git commit history should cleanly lead reviewers how you got from A to B where
- A is the base
- B your final design
- and there are no interim designs (no
fix A, nodesign A, revert design A, use design B)
5079ec7 to
ffb7358
Compare
|
I have rewrote git history to just 3 commits. Each of them passes checks done in github CI. |
ffb7358 to
264183f
Compare
| operation: PciRootBridgeIoProtocolOperation, | ||
| to_map: &'r PciBuffer<'p, T>, | ||
| offset: usize, | ||
| ) -> crate::Result<(PciMappedRegion<'p, 'r, T>, usize)> { |
There was a problem hiding this comment.
The offset parameter is for calling this function multiple times. UEFI specification mentions that:
In all mapping requests the resulting NumberOfBytes actually mapped may be less than the requested amount. In this case, the DMA operation will have to be broken up into smaller chunks. The Map() function will map as much of the DMA operation as it can at one time. The caller may have to loop on Map() and Unmap() in order to complete a large DMA transfer.
This means users will have to call this function multiple times while moving the pointer forward. We could also provide function for looping until entire buffer is mapped, but bug in PCI implementation can return weird value for length of bytes forward, potentially causing infinite loop. That's probably unlikely though.
dda6680 to
d0d0c5b
Compare
d0d0c5b to
0c4115d
Compare
This is continuation of #1705
As requested by @phil-opp I decided to split the pr into multiple.
This one only contains wrapper for pages allocated and regions mapped by the protocol.
Motivation
When I was writing demo program for playing sound in uefi, I needed to access audio devices on PCI root bridge. Unfortunately back then It did not have abstraction for communicating with those. In fact it lacked a lot of PCI root bridge protocol's features. I decided to implement all of these. Starting with memory management and mapping. Which was crucial for sending raw audio data.
Checklist