-
Notifications
You must be signed in to change notification settings - Fork 102
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
virt_mshv_vtl: Proxy irr filtering #609
Merged
Merged
Changes from 11 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
6c54673
irr-proxy filter code complete for hardware CVM (SNP/TDX), compiling,…
kmehtaintel ff5ca4a
FIX: Moved filter update after SINT is updated
kmehtaintel 5b2930c
Merge branch 'microsoft:main' into proxy-irr-filtering
kmehtaintel e2d935b
Merge branch 'microsoft:main' into proxy-irr-filtering
kmehtaintel 2b3bfcb
proxy_irr_filtering working and some refactoring
kmehtaintel 5a0e6ca
Removed IRR filter todo comment
kmehtaintel 583f17d
New wake reason for filter update, ported code to work with kernel IR…
kmehtaintel 4ac1fe2
rebase with main
kmehtaintel 3515e60
Merge branch 'microsoft:main' into proxy-irr-filtering
kmehtaintel 1bae5f6
Accessing as atomic during updates, implemented inspect for filter a…
kmehtaintel 34bfcc4
clippy warning fix: removed unnecessary mask while updating proxy_ir…
kmehtaintel 043f470
Merge branch 'microsoft:main' into proxy-irr-filtering
kmehtaintel 6d72adb
Addressed few more review comments
kmehtaintel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,9 @@ cfg_if::cfg_if!( | |
use processor::tdx::TdxBackedShared; | ||
use std::arch::x86_64::CpuidResult; | ||
use virt::CpuidLeaf; | ||
use bitvec::prelude::BitArray; | ||
use bitvec::prelude::Lsb0; | ||
type IrrBitmap = BitArray<[u32; 8], Lsb0>; | ||
chris-oo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else if #[cfg(target_arch = "aarch64")] { // xtask-fmt allow-target-arch sys-crate | ||
pub use crate::processor::mshv::arm64::HypervisorBackedArm64 as HypervisorBacked; | ||
use hvdef::HvArm64RegisterName; | ||
|
@@ -223,6 +226,10 @@ struct UhPartitionInner { | |
no_sidecar_hotplug: AtomicBool, | ||
use_mmio_hypercalls: bool, | ||
backing_shared: BackingShared, | ||
#[cfg(guest_arch = "x86_64")] | ||
// N.B For now, only one device vector table i.e. for VTL0 only | ||
#[inspect(with = "|x| inspect::iter_by_index(x.read().into_inner().map(inspect::AsHex))")] | ||
device_vector_table: RwLock<IrrBitmap>, | ||
} | ||
|
||
#[derive(Inspect)] | ||
|
@@ -628,7 +635,8 @@ struct WakeReason { | |
message_queues: bool, | ||
hv_start_enable_vtl_vp: bool, | ||
intcon: bool, | ||
#[bits(28)] | ||
update_proxy_irr_filter: bool, | ||
#[bits(27)] | ||
_reserved: u32, | ||
} | ||
|
||
|
@@ -638,6 +646,8 @@ impl WakeReason { | |
const MESSAGE_QUEUES: Self = Self::new().with_message_queues(true); | ||
const HV_START_ENABLE_VP_VTL: Self = Self::new().with_hv_start_enable_vtl_vp(true); // StartVp/EnableVpVtl handling | ||
const INTCON: Self = Self::new().with_intcon(true); | ||
#[cfg(guest_arch = "x86_64")] | ||
const UPDATE_PROXY_IRR_FILTER: Self = Self::new().with_update_proxy_irr_filter(true); | ||
} | ||
|
||
/// Immutable access to useful bits of Partition state. | ||
|
@@ -749,6 +759,39 @@ impl UhPartitionInner { | |
self.vps.get(index.index() as usize) | ||
} | ||
|
||
/// For requester VP to issue `proxy_irr_blocked` update to other VPs | ||
#[cfg(guest_arch = "x86_64")] | ||
fn request_proxy_irr_filter_update(&self, vtl: GuestVtl, device_vector: u8, req_vp_index: u32) { | ||
tracing::debug!( | ||
?vtl, | ||
device_vector, | ||
req_vp_index, | ||
"request_proxy_irr_filter_update" | ||
); | ||
|
||
// Add given vector to partition global device vector table (VTL0 only for now) | ||
{ | ||
let mut device_vector_table = self.device_vector_table.write(); | ||
device_vector_table.set(device_vector as usize, true); | ||
} | ||
|
||
// Wake all other VPs for their `proxy_irr_blocked` filter update | ||
for vp in self.vps.iter() { | ||
if vp.cpu_index != req_vp_index { | ||
vp.wake(vtl, WakeReason::UPDATE_PROXY_IRR_FILTER); | ||
} | ||
} | ||
} | ||
|
||
/// Get current partition global device irr vectors (VTL0 for now) | ||
#[cfg(guest_arch = "x86_64")] | ||
fn get_device_vectors(&self, _vtl: GuestVtl, irr_vectors: &mut IrrBitmap) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: we usually don't use |
||
let device_vector_table = self.device_vector_table.read(); | ||
for idx in device_vector_table.iter_ones() { | ||
irr_vectors.set(idx, true); | ||
} | ||
} | ||
|
||
fn inspect_extra(&self, resp: &mut inspect::Response<'_>) { | ||
let mut wake_vps = false; | ||
resp.field_mut( | ||
|
@@ -1609,6 +1652,8 @@ impl<'a> UhProtoPartition<'a> { | |
no_sidecar_hotplug: params.no_sidecar_hotplug.into(), | ||
use_mmio_hypercalls: params.use_mmio_hypercalls, | ||
backing_shared: BackingShared::new(isolation, BackingSharedParams { cvm_state })?, | ||
#[cfg(guest_arch = "x86_64")] | ||
device_vector_table: RwLock::new(IrrBitmap::new(Default::default())), | ||
}); | ||
|
||
if cfg!(guest_arch = "x86_64") { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -23,6 +23,8 @@ cfg_if::cfg_if! { | |||||
use virt::x86::MsrError; | ||||||
use virt_support_apic::LocalApic; | ||||||
use virt_support_x86emu::translate::TranslationRegisters; | ||||||
use bitvec::prelude::BitArray; | ||||||
use bitvec::prelude::Lsb0; | ||||||
} else if #[cfg(guest_arch = "aarch64")] { | ||||||
use hv1_hypercall::Arm64RegisterState; | ||||||
use hvdef::HvArm64RegisterName; | ||||||
|
@@ -934,6 +936,13 @@ impl<'a, T: Backing> UhProcessor<'a, T> { | |||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
#[cfg(guest_arch = "x86_64")] | ||||||
if wake_reasons.update_proxy_irr_filter() { | ||||||
// update `proxy_irr_blocked` filter | ||||||
debug_assert!(self.partition.isolation.is_hardware_isolated()); | ||||||
self.update_proxy_irr_filter(vtl); | ||||||
} | ||||||
} | ||||||
|
||||||
Ok(wake_reasons_vtl.map(|w| w.intcon()).into()) | ||||||
|
@@ -967,8 +976,23 @@ impl<'a, T: Backing> UhProcessor<'a, T> { | |||||
fn write_msr(&mut self, msr: u32, value: u64, vtl: GuestVtl) -> Result<(), MsrError> { | ||||||
if msr & 0xf0000000 == 0x40000000 { | ||||||
if let Some(hv) = self.backing.hv_mut(vtl).as_mut() { | ||||||
// If updated is Synic MSR, then check if its proxy or previous was proxy | ||||||
// in either case, we need to update the `proxy_irr_blocked` | ||||||
let mut irr_filter_update = false; | ||||||
if matches!(msr, hvdef::HV_X64_MSR_SINT0..=hvdef::HV_X64_MSR_SINT15) { | ||||||
let sint_curr = | ||||||
HvSynicSint::from(hv.synic.sint((msr - hvdef::HV_X64_MSR_SINT0) as u8)); | ||||||
let sint_new = HvSynicSint::from(value); | ||||||
if sint_curr.proxy() || sint_new.proxy() { | ||||||
irr_filter_update = true; | ||||||
} | ||||||
} | ||||||
let r = hv.msr_write(msr, value); | ||||||
if !matches!(r, Err(MsrError::Unknown)) { | ||||||
// Check if proxy filter update was required (in case of SINT writes) | ||||||
if irr_filter_update { | ||||||
self.update_proxy_irr_filter(vtl); | ||||||
} | ||||||
return r; | ||||||
} | ||||||
} | ||||||
|
@@ -1128,6 +1152,28 @@ impl<'a, T: Backing> UhProcessor<'a, T> { | |||||
|
||||||
self.request_sint_notifications(vtl, pending_sints); | ||||||
} | ||||||
|
||||||
#[cfg(guest_arch = "x86_64")] | ||||||
fn update_proxy_irr_filter(&mut self, vtl: GuestVtl) { | ||||||
let mut irr_bits: BitArray<[u32; 8], Lsb0> = BitArray::new(Default::default()); | ||||||
|
||||||
// Get all not maksed && proxy SINT vectors | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
if let Some(hv) = self.backing.hv(vtl).as_ref() { | ||||||
for sint in 0..NUM_SINTS as u8 { | ||||||
let sint_msr = hv.synic.sint(sint); | ||||||
let hv_sint = HvSynicSint::from(sint_msr); | ||||||
if hv_sint.proxy() && !hv_sint.masked() { | ||||||
irr_bits.set(hv_sint.vector() as usize, true); | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
// Get all device vectors | ||||||
self.partition.get_device_vectors(vtl, &mut irr_bits); | ||||||
|
||||||
// Update `proxy_irr_blocked` filter in run page | ||||||
self.runner.update_proxy_irr_filter(&irr_bits.into_inner()); | ||||||
} | ||||||
} | ||||||
|
||||||
fn signal_mnf(dev: &impl CpuIo, connection_id: u32) { | ||||||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 be more descriptive that irr_filter is the vectors you want to allow?
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.
and also, that we don't respect what's currently set - this fully overwrites it?
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.
Sure, I will add a comment that
irr_filter
is allowed vector bitmap (or may be name change?) and yes, this function overwrites the existing set, without respecting what is set, as the intention is the caller is going to provide the cumulative map. As you can see currently, before invoking this method, first we iterate over all sints and then we capture all device vectors (device_vector_table
) and finally cumulative map is the one we pass asirr_filter
argument. Also, device vector map i.e..device_vector_table
, is global at partition level and vectors are never removed from it. So, whenever there is a SINT update or device retarget VMCALL, all SINTs vector anddevice_vector_table
is considered to populate a cumulative map, before invoking this method.