Module Name: src
Committed By: bouyer
Date: Thu Feb 23 19:17:32 UTC 2012
Modified Files:
src/sys/arch/xen/xen: xengnt.c
Log Message:
Fix locking; xengnt_get_entry() needs to have the lock held to avoid
allocating the same entry twice. xengnt_more_entries() also needs the lock
for the same reason.
To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/xen/xen/xengnt.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/xen/xen/xengnt.c
diff -u src/sys/arch/xen/xen/xengnt.c:1.22 src/sys/arch/xen/xen/xengnt.c:1.23
--- src/sys/arch/xen/xen/xengnt.c:1.22 Sat Feb 4 02:00:07 2012
+++ src/sys/arch/xen/xen/xengnt.c Thu Feb 23 19:17:32 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: xengnt.c,v 1.22 2012/02/04 02:00:07 riz Exp $ */
+/* $NetBSD: xengnt.c,v 1.23 2012/02/23 19:17:32 bouyer Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xengnt.c,v 1.22 2012/02/04 02:00:07 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xengnt.c,v 1.23 2012/02/23 19:17:32 bouyer Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -118,10 +118,12 @@ xengnt_resume(void)
last_gnt_entry = 0;
gnt_nr_grant_frames = 0;
+ mutex_enter(&grant_lock);
while (gnt_nr_grant_frames < previous_nr_grant_frames) {
if (xengnt_more_entries() != 0)
panic("xengnt_resume: can't restore grant frames");
}
+ mutex_exit(&grant_lock);
return true;
}
@@ -133,6 +135,7 @@ xengnt_suspend(void) {
int i;
+ mutex_enter(&grant_lock);
KASSERT(gnt_entries[last_gnt_entry] == XENGNT_NO_ENTRY);
for (i = 0; i < last_gnt_entry; i++) {
@@ -143,7 +146,7 @@ xengnt_suspend(void) {
/* Remove virtual => machine mapping */
pmap_kremove((vaddr_t)grant_table, gnt_nr_grant_frames * PAGE_SIZE);
pmap_update(pmap_kernel());
-
+ mutex_exit(&grant_lock);
return true;
}
@@ -159,6 +162,7 @@ xengnt_more_entries(void)
u_long *pages;
int nframes_new = gnt_nr_grant_frames + 1;
int i;
+ KASSERT(mutex_owned(&grant_lock));
if (gnt_nr_grant_frames == gnt_max_grant_frames)
return ENOMEM;
@@ -221,13 +225,11 @@ static grant_ref_t
xengnt_get_entry(void)
{
grant_ref_t entry;
- mutex_enter(&grant_lock);
static struct timeval xengnt_nonmemtime;
static const struct timeval xengnt_nonmemintvl = {5,0};
if (last_gnt_entry == 0) {
if (xengnt_more_entries()) {
- mutex_exit(&grant_lock);
if (ratecheck(&xengnt_nonmemtime, &xengnt_nonmemintvl))
printf("xengnt_get_entry: out of grant "
"table entries\n");
@@ -238,7 +240,6 @@ xengnt_get_entry(void)
last_gnt_entry--;
entry = gnt_entries[last_gnt_entry];
gnt_entries[last_gnt_entry] = XENGNT_NO_ENTRY;
- mutex_exit(&grant_lock);
KASSERT(entry != XENGNT_NO_ENTRY);
KASSERT(last_gnt_entry >= 0);
KASSERT(last_gnt_entry <= gnt_max_grant_frames * NR_GRANT_ENTRIES_PER_PAGE);
@@ -263,11 +264,14 @@ xengnt_free_entry(grant_ref_t entry)
int
xengnt_grant_access(domid_t dom, paddr_t ma, int ro, grant_ref_t *entryp)
{
+ mutex_enter(&grant_lock);
+
*entryp = xengnt_get_entry();
- if (__predict_false(*entryp == XENGNT_NO_ENTRY))
+ if (__predict_false(*entryp == XENGNT_NO_ENTRY)) {
+ mutex_exit(&grant_lock);
return ENOMEM;
+ }
- mutex_enter(&grant_lock);
grant_table[*entryp].frame = ma >> PAGE_SHIFT;
grant_table[*entryp].domid = dom;
/*
@@ -300,11 +304,14 @@ xengnt_revoke_access(grant_ref_t entry)
int
xengnt_grant_transfer(domid_t dom, grant_ref_t *entryp)
{
+ mutex_enter(&grant_lock);
+
*entryp = xengnt_get_entry();
- if (__predict_false(*entryp == XENGNT_NO_ENTRY))
+ if (__predict_false(*entryp == XENGNT_NO_ENTRY)) {
+ mutex_exit(&grant_lock);
return ENOMEM;
+ }
- mutex_enter(&grant_lock);
grant_table[*entryp].frame = 0;
grant_table[*entryp].domid = dom;
/*