|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Page table sync. in Xen arm (Arndale) with SMP enabled (Bug fix included)
Hello,
I'm running Xen on Arndale (Exynos5250) board with the following source.
Xen repo: //xenbits.xen.org/people/julieng/xen-unstable.git
branch: arndale
And when I generate heavy network traffic at DomU (with SMP enabled)
the following error occasionally occurs:
(XEN) Assertion 'map[slot].pt.avail != 0' failed, line 219, file mm.c
(XEN) Xen BUG at mm.c:219
(XEN) CPU1: Unexpected Trap: Undefined Instruction
(XEN) ----[ Xen-4.3-unstable arm32 debug=y Tainted: C ]----
(XEN) CPU: 1
(XEN) PC: 0023d1bc __bug+0x2c/0x44
(XEN) CPSR: 200001da MODE:Hypervisor
(XEN) R0: 0025c70c R1: 00000003 R2: 3fd4fd80 R3: 00000fff
(XEN) R4: 00259170 R5: 000000db R6: 0025a4ec R7: 7ffd7180
(XEN) R8: bfcf8000 R9: 7ffd516c R10:7ffd7000 R11:7ffe7d2c R12:00000004
(XEN) HYP: SP: 7ffe7d24 LR: 0023d1bc
... skip
(XEN) [<0023d1bc>] __bug+0x2c/0x44
(XEN) [<00243a18>] unmap_domain_page+0x7c/0xac
(XEN) [<002452a8>] p2m_lookup+0x13c/0x170
(XEN) [<0024562c>] gmfn_to_mfn+0x14/0x20
(XEN) [<00209e04>] __get_paged_frame+0x24/0x9c
(XEN) [<0020a2f4>] __acquire_grant_for_copy+0x478/0x6b0
(XEN) [<0020cd30>] do_grant_table_op+0x1938/0x2cb8
(XEN) [<00247d00>] do_trap_hypervisor+0x70c/0xa7c
(XEN) [<0024a030>] return_from_trap+0/0x4
I have digged a little bit and figured out that map_domain_page and
unmap_domain_page functions access page table without synchronization.
Here goes a simple fix and I hope you guys make it xen-compatible :)
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index ba378d0..7821db0 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -70,6 +70,8 @@ unsigned long total_pages;
extern char __init_begin[], __init_end[];
+spinlock_t avail_lock;
+
void dump_pt_walk(lpae_t *first, paddr_t addr)
{
lpae_t *second = NULL, *third = NULL;
@@ -151,6 +153,7 @@ void *map_domain_page(unsigned long mfn)
int i, slot;
local_irq_save(flags);
+ spin_lock(&avail_lock);
/* The map is laid out as an open-addressed hash table where each
* entry is a 2MB superpage pte. We use the available bits of each
@@ -191,6 +194,7 @@ void *map_domain_page(unsigned long mfn)
}
#endif
+ spin_unlock(&avail_lock);
local_irq_restore(flags);
va = (DOMHEAP_VIRT_START
@@ -214,12 +218,14 @@ void unmap_domain_page(const void *va)
int slot = ((unsigned long) va - DOMHEAP_VIRT_START) >> SECOND_SHIFT;
local_irq_save(flags);
+ spin_lock(&avail_lock);
ASSERT(slot >= 0 && slot < DOMHEAP_ENTRIES);
ASSERT(map[slot].pt.avail != 0);
map[slot].pt.avail--;
+ spin_unlock(&avail_lock);
local_irq_restore(flags);
}
@@ -368,6 +374,8 @@ void __init setup_pagetables(unsigned long
boot_phys_offset, paddr_t xen_paddr)
WRITE_SYSREG32(READ_SYSREG32(SCTLR_EL2) | SCTLR_WXN, SCTLR_EL2);
/* Flush everything after setting WXN bit. */
flush_xen_text_tlb();
+
+ spin_lock_init(&avail_lock);
}
Sincerely,
Thomas
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |