Sometimes while debugging problems related to how kernel and devices are
memory-mapped it is helpful to see it in some form in gdb or by reading
a procfs file just like we can do with mmap-ed VMAs. In addition we
need to know where linear VMAs are located so that we can avoid
collisions with mmap() as described by the issue #1135.

To that end this patch adds new struct - linear_vma and collection
of those - linear_vma_set - to track how memory gets mapped using
linear_map(). It also modifies all places calling linear_map() to
pass new argument - name.

Please note that we can not re-use existing vma class, as it holds
much richer information and lots of it is not applicable to linear map
which is quite static and is simply a pre-populated mapping between
some area of virtual and physical memory.

Upcoming patches will add new 'osv linear_mmap' to loader.py
and implementation of new sysfs pseudo file.

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>
---
 arch/aarch64/arch-setup.cc | 20 +++++++++++---------
 arch/x64/apic.cc           |  2 +-
 arch/x64/arch-setup.cc     | 11 ++++++++---
 arch/x64/dmi.cc            |  4 ++--
 arch/x64/ioapic.cc         |  2 +-
 bsd/porting/mmu.cc         |  2 +-
 core/mmio.cc               |  4 ++--
 core/mmu.cc                | 28 +++++++++++++++++++++++++++-
 drivers/acpi.cc            |  2 +-
 drivers/hpet.cc            |  2 +-
 drivers/mmio-isa-serial.cc |  2 +-
 drivers/pci-function.cc    |  2 +-
 drivers/pl031.cc           |  2 +-
 drivers/virtio-mmio.cc     |  2 +-
 drivers/xenconsole.cc      |  2 +-
 include/osv/mmio.hh        |  2 +-
 include/osv/mmu.hh         | 16 +++++++++++++++-
 include/osv/prio.hh        |  1 +
 18 files changed, 77 insertions(+), 29 deletions(-)

diff --git a/arch/aarch64/arch-setup.cc b/arch/aarch64/arch-setup.cc
index f9854b6a..622fb75f 100644
--- a/arch/aarch64/arch-setup.cc
+++ b/arch/aarch64/arch-setup.cc
@@ -61,7 +61,7 @@ void arch_setup_pci()
     pci::set_pci_cfg(pci_cfg, pci_cfg_len);
     pci_cfg = pci::get_pci_cfg(&pci_cfg_len);
     mmu::linear_map((void *)pci_cfg, (mmu::phys)pci_cfg, pci_cfg_len,
-                   mmu::page_size, mmu::mattr::dev);
+                   "pci_cfg", mmu::page_size, mmu::mattr::dev);
 
     /* linear_map [TTBR0 - PCI I/O and memory ranges] */
     u64 ranges[2]; size_t ranges_len[2];
@@ -73,9 +73,9 @@ void arch_setup_pci()
     ranges[0] = pci::get_pci_io(&ranges_len[0]);
     ranges[1] = pci::get_pci_mem(&ranges_len[1]);
     mmu::linear_map((void *)ranges[0], (mmu::phys)ranges[0], ranges_len[0],
-                    mmu::page_size, mmu::mattr::dev);
+                    "pci_io", mmu::page_size, mmu::mattr::dev);
     mmu::linear_map((void *)ranges[1], (mmu::phys)ranges[1], ranges_len[1],
-                    mmu::page_size, mmu::mattr::dev);
+                    "pci_mem", mmu::page_size, mmu::mattr::dev);
 }
 #endif
 
