summaryrefslogtreecommitdiff
path: root/libhurd-mm/pager.c
diff options
context:
space:
mode:
authorneal <neal>2008-02-08 10:46:36 +0000
committerneal <neal>2008-02-08 10:46:36 +0000
commite2a45e8e3189aa0bb4383928a1da9e24cdba3755 (patch)
treed55f82b5bc5e67b1ca3ca172c1829af2dc4202da /libhurd-mm/pager.c
parent80483bc20c75b9f16c966d3f636df505d87b6b8a (diff)
2008-02-08 Neal H. Walfield <neal@gnu.org>
* pager.c (__attribute__): New function. (pager_fault): Call it before taking PAGERS_LOCK.
Diffstat (limited to 'libhurd-mm/pager.c')
-rw-r--r--libhurd-mm/pager.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/libhurd-mm/pager.c b/libhurd-mm/pager.c
index 4823c23..558dccc 100644
--- a/libhurd-mm/pager.c
+++ b/libhurd-mm/pager.c
@@ -90,6 +90,18 @@ pager_deinstall (struct pager *pager)
hurd_btree_pager_detach (&pagers, pager);
}
+static void __attribute__ ((noinline))
+ensure_stack(int i)
+{
+ /* XXX: If we fault on the stack while we have PAGERS_LOCK, we
+ deadlock. Ensure that we have some stack space and hope it is
+ enough. (This can't be too much as we may be running on the
+ exception handler's stack.) */
+ volatile char space[1024 + 512];
+ space[0] = 0;
+ space[sizeof (space) - 1] = 0;
+}
+
bool
pager_fault (addr_t addr, uintptr_t ip, struct exception_info info)
{
@@ -98,6 +110,8 @@ pager_fault (addr_t addr, uintptr_t ip, struct exception_info info)
region.start = addr;
region.count = 1;
+ ensure_stack (1);
+
ss_mutex_lock (&pagers_lock);
struct pager *pager = hurd_btree_pager_find (&pagers, &region);