Skip to content

Commit

Permalink
BHYVE: OS-6837 bhyve must use separate ipi vector for PIR
Browse files Browse the repository at this point in the history
Reviewed by: Bryan Cantrill <bryan@joyent.com>
Reviewed by: John Levon <john.levon@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Robert Mustacchi <rm@joyent.com>
  • Loading branch information
pfmooney authored and citrus-it committed Apr 5, 2018
1 parent d653bab commit 7834e90
Show file tree
Hide file tree
Showing 20 changed files with 167 additions and 78 deletions.
5 changes: 5 additions & 0 deletions usr/src/cmd/mdb/i86pc/modules/apix/apix.c
Expand Up @@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2018 Joyent, Inc.
*/

#include "intr_common.h"
Expand Down Expand Up @@ -170,5 +171,9 @@ _mdb_init(void)
if (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
gld_intr_addr = (uintptr_t)sym.st_value;

if (mdb_readvar(&apic_pir_vect, "apic_pir_vect") == -1) {
apic_pir_vect = -1;
}

return (&modinfo);
}
26 changes: 19 additions & 7 deletions usr/src/cmd/mdb/i86pc/modules/common/intr_common.c
Expand Up @@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2018 Joyent, Inc.
*/

#include "intr_common.h"
Expand All @@ -29,6 +30,7 @@

int option_flags;
uintptr_t gld_intr_addr;
int apic_pir_vect;
static struct av_head softvec_tbl[LOCK_LEVEL + 1];

static char *businfo_array[] = {
Expand Down Expand Up @@ -302,11 +304,16 @@ apic_interrupt_dump(apic_irq_t *irqp, struct av_head *avp,

} else {
if (irqp->airq_mps_intr_index == RESERVE_INDEX &&
!irqp->airq_share)
mdb_printf("poke_cpu");
else if (mdb_vread(&avhp, sizeof (struct autovec),
(uintptr_t)avp->avh_link) != -1)
!irqp->airq_share) {
if (irqp->airq_vector == apic_pir_vect) {
mdb_printf("pir_ipi");
} else {
mdb_printf("poke_cpu");
}
} else if (mdb_vread(&avhp, sizeof (struct autovec),
(uintptr_t)avp->avh_link) != -1) {
mdb_printf("%a", avhp.av_vector);
}
}
mdb_printf("\n");
}
Expand Down Expand Up @@ -446,10 +453,15 @@ apix_interrupt_ipi_dump(apix_vector_t *vectp, struct autovec *avp,
mdb_printf("%-9s %-3s %s%-3s %-6s %-3s %-6s %-3d %-9s ",
cpu_vector, "- ", evtchn, ipl, "- ", "Edg",
intr_type, vectp->v_share, ioapic_iline);
if (!vectp->v_share)
mdb_printf("poke_cpu");
else
if (!vectp->v_share) {
if (vectp->v_vector == apic_pir_vect) {
mdb_printf("pir_ipi");
} else {
mdb_printf("poke_cpu");
}
} else {
mdb_printf("%a", avp->av_vector);
}

mdb_printf("\n");
}
4 changes: 4 additions & 0 deletions usr/src/cmd/mdb/i86pc/modules/common/intr_common.h
Expand Up @@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2018 Joyent, Inc.
*/

#ifndef _MDB_INTR_COMMON_H
Expand Down Expand Up @@ -73,6 +74,9 @@ extern int option_flags;
*/
extern uintptr_t gld_intr_addr;

/* cached the PIR ipi vector to differentiate it from poke_cpu */
extern int apic_pir_vect;

#ifdef __cplusplus
}
#endif
Expand Down
5 changes: 5 additions & 0 deletions usr/src/cmd/mdb/i86pc/modules/pcplusmp/pcplusmp.c
Expand Up @@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2018 Joyent, Inc.
*/

#include "intr_common.h"
Expand Down Expand Up @@ -116,5 +117,9 @@ _mdb_init(void)
if (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
gld_intr_addr = (uintptr_t)sym.st_value;

if (mdb_readvar(&apic_pir_vect, "apic_pir_vect") == -1) {
apic_pir_vect = -1;
}

return (&modinfo);
}
16 changes: 4 additions & 12 deletions usr/src/compat/freebsd/amd64/machine/smp.h
Expand Up @@ -11,6 +11,7 @@

