revert r315959 because it causes build problems

The change introduced a dependency between genassym.c and header files
generated from .m files, but that dependency is not specified in the
make files.

Also, the change could be not as useful as I thought it was.

Reported by:	dchagin, Manfred Antar <null@pozo.com>, and many others
This commit is contained in:
Andriy Gapon 2017-03-27 12:34:29 +00:00
parent 80b9074a51
commit 978f3da16f
12 changed files with 114 additions and 145 deletions

View File

@ -50,6 +50,22 @@
#define LK
#endif
.text
SUPERALIGN_TEXT
/* End Of Interrupt to APIC */
as_lapic_eoi:
cmpl $0,x2apic_mode
jne 1f
movq lapic_map,%rax
movl $0,LA_EOI(%rax)
ret
1:
movl $MSR_APIC_EOI,%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
ret
/*
* I/O Interrupt Entry Point. Rather than having one entry point for
* each interrupt source, we use one entry point for each 32-bit word
@ -166,7 +182,7 @@ IDTVEC(xen_intr_upcall)
SUPERALIGN_TEXT
invltlb_ret:
call native_lapic_eoi
call as_lapic_eoi
POP_FRAME
jmp doreti_iret
@ -175,21 +191,18 @@ IDTVEC(invltlb)
PUSH_FRAME
call invltlb_handler
movl $IPI_INVLTLB, %edi
jmp invltlb_ret
IDTVEC(invltlb_pcid)
PUSH_FRAME
call invltlb_pcid_handler
movl $IPI_INVLTLB, %edi
jmp invltlb_ret
IDTVEC(invltlb_invpcid)
PUSH_FRAME
call invltlb_invpcid_handler
movl $IPI_INVLTLB, %edi
jmp invltlb_ret
/*
@ -202,7 +215,6 @@ IDTVEC(invlpg)
PUSH_FRAME
call invlpg_handler
movl $IPI_INVLPG, %edi
jmp invltlb_ret
/*
@ -214,7 +226,6 @@ IDTVEC(invlrng)
PUSH_FRAME
call invlrng_handler
movl $IPI_INVLRNG, %edi
jmp invltlb_ret
/*
@ -226,7 +237,6 @@ IDTVEC(invlcache)
PUSH_FRAME
call invlcache_handler
movl $IPI_INVLCACHE, %edi
jmp invltlb_ret
/*
@ -237,8 +247,7 @@ IDTVEC(invlcache)
IDTVEC(ipi_intr_bitmap_handler)
PUSH_FRAME
movl $IPI_BITMAP_VECTOR, %edi
call native_lapic_eoi
call as_lapic_eoi
FAKE_MCOUNT(TF_RIP(%rsp))
@ -254,8 +263,7 @@ IDTVEC(ipi_intr_bitmap_handler)
IDTVEC(cpustop)
PUSH_FRAME
movl $IPI_STOP, %edi
call native_lapic_eoi
call as_lapic_eoi
call cpustop_handler
jmp doreti
@ -269,8 +277,7 @@ IDTVEC(cpususpend)
PUSH_FRAME
call cpususpend_handler
movl $IPI_SUSPEND, %edi
call native_lapic_eoi
call as_lapic_eoi
jmp doreti
/*
@ -288,22 +295,37 @@ IDTVEC(rendezvous)
incq (%rax)
#endif
call smp_rendezvous_action
movl $IPI_RENDEZVOUS, %edi
call native_lapic_eoi
call as_lapic_eoi
jmp doreti
/*
* IPI handler whose purpose is to interrupt the CPU with minimum overhead.
* This is used by bhyve to force a host cpu executing in guest context to
* trap into the hypervisor.
*
* This handler is different from other IPI handlers in the following aspects:
*
* 1. It doesn't push a trapframe on the stack.
*
* This implies that a DDB backtrace involving 'justreturn' will skip the
* function that was interrupted by this handler.
*
* 2. It doesn't 'swapgs' when userspace is interrupted.
*
* The 'justreturn' handler does not access any pcpu data so it is not an
* issue. Moreover the 'justreturn' handler can only be interrupted by an NMI
* whose handler already doesn't trust GS.base when kernel code is interrupted.
*/
.text
SUPERALIGN_TEXT
IDTVEC(justreturn)
PUSH_FRAME
movl vmm_ipinum, %edi
call native_lapic_eoi
POP_FRAME
pushq %rax
pushq %rcx
pushq %rdx
call as_lapic_eoi
popq %rdx
popq %rcx
popq %rax
jmp doreti_iret
#endif /* SMP */

