summaryrefslogtreecommitdiff
path: root/src/dev/virtio
diff options
context:
space:
mode:
authorSascha Bischoff <sascha.bischoff@arm.com>2017-03-24 16:02:30 +0000
committerAndreas Sandberg <andreas.sandberg@arm.com>2017-04-03 16:36:15 +0000
commitd7aef8be964b5f7eee2dace0cfc347fb23fa7ab2 (patch)
tree7d75cd25df5e346e35e8b5aa52c1cdd5150a462f /src/dev/virtio
parentba00d7449df87c99bf8aca97a877b493c14f4866 (diff)
downloadgem5-d7aef8be964b5f7eee2dace0cfc347fb23fa7ab2.tar.xz
dev: Align BAR0 size to power of 2 for VirtIO devices
When setting the size of a PCI BAR, the kernel only supports powers of two (as per the PCI spec). Previously, the size was incorrectly read by the kernel, and the address ranges assigned to the PCI devices could overlap, resulting in gem5 crashes. We now round up to the next power of two. Kudos to Sergei Trofimov who helped to debug this issue! Change-Id: I54ca399b62ea07c09d4cd989b17dfa670e841bbe Reviewed-by: Anouk Van Laer <anouk.vanlaer@arm.com> Reviewed-by: Sergei Trofimov <sergei.trofimov@arm.com> Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2580 Reviewed-by: Paul Rosenfeld <prosenfeld@micron.com>
Diffstat (limited to 'src/dev/virtio')
-rw-r--r--src/dev/virtio/pci.cc10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/dev/virtio/pci.cc b/src/dev/virtio/pci.cc
index d8ec4f5f8..783b43e65 100644
--- a/src/dev/virtio/pci.cc
+++ b/src/dev/virtio/pci.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 ARM Limited
+ * Copyright (c) 2014, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -39,6 +39,7 @@
#include "dev/virtio/pci.hh"
+#include "base/bitfield.hh"
#include "debug/VIOIface.hh"
#include "mem/packet_access.hh"
#include "params/PciVirtIO.hh"
@@ -49,7 +50,12 @@ PciVirtIO::PciVirtIO(const Params *params)
{
// Override the subsystem ID with the device ID from VirtIO
config.subsystemID = htole(vio.deviceId);
- BARSize[0] = BAR0_SIZE_BASE + vio.configSize;
+
+ // The kernel driver expects the BAR size to be an exact power of
+ // two. Nothing else is supported. Therefore, we need to force
+ // that alignment here. We do not touch vio.configSize as this is
+ // used to check accesses later on.
+ BARSize[0] = alignToPowerOfTwo(BAR0_SIZE_BASE + vio.configSize);
vio.registerKickCallback(&callbackKick);
}