@@ -94,17 +94,19 @@ void arch_setup_free_memory()
     /* linear_map [TTBR1] */
     for (auto&& area : mmu::identity_mapped_areas) {
         auto base = reinterpret_cast<void*>(get_mem_area_base(area));
-        mmu::linear_map(base + addr, addr, memory::phys_mem_size);
+        mmu::linear_map(base + addr, addr, memory::phys_mem_size,
+            area == mmu::mem_area::main ? "main" :
+            area == mmu::mem_area::page ? "page" : "mempool");
     }
 
     /* linear_map [TTBR0 - boot, DTB and ELF] */
     mmu::linear_map((void *)mmu::mem_addr, (mmu::phys)mmu::mem_addr,
-                    addr - mmu::mem_addr);
+                    addr - mmu::mem_addr, "kernel");
 
     if (console::PL011_Console::active) {
         /* linear_map [TTBR0 - UART] */
         addr = (mmu::phys)console::aarch64_console.pl011.get_base_addr();
-        mmu::linear_map((void *)addr, addr, 0x1000, mmu::page_size,
+        mmu::linear_map((void *)addr, addr, 0x1000, "pl011", mmu::page_size,
                         mmu::mattr::dev);
     }
 
@@ -112,7 +114,7 @@ void arch_setup_free_memory()
     if (console::Cadence_Console::active) {
         // linear_map [TTBR0 - UART]
         addr = (mmu::phys)console::aarch64_console.cadence.get_base_addr();
-        mmu::linear_map((void *)addr, addr, 0x1000, mmu::page_size,
+        mmu::linear_map((void *)addr, addr, 0x1000, "cadence", mmu::page_size,
                         mmu::mattr::dev);
     }
 #endif
@@ -124,9 +126,9 @@ void arch_setup_free_memory()
         abort("arch-setup: failed to get GICv2 information from dtb.\n");
     }
     gic::gic = new gic::gic_driver(dist, cpu);
-    mmu::linear_map((void *)dist, (mmu::phys)dist, dist_len, mmu::page_size,
+    mmu::linear_map((void *)dist, (mmu::phys)dist, dist_len, "gic_dist", 
mmu::page_size,
                     mmu::mattr::dev);
-    mmu::linear_map((void *)cpu, (mmu::phys)cpu, cpu_len, mmu::page_size,
+    mmu::linear_map((void *)cpu, (mmu::phys)cpu, cpu_len, "gic_cpu", 
mmu::page_size,
                     mmu::mattr::dev);
 
 #if CONF_drivers_pci
diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc
index 03518deb..a026ab7b 100644
--- a/arch/x64/apic.cc
+++ b/arch/x64/apic.cc
@@ -103,7 +103,7 @@ void apic_driver::read_base()
 xapic::xapic()
     : apic_driver()
 {
-    mmu::linear_map(static_cast<void*>(_base_virt), _apic_base, 4096);
+    mmu::linear_map(static_cast<void*>(_base_virt), _apic_base, 4096, "xapic");
     xapic::enable();
 }
 
diff --git a/arch/x64/arch-setup.cc b/arch/x64/arch-setup.cc
index 582cb1b5..e1fb5380 100644
--- a/arch/x64/arch-setup.cc
+++ b/arch/x64/arch-setup.cc
@@ -164,7 +164,10 @@ void arch_setup_free_memory()
     });
     for (auto&& area : mmu::identity_mapped_areas) {
         auto base = reinterpret_cast<void*>(get_mem_area_base(area));
-        mmu::linear_map(base, 0, initial_map, initial_map);
+        mmu::linear_map(base, 0, initial_map,
+            area == mmu::mem_area::main ? "main" :
+            area == mmu::mem_area::page ? "page" : "mempool",
+            initial_map);
     }
     // Map the core, loaded by the boot loader
     // In order to properly setup mapping between virtual
@@ -176,7 +179,7 @@ void arch_setup_free_memory()
     // as expressed by the assignment below
     elf_start = reinterpret_cast<void*>(elf_phys_start + OSV_KERNEL_VM_SHIFT);
     elf_size = edata_phys - elf_phys_start;
-    mmu::linear_map(elf_start, elf_phys_start, elf_size, OSV_KERNEL_BASE);
+    mmu::linear_map(elf_start, elf_phys_start, elf_size, "kernel", 
OSV_KERNEL_BASE);
     // get rid of the command line, before low memory is unmapped
     parse_cmdline(mb);
     // now that we have some free memory, we can start mapping the rest
@@ -205,7 +208,9 @@ void arch_setup_free_memory()
         }
         for (auto&& area : mmu::identity_mapped_areas) {
             auto base = reinterpret_cast<void*>(get_mem_area_base(area));
-            mmu::linear_map(base + ent.addr, ent.addr, ent.size, ~0);
+            mmu::linear_map(base + ent.addr, ent.addr, ent.size,
+               area == mmu::mem_area::main ? "main" :
+               area == mmu::mem_area::page ? "page" : "mempool", ~0);
         }
         mmu::free_initial_memory_range(ent.addr, ent.size);
     });
