kern_exec.c (237474) | kern_exec.c (237477) |
---|---|
1/*- 2 * Copyright (c) 1993, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1993, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/kern/kern_exec.c 237474 2012-06-23 09:33:06Z kib $"); | 28__FBSDID("$FreeBSD: head/sys/kern/kern_exec.c 237477 2012-06-23 10:15:23Z kib $"); |
29 30#include "opt_capsicum.h" | 29 30#include "opt_capsicum.h" |
31#include "opt_compat.h" | |
32#include "opt_hwpmc_hooks.h" 33#include "opt_kdtrace.h" 34#include "opt_ktrace.h" 35#include "opt_vm.h" 36 37#include <sys/param.h> 38#include <sys/capability.h> 39#include <sys/systm.h> --- 20 unchanged lines hidden (view full) --- 60#include <sys/resourcevar.h> 61#include <sys/sched.h> 62#include <sys/sdt.h> 63#include <sys/sf_buf.h> 64#include <sys/syscallsubr.h> 65#include <sys/sysent.h> 66#include <sys/shm.h> 67#include <sys/sysctl.h> | 31#include "opt_hwpmc_hooks.h" 32#include "opt_kdtrace.h" 33#include "opt_ktrace.h" 34#include "opt_vm.h" 35 36#include <sys/param.h> 37#include <sys/capability.h> 38#include <sys/systm.h> --- 20 unchanged lines hidden (view full) --- 59#include <sys/resourcevar.h> 60#include <sys/sched.h> 61#include <sys/sdt.h> 62#include <sys/sf_buf.h> 63#include <sys/syscallsubr.h> 64#include <sys/sysent.h> 65#include <sys/shm.h> 66#include <sys/sysctl.h> |
68#include <sys/vdso.h> | |
69#include <sys/vnode.h> 70#include <sys/stat.h> 71#ifdef KTRACE 72#include <sys/ktrace.h> 73#endif 74 75#include <vm/vm.h> 76#include <vm/vm_param.h> --- 1431 unchanged lines hidden (view full) --- 1508 if (*es != execsw_arg) 1509 *xs++ = *es; 1510 *xs = NULL; 1511 if (execsw) 1512 free(execsw, M_TEMP); 1513 execsw = newexecsw; 1514 return (0); 1515} | 67#include <sys/vnode.h> 68#include <sys/stat.h> 69#ifdef KTRACE 70#include <sys/ktrace.h> 71#endif 72 73#include <vm/vm.h> 74#include <vm/vm_param.h> --- 1431 unchanged lines hidden (view full) --- 1506 if (*es != execsw_arg) 1507 *xs++ = *es; 1508 *xs = NULL; 1509 if (execsw) 1510 free(execsw, M_TEMP); 1511 execsw = newexecsw; 1512 return (0); 1513} |
1516 1517static struct sx shared_page_alloc_sx; 1518static vm_object_t shared_page_obj; 1519static int shared_page_free; 1520char *shared_page_mapping; 1521 1522void 1523shared_page_write(int base, int size, const void *data) 1524{ 1525 1526 bcopy(data, shared_page_mapping + base, size); 1527} 1528 1529static int 1530shared_page_alloc_locked(int size, int align) 1531{ 1532 int res; 1533 1534 res = roundup(shared_page_free, align); 1535 if (res + size >= IDX_TO_OFF(shared_page_obj->size)) 1536 res = -1; 1537 else 1538 shared_page_free = res + size; 1539 return (res); 1540} 1541 1542int 1543shared_page_alloc(int size, int align) 1544{ 1545 int res; 1546 1547 sx_xlock(&shared_page_alloc_sx); 1548 res = shared_page_alloc_locked(size, align); 1549 sx_xunlock(&shared_page_alloc_sx); 1550 return (res); 1551} 1552 1553int 1554shared_page_fill(int size, int align, const void *data) 1555{ 1556 int res; 1557 1558 sx_xlock(&shared_page_alloc_sx); 1559 res = shared_page_alloc_locked(size, align); 1560 if (res != -1) 1561 shared_page_write(res, size, data); 1562 sx_xunlock(&shared_page_alloc_sx); 1563 return (res); 1564} 1565 1566static void 1567shared_page_init(void *dummy __unused) 1568{ 1569 vm_page_t m; 1570 vm_offset_t addr; 1571 1572 sx_init(&shared_page_alloc_sx, "shpsx"); 1573 shared_page_obj = vm_pager_allocate(OBJT_PHYS, 0, PAGE_SIZE, 1574 VM_PROT_DEFAULT, 0, NULL); 1575 VM_OBJECT_LOCK(shared_page_obj); 1576 m = vm_page_grab(shared_page_obj, 0, VM_ALLOC_RETRY | VM_ALLOC_NOBUSY | 1577 VM_ALLOC_ZERO); 1578 m->valid = VM_PAGE_BITS_ALL; 1579 VM_OBJECT_UNLOCK(shared_page_obj); 1580 addr = kmem_alloc_nofault(kernel_map, PAGE_SIZE); 1581 pmap_qenter(addr, &m, 1); 1582 shared_page_mapping = (char *)addr; 1583} 1584 1585SYSINIT(shp, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t)shared_page_init, 1586 NULL); 1587 1588static void 1589timehands_update(struct sysentvec *sv) 1590{ 1591 struct vdso_timehands th; 1592 struct vdso_timekeep *tk; 1593 uint32_t enabled, idx; 1594 1595 enabled = tc_fill_vdso_timehands(&th); 1596 tk = (struct vdso_timekeep *)(shared_page_mapping + 1597 sv->sv_timekeep_off); 1598 idx = sv->sv_timekeep_curr; 1599 atomic_store_rel_32(&tk->tk_th[idx].th_gen, 0); 1600 if (++idx >= VDSO_TH_NUM) 1601 idx = 0; 1602 sv->sv_timekeep_curr = idx; 1603 if (++sv->sv_timekeep_gen == 0) 1604 sv->sv_timekeep_gen = 1; 1605 th.th_gen = 0; 1606 if (enabled) 1607 tk->tk_th[idx] = th; 1608 tk->tk_enabled = enabled; 1609 atomic_store_rel_32(&tk->tk_th[idx].th_gen, sv->sv_timekeep_gen); 1610 tk->tk_current = idx; 1611} 1612 1613#ifdef COMPAT_FREEBSD32 1614static void 1615timehands_update32(struct sysentvec *sv) 1616{ 1617 struct vdso_timekeep32 *tk; 1618 struct vdso_timehands32 th; 1619 uint32_t enabled, idx; 1620 1621 enabled = tc_fill_vdso_timehands32(&th); 1622 tk = (struct vdso_timekeep32 *)(shared_page_mapping + 1623 sv->sv_timekeep_off); 1624 idx = sv->sv_timekeep_curr; 1625 atomic_store_rel_32(&tk->tk_th[idx].th_gen, 0); 1626 if (++idx >= VDSO_TH_NUM) 1627 idx = 0; 1628 sv->sv_timekeep_curr = idx; 1629 if (++sv->sv_timekeep_gen == 0) 1630 sv->sv_timekeep_gen = 1; 1631 th.th_gen = 0; 1632 if (enabled) 1633 tk->tk_th[idx] = th; 1634 tk->tk_enabled = enabled; 1635 atomic_store_rel_32(&tk->tk_th[idx].th_gen, sv->sv_timekeep_gen); 1636 tk->tk_current = idx; 1637} 1638#endif 1639 1640/* 1641 * This is hackish, but easiest way to avoid creating list structures 1642 * that needs to be iterated over from the hardclock interrupt 1643 * context. 1644 */ 1645static struct sysentvec *host_sysentvec; 1646#ifdef COMPAT_FREEBSD32 1647static struct sysentvec *compat32_sysentvec; 1648#endif 1649 1650void 1651timekeep_push_vdso(void) 1652{ 1653 1654 if (host_sysentvec != NULL && host_sysentvec->sv_timekeep_base != 0) 1655 timehands_update(host_sysentvec); 1656#ifdef COMPAT_FREEBSD32 1657 if (compat32_sysentvec != NULL && 1658 compat32_sysentvec->sv_timekeep_base != 0) 1659 timehands_update32(compat32_sysentvec); 1660#endif 1661} 1662 1663void 1664exec_sysvec_init(void *param) 1665{ 1666 struct sysentvec *sv; 1667 int tk_base; 1668 uint32_t tk_ver; 1669 1670 sv = (struct sysentvec *)param; 1671 1672 if ((sv->sv_flags & SV_SHP) == 0) 1673 return; 1674 sv->sv_shared_page_obj = shared_page_obj; 1675 sv->sv_sigcode_base = sv->sv_shared_page_base + 1676 shared_page_fill(*(sv->sv_szsigcode), 16, sv->sv_sigcode); 1677 if ((sv->sv_flags & SV_ABI_MASK) != SV_ABI_FREEBSD) 1678 return; 1679 tk_ver = VDSO_TK_VER_CURR; 1680#ifdef COMPAT_FREEBSD32 1681 if ((sv->sv_flags & SV_ILP32) != 0) { 1682 tk_base = shared_page_alloc(sizeof(struct vdso_timekeep32) + 1683 sizeof(struct vdso_timehands32) * VDSO_TH_NUM, 16); 1684 KASSERT(tk_base != -1, ("tk_base -1 for 32bit")); 1685 shared_page_write(tk_base + offsetof(struct vdso_timekeep32, 1686 tk_ver), sizeof(uint32_t), &tk_ver); 1687 KASSERT(compat32_sysentvec == 0, 1688 ("Native compat32 already registered")); 1689 compat32_sysentvec = sv; 1690 } else { 1691#endif 1692 tk_base = shared_page_alloc(sizeof(struct vdso_timekeep) + 1693 sizeof(struct vdso_timehands) * VDSO_TH_NUM, 16); 1694 KASSERT(tk_base != -1, ("tk_base -1 for native")); 1695 shared_page_write(tk_base + offsetof(struct vdso_timekeep, 1696 tk_ver), sizeof(uint32_t), &tk_ver); 1697 KASSERT(host_sysentvec == 0, ("Native already registered")); 1698 host_sysentvec = sv; 1699#ifdef COMPAT_FREEBSD32 1700 } 1701#endif 1702 sv->sv_timekeep_base = sv->sv_shared_page_base + tk_base; 1703 sv->sv_timekeep_off = tk_base; 1704 timekeep_push_vdso(); 1705} | |