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

Method detect_bar_reprogramming

pci/src/configuration.rs:972–1087  ·  view source on GitHub ↗
(
        &mut self,
        reg_idx: usize,
        data: &[u8],
    )

Source from the content-addressed store, hash-verified

970 }
971
972 fn detect_bar_reprogramming(
973 &mut self,
974 reg_idx: usize,
975 data: &[u8],
976 ) -> Option<BarReprogrammingParams> {
977 if data.len() != 4 {
978 return None;
979 }
980
981 let value = LittleEndian::read_u32(data);
982
983 let mask = self.writable_bits[reg_idx];
984 if (BAR0_REG..BAR0_REG + NUM_BAR_REGS).contains(&reg_idx) {
985 // Ignore the case where the BAR size is being asked for.
986 if value == 0xffff_ffff {
987 return None;
988 }
989
990 let bar_idx = reg_idx - BAR0_REG;
991 // Handle special case where the address being written is
992 // different from the address initially provided. This is a
993 // BAR reprogramming case which needs to be properly caught.
994 if let Some(bar_type) = self.bars[bar_idx].r#type {
995 // In case of 64 bits memory BAR, we don't do anything until
996 // the upper BAR is modified, otherwise we would be moving the
997 // BAR to a wrong location in memory.
998 if bar_type == PciBarRegionType::Memory64BitRegion {
999 return None;
1000 }
1001
1002 // Ignore the case where the value is unchanged.
1003 if (value & mask) == (self.bars[bar_idx].addr & mask) {
1004 return None;
1005 }
1006
1007 info!(
1008 "Detected BAR reprogramming: (BAR {}) 0x{:x}->0x{:x}",
1009 bar_idx, self.bars[bar_idx].addr, value
1010 );
1011 let old_base = u64::from(self.bars[bar_idx].addr & mask);
1012 let new_base = u64::from(value & mask);
1013 let len = u64::from(
1014 decode_32_bits_bar_size(self.bars[bar_idx].size)
1015 .ok_or(Error::Decode32BarSize)
1016 .unwrap(),
1017 );
1018 let region_type = bar_type;
1019
1020 self.bars[bar_idx].addr = value;
1021
1022 return Some(BarReprogrammingParams {
1023 old_base,
1024 new_base,
1025 len,
1026 region_type,
1027 });
1028 } else if (bar_idx > 0)
1029 && ((self.registers[reg_idx - 1] & self.writable_bits[reg_idx - 1])

Callers 1

write_config_registerMethod · 0.80

Calls 4

decode_32_bits_bar_sizeFunction · 0.85
decode_64_bits_bar_sizeFunction · 0.85
containsMethod · 0.80
lenMethod · 0.45

Tested by

no test coverage detected