diff --git a/arch/x64/dmi.cc b/arch/x64/dmi.cc
index f28e480a..9a5a510c 100644
--- a/arch/x64/dmi.cc
+++ b/arch/x64/dmi.cc
@@ -53,7 +53,7 @@ static void dmi_table(u32 base, u16 len, u16 num)
 {
     u8* const table_virt = mmu::phys_cast<u8>(base);
 
-    mmu::linear_map(static_cast<void*>(table_virt), base, len);
+    mmu::linear_map(static_cast<void*>(table_virt), base, len, "smbios");
 
     auto start = reinterpret_cast<const char*>(table_virt);
 
@@ -131,7 +131,7 @@ void dmi_probe()
 
     u8* const dmi_virt = mmu::phys_cast<u8>(dmi_base);
 
-    mmu::linear_map(static_cast<void*>(dmi_virt), dmi_base, 0x10000);
+    mmu::linear_map(static_cast<void*>(dmi_virt), dmi_base, 0x10000, "dmi");
 
     auto start = reinterpret_cast<const char*>(dmi_virt);
 
diff --git a/arch/x64/ioapic.cc b/arch/x64/ioapic.cc
index 339949a3..bd7a5ac5 100644
--- a/arch/x64/ioapic.cc
+++ b/arch/x64/ioapic.cc
@@ -43,7 +43,7 @@ void write(unsigned reg, u32 data)
 
 void init()
 {
-    mmu::linear_map(const_cast<void*>(base), base_phys, 4096);
+    mmu::linear_map(const_cast<void*>(base), base_phys, 4096, "ioapic");
 }
 
 }
diff --git a/bsd/porting/mmu.cc b/bsd/porting/mmu.cc
index e810f238..89aeb084 100644
--- a/bsd/porting/mmu.cc
+++ b/bsd/porting/mmu.cc
@@ -15,7 +15,7 @@
 
 void *pmap_mapdev(uint64_t paddr, size_t size)
 {
-    return (void *)mmio_map(paddr, size);
+    return (void *)mmio_map(paddr, size, "xen_store");
 }
 
 uint64_t virt_to_phys(void *virt)
diff --git a/core/mmio.cc b/core/mmio.cc
index cebd2cc8..67f8a69e 100644
--- a/core/mmio.cc
+++ b/core/mmio.cc
@@ -51,10 +51,10 @@ u64 mmio_getq(mmioaddr_t addr)
     return (*reinterpret_cast<volatile u64*>(addr));
 }
 
-mmioaddr_t mmio_map(u64 paddr, size_t size_bytes)
+mmioaddr_t mmio_map(u64 paddr, size_t size_bytes, const char* name)
 {
     char* map_to = mmu::phys_mem + paddr;
-    linear_map(map_to, paddr, size_bytes);
+    linear_map(map_to, paddr, size_bytes, name);
     return map_to;
 }
 
diff --git a/core/mmu.cc b/core/mmu.cc
index 3125a8aa..7c78ac5b 100644
--- a/core/mmu.cc
+++ b/core/mmu.cc
@@ -28,6 +28,7 @@
 #include <osv/rcu.hh>
 #include <osv/rwlock.h>
 #include <numeric>
+#include <set>
 
 // FIXME: Without this pragma, we get a lot of warnings that I don't know
 // how to explain or fix. For now, let's just ignore them :-(
