From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26421 invoked by alias); 26 Nov 2011 01:50:56 -0000 Received: (qmail 26410 invoked by uid 22791); 26 Nov 2011 01:50:54 -0000 X-SWARE-Spam-Status: No, hits=-7.2 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 26 Nov 2011 01:50:35 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pAQ1oTsl011207 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 25 Nov 2011 20:50:29 -0500 Received: from springer.wildebeest.org (ovpn-116-61.ams2.redhat.com [10.36.116.61]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pAQ1oRS8018784 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 25 Nov 2011 20:50:28 -0500 Received: by springer.wildebeest.org (Postfix, from userid 500) id 0F39F4C6CB; Sat, 26 Nov 2011 02:50:26 +0100 (CET) Subject: Re: s390x help needed - kernel read faults From: Mark Wielaard To: David Smith Cc: Heiko Carstens , Ananth N Mavinakayanahalli , Systemtap List In-Reply-To: <20111107171736.GA11606@hermans.wildebeest.org> References: <4E9C76F7.6010802@redhat.com> <20111018052305.GA22831@in.ibm.com> <20111018081753.GA2578@osiris.boeblingen.de.ibm.com> <4E9D8577.9030705@redhat.com> <20111028124058.GA2475@osiris.boeblingen.de.ibm.com> <4EAAF791.1060109@redhat.com> <20111031102934.GA4768@osiris.boeblingen.de.ibm.com> <4EB80147.8050303@redhat.com> <20111107171736.GA11606@hermans.wildebeest.org> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Date: Sat, 26 Nov 2011 01:50:00 -0000 Message-ID: <1322272226.4539.24.camel@springer.wildebeest.org> Mime-Version: 1.0 Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org X-SW-Source: 2011-q4/txt/msg00220.txt.bz2 On Mon, 2011-11-07 at 18:17 +0100, Mark Wielaard wrote: > On Mon, Nov 07, 2011 at 10:03:19AM -0600, David Smith wrote: > > I'm not sure why we provided our own functions, that decision was made a > > long time ago. If we can't look at the address and know whether it is a > > user space or kernel space address, then I don't see much choice than to > > break up our memory accesses and require the callers to know whether > > they are accessing kernel space or user space. >=20 > Yes, it seems not that hard to track fully, we mostly do know already. So I split our deref and store_deref into uderef/kderef and store_u/kderef that are now used when user or kernel addresses are accessed. For most architectures these are equal. But for s390x I replaced our custom accessor functions with with standard s390 kernel __get_user() and __put_user() functions and then wrap those in get_fs() set_fs() calls to switch between user/kernel space addresses. See below. Tested against 2.6.18 (rhel5) and 2.6.32 (rhel6) kernels. It improves the make installcheck results a lot. There is still some work to do for the user space dwarf unwinder. Cheers, Mark =3D=3D=3D runtime/loc2c-runtime.h s390 deref functions =3D=3D=3D #elif defined (__s390__) || defined (__s390x__) /* Use same __get_user() and __put_user() for both user and kernel addresses, but make sure set_fs() is called appropriately first. */ #define uderef(size, addr) ({ \ u8 _b; u16 _w; u32 _l; u64 _q; \ uintptr_t _a =3D (uintptr_t) addr; \ intptr_t _v =3D 0; \ int _bad =3D 0; \ mm_segment_t _oldfs =3D get_fs(); \ set_fs (USER_DS); \ switch (size) { \ case 1: _bad =3D __get_user(_b, (u8 *)(_a)); _v =3D _b; break; \ case 2: _bad =3D __get_user(_w, (u16 *)(_a)); _v =3D _w; break; \ case 4: _bad =3D __get_user(_l, (u32 *)(_a)); _v =3D _l; break; \ case 8: _bad =3D __get_user(_q, (u64 *)(_a)); _v =3D _q; break; \ default: __get_user_bad(); \ } \ set_fs (_oldfs); \ if (_bad) \ DEREF_FAULT(addr); \ _v; \ }) #define store_uderef(size, addr, value) ({ \ int _bad =3D 0; \ mm_segment_t _oldfs =3D get_fs(); \ set_fs (USER_DS); \ switch (size) { \ case 1: _bad =3D __put_user(((u8)(value)), ((u8 *)(addr))); break; \ case 2: _bad =3D __put_user(((u16)(value)), ((u16 *)(addr))); break; \ case 4: _bad =3D __put_user(((u32)(value)), ((u32 *)(addr))); break; \ case 8: _bad =3D __put_user(((u64)(value)), ((u64 *)(addr))); break; \ default: __put_user_bad(); \ } \ set_fs (_oldfs); \ if (_bad) \ STORE_DEREF_FAULT(addr); \ }) #define kderef(size, addr) ({ \ u8 _b; u16 _w; u32 _l; u64 _q; \ uintptr_t _a =3D (uintptr_t) addr; \ intptr_t _v =3D 0; \ int _bad =3D 0; \ mm_segment_t _oldfs =3D get_fs(); \ set_fs (KERNEL_DS); \ switch (size) { \ case 1: _bad =3D __get_user(_b, (u8 *)(_a)); _v =3D _b; break; \ case 2: _bad =3D __get_user(_w, (u16 *)(_a)); _v =3D _w; break; \ case 4: _bad =3D __get_user(_l, (u32 *)(_a)); _v =3D _l; break; \ case 8: _bad =3D __get_user(_q, (u64 *)(_a)); _v =3D _q; break; \ default: __get_user_bad(); \ } \ set_fs (_oldfs); \ if (_bad) \ DEREF_FAULT(addr); \ _v; \ }) #define store_kderef(size, addr, value) ({ \ int _bad =3D 0; \ mm_segment_t _oldfs =3D get_fs(); \ set_fs (KERNEL_DS); \ switch (size) { \ case 1: _bad =3D __put_user(((u8)(value)), ((u8 *)(addr))); break; \ case 2: _bad =3D __put_user(((u16)(value)), ((u16 *)(addr))); break; \ case 4: _bad =3D __put_user(((u32)(value)), ((u32 *)(addr))); break; \ case 8: _bad =3D __put_user(((u64)(value)), ((u64 *)(addr))); break; \ default: __put_user_bad(); \ } \ set_fs (_oldfs); \ if (_bad) \ STORE_DEREF_FAULT(addr); \ }) #endif /* (s390) || (s390x) */