From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from omta001.cacentral1.a.cloudfilter.net (omta001.cacentral1.a.cloudfilter.net [3.97.99.32]) by sourceware.org (Postfix) with ESMTPS id ABE7F385782E for ; Wed, 25 Aug 2021 16:59:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org ABE7F385782E Received: from shw-obgw-4001a.ext.cloudfilter.net ([10.228.9.142]) by cmsmtp with ESMTP id IfcRmYHHYRXZfIwF0mXE8F; Wed, 25 Aug 2021 16:59:06 +0000 Received: from kylheku.com ([70.79.163.252]) by cmsmtp with ESMTPA id IwEzmxV4b7ezUIwF0mVwaS; Wed, 25 Aug 2021 16:59:06 +0000 X-Authority-Analysis: v=2.4 cv=Pv9W0yA3 c=1 sm=1 tr=0 ts=612676da a=95A0EdhkF1LMGt25d7h1IQ==:117 a=95A0EdhkF1LMGt25d7h1IQ==:17 a=IkcTkHD0fZMA:10 a=SMorJkV_YP8A:10 a=MhDmnRu9jo8A:10 a=5KLPUuaC_9wA:10 a=K0uT-WWBcUUC0MbTKJ4A:9 a=QEXdDO2ut3YA:10 Received: from www-data by kylheku.com with local (Exim 4.72) (envelope-from <382-725-6798@kylheku.com>) id 1mIwEz-0006Zi-E3; Wed, 25 Aug 2021 09:59:05 -0700 To: Andrew Haley Subject: Re: is fork() =?UTF-8?Q?supported=3F?= X-PHP-Originating-Script: 501:rcmail.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Date: Wed, 25 Aug 2021 09:59:05 -0700 From: "Kaz Kylheku (libffi)" <382-725-6798@kylheku.com> Cc: libffi-discuss@sourceware.org In-Reply-To: <4da1a4e5-fbac-5d5f-b5ee-abe0b252ed80@redhat.com> References: <09e0d2b62f62482b2fa1c29120a43078@mail.kylheku.com> <4da1a4e5-fbac-5d5f-b5ee-abe0b252ed80@redhat.com> Message-ID: <8a8c093795597dcc8e71e844e235a57d@mail.kylheku.com> X-Sender: 382-725-6798@kylheku.com User-Agent: Roundcube Webmail/0.9.2 X-CMAE-Envelope: MS4xfJ4SOhbMlEbnwJb/GtOuvUsLUHsE8zkK3raYcZrTIitGeCJZM+8bTbEKlwuaiQSB74inh0LtnLSEBWc4tyaOfDsViVRbAHjaSXuVoET5t7roi90E0kYW OEJ7Ohn9Jz+GtoZppoGpqQvtF2bvWpE4aWOj+5uC5vLj+Fyq9UKXZqOXaQC8AviWVgsQSMBoaf4sYadJ3ka977wXh1f9Y28sC9pI91oDesMGAC/gBKlV5DF1 X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FROM_STARTS_WITH_NUMS, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=no autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libffi-discuss@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libffi-discuss mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Aug 2021 16:59:10 -0000 On 2021-08-25 02:27, Andrew Haley via Libffi-discuss wrote: > Note that this is *per thread*. other threads will simply continue to > execute code in the JITted region. The JIT can generate code, but can > not execute any JITted code until it calls > pthread_jit_write_protect_np(true). Of course this requires threads to > have differently-mapped regions. It would be very nice to have in > Linux. It is the right way to do it. It's *a* way to do it, but tweaking the address space so that it looks different in different threads seems extremely wrong and repugnant. The threads of a process should live in exactly the same address space, in every detail: every page, every protection bit. There should be no TLB switching/flushing when we task switch from one thread to another in the same process. Of course, this is just another requirement, and no requirement is absolutely non-negotiable otherwise otherwise we have religion and not engineering. However, this is a pretty firm, fundamental thing, I would think! If it was done without actually making different memory maps per thread that would be great. For instance, suppose the mapping that is opened up for writing for one thread is actually write protected to all threads. What happens is this: 1. The "blessed" thread which owns the JIT mapping performs a write. 2. This traps into the kernel. 3. The kernel sees, aha, this is the blessed thread which is allowed to write. 4. The kernel emulates the write. 5. The thread's instruction pointer and other machine state is fixed up to look like it had done the write. 6. The thread is restarted. If the thread is not the blessed one, a fatal signal is generated, as usual. One the JITted code is installed, the blessedness goes away; all threads bomb if they write access it. Prior art for this, is obviously, things like simulating misaligned memory accesses on machines that trap on misalignment. The downside is that it's slow for writing a large amount of JIT material. Though installation of JIT material is amortized over the cost of compiling it in the first place, that may still be unacceptable overhead. (Also, it's not always amortized. Some ahead-of-time compiling situations would also use this mechanism; JIT is just a convenient acronym. Not all code loading is done by mapping directly into memory. In some languages, an code object might be read containing the executable code as a blob literal, which is then installed as if it came from JIT). Really, you need a dedicated write-like syscall for this, which the blessed thread can use to specify the bytes to be written to the JIT memory. That is similar to the solution involving writes to a file, except there is no file. In Linux, a possible place to dump this this might be oh, let's see, prctl? prctl(PR_WRITE_JIT, (long) dst, (long) src, (long) size); [dst, dst + size) must be a MAP_JIT mapping indicating the calling thread as being blessed, otherwise it fails.