[BACK]Return to idt.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / x86 / x86

Annotation of src/sys/arch/x86/x86/idt.c, Revision 1.6.2.1

1.6.2.1 ! pgoyette    1: /*     $NetBSD: idt.c,v 1.8 2018/09/23 15:28:49 cherry Exp $   */
1.1       yamt        2:
                      3: /*-
1.3       ad          4:  * Copyright (c) 1996, 1997, 1998, 2000, 2009 The NetBSD Foundation, Inc.
1.1       yamt        5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
1.3       ad          8:  * by Charles M. Hannum, by Jason R. Thorpe of the Numerical Aerospace
                      9:  * Simulation Facility NASA Ames Research Center, and by Andrew Doran.
1.1       yamt       10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     21:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     23:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     24:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     25:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     26:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     27:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     28:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     29:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     30:  * POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*-
                     34:  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
                     35:  * All rights reserved.
                     36:  *
                     37:  * This code is derived from software contributed to Berkeley by
                     38:  * William Jolitz.
                     39:  *
                     40:  * Redistribution and use in source and binary forms, with or without
                     41:  * modification, are permitted provided that the following conditions
                     42:  * are met:
                     43:  * 1. Redistributions of source code must retain the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer.
                     45:  * 2. Redistributions in binary form must reproduce the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer in the
                     47:  *    documentation and/or other materials provided with the distribution.
                     48:  * 3. Neither the name of the University nor the names of its contributors
                     49:  *    may be used to endorse or promote products derived from this software
                     50:  *    without specific prior written permission.
                     51:  *
                     52:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     53:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     54:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     55:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     56:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     57:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     58:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     59:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     60:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     61:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     62:  * SUCH DAMAGE.
                     63:  *
                     64:  *     @(#)machdep.c   7.4 (Berkeley) 6/3/91
                     65:  */
                     66:
                     67: #include <sys/cdefs.h>
1.6.2.1 ! pgoyette   68: __KERNEL_RCSID(0, "$NetBSD: idt.c,v 1.8 2018/09/23 15:28:49 cherry Exp $");
1.1       yamt       69:
                     70: #include <sys/param.h>
                     71: #include <sys/systm.h>
                     72: #include <sys/mutex.h>
1.3       ad         73: #include <sys/cpu.h>
                     74: #include <sys/atomic.h>
1.1       yamt       75:
1.6.2.1 ! pgoyette   76: #include <uvm/uvm.h>
1.1       yamt       77:
1.6.2.1 ! pgoyette   78: #include <machine/segments.h>
1.1       yamt       79:
1.6.2.1 ! pgoyette   80: /*
        !            81:  * XEN PV and native have a different idea of what idt entries should
        !            82:  * look like.
        !            83:  */
        !            84: idt_descriptor_t *idt;
1.6       cherry     85:
1.1       yamt       86: static char idt_allocmap[NIDT];
                     87:
1.6.2.1 ! pgoyette   88: /* Normalise across XEN PV and native */
        !            89: #if defined(XEN)
        !            90:
        !            91: void
        !            92: set_idtgate(idt_descriptor_t *xen_idd, void *function, int ist,
        !            93:            int type, int dpl, int sel)
        !            94: {
        !            95:        /*
        !            96:         * Find the page boundary in which the descriptor resides.
        !            97:         * We make an assumption here, that the descriptor is part of
        !            98:         * a table (array), which fits in a page and is page aligned.
        !            99:         *
        !           100:         * This assumption is from the usecases at early startup in
        !           101:         * machine/machdep.c
        !           102:         *
        !           103:         * Thus this function may not work in the "general" case of a
        !           104:         * randomly located idt entry template (for eg:).
        !           105:         */
        !           106:
        !           107:        vaddr_t xen_idt_vaddr = ((vaddr_t) xen_idd) & ~PAGE_MASK;
        !           108:
        !           109:        //kpreempt_disable();
        !           110: #if defined(__x86_64__)
        !           111:        /* Make it writeable, so we can update the values. */
        !           112:        pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ|VM_PROT_WRITE);
        !           113: #endif /* __x86_64 */
        !           114:        xen_idd->cs = sel;
        !           115:        xen_idd->address = (unsigned long) function;
        !           116:        xen_idd->flags = dpl;
        !           117:
        !           118:        /*
        !           119:         * Again we make the assumption that the descriptor is
        !           120:         * implicitly part of an idt, which we infer as
        !           121:         * xen_idt_vaddr. (See above).
        !           122:         */
        !           123:        xen_idd->vector = xen_idd - (idt_descriptor_t *)xen_idt_vaddr;
        !           124:
        !           125:        /* Back to read-only, as it should be. */
        !           126: #if defined(__x86_64__)
        !           127:        pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ);
        !           128: #endif /* __x86_64 */
        !           129:        //kpreempt_enable();
        !           130: }
        !           131: void
        !           132: unset_idtgate(idt_descriptor_t *xen_idd)
        !           133: {
        !           134: #if defined(__x86_64__)
        !           135:        vaddr_t xen_idt_vaddr = ((vaddr_t) xen_idd) & PAGE_MASK;
        !           136:
        !           137:        /* Make it writeable, so we can update the values. */
        !           138:        pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ|VM_PROT_WRITE);
        !           139: #endif /* __x86_64 */
        !           140:
        !           141:        /* Zero it */
        !           142:        memset(xen_idd, 0, sizeof (*xen_idd));
        !           143:
        !           144: #if defined(__x86_64__)
        !           145:        /* Back to read-only, as it should be. */
        !           146:        pmap_changeprot_local(xen_idt_vaddr, VM_PROT_READ);
        !           147: #endif /* __x86_64 */
        !           148: }
        !           149: #else /* XEN */
        !           150: void
        !           151: set_idtgate(idt_descriptor_t *idd, void *function, int ist, int type, int dpl, int sel)
        !           152: {
        !           153:        setgate(idd, function, ist, type, dpl,  sel);
        !           154: }
        !           155: void
        !           156: unset_idtgate(idt_descriptor_t *idd)
        !           157: {
        !           158:        unsetgate(idd);
        !           159: }
        !           160: #endif /* XEN */
        !           161:
1.1       yamt      162: /*
                    163:  * Allocate an IDT vector slot within the given range.
1.3       ad        164:  * cpu_lock will be held unless single threaded during early boot.
1.1       yamt      165:  */
                    166: int
                    167: idt_vec_alloc(int low, int high)
                    168: {
                    169:        int vec;
                    170:
1.3       ad        171:        KASSERT(mutex_owned(&cpu_lock) || !mp_online);
                    172:
1.1       yamt      173:        for (vec = low; vec <= high; vec++) {
                    174:                if (idt_allocmap[vec] == 0) {
1.3       ad        175:                        /* idt_vec_free() can be unlocked, so membar. */
                    176:                        membar_sync();
1.1       yamt      177:                        idt_allocmap[vec] = 1;
                    178:                        return vec;
                    179:                }
                    180:        }
                    181:        return 0;
                    182: }
                    183:
                    184: void
                    185: idt_vec_reserve(int vec)
                    186: {
1.3       ad        187:        int result;
                    188:
                    189:        KASSERT(mutex_owned(&cpu_lock) || !mp_online);
1.1       yamt      190:
1.3       ad        191:        result = idt_vec_alloc(vec, vec);
1.1       yamt      192:        if (result != vec) {
                    193:                panic("%s: failed to reserve vec %d", __func__, vec);
                    194:        }
                    195: }
                    196:
                    197: void
                    198: idt_vec_set(int vec, void (*function)(void))
                    199: {
                    200:
                    201:        KASSERT(idt_allocmap[vec] == 1);
1.6.2.1 ! pgoyette  202:        set_idtgate(&idt[vec], function, 0, SDT_SYS386IGT, SEL_KPL,
        !           203:               GSEL(GCODE_SEL, SEL_KPL));
1.1       yamt      204: }
                    205:
1.3       ad        206: /*
                    207:  * Free IDT vector.  No locking required as release is atomic.
                    208:  */
1.1       yamt      209: void
                    210: idt_vec_free(int vec)
                    211: {
                    212:
1.6.2.1 ! pgoyette  213:        unset_idtgate(&idt[vec]);
1.1       yamt      214:        idt_allocmap[vec] = 0;
                    215: }
                    216:

CVSweb <webmaster@jp.NetBSD.org>