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

Fix support for big-endian architectures #118

Merged
merged 4 commits into from
Dec 3, 2021

Conversation

slp
Copy link
Collaborator

@slp slp commented Nov 17, 2021

This is an attempt at fixing support for big-endian architectures by:

  • Stating that Descriptor and VirtqUsedElem fields are stored with little-endian ordering.
  • Transforming from to little-endian in their respective new methods, and from little-endian on their accessors.
  • Ensuring we're always using the accessors to read the fields.
  • Doing endianess conversions when reading/writing individual values from/to memory.

The ::from_le and ::to_le methods are no-ops on little-endian machines, so their introduction shouldn't have any impact on those architectures.

I'm marking this PR as a draft, as I don't think it makes sense to merge it until we've reached a final decision about the API change in #111

@slp slp force-pushed the fix-endianess branch 2 times, most recently from 2183f1d to 39b7896 Compare November 18, 2021 13:40
@slp slp marked this pull request as ready for review November 18, 2021 14:32
@slp
Copy link
Collaborator Author

slp commented Nov 18, 2021

Since there's no agreement about #111, I'm marking this one as ready to review to move things forward.

jiangliu
jiangliu previously approved these changes Nov 18, 2021
@slp slp changed the title Fix support for big-endian architectures Draft: Fix support for big-endian architectures Nov 19, 2021
@slp slp marked this pull request as draft November 19, 2021 16:49
@slp
Copy link
Collaborator Author

slp commented Nov 19, 2021

Turning this PR back into a draft. I want to make use of vm_memory:{Le16, Le32, Le64}, and make sure that all tests that do assertions of Descriptor fields apply the proper endianess conversions.

slp added 2 commits November 26, 2021 14:19
Ensure that we're using the Descriptor accessors everywhere, instead
of accessing its fields directly.

This is needed for the next commit, where we'll be fixing the
endianess of each field on its accessor.

Signed-off-by: Sergio Lopez <[email protected]>
According to the virtio specification, on non-legacy devices the
values in the virtqueue are represented in little-endian, no matter
the host nor the guest actual endianess.

If needed, fix the endianess of values that have been read from memory
or will be written to it. The methods "from_le" and "to_le" are a
no-op on little-endian machines, so this shouldn't have a performance
impact on those.

Fixes rust-vmm#117

Signed-off-by: Sergio Lopez <[email protected]>
@slp slp force-pushed the fix-endianess branch 2 times, most recently from 3479085 to cfd7369 Compare November 26, 2021 13:41
In the tests, the driver behavior is emulated by writting directly
into the memory. According to the specification, the driver must write
virtqueue-related data in little-endian, even if it's running on a
big-endian machine.

Fix those accesses by using u16::to_le() and u16::from_le() where
needed. These operations become no-ops on little-endian machines.

With this change, the unit tests pass on big-endian machines (tested
on s390x).

Signed-off-by: Sergio Lopez <[email protected]>
@slp slp marked this pull request as ready for review November 26, 2021 15:13
@slp
Copy link
Collaborator Author

slp commented Nov 26, 2021

Rebased and tests working in big-endian, it's now ready to be reviewed.

@slp slp changed the title Draft: Fix support for big-endian architectures Fix support for big-endian architectures Nov 26, 2021
@jiangliu
Copy link
Member

Has this patch been tested on any big-endian platform?

@slp
Copy link
Collaborator Author

slp commented Nov 29, 2021

Has this patch been tested on any big-endian platform?

Yes, on s390x.

@jiangliu
Copy link
Member

Has this patch been tested on any big-endian platform?

Yes, on s390x.

great, feel much more confident:)

@slp
Copy link
Collaborator Author

slp commented Nov 30, 2021

@jiangliu @alexandruag How would you feel about merging this one? We really need it for virtiofsd.

@andreeaflorescu andreeaflorescu requested review from andreeaflorescu and removed request for alexandruag December 2, 2021 13:11
@andreeaflorescu
Copy link
Member

@slp I will take a look at this one today/tomorrow.

Copy link
Member

@andreeaflorescu andreeaflorescu left a comment

Choose a reason for hiding this comment

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

Nice written commit messages 👍

I have a slight concern that we might miss some of these checks in the tests going forward. It would be nice to setup a big endian platform for testing in the future.

vq.avail().ring().ref_at(1).store(2);
vq.avail().ring().ref_at(2).store(5);
vq.avail().idx().store(3);
vq.avail().ring().ref_at(0).store(u16::to_le(0));
Copy link
Member

Choose a reason for hiding this comment

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

Should we instead update the store and load from the mock interface to write and read little endian values so we don't need to use the conversion in all tests?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I thought about that, the problem is that we don't always want to do the endianess translation. For instance, we don't want to do it for Descriptor, as it's already in the right endianess. Adding a new dedicated method doesn't solve the problem, as the dev would still need if the conversion needs to be done. I think the only "right" solution would be revamping the mock objects to avoid naked loads/stores from/to memory, having dedicated methods for each field with the right types, but that seems like too huge of a change to me.

Being pragmatic, as this only affects tests and it's probably going to be very hard to integrate a big-endian machine into the CI, I think it's fine if they get broken from time to time. I'll give them a try on each new virtiofsd-rs release and fix them if needed.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good. We want to do some more improvements to the mock interface, do you mind opening an issue with this suggestion that you just mentioned?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, I've created #123 to track this. Thanks!

@andreeaflorescu andreeaflorescu merged commit cc1fa35 into rust-vmm:main Dec 3, 2021
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