devices: pci: check BAR address alignment

Each PCI BAR address must be aligned to at least its own size to allow
the BAR sizing mechanism to work properly.  Add a check in add_pci_bar()
to enforce this.

BUG=None
TEST=Boot vm_kernel in crosvm

Change-Id: Iee9d866c4982bd79935337682bd50b9205b95024
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1660203
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Daniel Verkamp 2019-06-14 15:17:09 -07:00 committed by Commit Bot
parent 4dd6ddbc39
commit 5e3442e675

View file

@ -200,6 +200,7 @@ pub struct PciBarConfiguration {
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
BarAddressInvalid(u64, u64), BarAddressInvalid(u64, u64),
BarAlignmentInvalid(u64, u64),
BarInUse(usize), BarInUse(usize),
BarInUse64(usize), BarInUse64(usize),
BarInvalid(usize), BarInvalid(usize),
@ -218,6 +219,7 @@ impl Display for Error {
use self::Error::*; use self::Error::*;
match self { match self {
BarAddressInvalid(a, s) => write!(f, "address {} size {} too big", a, s), BarAddressInvalid(a, s) => write!(f, "address {} size {} too big", a, s),
BarAlignmentInvalid(a, s) => write!(f, "address {} is not aligned to size {}", a, s),
BarInUse(b) => write!(f, "bar {} already used", b), BarInUse(b) => write!(f, "bar {} already used", b),
BarInUse64(b) => write!(f, "64bit bar {} already used(requires two regs)", b), BarInUse64(b) => write!(f, "64bit bar {} already used(requires two regs)", b),
BarInvalid(b) => write!(f, "bar {} invalid, max {}", b, NUM_BAR_REGS - 1), BarInvalid(b) => write!(f, "bar {} invalid, max {}", b, NUM_BAR_REGS - 1),
@ -358,6 +360,10 @@ impl PciConfiguration {
return Err(Error::BarInvalid(config.reg_idx)); return Err(Error::BarInvalid(config.reg_idx));
} }
if config.addr % config.size != 0 {
return Err(Error::BarAlignmentInvalid(config.addr, config.size));
}
let bar_idx = BAR0_REG + config.reg_idx; let bar_idx = BAR0_REG + config.reg_idx;
let end_addr = config let end_addr = config
.addr .addr