View File

@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$");
#include <sys/assym.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/bus.h>
#include <sys/proc.h>
#ifdef HWPMC_HOOKS
#include <sys/pmckern.h>
@ -62,9 +61,7 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <sys/proc.h>
#include <machine/intr_machdep.h>
#include <x86/apicreg.h>
#include <x86/apicvar.h>
#include <machine/cpu.h>
#include <machine/pcb.h>
#include <machine/sigframe.h>
@ -218,19 +215,10 @@ ASSYM(PC_LDT, offsetof(struct pcpu, pc_ldt));
ASSYM(PC_COMMONTSSP, offsetof(struct pcpu, pc_commontssp));
ASSYM(PC_TSS, offsetof(struct pcpu, pc_tss));
ASSYM(PC_PM_SAVE_CNT, offsetof(struct pcpu, pc_pm_save_cnt));
ASSYM(LA_EOI, LAPIC_EOI * LAPIC_MEM_MUL);
ASSYM(LA_ISR, LAPIC_ISR0 * LAPIC_MEM_MUL);
ASSYM(IPI_INVLTLB, IPI_INVLTLB);
ASSYM(IPI_INVLPG, IPI_INVLPG);
ASSYM(IPI_INVLRNG, IPI_INVLRNG);
ASSYM(IPI_INVLCACHE, IPI_INVLCACHE);
ASSYM(IPI_BITMAP_VECTOR, IPI_BITMAP_VECTOR);
ASSYM(IPI_STOP, IPI_STOP);
ASSYM(IPI_SUSPEND, IPI_SUSPEND);
ASSYM(IPI_RENDEZVOUS, IPI_RENDEZVOUS);
ASSYM(KCSEL, GSEL(GCODE_SEL, SEL_KPL));
ASSYM(KDSEL, GSEL(GDATA_SEL, SEL_KPL));
ASSYM(KUCSEL, GSEL(GUCODE_SEL, SEL_UPL));

View File

