-
Notifications
You must be signed in to change notification settings - Fork 13
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
[WIP] Update get/set Standard Registers to use VP register page #183
base: main
Are you sure you want to change the base?
Conversation
53c3cea
to
349a0b5
Compare
@jinankjain What do you think about arm64? I added the wrapper struct to lib.rs, I am open to add a similar regs.rs to arm64 and add the RegisterPage wrapper struct there. |
349a0b5
to
05d26e5
Compare
Yes there would be similar regs for ARM64, but I haven't finalized the set of registers we would need. |
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.
It looks like we need to handle the case where the register page is unavailable, e.g. in encrypted partitions.
mshv-bindings/src/lib.rs
Outdated
#[derive(Debug)] | ||
pub struct RegisterPage(pub *mut hv_vp_register_page); | ||
|
||
// SAFETY: struct is based on reguster page in the hypervisor, |
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.
typo: reguser -> register
mshv-ioctls/src/ioctls/vcpu.rs
Outdated
@@ -64,6 +69,11 @@ impl AsRawFd for VcpuFd { | |||
} | |||
|
|||
impl VcpuFd { | |||
/// Get mut refeferenc eof VP register page |
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.
typo: refeferenc -> reference
mshv-ioctls/src/ioctls/vcpu.rs
Outdated
@@ -46,15 +46,20 @@ macro_rules! set_registers_64 { | |||
pub struct VcpuFd { | |||
index: u32, | |||
vcpu: File, | |||
vp_page: RegisterPage, |
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.
Have you checked that this will always be available? Wondering if we should make it an Option
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.
I just checked the driver code to be sure. We don't map the register page if it's an encrypted partition, so we need to make this optional.
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.
Yes. This should be optional
mshv-ioctls/src/ioctls/vcpu.rs
Outdated
/// Sets the vCPU general purpose registers | ||
#[cfg(not(target_arch = "aarch64"))] | ||
pub fn set_regs(&self, regs: &StandardRegisters) -> Result<()> { | ||
let reg_assocs = [ |
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.
I had suggested keeping the existing set_regs()
and adding a new API. Maybe RegisterPage.set_gpregs()
or something.
The semantics are not exactly the same - e.g. if you set a register using the register page, then before restarting the VP, get a register using the IOCTL, you won't get the value you just put in the page. So it might be better to differentiate these cases or be explicit that this is using the register page method.
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.
We don't have the page in some cases, so we need to do this a different way.
We could have set_regs()
dispatch to either the IOCTL or the register page, if it is available.
Then it will always pick the fastest way. It would still be nice to differentiate using the IOCTL vs using the register page, for reasons I mentioned above, as well.
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.
We don't have the page in some cases, so we need to do this a different way. We could have
set_regs()
dispatch to either the IOCTL or the register page, if it is available. Then it will always pick the fastest way. It would still be nice to differentiate using the IOCTL vs using the register page, for reasons I mentioned above, as well.
Ar the moment it is always available except encrypted VM. How dowe exactly check is the page is available here? Checking the option?
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.
I had suggested keeping the existing
set_regs()
and adding a new API. MaybeRegisterPage.set_gpregs()
or something. The semantics are not exactly the same - e.g. if you set a register using the register page, then before restarting the VP, get a register using the IOCTL, you won't get the value you just put in the page. So it might be better to differentiate these cases or be explicit that this is using the register page method.
We need to have this part of vcpu API for vmm to use. Are you suggesting make the set_regs conditioonal inside? For encrypted case this API will never be called BTW.
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.
How dowe exactly check is the page is available here? Checking the option?
Yes
We need to have this part of vcpu API for vmm to use.
We can change it however we like and as long as we make the matching changes on the VMM side.
Are you suggesting make the set_regs conditioonal inside
It might be the easiest way to do it, because we wouldn't have to change much in the VMM.
But, making it transparent to the VMM like that could lead to cases where IOCTL and register page usage are mixed, so differentiating those methods might save some trouble in future.
Ar the moment it is always available except encrypted VM.
...
For encrypted case this API will never be called BTW.
Ok, maybe just replacing the current set_regs()
etc is fine then... I think I'd still like it better if the API made it clear this was a different method of setting the registers than using set_reg()
/set_registers_64!
.
E.g. renaming set_regs
to set_vp_page_gp_regs
or something
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.
This sounds good.
Signed-off-by: Muminul Islam <[email protected]>
Define a new struct RegisterPage with mutable pointer to hv_vp_register_page. Signed-off-by: Muminul Islam <[email protected]>
Include the register page in vcpu object for later use to read and write the VP registers. Signed-off-by: Muminul Islam <[email protected]>
One more API to VCPU implementation sin signature get_vp_reg_page, that return mutable reference to VP register page. This API could be used by VMM or other VCPU implementations. Signed-off-by: Muminul Islam <[email protected]>
05d26e5
to
e42898d
Compare
This API use mapped VP register page to set the registers. Signed-off-by: Muminul Islam <[email protected]>
e42898d
to
5d883df
Compare
This API uses VP register page to populate the registers. Signed-off-by: Muminul Islam <[email protected]>
5d883df
to
5a74c89
Compare
@NunoDasNeves Please take another look. |
If KVM supports a similar interface, can you check if they require the VMM to explicitly opt-in / enable to use this feature? We want to be careful here. The kernel may decide some day that it also wants to touch that page. |
I do not see any such feature in KVM. @NunoDasNeves What is the kernel scenario in our driver code. Can the driver change the page contents? |
It is all very nebulous in my head, but supposedly one day we may decide we want to do code emulation in Linux kernel, or make the kernel to directly inspect / modify guest register states. We need to be thorough here. If such use cases arise, we need to make sure correctness is maintained. With the current code, the VMM blindly maps the page. It may or may not be okay. I'm looking for the reasoning why the current scheme is okay; if not, what needs to be done. |
The whole purpose of this PR is to speed up the boot process. Mainly the emulation code is accessing GP and Control registers. If you move the emulation in the Kernel later we might remove this mapping from the VMM. |
Actually the code as-is already makes a case for gating that feature with a flag. Mapping the register page can be separated from the guest type.
In general, you should always provide a mechanism to discover features across component boundary. |
@@ -64,6 +69,13 @@ impl AsRawFd for VcpuFd { | |||
} | |||
|
|||
impl VcpuFd { | |||
/// Get mut reference of VP register page | |||
pub fn get_vp_reg_page(&self) -> *mut hv_vp_register_page { |
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.
If this can fail, you should return an Option. That's far better than expecting someone to read your comment in the function.
match self.vp_page { Some(p) => p, None => None }
.
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.
We can just return as is self.vp_page.
In your example two incompatible return type.
For encrypted guest, there is no register page in the driver. that means mmap will fail and we have to store None. |
Why this might be a problem from your POV? |
After a discussion with Wei, I think we need to have some feature sets returned from the Kernel driver and make appropriate features available in the VMM. As a result, I am making this PR draft and continue to work on the Kernel and resume here once Kernel implementation is done. |
When two entities modify the same page in an overlapping manner, there needs to be a way to synchronize them. We don't have a clear model yet. Having a mechanism to clearly denote what feature is available gives us some leeway if something happens in the future. |
Summary of the PR
Please summarize here why the changes in this PR are needed.
Requirements
Before submitting your PR, please make sure you addressed the following
requirements:
git commit -s
), and the commit message has max 60 characters for thesummary and max 75 characters for each description line.
test.
Release" section of CHANGELOG.md (if no such section exists, please create one).
unsafe
code is properly documented.