From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46162) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bK151-0006FQ-7q for qemu-devel@nongnu.org; Mon, 04 Jul 2016 06:26:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bK14v-0004eL-7x for qemu-devel@nongnu.org; Mon, 04 Jul 2016 06:26:18 -0400 Received: from mx-v6.kamp.de ([2a02:248:0:51::16]:53632 helo=mx01.kamp.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bK14u-0004dl-UP for qemu-devel@nongnu.org; Mon, 04 Jul 2016 06:26:13 -0400 References: <1467272240-32123-1-git-send-email-pl@kamp.de> <1467272240-32123-2-git-send-email-pl@kamp.de> <851cfb04-5e9d-6f9a-5932-09e697aa500e@twiddle.net> <6bc08536-27f5-e4b1-fc8b-4bb04a8655dc@twiddle.net> <5779FF99.20605@kamp.de> <8b78fc50-8bbd-4383-6dda-6d56fd28e449@redhat.com> From: Peter Lieven Message-ID: <577A39B7.2010007@kamp.de> Date: Mon, 4 Jul 2016 12:25:59 +0200 MIME-Version: 1.0 In-Reply-To: <8b78fc50-8bbd-4383-6dda-6d56fd28e449@redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 1/6] oslib-posix: add helpers for stack alloc and free List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini , Richard Henderson , qemu-devel@nongnu.org Cc: kwolf@redhat.com, peter.maydell@linaro.org, mst@redhat.com, dgilbert@redhat.com, mreitz@redhat.com Am 04.07.2016 um 12:19 schrieb Paolo Bonzini: > > On 04/07/2016 08:18, Peter Lieven wrote: >> Am 01.07.2016 um 22:49 schrieb Richard Henderson: >>> On 07/01/2016 01:12 PM, Richard Henderson wrote: >>>> On 06/30/2016 12:37 AM, Peter Lieven wrote: >>>>> +void *qemu_alloc_stack(size_t sz) >>>>> +{ >>>>> + /* allocate sz bytes plus one extra page for a guard >>>>> + * page at the bottom of the stack */ >>>>> + void *ptr = mmap(NULL, sz + getpagesize(), PROT_NONE, >>>>> + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); >>>>> + if (ptr == MAP_FAILED) { >>>>> + abort(); >>>>> + } >>>>> + if (mmap(ptr + getpagesize(), sz, PROT_READ | PROT_WRITE, >>>>> + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) == >>>>> MAP_FAILED) { >>>>> + abort(); >>>>> + } >>> Rare platforms now, but fwiw, this is incorrect for hppa and ia64. >>> >>> For hppa, stack grows up, so the guard page needs to be at the top. >>> >>> For ia64, there are two stacks, the "normal" program stack (grows >>> down) and the register window stack (grows up). The guard page goes >>> in between. >>> >>> See e.g. glibc/nptl/allocatestack.c >>> >>> #ifdef NEED_SEPARATE_REGISTER_STACK >>> char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1); >>> #elif _STACK_GROWS_DOWN >>> char *guard = mem; >>> #elif _STACK_GROWS_UP >>> char *guard = (char *) (((uintptr_t) pd - guardsize) & >>> ~pagesize_m1); >>> #endif >>> if (mprotect (guard, guardsize, PROT_NONE) != 0) >> It seems that ia64 needs even more care when allocating a stack, right? > No, you just pass the stack and the runtime takes care of initializing > the two stack pointers: > > uc.uc_link = &old_uc; > uc.uc_stack.ss_sp = co->stack; > uc.uc_stack.ss_size = stack_size; > uc.uc_stack.ss_flags = 0; > > FWIW, I've heard about some experiments with "split" stacks on x86 too. > In this case variables that escaped went on the "grows up" part, while > everything else (parameters, spills and call return addresses) stayed on > the hardware "grows down" part. The result is more secure and actually > even faster because of better TLB locality. So, you would basically copy the if/elif part from allocatestack.c ? In this case I would also count the guardpage as part of the stack, so that the usable stack size is actually reduced by one page? Peter