/*
* Copyright 2013 Pluribus Networks Inc.
* Copyright 2018 Joyent, Inc.
*/

#ifndef _COMPAT_FREEBSD_AMD64_MACHINE_SMP_H_
Expand All @@ -19,20 +20,11 @@
#ifdef _KERNEL

/*
* APIC-related definitions would normally be stored in x86/include/apicvar.h,
* accessed here via x86/include/x86_smp.h. Until it becomes necessary to
* implment that whole chain of includes, those definitions are short-circuited
* into this file.
* APIC-related functions are replaced with native calls rather than shims
* which attempt to replicate the FreeBSD interfaces. This is empty, but will
* remain present to appease sources which wish to include the path.
*/

#define IDTVEC(name) idtvec_ ## name

extern int idtvec_justreturn;

extern int lapic_ipi_alloc(int *);
extern void lapic_ipi_free(int vec);


#endif /* _KERNEL */

#endif /* _COMPAT_FREEBSD_AMD64_MACHINE_SMP_H_ */
13 changes: 11 additions & 2 deletions usr/src/uts/i86pc/io/apix/apix.c
Expand Up @@ -166,7 +166,8 @@ static struct psm_ops apix_ops = {
apic_state, /* save, restore apic state for S3 */
apic_cpu_ops, /* CPU control interface. */

apic_cached_ipivect,
apic_get_pir_ipivect,
apic_send_pir_ipi,
};

struct psm_ops *psmops = &apix_ops;
Expand Down Expand Up @@ -384,6 +385,8 @@ apix_init()
apic_have_32bit_cr8 = 1;
#endif

apic_pir_vect = apix_get_ipivect(XC_CPUPOKE_PIL, -1);

/*
* Initialize IRM pool parameters
*/
Expand Down Expand Up @@ -1127,9 +1130,11 @@ x2apic_update_psm()
* being apix_foo as opposed to apic_foo and x2apic_foo.
*/
pops->psm_send_ipi = x2apic_send_ipi;

send_dirintf = pops->psm_send_ipi;

pops->psm_send_pir_ipi = x2apic_send_pir_ipi;
psm_send_pir_ipi = pops->psm_send_pir_ipi;

apic_mode = LOCAL_X2APIC;
apic_change_ops();
}
Expand Down Expand Up @@ -2588,6 +2593,8 @@ apic_switch_ipi_callback(boolean_t enter)
if (apic_poweron_cnt == 0) {
pops->psm_send_ipi = apic_common_send_ipi;
send_dirintf = pops->psm_send_ipi;
pops->psm_send_pir_ipi = apic_common_send_pir_ipi;
psm_send_pir_ipi = pops->psm_send_pir_ipi;
}
apic_poweron_cnt++;
} else {
Expand All @@ -2596,6 +2603,8 @@ apic_switch_ipi_callback(boolean_t enter)
if (apic_poweron_cnt == 0) {
pops->psm_send_ipi = x2apic_send_ipi;
send_dirintf = pops->psm_send_ipi;
pops->psm_send_pir_ipi = x2apic_send_pir_ipi;
psm_send_pir_ipi = pops->psm_send_pir_ipi;
}
}
lock_clear(&apic_mode_switch_lock);
Expand Down
44 changes: 43 additions & 1 deletion usr/src/uts/i86pc/io/apix/apix_regops.c
Expand Up @@ -25,13 +25,14 @@
/*
* Copyright 2014 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
* Copyright (c) 2014 by Delphix. All rights reserved.
* Copyright 2017 Joyent, Inc.
* Copyright 2018 Joyent, Inc.
*/

#include <sys/cpuvar.h>
#include <sys/psm.h>
#include <sys/archsystm.h>
#include <sys/apic.h>
#include <sys/apic_common.h>
#include <sys/sunddi.h>
#include <sys/ddi_impldefs.h>
#include <sys/mach_intr.h>
Expand Down Expand Up @@ -218,6 +219,34 @@ x2apic_send_ipi(int cpun, int ipl)
intr_restore(flag);
}

