-
Notifications
You must be signed in to change notification settings - Fork 2
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
MSIX Implementation for Linux Kernel >= 5.0.0 #5
base: vfio-over-socket
Are you sure you want to change the base?
Conversation
Thanks for the patch! First of all, what exactly doe this patch fix specifically for kernel >= 5? This is a based on the vfio-over-socet branch so the host kernel doesn't really come into play here, right? The fix for the alignment is legitimate. Howerver I don't understand the problem regarding enforcing the capabilities to be contiguous.
Are you trying to allow the non-standard path of the PCI header (>= 0x40) to be memory mapped? If so, why? And if there really is a legitimate for that then I think the fix would be to keep the capabilities on a chunk of memory the same way we do for the PCI header instead of keeping in the in a list. |
caps->caps[i].start = prev_end + 1; | ||
caps->caps[i].end = prev_end = caps->caps[i].start + lm_caps[i].size - 1; | ||
caps->caps[i].end = prev_end = caps->caps[i].start + ALIGN(lm_caps[i].size, 8) - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you make this fix a separate patch?
I had to force them to be contiguous otherwise something, from libmuser side, didn't work as expected. I tried to understand what was wrong but without any success. So I decided to come up with this workaround
Sure. Take for example the case of
So, let we say that, in your device, you have defined a .caps[0] = {
.id = PCI_CAP_ID_MSIX,
.size = 12,
.fn = &cap_msix
}, in the function struct cap {
start = prev_end + 1;
end = caps->caps[i].start + ALIGN(lm_caps[i].size, 8) - 1;
...
} so you can easily understand that the
No |
I'm looking at the documentation of
MUSER allows any BAR to be mmaped, however my understanding is that this is not a hard requirement for MSI-X to work, correct? I understand that this might be broken in MUSER because capabilities aren't properly aligned, but hopefully your fix addresses this. Are you trying to fix two things in the same patch (fix alignment + add support for Regarding the alignment problem, at the time we were implementing capabilities it seemed easier from an API point of view to implement it the way we did, however it turns out that having all capabilities in a buffer right after the PCI header would solve multiple problems. Regarding adding support for Is my understanding correct? I had realised that capabilities need improvement and had created issue nutanix#14. In fact I had started working on it (https://github.com/tmakatos/muser/commits/issue-14-rework) but then decided to stop because it would make creating an |
I just checked the PCI spec (rev 3.0) and it says that capabilities must be DWORD aligned (p. 667), and DWORD is defined as 4 bytes (p. 31), not 8. I'm looking at |
No, I think you're not correct. Check what I wrote previously:
So, in one way (
To my (very little and maybe wrong) understanding, DWORD alignment implies that the size must be an even multiplier of DWORD. So, because 12bytes are 3 DWORDs, to my understanding, it's not DWORD aligned. Am I wrong? Btw, if you prefer, we can split the discussion between capabilities and MSIX. They are related to some extent but not that deeply. |
Yes I think we need to split the discussion. DWORD alignment means that that the size must be a multiple of DWORD: 3 (size o MSI-X) * 4 (size of DWORD) == 12. Check https://en.wikipedia.org/wiki/Data_structure_alignment:
Regarding |
@atomass I discovered a bug in libmuser where the capability ID is always returned, this seems to be affected by alignment so I suppose that's why it works with QWORD alignment. I'll be fixing this shortly. |
@atomass I've refactored PCI capabilities (which sligtly changed the API) and the bug is now gone. The code now is actually smaller, simpler and most importantly correct. There some more room for improvement. Please try it out and let me know if it works for you. |
Some comments on this PR:
flags
member oflm_reg_info_t
instead of adding the newis_msix
one. But I couldn't becauseflags
is directly used as VFIO flags.cap.c
implementation. So I ended up withcaps->caps[i].end = prev_end = caps->caps[i].start + ALIGN(lm_caps[i].size, 8) - 1;
to ensure DWORD alignment. This is not the best option because there could be a (very rare/impossible) case were to the callback function it will be asked to read/write an offset greater than what it's expecting.I needed the DWORD alignment because
PCI_CAP_ID_MSIX
is 12bytesVFIO_REGION_INFO_CAP_MSIX_MAPPABLE
capability, it will mmap it as follows:The problem is that libmuser derives the
fd_offset
of each region accordingly to the functionregion_to_offset
->return (uint64_t)region << LM_REGION_SHIFT;
, a huge shift. That's why I decided that MSIX structures should reside on BAR 0.