Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/xen Introduce locking primitives for Xen pte operat...
details: https://anonhg.NetBSD.org/src/rev/b959bb5e7f37
branches: trunk
changeset: 768175:b959bb5e7f37
user: cherry <cherry%NetBSD.org@localhost>
date: Wed Aug 10 09:50:37 2011 +0000
description:
Introduce locking primitives for Xen pte operations, and xen helper calls for MP related MMU ops
diffstat:
sys/arch/xen/include/xenpmap.h | 11 ++-
sys/arch/xen/x86/x86_xpmap.c | 169 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 174 insertions(+), 6 deletions(-)
diffs (truncated from 333 to 300 lines):
diff -r e7a38b769e21 -r b959bb5e7f37 sys/arch/xen/include/xenpmap.h
--- a/sys/arch/xen/include/xenpmap.h Wed Aug 10 09:42:28 2011 +0000
+++ b/sys/arch/xen/include/xenpmap.h Wed Aug 10 09:50:37 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xenpmap.h,v 1.27 2011/04/29 22:45:41 jym Exp $ */
+/* $NetBSD: xenpmap.h,v 1.28 2011/08/10 09:50:37 cherry Exp $ */
/*
*
@@ -36,6 +36,8 @@
#define INVALID_P2M_ENTRY (~0UL)
+void xpq_queue_lock(void);
+void xpq_queue_unlock(void);
void xpq_queue_machphys_update(paddr_t, paddr_t);
void xpq_queue_invlpg(vaddr_t);
void xpq_queue_pte_update(paddr_t, pt_entry_t);
@@ -46,6 +48,13 @@
void xpq_queue_pin_table(paddr_t, int);
void xpq_queue_unpin_table(paddr_t);
int xpq_update_foreign(paddr_t, pt_entry_t, int);
+void xen_vcpu_mcast_invlpg(vaddr_t, vaddr_t, uint32_t);
+void xen_vcpu_bcast_invlpg(vaddr_t, vaddr_t);
+void xen_mcast_tlbflush(uint32_t);
+void xen_bcast_tlbflush(void);
+void xen_mcast_invlpg(vaddr_t, uint32_t);
+void xen_bcast_invlpg(vaddr_t);
+
#define xpq_queue_pin_l1_table(pa) \
xpq_queue_pin_table(pa, MMUEXT_PIN_L1_TABLE)
diff -r e7a38b769e21 -r b959bb5e7f37 sys/arch/xen/x86/x86_xpmap.c
--- a/sys/arch/xen/x86/x86_xpmap.c Wed Aug 10 09:42:28 2011 +0000
+++ b/sys/arch/xen/x86/x86_xpmap.c Wed Aug 10 09:50:37 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_xpmap.c,v 1.28 2011/06/15 20:50:02 rmind Exp $ */
+/* $NetBSD: x86_xpmap.c,v 1.29 2011/08/10 09:50:37 cherry Exp $ */
/*
* Copyright (c) 2006 Mathieu Ropert <mro%adviseo.fr@localhost>
@@ -69,7 +69,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.28 2011/06/15 20:50:02 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.29 2011/08/10 09:50:37 cherry Exp $");
#include "opt_xen.h"
#include "opt_ddb.h"
@@ -77,6 +77,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/simplelock.h>
#include <uvm/uvm.h>
@@ -152,7 +153,9 @@
pmap_pte_clearbits(ptp, PG_RW);
}
s = splvm();
+ xpq_queue_lock();
xpq_queue_set_ldt(base, entries);
+ xpq_queue_unlock();
splx(s);
}
@@ -163,12 +166,27 @@
#define XPQUEUE_SIZE 2048
static mmu_update_t xpq_queue[XPQUEUE_SIZE];
static int xpq_idx = 0;
+static struct simplelock xpq_lock = SIMPLELOCK_INITIALIZER;
void
+xpq_queue_lock(void)
+{
+ simple_lock(&xpq_lock);
+}
+
+void
+xpq_queue_unlock(void)
+{
+ simple_unlock(&xpq_lock);
+}
+
+/* Must be called with xpq_lock held */
+void
xpq_flush_queue(void)
{
int i, ok, ret;
+ KASSERT(simple_lock_held(&xpq_lock));
XENPRINTK2(("flush queue %p entries %d\n", xpq_queue, xpq_idx));
for (i = 0; i < xpq_idx; i++)
XENPRINTK2(("%d: 0x%08" PRIx64 " 0x%08" PRIx64 "\n", i,
@@ -187,10 +205,12 @@
xpq_idx = 0;
}
+/* Must be called with xpq_lock held */
static inline void
xpq_increment_idx(void)
{
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_idx++;
if (__predict_false(xpq_idx == XPQUEUE_SIZE))
xpq_flush_queue();
@@ -201,6 +221,7 @@
{
XENPRINTK2(("xpq_queue_machphys_update ma=0x%" PRIx64 " pa=0x%" PRIx64
"\n", (int64_t)ma, (int64_t)pa));
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_queue[xpq_idx].ptr = ma | MMU_MACHPHYS_UPDATE;
xpq_queue[xpq_idx].val = (pa - XPMAP_OFFSET) >> PAGE_SHIFT;
xpq_increment_idx();
@@ -214,6 +235,7 @@
{
KASSERT((ptr & 3) == 0);
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_queue[xpq_idx].ptr = (paddr_t)ptr | MMU_NORMAL_PT_UPDATE;
xpq_queue[xpq_idx].val = val;
xpq_increment_idx();
@@ -226,6 +248,7 @@
xpq_queue_pt_switch(paddr_t pa)
{
struct mmuext_op op;
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_flush_queue();
XENPRINTK2(("xpq_queue_pt_switch: 0x%" PRIx64 " 0x%" PRIx64 "\n",
@@ -240,6 +263,8 @@
xpq_queue_pin_table(paddr_t pa, int lvl)
{
struct mmuext_op op;
+
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_flush_queue();
XENPRINTK2(("xpq_queue_pin_l%d_table: %#" PRIxPADDR "\n",
@@ -256,6 +281,8 @@
xpq_queue_unpin_table(paddr_t pa)
{
struct mmuext_op op;
+
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_flush_queue();
XENPRINTK2(("xpq_queue_unpin_table: %#" PRIxPADDR "\n", pa));
@@ -269,6 +296,8 @@
xpq_queue_set_ldt(vaddr_t va, uint32_t entries)
{
struct mmuext_op op;
+
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_flush_queue();
XENPRINTK2(("xpq_queue_set_ldt\n"));
@@ -284,6 +313,8 @@
xpq_queue_tlb_flush(void)
{
struct mmuext_op op;
+
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_flush_queue();
XENPRINTK2(("xpq_queue_tlb_flush\n"));
@@ -296,20 +327,25 @@
xpq_flush_cache(void)
{
struct mmuext_op op;
- int s = splvm();
+ int s = splvm(), err;
+
+ xpq_queue_lock();
xpq_flush_queue();
XENPRINTK2(("xpq_queue_flush_cache\n"));
op.cmd = MMUEXT_FLUSH_CACHE;
- if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0)
+ if ((err = HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) < 0)
+ printf("errno == %d\n", err);
panic("xpq_flush_cache");
- splx(s);
+ xpq_queue_unlock();
+ splx(s); /* XXX: removeme */
}
void
xpq_queue_invlpg(vaddr_t va)
{
struct mmuext_op op;
+ KASSERT(simple_lock_held(&xpq_lock));
xpq_flush_queue();
XENPRINTK2(("xpq_queue_invlpg %#" PRIxVADDR "\n", va));
@@ -319,11 +355,134 @@
panic("xpq_queue_invlpg");
}
+void
+xen_mcast_invlpg(vaddr_t va, uint32_t cpumask)
+{
+ mmuext_op_t op;
+
+ KASSERT(simple_lock_held(&xpq_lock));
+
+ /* Flush pending page updates */
+ xpq_flush_queue();
+
+ op.cmd = MMUEXT_INVLPG_MULTI;
+ op.arg1.linear_addr = va;
+ op.arg2.vcpumask = &cpumask;
+
+ if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0) {
+ panic("xpq_queue_invlpg_all");
+ }
+
+ return;
+}
+
+void
+xen_bcast_invlpg(vaddr_t va)
+{
+ mmuext_op_t op;
+
+ /* Flush pending page updates */
+ KASSERT(simple_lock_held(&xpq_lock));
+ xpq_flush_queue();
+
+ op.cmd = MMUEXT_INVLPG_ALL;
+ op.arg1.linear_addr = va;
+
+ if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0) {
+ panic("xpq_queue_invlpg_all");
+ }
+
+ return;
+}
+
+/* This is a synchronous call. */
+void
+xen_mcast_tlbflush(uint32_t cpumask)
+{
+ mmuext_op_t op;
+
+ /* Flush pending page updates */
+ KASSERT(simple_lock_held(&xpq_lock));
+ xpq_flush_queue();
+
+ op.cmd = MMUEXT_TLB_FLUSH_MULTI;
+ op.arg2.vcpumask = &cpumask;
+
+ if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0) {
+ panic("xpq_queue_invlpg_all");
+ }
+
+ return;
+}
+
+/* This is a synchronous call. */
+void
+xen_bcast_tlbflush(void)
+{
+ mmuext_op_t op;
+
+ /* Flush pending page updates */
+ KASSERT(simple_lock_held(&xpq_lock));
+ xpq_flush_queue();
+
+ op.cmd = MMUEXT_TLB_FLUSH_ALL;
+
+ if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0) {
+ panic("xpq_queue_invlpg_all");
+ }
+
+ return;
+}
+
+/* This is a synchronous call. */
+void
+xen_vcpu_mcast_invlpg(vaddr_t sva, vaddr_t eva, uint32_t cpumask)
+{
+ KASSERT(eva > sva);
+
+ /* Flush pending page updates */
+ KASSERT(simple_lock_held(&xpq_lock));
+ xpq_flush_queue();
+
+ /* Align to nearest page boundary */
+ sva &= ~PAGE_MASK;
+ eva &= ~PAGE_MASK;
+
+ for ( ; sva <= eva; sva += PAGE_SIZE) {
+ xen_mcast_invlpg(sva, cpumask);
+ }
+
+ return;
Home |
Main Index |
Thread Index |
Old Index