From owner-freebsd-virtualization@FreeBSD.ORG Mon Jul 25 20:46:53 2011 Return-Path: Delivered-To: freebsd-virtualization@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7BCBD1065678; Mon, 25 Jul 2011 20:46:53 +0000 (UTC) (envelope-from to.my.trociny@gmail.com) Received: from mail-ey0-f176.google.com (mail-ey0-f176.google.com [209.85.215.176]) by mx1.freebsd.org (Postfix) with ESMTP id 5FEAE8FC16; Mon, 25 Jul 2011 20:46:52 +0000 (UTC) Received: by eya28 with SMTP id 28so4485952eya.21 for ; Mon, 25 Jul 2011 13:46:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:references:x-comment-to:sender:date:message-id :user-agent:mime-version:content-type; bh=OwcOD5hynsQ3kozWU93SHn7ywWnK6v4bXQI0q29YR+A=; b=M4QbTThFMPmiizg/jF1rXGLtXMgVap0QQ+iSrlS+41dRGxpDd+rvyYlpfCtl5GaUsI GC6cd0GRDGAaXcrnJBxbd8Xk16CMLum6m/b1VHmzY2XTZIyInqTLAxj9B3bdqGRJXEus OqU+nqgkznU6vy8n2VbV7YpcOi3eTtT+AYmQ8= Received: by 10.204.3.21 with SMTP id 21mr1520079bkl.6.1311626811219; Mon, 25 Jul 2011 13:46:51 -0700 (PDT) Received: from localhost ([95.69.173.122]) by mx.google.com with ESMTPS id i1sm1423011bku.54.2011.07.25.13.46.47 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 25 Jul 2011 13:46:48 -0700 (PDT) From: Mikolaj Golub To: Kostik Belousov References: <86r55ghzsi.fsf@kopusha.home.net> <20110724151114.GP17489@deviant.kiev.zoral.com.ua> X-Comment-To: Kostik Belousov Sender: Mikolaj Golub Date: Mon, 25 Jul 2011 23:46:46 +0300 Message-ID: <868vrmulzd.fsf@kopusha.home.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (berkeley-unix) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Cc: Marko Zec , "Bjoern A. Zeeb" , Robert Watson , freebsd-virtualization@freebsd.org Subject: Re: FIX: accessing module's virtualized global variables from another module X-BeenThere: freebsd-virtualization@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Discussion of various virtualization techniques FreeBSD supports." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Jul 2011 20:46:53 -0000 --=-=-= On Sun, 24 Jul 2011 18:11:14 +0300 Kostik Belousov wrote: KB> On Sun, Jul 24, 2011 at 11:02:21AM +0300, Mikolaj Golub wrote: >> Also, could someone explain what is kern/link_elf_obj.c for? The patch does >> not deal with this file, but I see the reloactions here similar to those in >> link_elf.c. So I might need to do similar modifiactions in link_elf_obj.c too, >> but I don't know where this code is used (it looks like it is not executed on >> my box, so I don't know how to test it). KB> The link_elf_obj is a linker for architectures that use object file format KB> for the modules. So far, the list consists only of amd64. Thanks! And there is no need in hacks with relocations in this case: in link_elf_load_file() it just allocates space in kernel 'set_vnet' set for 'set_vnet' from the module and sets addr to point to this space. As the fix appears to be link_elf.c specific and the code is used only in this file I have modified the patch placing set_vnet list and its functions in link_elf.c. -- Mikolaj Golub --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=vnet.set_vnet.patch Index: sys/kern/link_elf.c =================================================================== --- sys/kern/link_elf.c (revision 224397) +++ sys/kern/link_elf.c (working copy) @@ -123,6 +123,17 @@ typedef struct elf_file { #endif } *elf_file_t; +#ifdef VIMAGE +struct set_vnet { + uintptr_t vs_start; + uintptr_t vs_stop; + uintptr_t vs_base; + TAILQ_ENTRY(set_vnet) vs_link; +}; + +static TAILQ_HEAD(set_vnet_head, set_vnet) set_vnet_list; +#endif + #include static int link_elf_link_common_finish(linker_file_t); @@ -345,6 +356,9 @@ link_elf_init(void* arg) (void)link_elf_link_common_finish(linker_kernel_file); linker_kernel_file->flags |= LINKER_FILE_LINKED; +#ifdef VIMAGE + TAILQ_INIT(&set_vnet_list); +#endif } SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_THIRD, link_elf_init, 0); @@ -520,7 +534,89 @@ parse_dpcpu(elf_file_t ef) } #ifdef VIMAGE +static void +set_vnet_insert(struct set_vnet *set) +{ + struct set_vnet *iter; + + TAILQ_FOREACH(iter, &set_vnet_list, vs_link) { + + KASSERT((set->vs_start < iter->vs_start && set->vs_stop < iter->vs_stop) || + (set->vs_start > iter->vs_start && set->vs_stop > iter->vs_stop), + ("vnet sets intersection: to insert: 0x%jx-0x%jx; inserted: 0x%jx-0x%jx", + (uintmax_t)set->vs_start, (uintmax_t)set->vs_stop, + (uintmax_t)iter->vs_start, (uintmax_t)iter->vs_stop)); + + if (iter->vs_start > set->vs_start) { + TAILQ_INSERT_BEFORE(iter, set, vs_link); + break; + } + } + + if (iter == NULL) + TAILQ_INSERT_TAIL(&set_vnet_list, set, vs_link); +} + +static void +set_vnet_remove(struct set_vnet *set) +{ + TAILQ_REMOVE(&set_vnet_list, set, vs_link); +} + +static struct set_vnet * +set_vnet_search(uintptr_t addr) +{ + struct set_vnet *set; + + TAILQ_FOREACH(set, &set_vnet_list, vs_link) { + if (addr < set->vs_start) + return (NULL); + if (addr < set->vs_stop) + return (set); + } + return (NULL); +} + +static void +set_vnet_add(uintptr_t start, uintptr_t stop, uintptr_t base) +{ + struct set_vnet *set; + + set = malloc(sizeof(*set), M_LINKER, M_WAITOK); + set->vs_start = start; + set->vs_stop = stop; + set->vs_base = base; + set_vnet_insert(set); +} + +static void +set_vnet_delete(uintptr_t start) +{ + struct set_vnet *set; + + set = set_vnet_search(start); + KASSERT(set != NULL, ("deleting unknown vnet set (start = 0x%jx)", + (uintmax_t)start)); + set_vnet_remove(set); + free(set, M_LINKER); +} + static int +set_vnet_find(uintptr_t addr, uintptr_t *start, uintptr_t *base) +{ + struct set_vnet *set; + + set = set_vnet_search(addr); + if (set != NULL) { + *start = set->vs_start; + *base = set->vs_base; + return (1); + } else { + return (0); + } +} + +static int parse_vnet(elf_file_t ef) { int count; @@ -544,6 +640,7 @@ parse_vnet(elf_file_t ef) return (ENOSPC); memcpy((void *)ef->vnet_base, (void *)ef->vnet_start, count); vnet_data_copy((void *)ef->vnet_base, count); + set_vnet_add(ef->vnet_start, ef->vnet_stop, ef->vnet_base); return (0); } @@ -1000,6 +1097,7 @@ link_elf_unload_file(linker_file_t file) if (ef->vnet_base != 0) { vnet_data_free((void *)ef->vnet_base, ef->vnet_stop - ef->vnet_start); + set_vnet_delete(ef->vnet_start); } #endif #ifdef GDB @@ -1438,6 +1536,10 @@ elf_lookup(linker_file_t lf, Elf_Size symidx, int elf_file_t ef = (elf_file_t)lf; const Elf_Sym *sym; const char *symbol; + Elf_Addr addr; +#ifdef VIMAGE + uintptr_t vnet_start, vnet_base; +#endif /* Don't even try to lookup the symbol if the index is bogus. */ if (symidx >= ef->nchains) @@ -1469,7 +1571,13 @@ elf_lookup(linker_file_t lf, Elf_Size symidx, int if (*symbol == 0) return (0); - return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); + addr = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); + +#ifdef VIMAGE + if (set_vnet_find(addr, &vnet_start, &vnet_base)) + addr = addr - vnet_start + vnet_base; +#endif + return addr; } static void --=-=-=--