MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / gain_page_access

Method gain_page_access

hypervisor/src/mshv/mod.rs:2429–2492  ·  view source on GitHub ↗
(&self, gpa: u64, size: u32)

Source from the content-addressed store, hash-verified

2427
2428 #[cfg(feature = "sev_snp")]
2429 fn gain_page_access(&self, gpa: u64, size: u32) -> vm::Result<()> {
2430 use mshv_ioctls::set_bits;
2431 const ONE_GB: usize = 1024 * 1024 * 1024;
2432
2433 if !self.sev_snp_enabled {
2434 return Ok(());
2435 }
2436
2437 let start_gpfn: u64 = gpa >> PAGE_SHIFT;
2438 let end_gpfn: u64 = (gpa + size as u64 - 1) >> PAGE_SHIFT;
2439
2440 // Enlarge the bitmap if the PFN is greater than the bitmap length
2441 if end_gpfn >= self.host_access_pages.load().as_ref().len() as u64 {
2442 self.host_access_pages.rcu(|bitmap| {
2443 let mut bm = bitmap.as_ref().clone();
2444 bm.enlarge(ONE_GB);
2445 bm
2446 });
2447 }
2448
2449 let gpas: Vec<u64> = (start_gpfn..=end_gpfn)
2450 .filter(|x| {
2451 !self
2452 .host_access_pages
2453 .load()
2454 .as_ref()
2455 .is_bit_set(*x as usize)
2456 })
2457 .map(|x| x << PAGE_SHIFT)
2458 .collect();
2459
2460 if !gpas.is_empty() {
2461 let mut gpa_list = vec_with_array_field::<mshv_modify_gpa_host_access, u64>(gpas.len());
2462 gpa_list[0].page_count = gpas.len() as u64;
2463 gpa_list[0].flags = set_bits!(
2464 u8,
2465 MSHV_GPA_HOST_ACCESS_BIT_ACQUIRE,
2466 MSHV_GPA_HOST_ACCESS_BIT_READABLE,
2467 MSHV_GPA_HOST_ACCESS_BIT_WRITABLE
2468 );
2469
2470 // SAFETY: gpa_list initialized with gpas.len() and now it is being turned into
2471 // gpas_slice with gpas.len() again. It is guaranteed to be large enough to hold
2472 // everything from gpas.
2473 unsafe {
2474 let gpas_slice: &mut [u64] = gpa_list[0].guest_pfns.as_mut_slice(gpas.len());
2475 gpas_slice.copy_from_slice(gpas.as_slice());
2476 }
2477
2478 self.fd
2479 .modify_gpa_host_access(&gpa_list[0])
2480 .map_err(|e| vm::HypervisorVmError::ModifyGpaHostAccess(e.into()))?;
2481
2482 for acquired_gpa in gpas {
2483 self.host_access_pages.rcu(|bitmap| {
2484 let bm = bitmap.clone();
2485 bm.set_bit((acquired_gpa >> PAGE_SHIFT) as usize);
2486 bm

Callers

nothing calls this directly

Calls 7

as_mut_sliceMethod · 0.80
as_sliceMethod · 0.80
set_bitMethod · 0.80
lenMethod · 0.45
cloneMethod · 0.45
mapMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected