Commit aa3ea612 authored by Konstantin Belousov's avatar Konstantin Belousov
Browse files

x86: remove gcov kernel support

Reviewed by:	jhb
Sponsored by:	The FreeBSD Foundation
Differential revision:	https://reviews.freebsd.org/D29529
parent 76b1b5ce
......@@ -81,7 +81,6 @@ as_lapic_eoi:
*/
.macro ISR_VEC index, vec_name
INTR_HANDLER \vec_name
FAKE_MCOUNT(TF_RIP(%rsp))
cmpl $0,x2apic_mode
je 1f
movl $(MSR_APIC_ISR0 + \index),%ecx
......@@ -98,7 +97,6 @@ as_lapic_eoi:
movl %eax, %edi /* pass the IRQ */
call lapic_handle_intr
3:
MEXITCOUNT
jmp doreti
.endm
......@@ -127,28 +125,22 @@ IDTVEC(spuriousint)
* Local APIC periodic timer handler.
*/
INTR_HANDLER timerint
FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp, %rdi
call lapic_handle_timer
MEXITCOUNT
jmp doreti
/*
* Local APIC CMCI handler.
*/
INTR_HANDLER cmcint
FAKE_MCOUNT(TF_RIP(%rsp))
call lapic_handle_cmc
MEXITCOUNT
jmp doreti
/*
* Local APIC error interrupt handler.
*/
INTR_HANDLER errorint
FAKE_MCOUNT(TF_RIP(%rsp))
call lapic_handle_error
MEXITCOUNT
jmp doreti
#ifdef XENHVM
......@@ -157,10 +149,8 @@ IDTVEC(spuriousint)
* Only used when the hypervisor supports direct vector callbacks.
*/
INTR_HANDLER xen_intr_upcall
FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp, %rdi
call xen_intr_handle_upcall
MEXITCOUNT
jmp doreti
#endif
......@@ -184,9 +174,7 @@ IDTVEC(spuriousint)
*/
INTR_HANDLER ipi_intr_bitmap_handler
call as_lapic_eoi
FAKE_MCOUNT(TF_RIP(%rsp))
call ipi_bitmap_handler
MEXITCOUNT
jmp doreti
/*
......@@ -210,9 +198,7 @@ IDTVEC(spuriousint)
*/
INTR_HANDLER ipi_swi
call as_lapic_eoi
FAKE_MCOUNT(TF_RIP(%rsp))
call ipi_swi_handler
MEXITCOUNT
jmp doreti
/*
......
......@@ -44,11 +44,9 @@
*/
.macro INTR irq_num, vec_name
INTR_HANDLER \vec_name
FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp, %rsi
movl $\irq_num, %edi /* pass the IRQ */
call atpic_handle_intr
MEXITCOUNT
jmp doreti
.endm
......
......@@ -101,9 +101,6 @@ dtrace_invop_calltrap_addr:
* registers are reloaded on return to the usermode.
*/
MCOUNT_LABEL(user)
MCOUNT_LABEL(btrap)
/* Traps that we leave interrupts disabled for. */
.macro TRAP_NOEN l, trapno
PTI_ENTRY \l,\l\()_pti_k,\l\()_pti_u
......@@ -257,7 +254,6 @@ alltraps_pushregs_no_rax:
pushfq
andq $~(PSL_D | PSL_AC),(%rsp)
popfq
FAKE_MCOUNT(TF_RIP(%rsp))
#ifdef KDTRACE_HOOKS
/*
* DTrace Function Boundary Trace (fbt) probes are triggered
......@@ -288,7 +284,6 @@ alltraps_pushregs_no_rax:
calltrap:
movq %rsp,%rdi
call trap_check
MEXITCOUNT
jmp doreti /* Handle any pending ASTs */
/*
......@@ -576,7 +571,6 @@ fast_syscall_common:
movq %r14,TF_R14(%rsp) /* C preserved */
movq %r15,TF_R15(%rsp) /* C preserved */
movl $TF_HASSEGS,TF_FLAGS(%rsp)
FAKE_MCOUNT(TF_RIP(%rsp))
movq PCPU(CURTHREAD),%rdi
movq %rsp,TD_FRAME(%rdi)
movl TF_RFLAGS(%rsp),%esi
......@@ -594,7 +588,6 @@ fast_syscall_common:
call handle_ibrs_exit
callq *mds_handler
/* Restore preserved registers. */
MEXITCOUNT
movq TF_RDI(%rsp),%rdi /* bonus; preserve arg 1 */
movq TF_RSI(%rsp),%rsi /* bonus: preserve arg 2 */
movq TF_RDX(%rsp),%rdx /* return value 2 */
......@@ -621,7 +614,6 @@ fast_syscall_common:
jmp 1b
4: /* Requested full context restore, use doreti for that. */
MEXITCOUNT
jmp doreti
/*
......@@ -692,10 +684,8 @@ IDTVEC(dbg)
rdmsr
movl %eax,%r14d
call handle_ibrs_entry
2: FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp,%rdi
2: movq %rsp,%rdi
call trap
MEXITCOUNT
testl $CPUID_STDEXT3_IBPB,cpu_stdext_feature3(%rip)
je 3f
movl %r14d,%eax
......@@ -866,10 +856,8 @@ nmi_fromuserspace:
3:
/* Note: this label is also used by ddb and gdb: */
nmi_calltrap:
FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp,%rdi
call trap
MEXITCOUNT
#ifdef HWPMC_HOOKS
/*
* Capture a userspace callchain if needed.
......@@ -1055,10 +1043,8 @@ mchk_fromuserspace:
1: call handle_ibrs_entry
/* Note: this label is also used by ddb and gdb: */
mchk_calltrap:
FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp,%rdi
call mca_intr
MEXITCOUNT
testl %ebx,%ebx /* %ebx != 0 => return to userland */
jnz doreti_exit
/*
......@@ -1089,7 +1075,6 @@ ENTRY(fork_trampoline)
movq %rbx,%rsi /* arg1 */
movq %rsp,%rdx /* trapframe pointer */
call fork_exit
MEXITCOUNT
jmp doreti /* Handle any ASTs */
/*
......@@ -1115,8 +1100,6 @@ ENTRY(fork_trampoline)
.p2align 4
.text
SUPERALIGN_TEXT
MCOUNT_LABEL(bintr)
#include <amd64/amd64/apic_vector.S>
#ifdef DEV_ATPIC
......@@ -1128,9 +1111,6 @@ MCOUNT_LABEL(bintr)
#include <amd64/amd64/atpic_vector.S>
#endif
.text
MCOUNT_LABEL(eintr)
/*
* void doreti(struct trapframe)
*
......@@ -1141,7 +1121,6 @@ MCOUNT_LABEL(eintr)
.type doreti,@function
.globl doreti
doreti:
FAKE_MCOUNT($bintr) /* init "from" bintr -> doreti */
/*
* Check if ASTs can be handled now.
*/
......@@ -1171,7 +1150,6 @@ doreti_ast:
* registers. The fault is handled in trap.c.
*/
doreti_exit:
MEXITCOUNT
movq PCPU(CURPCB),%r8
/*
......@@ -1332,7 +1310,6 @@ doreti_iret_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq $0,TF_ERR(%rsp) /* XXX should be the error code */
movq $0,TF_ADDR(%rsp)
FAKE_MCOUNT(TF_RIP(%rsp))
jmp calltrap
ALIGN_TEXT
......
......@@ -54,7 +54,7 @@
*
* We are already in long mode, on a 64 bit %cs and running at KERNBASE.
*/
NON_GPROF_ENTRY(btext)
ENTRY(btext)
/* Tell the bios to warmboot next time */
movw $0x1234,0x472
......@@ -79,7 +79,7 @@ NON_GPROF_ENTRY(btext)
jmp 0b
/* la57_trampoline(%rdi pml5) */
NON_GPROF_ENTRY(la57_trampoline)
ENTRY(la57_trampoline)
movq %rsp,%r11
movq %rbx,%r10
leaq la57_trampoline_end(%rip),%rsp
......@@ -118,11 +118,11 @@ l2: movq %r11,%rsp
movq %r10,%rbx
retq
.p2align 4,0
NON_GPROF_ENTRY(la57_trampoline_gdt_desc)
ENTRY(la57_trampoline_gdt_desc)
.word la57_trampoline_end - la57_trampoline_gdt
.long 0 /* filled by pmap_bootstrap_la57 */
.p2align 4,0
NON_GPROF_ENTRY(la57_trampoline_gdt)
ENTRY(la57_trampoline_gdt)
.long 0x00000000 /* null desc */
.long 0x00000000
.long 0x00000000 /* 64bit code */
......@@ -132,7 +132,7 @@ NON_GPROF_ENTRY(la57_trampoline_gdt)
.long 0x0000ffff /* universal data */
.long 0x00cf9300
.dcb.l 16,0
NON_GPROF_ENTRY(la57_trampoline_end)
ENTRY(la57_trampoline_end)
.bss
ALIGN_DATA /* just to be sure */
......
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 1996 Bruce D. Evans.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifdef GUPROF
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/eventhandler.h>
#include <sys/gmon.h>
#include <sys/kernel.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <machine/clock.h>
#include <machine/timerreg.h>
#define CPUTIME_CLOCK_UNINITIALIZED 0
#define CPUTIME_CLOCK_I8254 1
#define CPUTIME_CLOCK_TSC 2
#define CPUTIME_CLOCK_I8254_SHIFT 7
int cputime_bias = 1; /* initialize for locality of reference */
static int cputime_clock = CPUTIME_CLOCK_UNINITIALIZED;
static int cputime_prof_active;
#endif /* GUPROF */
#ifdef __GNUCLIKE_ASM
#if defined(SMP) && defined(GUPROF)
#define MPLOCK " \n\
movl $1,%edx \n\
9: \n\
xorl %eax,%eax \n\
lock \n\
cmpxchgl %edx,mcount_lock \n\
jne 9b \n"
#define MPUNLOCK "movl $0,mcount_lock \n"
#else /* !(SMP && GUPROF) */
#define MPLOCK
#define MPUNLOCK
#endif /* SMP && GUPROF */
__asm(" \n\
GM_STATE = 0 \n\
GMON_PROF_OFF = 3 \n\
\n\
.text \n\
.p2align 4,0x90 \n\
.globl __mcount \n\
.type __mcount,@function \n\
__mcount: \n\
# \n\
# Check that we are profiling. Do it early for speed. \n\
# \n\
cmpl $GMON_PROF_OFF,_gmonparam+GM_STATE \n\
je .mcount_exit \n\
# \n\
# __mcount is the same as [.]mcount except the caller \n\
# hasn't changed the stack except to call here, so the \n\
# caller's raddr is above our raddr. \n\
# \n\
pushq %rax \n\
pushq %rdx \n\
pushq %rcx \n\
pushq %rsi \n\
pushq %rdi \n\
pushq %r8 \n\
pushq %r9 \n\
movq 7*8+8(%rsp),%rdi \n\
jmp .got_frompc \n\
\n\
.p2align 4,0x90 \n\
.globl .mcount \n\
.mcount: \n\
cmpl $GMON_PROF_OFF,_gmonparam+GM_STATE \n\
je .mcount_exit \n\
# \n\
# The caller's stack frame has already been built, so \n\
# %rbp is the caller's frame pointer. The caller's \n\
# raddr is in the caller's frame following the caller's \n\
# caller's frame pointer. \n\
# \n\
pushq %rax \n\
pushq %rdx \n\
pushq %rcx \n\
pushq %rsi \n\
pushq %rdi \n\
pushq %r8 \n\
pushq %r9 \n\
movq 8(%rbp),%rdi \n\
.got_frompc: \n\
# \n\
# Our raddr is the caller's pc. \n\
# \n\
movq 7*8(%rsp),%rsi \n\
\n\
pushfq \n\
cli \n"
MPLOCK " \n\
call mcount \n"
MPUNLOCK " \n\
popfq \n\
popq %r9 \n\
popq %r8 \n\
popq %rdi \n\
popq %rsi \n\
popq %rcx \n\
popq %rdx \n\
popq %rax \n\
.mcount_exit: \n\
ret $0 \n\
");
#else /* !__GNUCLIKE_ASM */
#error "this file needs to be ported to your compiler"
#endif /* __GNUCLIKE_ASM */
#ifdef GUPROF
/*
* [.]mexitcount saves the return register(s), loads selfpc and calls
* mexitcount(selfpc) to do the work. Someday it should be in a machine
* dependent file together with cputime(), __mcount and [.]mcount. cputime()
* can't just be put in machdep.c because it has to be compiled without -pg.
*/
#ifdef __GNUCLIKE_ASM
__asm(" \n\
.text \n\
# \n\
# Dummy label to be seen when gprof -u hides [.]mexitcount. \n\
# \n\
.p2align 4,0x90 \n\
.globl __mexitcount \n\
.type __mexitcount,@function \n\
__mexitcount: \n\
nop \n\
\n\
GMON_PROF_HIRES = 4 \n\
\n\
.p2align 4,0x90 \n\
.globl .mexitcount \n\
.mexitcount: \n\
cmpl $GMON_PROF_HIRES,_gmonparam+GM_STATE \n\
jne .mexitcount_exit \n\
pushq %rax \n\
pushq %rdx \n\
pushq %rcx \n\
pushq %rsi \n\
pushq %rdi \n\
pushq %r8 \n\
pushq %r9 \n\
movq 7*8(%rsp),%rdi \n\
pushfq \n\
cli \n"
MPLOCK " \n\
call mexitcount \n"
MPUNLOCK " \n\
popfq \n\
popq %r9 \n\
popq %r8 \n\
popq %rdi \n\
popq %rsi \n\
popq %rcx \n\
popq %rdx \n\
popq %rax \n\
.mexitcount_exit: \n\
ret $0 \n\
");
#endif /* __GNUCLIKE_ASM */
/*
* Return the time elapsed since the last call. The units are machine-
* dependent.
*/
int
cputime()
{
u_int count;
int delta;
u_char high, low;
static u_int prev_count;
if (cputime_clock == CPUTIME_CLOCK_TSC) {
/*
* Scale the TSC a little to make cputime()'s frequency
* fit in an int, assuming that the TSC frequency fits
* in a u_int. Use a fixed scale since dynamic scaling
* would be slower and we can't really use the low bit
* of precision.
*/
count = (u_int)rdtsc() & ~1u;
delta = (int)(count - prev_count) >> 1;
prev_count = count;
return (delta);
}
/*
* Read the current value of the 8254 timer counter 0.
*/
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
count = ((high << 8) | low) << CPUTIME_CLOCK_I8254_SHIFT;
/*
* The timer counts down from TIMER_CNTR0_MAX to 0 and then resets.
* While profiling is enabled, this routine is called at least twice
* per timer reset (for mcounting and mexitcounting hardclock()),
* so at most one reset has occurred since the last call, and one
* has occurred iff the current count is larger than the previous
* count. This allows counter underflow to be detected faster
* than in microtime().
*/
delta = prev_count - count;
prev_count = count;
if ((int) delta <= 0)
return (delta + (i8254_max_count << CPUTIME_CLOCK_I8254_SHIFT));
return (delta);
}
static int
sysctl_machdep_cputime_clock(SYSCTL_HANDLER_ARGS)
{
int clock;
int error;
clock = cputime_clock;
error = sysctl_handle_opaque(oidp, &clock, sizeof clock, req);
if (error == 0 && req->newptr != NULL) {
if (clock < 0 || clock > CPUTIME_CLOCK_TSC)
return (EINVAL);
cputime_clock = clock;
}
return (error);
}
SYSCTL_PROC(_machdep, OID_AUTO, cputime_clock,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 0, sizeof(u_int),
sysctl_machdep_cputime_clock, "I",
"");
/*
* The start and stop routines need not be here since we turn off profiling
* before calling them. They are here for convenience.
*/
void
startguprof(gp)
struct gmonparam *gp;
{
uint64_t freq;
freq = atomic_load_acq_64(&tsc_freq);
if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED) {
if (freq != 0 && mp_ncpus == 1)
cputime_clock = CPUTIME_CLOCK_TSC;
else
cputime_clock = CPUTIME_CLOCK_I8254;
}
if (cputime_clock == CPUTIME_CLOCK_TSC) {
gp->profrate = freq >> 1;
cputime_prof_active = 1;
} else
gp->profrate = i8254_freq << CPUTIME_CLOCK_I8254_SHIFT;
cputime_bias = 0;
cputime();
}
void
stopguprof(gp)
struct gmonparam *gp;
{
if (cputime_clock == CPUTIME_CLOCK_TSC)
cputime_prof_active = 0;
}
/* If the cpu frequency changed while profiling, report a warning. */
static void
tsc_freq_changed(void *arg, const struct cf_level *level, int status)
{
/*
* If there was an error during the transition or
* TSC is P-state invariant, don't do anything.
*/
if (status != 0 || tsc_is_invariant)
return;
if (cputime_prof_active && cputime_clock == CPUTIME_CLOCK_TSC)
printf("warning: cpu freq changed while profiling active\n");
}
EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL,
EVENTHANDLER_PRI_ANY);
#endif /* GUPROF */
......@@ -38,7 +38,7 @@
* Signal trampoline, copied to top of user stack
*
*/
NON_GPROF_ENTRY(sigcode)
ENTRY(sigcode)
call *SIGF_HANDLER(%rsp) /* call signal handler */
lea SIGF_UC(%rsp),%rdi /* get ucontext_t */
pushq $0 /* junk to fake return addr. */
......
......@@ -1490,7 +1490,6 @@ ENTRY(lgdt)
popq %rax
pushq $KCSEL
pushq %rax
MEXITCOUNT
lretq
END(lgdt)
......
......@@ -69,11 +69,11 @@
.text
.p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */
NON_GPROF_ENTRY(hypercall_page)
ENTRY(hypercall_page)
.skip 0x1000, 0x90 /* Fill with "nop"s */
/* Legacy PVH entry point, to be removed. */
NON_GPROF_ENTRY(xen_start)
ENTRY(xen_start)
/* Don't trust what the loader gives for rflags. */
pushq $PSL_KERNEL
popfq
......@@ -97,7 +97,7 @@ NON_GPROF_ENTRY(xen_start)
/* PVH entry point. */
.code32
NON_GPROF_ENTRY(xen_start32)
ENTRY(xen_start32)
/* Load flat GDT */
movl $VTOP(gdtdesc32), %eax
......
......@@ -7,10 +7,6 @@
# $FreeBSD$
#
#