void
x2apic_send_pir_ipi(processorid_t cpun)
{
const int vector = apic_pir_vect;
ulong_t flag;

ASSERT(apic_mode == LOCAL_X2APIC);
ASSERT((vector >= APIC_BASE_VECT) && (vector <= APIC_SPUR_INTR));

/* Serialize as described in x2apic_send_ipi() above. */
atomic_or_ulong(&flag, 1);

flag = intr_clear();

/* Self-IPI for inducing PIR makes no sense. */
if ((cpun != psm_get_cpu_id())) {
#ifdef DEBUG
/* Only for debugging. (again, see: x2apic_send_ipi) */
APIC_AV_PENDING_SET();
#endif /* DEBUG */

apic_reg_ops->apic_write_int_cmd(apic_cpus[cpun].aci_local_id,
vector);
}

intr_restore(flag);
}

/*
* Generates IPI to another CPU depending on the local APIC mode.
* apic_send_ipi() and x2apic_send_ipi() depends on the configured
Expand Down Expand Up @@ -250,3 +279,16 @@ apic_common_send_ipi(int cpun, int ipl)
vector);
intr_restore(flag);
}

void
apic_common_send_pir_ipi(processorid_t cpun)
{
const int mode = apic_local_mode();

if (mode == LOCAL_X2APIC) {
x2apic_send_pir_ipi(cpun);
return;
}

apic_send_pir_ipi(cpun);
}
5 changes: 4 additions & 1 deletion usr/src/uts/i86pc/io/pcplusmp/apic.c
Expand Up @@ -201,7 +201,8 @@ static struct psm_ops apic_ops = {
apic_state, /* save, restore apic state for S3 */
apic_cpu_ops, /* CPU control interface. */

apic_cached_ipivect,
apic_get_pir_ipivect,
apic_send_pir_ipi,
};

struct psm_ops *psmops = &apic_ops;
Expand Down Expand Up @@ -298,6 +299,8 @@ apic_init(void)
apic_ipltopri[j] = (i << APIC_IPL_SHIFT) + APIC_BASE_VECT;
apic_init_common();

apic_pir_vect = apic_get_ipivect(XC_CPUPOKE_PIL, -1);

#if !defined(__amd64)
if (cpuid_have_cr8access(CPU))
apic_have_32bit_cr8 = 1;
Expand Down
38 changes: 27 additions & 11 deletions usr/src/uts/i86pc/io/pcplusmp/apic_common.c
Expand Up @@ -130,6 +130,8 @@ int cmci_cpu_setup_registered;

lock_t apic_mode_switch_lock;

int apic_pir_vect;

/*
* Patchable global variables.
*/
Expand Down Expand Up @@ -629,6 +631,31 @@ apic_send_ipi(int cpun, int ipl)
intr_restore(flag);
}

void
apic_send_pir_ipi(processorid_t cpun)
{
const int vector = apic_pir_vect;
ulong_t flag;

ASSERT((vector >= APIC_BASE_VECT) && (vector <= APIC_SPUR_INTR));

flag = intr_clear();

/* Self-IPI for inducing PIR makes no sense. */
if ((cpun != psm_get_cpu_id())) {
APIC_AV_PENDING_SET();
apic_reg_ops->apic_write_int_cmd(apic_cpus[cpun].aci_local_id,
vector);
}

intr_restore(flag);
}

int
apic_get_pir_ipivect(void)
{
return (apic_pir_vect);
}

/*ARGSUSED*/
void
Expand Down Expand Up @@ -1707,14 +1734,3 @@ apic_get_ioapicid(uchar_t ioapicindex)

return (apic_io_id[ioapicindex]);
}

int
apic_cached_ipivect(int ipl, int type)
{
uchar_t vector = 0;

if (type != -1 && ipl >= 0 && ipl <= MAXIPL) {
vector = apic_resv_vector[ipl];
}
return ((vector != 0) ? vector : -1);
}
3 changes: 2 additions & 1 deletion usr/src/uts/i86pc/io/psm/uppc.c
Expand Up @@ -177,7 +177,8 @@ static struct psm_ops uppc_ops = {
uppc_state, /* psm_state */
(int (*)(psm_cpu_request_t *))NULL, /* psm_cpu_ops */

(int (*)(int, int))NULL, /* psm_cached_ipivect */
(int (*)(void))NULL, /* psm_get_pir_ipivect */
(void (*)(processorid_t))NULL, /* psm_send_pir_ipi */
};


Expand Down

0 comments on commit 7834e90

Please sign in to comment.