@@ -46,6 +47,16 @@ extern const char text_start[], text_end[];
 
 namespace mmu {
 
+struct linear_vma_compare {
+    bool operator()(const linear_vma* a, const linear_vma* b) {
+        return a->_virt_addr < b->_virt_addr;
+    }
+};
+
+__attribute__((init_priority((int)init_prio::linear_vma_set)))
+std::set<linear_vma*, linear_vma_compare> linear_vma_set;
+rwlock_t linear_vma_set_mutex;
+
 namespace bi = boost::intrusive;
 
 class vma_compare {
@@ -1857,7 +1868,18 @@ int shm_file::close()
     return 0;
 }
 
-void linear_map(void* _virt, phys addr, size_t size,
+linear_vma::linear_vma(void* virt, phys phys, size_t size, mattr mem_attr, 
const char* name) {
+    _virt_addr = virt;
+    _phys_addr = phys;
+    _size = size;
+    _mem_attr = mem_attr;
+    _name = name;
+}
+
+linear_vma::~linear_vma() {
+}
+
+void linear_map(void* _virt, phys addr, size_t size, const char* name,
                 size_t slop, mattr mem_attr)
 {
     uintptr_t virt = reinterpret_cast<uintptr_t>(_virt);
@@ -1865,6 +1887,10 @@ void linear_map(void* _virt, phys addr, size_t size,
     assert((virt & (slop - 1)) == (addr & (slop - 1)));
     linear_page_mapper phys_map(addr, size, mem_attr);
     map_range(virt, virt, size, phys_map, slop);
+    auto _vma = new linear_vma(_virt, addr, size, mem_attr, name);
+    WITH_LOCK(linear_vma_set_mutex.for_write()) {
+       linear_vma_set.insert(_vma);
+    }
 }
 
 void free_initial_memory_range(uintptr_t addr, size_t size)
diff --git a/drivers/acpi.cc b/drivers/acpi.cc
index d1f5f422..af4140a4 100644
--- a/drivers/acpi.cc
+++ b/drivers/acpi.cc
@@ -175,7 +175,7 @@ void *AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, 
ACPI_SIZE Length)
     uint64_t _where = align_down(Where, mmu::huge_page_size);
     size_t map_size = align_up(Length + Where - _where, mmu::huge_page_size);
     
-    mmu::linear_map(mmu::phys_to_virt(_where), _where, map_size);
+    mmu::linear_map(mmu::phys_to_virt(_where), _where, map_size, "acpi");
     return mmu::phys_to_virt(Where);
 }
 
diff --git a/drivers/hpet.cc b/drivers/hpet.cc
index f0828b89..f0985df1 100644
--- a/drivers/hpet.cc
+++ b/drivers/hpet.cc
@@ -174,7 +174,7 @@ void __attribute__((constructor(init_prio::hpet))) 
hpet_init()
 
         // Check what type of main counter - 32-bit or 64-bit - is available 
and
         // construct relevant hpet clock instance
-        mmioaddr_t hpet_mmio_address = mmio_map(hpet_address.Address, 4096);
+        mmioaddr_t hpet_mmio_address = mmio_map(hpet_address.Address, 4096, 
"hpet");
 
         auto cap = mmio_getl(hpet_mmio_address + HPET_CAP);
         if (cap & HPET_CAP_COUNT_SIZE) {
diff --git a/drivers/mmio-isa-serial.cc b/drivers/mmio-isa-serial.cc
index 3675ec5f..8bce1814 100644
--- a/drivers/mmio-isa-serial.cc
+++ b/drivers/mmio-isa-serial.cc
@@ -31,7 +31,7 @@ void mmio_isa_serial_console::early_init(u64 
mmio_phys_address)
 void mmio_isa_serial_console::memory_map()
 {
     if (_phys_mmio_address) {
-        _addr_mmio = mmio_map(_phys_mmio_address, mmu::page_size);
+        _addr_mmio = mmio_map(_phys_mmio_address, mmu::page_size, 
"isa_serial_console");
     }
 }
 
diff --git a/drivers/pci-function.cc b/drivers/pci-function.cc
index 9d3641eb..46286128 100644
--- a/drivers/pci-function.cc
+++ b/drivers/pci-function.cc
@@ -84,7 +84,7 @@ namespace pci {
     void bar::map()
     {
         if (_is_mmio) {
-            _addr_mmio = mmio_map(get_addr64(), get_size());
+            _addr_mmio = mmio_map(get_addr64(), get_size(), "pci_bar");
         }
     }
 
diff --git a/drivers/pl031.cc b/drivers/pl031.cc
index b81b38b9..4daee666 100644
--- a/drivers/pl031.cc
+++ b/drivers/pl031.cc
@@ -21,7 +21,7 @@
 pl031::pl031(u64 address)
 {
     _address = address;
-    mmu::linear_map((void *)_address, _address, mmu::page_size, mmu::page_size,
+    mmu::linear_map((void *)_address, _address, mmu::page_size, "pl031", 
mmu::page_size,
                     mmu::mattr::dev);
 }
 
diff --git a/drivers/virtio-mmio.cc b/drivers/virtio-mmio.cc
index 91f88d89..5731b858 100644
--- a/drivers/virtio-mmio.cc
+++ b/drivers/virtio-mmio.cc
@@ -112,7 +112,7 @@ void mmio_device::register_interrupt(interrupt_factory 
irq_factory)
 
 bool mmio_device::parse_config()
 {
-    _addr_mmio = mmio_map(_dev_info._address, _dev_info._size);
+    _addr_mmio = mmio_map(_dev_info._address, _dev_info._size, 
"virtio_mmio_cfg");
 
     u32 magic = mmio_getl(_addr_mmio + VIRTIO_MMIO_MAGIC_VALUE);
     if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
diff --git a/drivers/xenconsole.cc b/drivers/xenconsole.cc
index 92a76b69..f180cd67 100644
--- a/drivers/xenconsole.cc
+++ b/drivers/xenconsole.cc
@@ -83,7 +83,7 @@ void XEN_Console::dev_start()
             INTR_TYPE_MISC, &_irq) != 0)
         throw std::runtime_error("fail to bind evtchn");
 
-    _interface = (xencons_interface*)mmio_map(_pfn << PAGE_SHIFT, PAGE_SIZE);
+    _interface = (xencons_interface*)mmio_map(_pfn << PAGE_SHIFT, PAGE_SIZE, 
"xen_console");
 }
 
 void XEN_Console::flush()
diff --git a/include/osv/mmio.hh b/include/osv/mmio.hh
index 64e5d05d..586a56cf 100644
--- a/include/osv/mmio.hh
+++ b/include/osv/mmio.hh
@@ -25,7 +25,7 @@ u32 mmio_getl(mmioaddr_t addr);
 u64 mmio_getq(mmioaddr_t addr);
 
 // Map mmio regions
-mmioaddr_t mmio_map(u64 paddr, size_t size_bytes);
+mmioaddr_t mmio_map(u64 paddr, size_t size_bytes, const char* name);
 void mmio_unmap(mmioaddr_t addr, size_t size_bytes);
 
 #endif // MMIO_HH
diff --git a/include/osv/mmu.hh b/include/osv/mmu.hh
index 12fcb8a4..463f2001 100644
--- a/include/osv/mmu.hh
+++ b/include/osv/mmu.hh
@@ -43,6 +43,20 @@ constexpr inline unsigned pt_index(void *virt, unsigned 
level)
 
 struct page_allocator;
 
+struct linear_vma {
+    void* _virt_addr;
+    phys _phys_addr;
+    size_t _size;
+    mattr _mem_attr;
+    std::string _name;
+
+    linear_vma(void* virt, phys phys, size_t size, mattr mem_attr, const char* 
name);
+    ~linear_vma();
+
+    uintptr_t v_start() const { return 
reinterpret_cast<uintptr_t>(_virt_addr); }
+    uintptr_t v_end() const { return reinterpret_cast<uintptr_t>(_virt_addr + 
_size); }
+};
+
 class vma {
 public:
     vma(addr_range range, unsigned perm, unsigned flags, bool map_dirty, 
page_allocator *page_ops = nullptr);
@@ -298,7 +312,7 @@ bool is_page_aligned(void* addr)
 // an architecture-specific meaning.
 // Currently mem_attr is ignored on x86_64. For aarch64 specifics see
 // definitions in arch/aarch64/arch-mmu.hh
-void linear_map(void* virt, phys addr, size_t size,
+void linear_map(void* virt, phys addr, size_t size, const char* name,
                 size_t slop = mmu::page_size,
                 mattr mem_attr = mmu::mattr_default);
 
diff --git a/include/osv/prio.hh b/include/osv/prio.hh
index c3cb4742..23adc08f 100644
--- a/include/osv/prio.hh
+++ b/include/osv/prio.hh
@@ -16,6 +16,7 @@ enum {
     cpus,
     fpranges,
     pt_root,
+    linear_vma_set,
     mempool,
     routecache,
     pagecache,
-- 
2.31.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20220317012333.871483-1-jwkozaczuk%40gmail.com.

Reply via email to