@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$");
#include <machine/vmm_dev.h>
#include <machine/vmm_instruction_emul.h>
#include "vmm_host.h"
#include "vmm_lapic.h"
#include "vmm_stat.h"
#include "vmm_ktr.h"
@ -1621,7 +1620,7 @@ svm_inj_interrupts(struct svm_softc *sc, int vcpu, struct vlapic *vlapic)
* Although not explicitly specified in APMv2 the
* relative priorities were verified empirically.
*/
ipi_cpu(curcpu, vmm_ipinum);
ipi_cpu(curcpu, IPI_AST); /* XXX vmm_ipinum? */
} else {
vm_nmi_clear(sc->vm, vcpu);

View File

@ -215,6 +215,7 @@ SYSCTL_INT(_hw_vmm, OID_AUTO, halt_detection, CTLFLAG_RDTUN,
&halt_detection_enabled, 0,
"Halt VM if all vcpus execute HLT with interrupts disabled");
static int vmm_ipinum;
SYSCTL_INT(_hw_vmm, OID_AUTO, ipinum, CTLFLAG_RD, &vmm_ipinum, 0,
"IPI vector used for vcpu notifications");

View File

@ -33,8 +33,6 @@
#error "no user-serviceable parts inside"
#endif
extern int vmm_ipinum;
struct xsave_limits {
int xsave_enabled;
uint64_t xcr0_allowed;

View File

@ -44,6 +44,22 @@
#include "assym.s"
.text
SUPERALIGN_TEXT
/* End Of Interrupt to APIC */
as_lapic_eoi:
cmpl $0,x2apic_mode
jne 1f
movl lapic_map,%eax
movl $0,LA_EOI(%eax)
ret
1:
movl $MSR_APIC_EOI,%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
ret
/*
* I/O Interrupt Entry Point. Rather than having one entry point for
* each interrupt source, we use one entry point for each 32-bit word
@ -172,8 +188,7 @@ IDTVEC(xen_intr_upcall)
.text
SUPERALIGN_TEXT
invltlb_ret:
call native_lapic_eoi
add $4, %esp
call as_lapic_eoi
POP_FRAME
iret
@ -185,7 +200,6 @@ IDTVEC(invltlb)
call invltlb_handler
pushl $IPI_INVLTLB
jmp invltlb_ret
/*
@ -200,7 +214,6 @@ IDTVEC(invlpg)
call invlpg_handler
pushl $IPI_INVLPG
jmp invltlb_ret
/*
@ -215,7 +228,6 @@ IDTVEC(invlrng)
call invlrng_handler
pushl $IPI_INVLRNG
jmp invltlb_ret
/*
@ -230,7 +242,6 @@ IDTVEC(invlcache)
call invlcache_handler
pushl $IPI_INVLCACHE
jmp invltlb_ret
/*
@ -243,10 +254,8 @@ IDTVEC(ipi_intr_bitmap_handler)
SET_KERNEL_SREGS
cld
pushl $IPI_BITMAP_VECTOR
call native_lapic_eoi
add $4, %esp
call as_lapic_eoi
FAKE_MCOUNT(TF_EIP(%esp))
call ipi_bitmap_handler
@ -263,9 +272,7 @@ IDTVEC(cpustop)
SET_KERNEL_SREGS
cld
pushl $IPI_STOP
call native_lapic_eoi
add $4, %esp
call as_lapic_eoi
call cpustop_handler
POP_FRAME
@ -281,9 +288,7 @@ IDTVEC(cpususpend)
SET_KERNEL_SREGS
cld
pushl $IPI_SUSPEND
call native_lapic_eoi
add $4, %esp
call as_lapic_eoi
call cpususpend_handler
POP_FRAME
@ -308,9 +313,7 @@ IDTVEC(rendezvous)
#endif
call smp_rendezvous_action
pushl $IPI_RENDEZVOUS
call native_lapic_eoi
add $4, %esp
call as_lapic_eoi
POP_FRAME
iret

View File

@ -70,10 +70,7 @@ __FBSDID("$FreeBSD$");
#include <nfsclient/nfs.h>
#include <nfs/nfsdiskless.h>
#ifdef DEV_APIC
#include <sys/bus.h>
#include <machine/intr_machdep.h>
#include <x86/apicreg.h>
#include <x86/apicvar.h>
#endif
#include <machine/cpu.h>
#include <machine/pcb.h>
@ -222,15 +219,6 @@ ASSYM(PC_PRIVATE_TSS, offsetof(struct pcpu, pc_private_tss));
#ifdef DEV_APIC
ASSYM(LA_EOI, LAPIC_EOI * LAPIC_MEM_MUL);
ASSYM(LA_ISR, LAPIC_ISR0 * LAPIC_MEM_MUL);
ASSYM(IPI_INVLTLB, IPI_INVLTLB);
ASSYM(IPI_INVLPG, IPI_INVLPG);
ASSYM(IPI_INVLRNG, IPI_INVLRNG);
ASSYM(IPI_INVLCACHE, IPI_INVLCACHE);
ASSYM(IPI_BITMAP_VECTOR, IPI_BITMAP_VECTOR);
ASSYM(IPI_STOP, IPI_STOP);
ASSYM(IPI_SUSPEND, IPI_SUSPEND);
ASSYM(IPI_RENDEZVOUS, IPI_RENDEZVOUS);
#endif
ASSYM(KCSEL, GSEL(GCODE_SEL, SEL_KPL));

View File

@ -210,7 +210,7 @@ struct apic_ops {
void (*setup)(int);
void (*dump)(const char *);
void (*disable)(void);
void (*eoi)(u_int vector);
void (*eoi)(void);
int (*id)(void);
int (*intr_pending)(u_int);
void (*set_logical_id)(u_int, u_int, u_int);
@ -301,10 +301,10 @@ lapic_disable(void)
}
static inline void
lapic_eoi(u_int vector)
lapic_eoi(void)
{
apic_ops.eoi(vector);
apic_ops.eoi();
}
static inline int
@ -469,7 +469,6 @@ lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger)
return (apic_ops.set_lvt_triggermode(apic_id, lvt, trigger));
}
void native_lapic_eoi(u_int vector);
void lapic_handle_cmc(void);
void lapic_handle_error(void);
void lapic_handle_intr(int vector, struct trapframe *frame);

View File

@ -151,10 +151,10 @@ _ioapic_eoi_source(struct intsrc *isrc, int locked)
volatile uint32_t *apic_eoi;
uint32_t low1;
src = (struct ioapic_intsrc *)isrc;
lapic_eoi(src->io_vector);
lapic_eoi();
if (!lapic_eoi_suppression)
return;
src = (struct ioapic_intsrc *)isrc;
if (src->io_edgetrigger)
return;
io = (struct ioapic *)isrc->is_pic;

View File

@ -83,9 +83,6 @@ __FBSDID("$FreeBSD$");
#define GSEL_APIC GSEL(GCODE_SEL, SEL_KPL)
#endif
#define INTEL_SEOI 1
#define AMD_SEOI 2
/* Sanity checks on IDT vectors. */
CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_TIMER_INT);
CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS);
@ -187,10 +184,6 @@ static struct eventtimer lapic_et;
#ifdef SMP
static uint64_t lapic_ipi_wait_mult;
#endif
#ifdef __amd64__
/* IPI vector used for VMM VCPU notifications. */
int vmm_ipinum;
#endif
SYSCTL_NODE(_hw, OID_AUTO, apic, CTLFLAG_RD, 0, "APIC options");
SYSCTL_INT(_hw_apic, OID_AUTO, x2apic_mode, CTLFLAG_RD, &x2apic_mode, 0, "");
@ -319,6 +312,7 @@ static void native_lapic_xapic_mode(void);
static void native_lapic_setup(int boot);
static void native_lapic_dump(const char *str);
static void native_lapic_disable(void);
static void native_lapic_eoi(void);
static int native_lapic_id(void);
static int native_lapic_intr_pending(u_int vector);
static u_int native_apic_cpuid(u_int apic_id);
@ -453,31 +447,6 @@ elvt_mode(struct lapic *la, u_int idx, uint32_t value)
return (lvt_mode_impl(la, elvt, idx, value));
}
static inline uint32_t
amd_read_ext_features(void)
{
uint32_t version;
if (cpu_vendor_id != CPU_VENDOR_AMD)
return (0);
version = lapic_read32(LAPIC_VERSION);
if ((version & APIC_VER_AMD_EXT_SPACE) != 0)
return (lapic_read32(LAPIC_EXT_FEATURES));
return (0);
}
static inline uint32_t
amd_read_elvt_count(void)
{
uint32_t extf;
uint32_t count;
extf = amd_read_ext_features();
count = (extf & APIC_EXTF_ELVT_MASK) >> APIC_EXTF_ELVT_SHIFT;
count = min(count, APIC_ELVT_MAX + 1);
return (count);
}
/*
* Map the local APIC and setup necessary interrupt vectors.
*/
@ -487,9 +456,9 @@ native_lapic_init(vm_paddr_t addr)
#ifdef SMP
uint64_t r, r1, r2, rx;
#endif
uint32_t extf, ver;
uint32_t ver;
u_int regs[4];
int i, arat, seoi_enable;
int i, arat;
/*
* Enable x2APIC mode if possible. Map the local APIC
@ -577,27 +546,16 @@ native_lapic_init(vm_paddr_t addr)
*/
ver = lapic_read32(LAPIC_VERSION);
if ((ver & APIC_VER_EOI_SUPPRESSION) != 0) {
lapic_eoi_suppression = INTEL_SEOI;
} else {
extf = amd_read_ext_features();
if ((extf & APIC_EXTF_SEIO_CAP) != 0)
lapic_eoi_suppression = AMD_SEOI;
}
if (lapic_eoi_suppression != 0) {
seoi_enable = 1;
lapic_eoi_suppression = 1;
if (vm_guest == VM_GUEST_KVM) {
if (bootverbose)
printf(
"KVM -- disabling lapic eoi suppression\n");
seoi_enable = 0;
lapic_eoi_suppression = 0;
}
TUNABLE_INT_FETCH("hw.lapic_eoi_suppression",
&seoi_enable);
if (seoi_enable == 0)
lapic_eoi_suppression = 0;
&lapic_eoi_suppression);
}
if (lapic_eoi_suppression != 0)
printf("LAPIC specific EOI enabled\n");
#ifdef SMP
#define LOOPS 100000
@ -684,6 +642,32 @@ native_lapic_create(u_int apic_id, int boot_cpu)
#endif
}
static inline uint32_t
amd_read_ext_features(void)
{
uint32_t version;
if (cpu_vendor_id != CPU_VENDOR_AMD)
return (0);
version = lapic_read32(LAPIC_VERSION);
if ((version & APIC_VER_AMD_EXT_SPACE) != 0)
return (lapic_read32(LAPIC_EXT_FEATURES));
else
return (0);
}
static inline uint32_t
amd_read_elvt_count(void)
{
uint32_t extf;
uint32_t count;
extf = amd_read_ext_features();
count = (extf & APIC_EXTF_ELVT_MASK) >> APIC_EXTF_ELVT_SHIFT;
count = min(count, APIC_ELVT_MAX + 1);
return (count);
}
/*
* Dump contents of local APIC registers
*/
@ -718,11 +702,9 @@ native_lapic_dump(const char* str)
extf = amd_read_ext_features();
if (extf != 0) {
printf(" AMD ext features: 0x%08x\n", extf);
extf = lapic_read32(LAPIC_EXT_CTRL);
printf(" AMD ext control: 0x%08x\n", extf);
elvt_count = amd_read_elvt_count();
for (i = 0; i < elvt_count; i++)
printf(" AMD elvt%d: 0x%08x\n", i,
printf(" AMD elvt%d: 0x%08x\n", i,
lapic_read32(LAPIC_EXT_LVT0 + i));
}
}
@ -1040,15 +1022,9 @@ lapic_enable(void)
value = lapic_read32(LAPIC_SVR);
value &= ~(APIC_SVR_VECTOR | APIC_SVR_FOCUS);
value |= APIC_SVR_FEN | APIC_SVR_SWEN | APIC_SPURIOUS_INT;
if (lapic_eoi_suppression == INTEL_SEOI)
if (lapic_eoi_suppression)
value |= APIC_SVR_EOI_SUPPRESSION;
lapic_write32(LAPIC_SVR, value);
if (lapic_eoi_suppression == AMD_SEOI) {
value = lapic_read32(LAPIC_EXT_CTRL);
value |= APIC_EXTF_SEIO_CAP;
lapic_write32(LAPIC_EXT_CTRL, value);
}
}
/* Reset the local APIC on the BSP during resume. */
@ -1251,14 +1227,11 @@ lapic_set_tpr(u_int vector)
#endif
}
void
native_lapic_eoi(u_int vector)
static void
native_lapic_eoi(void)
{
if (lapic_eoi_suppression == AMD_SEOI)
lapic_write32(LAPIC_EXT_SEOI, vector);
else
lapic_write32_nofence(LAPIC_EOI, 0);
lapic_write32_nofence(LAPIC_EOI, 0);
}
void
@ -1279,7 +1252,7 @@ lapic_handle_timer(struct trapframe *frame)
struct thread *td;
/* Send EOI first thing. */
lapic_eoi(APIC_TIMER_INT);
lapic_eoi();
#if defined(SMP) && !defined(SCHED_ULE)
/*
@ -1400,7 +1373,7 @@ void
lapic_handle_cmc(void)
{
lapic_eoi(APIC_CMC_INT);
lapic_eoi();
cmc_intr();
}
@ -1474,7 +1447,7 @@ lapic_handle_error(void)
esr = lapic_read32(LAPIC_ESR);
printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr);
lapic_eoi(APIC_ERROR_INT);
lapic_eoi();
}
static u_int

View File

@ -177,18 +177,16 @@ msi_enable_source(struct intsrc *isrc)
static void
msi_disable_source(struct intsrc *isrc, int eoi)
{
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
if (eoi == PIC_EOI)
lapic_eoi(msi->msi_vector);
lapic_eoi();
}
static void
msi_eoi_source(struct intsrc *isrc)
{
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
lapic_eoi(msi->msi_vector);
lapic_eoi();
}
static void

View File

@ -147,7 +147,7 @@ xen_pv_lapic_is_x2apic(void)
}
static void
xen_pv_lapic_eoi(u_int vector)
xen_pv_lapic_eoi(void)
{
XEN_APIC_UNSUPPORTED;