diff --git a/sys/arch/x86/x86/intr.c b/sys/arch/x86/x86/intr.c index 94d4975a32c5..d0f52fb1a6dc 100644 --- a/sys/arch/x86/x86/intr.c +++ b/sys/arch/x86/x86/intr.c @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.29 2007/07/09 20:52:38 ad Exp $ */ +/* $NetBSD: intr.c,v 1.30 2007/08/29 22:21:51 dyoung Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -140,8 +140,9 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.29 2007/07/09 20:52:38 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.30 2007/08/29 22:21:51 dyoung Exp $"); +#include "opt_noredzone.h" #include "opt_multiprocessor.h" #include "opt_acpi.h" @@ -850,6 +851,16 @@ struct intrhand fake_ipi_intrhand; static const char *x86_ipi_names[X86_NIPI] = X86_IPI_NAMES; #endif +static inline int +redzone_const_or_zero(int x) +{ +#ifdef NOREDZONE + return 0; +#else + return x; +#endif /* !NOREDZONE */ +} + /* * Initialize all handlers that aren't dynamically allocated, and exist * for each CPU. @@ -862,7 +873,7 @@ cpu_intr_init(struct cpu_info *ci) int i; #endif #if defined(INTRSTACKSIZE) - char *cp; + vaddr_t istack; #endif /* defined(INTRSTACKSIZE) */ MALLOC(isp, struct intrsource *, sizeof (struct intrsource), M_DEVBUF, @@ -939,8 +950,20 @@ cpu_intr_init(struct cpu_info *ci) intr_calculatemasks(ci); #if defined(INTRSTACKSIZE) - cp = (char *)uvm_km_alloc(kernel_map, INTRSTACKSIZE, 0, UVM_KMF_WIRED); - ci->ci_intrstack = cp + INTRSTACKSIZE - sizeof(register_t); + /* If the red zone is activated, protect both the top and + * the bottom of the stack with an unmapped page. + */ + istack = uvm_km_alloc(kernel_map, + INTRSTACKSIZE + redzone_const_or_zero(2 * PAGE_SIZE), 0, + UVM_KMF_WIRED); + if (redzone_const_or_zero(1)) { + pmap_kremove(istack, PAGE_SIZE); + pmap_kremove(istack + INTRSTACKSIZE + PAGE_SIZE, PAGE_SIZE); + pmap_update(pmap_kernel()); + } + ci->ci_intrstack = + (char *)istack + redzone_const_or_zero(PAGE_SIZE) + INTRSTACKSIZE - + sizeof(register_t); ci->ci_idepth = -1; #endif /* defined(INTRSTACKSIZE) */ }