Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Nov 2013 22:18:09 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r258699 - in head: sys/amd64/vmm sys/amd64/vmm/io usr.sbin/bhyve
Message-ID:  <201311272218.rARMI9Y1065386@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Wed Nov 27 22:18:08 2013
New Revision: 258699
URL: http://svnweb.freebsd.org/changeset/base/258699

Log:
  Add support for level triggered interrupt pins on the vioapic. Prior to this
  commit level triggered interrupts would work as long as the pin was not shared
  among multiple interrupt sources.
  
  The vlapic now keeps track of level triggered interrupts in the trigger mode
  register and will forward the EOI for a level triggered interrupt to the
  vioapic. The vioapic in turn uses the EOI to sample the level on the pin and
  re-inject the vector if the pin is still asserted.
  
  The vhpet is the first consumer of level triggered interrupts and advertises
  that it can generate interrupts on pins 20 through 23 of the vioapic.
  
  Discussed with:	grehan@

Modified:
  head/sys/amd64/vmm/io/ppt.c
  head/sys/amd64/vmm/io/vhpet.c
  head/sys/amd64/vmm/io/vioapic.c
  head/sys/amd64/vmm/io/vioapic.h
  head/sys/amd64/vmm/io/vlapic.c
  head/sys/amd64/vmm/io/vlapic.h
  head/sys/amd64/vmm/vmm_dev.c
  head/sys/amd64/vmm/vmm_ktr.h
  head/sys/amd64/vmm/vmm_lapic.c
  head/sys/amd64/vmm/vmm_lapic.h
  head/usr.sbin/bhyve/acpi.c
  head/usr.sbin/bhyve/mptbl.c

Modified: head/sys/amd64/vmm/io/ppt.c
==============================================================================
--- head/sys/amd64/vmm/io/ppt.c	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/io/ppt.c	Wed Nov 27 22:18:08 2013	(r258699)
@@ -421,7 +421,7 @@ pptintr(void *arg)
 	vec = pptarg->vec;
 
 	if (ppt->vm != NULL)
-		(void) lapic_set_intr(ppt->vm, pptarg->vcpu, vec);
+		lapic_intr_edge(ppt->vm, pptarg->vcpu, vec);
 	else {
 		/*
 		 * XXX

Modified: head/sys/amd64/vmm/io/vhpet.c
==============================================================================
--- head/sys/amd64/vmm/io/vhpet.c	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/io/vhpet.c	Wed Nov 27 22:18:08 2013	(r258699)
@@ -266,14 +266,14 @@ vhpet_timer_interrupt(struct vhpet *vhpe
 		if (apicid != 0xff) {
 			/* unicast */
 			vcpuid = vm_apicid2vcpuid(vhpet->vm, apicid);
-			lapic_set_intr(vhpet->vm, vcpuid, vector);
+			lapic_intr_edge(vhpet->vm, vcpuid, vector);
 		} else {
 			/* broadcast */
 			dmask = vm_active_cpus(vhpet->vm);
 			while ((vcpuid = CPU_FFS(&dmask)) != 0) {
 				vcpuid--;
 				CPU_CLR(vcpuid, &dmask);
-				lapic_set_intr(vhpet->vm, vcpuid, vector);
+				lapic_intr_edge(vhpet->vm, vcpuid, vector);
 			}
 		}
 		return;
@@ -725,8 +725,9 @@ done:
 struct vhpet *
 vhpet_init(struct vm *vm)
 {
-	int i;
+	int i, pincount;
 	struct vhpet *vhpet;
+	uint64_t allowed_irqs;
 	struct vhpet_callout_arg *arg;
 	struct bintime bt;
 
@@ -737,12 +738,20 @@ vhpet_init(struct vm *vm)
 	FREQ2BT(HPET_FREQ, &bt);
 	vhpet->freq_sbt = bttosbt(bt);
 
+	pincount = vioapic_pincount(vm);
+	if (pincount >= 24)
+		allowed_irqs = 0x00f00000;	/* irqs 20, 21, 22 and 23 */
+	else
+		allowed_irqs = 0;
+
 	/*
 	 * Initialize HPET timer hardware state.
 	 */
 	for (i = 0; i < VHPET_NUM_TIMERS; i++) {
-		vhpet->timer[i].cap_config = 0UL << 32 |
-		    HPET_TCAP_FSB_INT_DEL | HPET_TCAP_PER_INT;
+		vhpet->timer[i].cap_config = allowed_irqs << 32;
+		vhpet->timer[i].cap_config |= HPET_TCAP_PER_INT;
+		vhpet->timer[i].cap_config |= HPET_TCAP_FSB_INT_DEL;
+
 		vhpet->timer[i].compval = 0xffffffff;
 		callout_init(&vhpet->timer[i].callout, 1);
 

Modified: head/sys/amd64/vmm/io/vioapic.c
==============================================================================
--- head/sys/amd64/vmm/io/vioapic.c	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/io/vioapic.c	Wed Nov 27 22:18:08 2013	(r258699)
@@ -49,8 +49,8 @@ __FBSDID("$FreeBSD$");
 #define	IOREGSEL	0x00
 #define	IOWIN		0x10
 
-#define	REDIR_ENTRIES	16
-#define	INTR_ASSERTED(vioapic, pin) ((vioapic)->rtbl[(pin)].pinstate == true)
+#define	REDIR_ENTRIES	24
+#define	RTBL_RO_BITS	((uint64_t)(IOART_REM_IRR | IOART_DELIVS))
 
 struct vioapic {
 	struct vm	*vm;
@@ -59,8 +59,7 @@ struct vioapic {
 	uint32_t	ioregsel;
 	struct {
 		uint64_t reg;
-		bool     pinstate;
-		bool     pending;
+		int	 acnt;	/* sum of pin asserts (+1) and deasserts (-1) */
 	} rtbl[REDIR_ENTRIES];
 };
 
@@ -79,6 +78,9 @@ static MALLOC_DEFINE(M_VIOAPIC, "vioapic
 #define	VIOAPIC_CTR3(vioapic, fmt, a1, a2, a3)				\
 	VM_CTR3((vioapic)->vm, fmt, a1, a2, a3)
 
+#define	VIOAPIC_CTR4(vioapic, fmt, a1, a2, a3, a4)			\
+	VM_CTR4((vioapic)->vm, fmt, a1, a2, a3, a4)
+
 #ifdef KTR
 static const char *
 pinstate_str(bool asserted)
@@ -89,14 +91,25 @@ pinstate_str(bool asserted)
 	else
 		return ("deasserted");
 }
+
+static const char *
+trigger_str(bool level)
+{
+
+	if (level)
+		return ("level");
+	else
+		return ("edge");
+}
 #endif
 
 static void
-vioapic_set_pinstate(struct vioapic *vioapic, int pin, bool newstate)
+vioapic_send_intr(struct vioapic *vioapic, int pin)
 {
 	int vector, apicid, vcpuid;
 	uint32_t low, high;
 	cpuset_t dmask;
+	bool level;
 
 	KASSERT(pin >= 0 && pin < REDIR_ENTRIES,
 	    ("vioapic_set_pinstate: invalid pin number %d", pin));
@@ -104,62 +117,96 @@ vioapic_set_pinstate(struct vioapic *vio
 	KASSERT(VIOAPIC_LOCKED(vioapic),
 	    ("vioapic_set_pinstate: vioapic is not locked"));
 
-	VIOAPIC_CTR2(vioapic, "ioapic pin%d %s", pin, pinstate_str(newstate));
+	low = vioapic->rtbl[pin].reg;
+	high = vioapic->rtbl[pin].reg >> 32;
 
-	/* Nothing to do if interrupt pin has not changed state */
-	if (vioapic->rtbl[pin].pinstate == newstate)
+	/*
+	 * XXX We only deal with:
+	 * - physical destination
+	 * - fixed delivery mode
+	 */
+	if ((low & IOART_DESTMOD) != IOART_DESTPHY) {
+		VIOAPIC_CTR2(vioapic, "ioapic pin%d: unsupported dest mode "
+		    "0x%08x", pin, low);
 		return;
+	}
 
-	vioapic->rtbl[pin].pinstate = newstate;	/* record it */
+	if ((low & IOART_DELMOD) != IOART_DELFIXED) {
+		VIOAPIC_CTR2(vioapic, "ioapic pin%d: unsupported delivery mode "
+		    "0x%08x", pin, low);
+		return;
+	}
 
-	/* Nothing to do if interrupt pin is deasserted */
-	if (!INTR_ASSERTED(vioapic, pin))
+	if ((low & IOART_INTMASK) == IOART_INTMSET) {
+		VIOAPIC_CTR1(vioapic, "ioapic pin%d: masked", pin);
 		return;
+	}
 
-	/*
-	 * XXX
-	 * We only deal with:
-	 * - edge triggered interrupts
-	 * - fixed delivery mode
-	 *  Level-triggered sources will work so long as there is no sharing.
-	 */
-	low = vioapic->rtbl[pin].reg;
-	high = vioapic->rtbl[pin].reg >> 32;
-	if ((low & IOART_INTMASK) == IOART_INTMCLR &&
-	    (low & IOART_DESTMOD) == IOART_DESTPHY &&
-	    (low & IOART_DELMOD) == IOART_DELFIXED) {
-		vector = low & IOART_INTVEC;
-		apicid = high >> APIC_ID_SHIFT;
-		if (apicid != 0xff) {
-			/* unicast */
-			vcpuid = vm_apicid2vcpuid(vioapic->vm, apicid);
-			VIOAPIC_CTR3(vioapic, "ioapic pin%d triggering "
-			    "intr vector %d on vcpuid %d", pin, vector, vcpuid);
-			lapic_set_intr(vioapic->vm, vcpuid, vector);
-		} else {
-			/* broadcast */
-			VIOAPIC_CTR2(vioapic, "ioapic pin%d triggering intr "
-			    "vector %d on all vcpus", pin, vector);
-			dmask = vm_active_cpus(vioapic->vm);
-			while ((vcpuid = CPU_FFS(&dmask)) != 0) {
-				vcpuid--;
-				CPU_CLR(vcpuid, &dmask);
-				lapic_set_intr(vioapic->vm, vcpuid, vector);
-			}
+	level = low & IOART_TRGRLVL ? true : false;
+	if (level)
+		vioapic->rtbl[pin].reg |= IOART_REM_IRR;
+
+	vector = low & IOART_INTVEC;
+	apicid = high >> APIC_ID_SHIFT;
+	if (apicid != 0xff) {
+		/* unicast */
+		vcpuid = vm_apicid2vcpuid(vioapic->vm, apicid);
+		VIOAPIC_CTR4(vioapic, "ioapic pin%d: %s triggered intr "
+		    "vector %d on vcpuid %d", pin, trigger_str(level),
+		    vector, vcpuid);
+		lapic_set_intr(vioapic->vm, vcpuid, vector, level);
+	} else {
+		/* broadcast */
+		VIOAPIC_CTR3(vioapic, "ioapic pin%d: %s triggered intr "
+		    "vector %d on all vcpus", pin, trigger_str(level), vector);
+		dmask = vm_active_cpus(vioapic->vm);
+		while ((vcpuid = CPU_FFS(&dmask)) != 0) {
+			vcpuid--;
+			CPU_CLR(vcpuid, &dmask);
+			lapic_set_intr(vioapic->vm, vcpuid, vector, level);
 		}
-	} else if ((low & IOART_INTMASK) != IOART_INTMCLR &&
-		   (low & IOART_TRGRLVL) != 0) {
-		/*
-		 * For level-triggered interrupts that have been
-		 * masked, set the pending bit so that an interrupt
-		 * will be generated on unmask and if the level is
-		 * still asserted
-		 */
-		VIOAPIC_CTR1(vioapic, "ioapic pin%d interrupt pending", pin);
-		vioapic->rtbl[pin].pending = true;
 	}
 }
 
+static void
+vioapic_set_pinstate(struct vioapic *vioapic, int pin, bool newstate)
+{
+	int oldcnt, newcnt;
+	bool needintr;
+
+	KASSERT(pin >= 0 && pin < REDIR_ENTRIES,
+	    ("vioapic_set_pinstate: invalid pin number %d", pin));
+
+	KASSERT(VIOAPIC_LOCKED(vioapic),
+	    ("vioapic_set_pinstate: vioapic is not locked"));
+
+	oldcnt = vioapic->rtbl[pin].acnt;
+	if (newstate)
+		vioapic->rtbl[pin].acnt++;
+	else
+		vioapic->rtbl[pin].acnt--;
+	newcnt = vioapic->rtbl[pin].acnt;
+
+	if (newcnt < 0) {
+		VIOAPIC_CTR2(vioapic, "ioapic pin%d: bad acnt %d",
+		    pin, newcnt);
+	}
+
+	needintr = false;
+	if (oldcnt == 0 && newcnt == 1) {
+		needintr = true;
+		VIOAPIC_CTR1(vioapic, "ioapic pin%d: asserted", pin);
+	} else if (oldcnt == 1 && newcnt == 0) {
+		VIOAPIC_CTR1(vioapic, "ioapic pin%d: deasserted", pin);
+	} else {
+		VIOAPIC_CTR3(vioapic, "ioapic pin%d: %s, ignored, acnt %d",
+		    pin, pinstate_str(newstate), newcnt);
+	}
+
+	if (needintr)
+		vioapic_send_intr(vioapic, pin);
+}
+
 enum irqstate {
 	IRQSTATE_ASSERT,
 	IRQSTATE_DEASSERT,
@@ -228,7 +275,7 @@ vioapic_read(struct vioapic *vioapic, ui
 		return (vioapic->id);
 		break;
 	case IOAPIC_VER:
-		return ((REDIR_ENTRIES << MAXREDIRSHIFT) | 0x11);
+		return (((REDIR_ENTRIES - 1) << MAXREDIRSHIFT) | 0x11);
 		break;
 	case IOAPIC_ARB:
 		return (vioapic->id);
@@ -255,6 +302,7 @@ vioapic_read(struct vioapic *vioapic, ui
 static void
 vioapic_write(struct vioapic *vioapic, uint32_t addr, uint32_t data)
 {
+	uint64_t data64, mask64;
 	int regnum, pin, lshift;
 
 	regnum = addr & 0xff;
@@ -279,30 +327,26 @@ vioapic_write(struct vioapic *vioapic, u
 		else
 			lshift = 0;
 
-		vioapic->rtbl[pin].reg &= ~((uint64_t)0xffffffff << lshift);
-		vioapic->rtbl[pin].reg |= ((uint64_t)data << lshift);
+		data64 = (uint64_t)data << lshift;
+		mask64 = (uint64_t)0xffffffff << lshift;
+		vioapic->rtbl[pin].reg &= ~mask64 | RTBL_RO_BITS;
+		vioapic->rtbl[pin].reg |= data64 & ~RTBL_RO_BITS;
 
-		VIOAPIC_CTR2(vioapic, "ioapic pin%d redir table entry %#lx",
+		VIOAPIC_CTR2(vioapic, "ioapic pin%d: redir table entry %#lx",
 		    pin, vioapic->rtbl[pin].reg);
 
-		if (vioapic->rtbl[pin].pending &&
-		    ((vioapic->rtbl[pin].reg & IOART_INTMASK) ==
-		    IOART_INTMCLR)) {
-			vioapic->rtbl[pin].pending = false;
-			/*
-			 * Inject the deferred level-triggered int if it is
-			 * still asserted. Simulate by toggling the pin
-			 * off and then on.
-			 */
-			if (vioapic->rtbl[pin].pinstate == true) {
-				VIOAPIC_CTR1(vioapic, "ioapic pin%d pending "
-				    "interrupt delivered", pin);
-				vioapic_set_pinstate(vioapic, pin, false);
-				vioapic_set_pinstate(vioapic, pin, true);
-			} else {
-				VIOAPIC_CTR1(vioapic, "ioapic pin%d pending "
-				    "interrupt dismissed", pin);
-			}
+		/*
+		 * Generate an interrupt if the following conditions are met:
+		 * - pin is not masked
+		 * - previous interrupt has been EOIed
+		 * - pin level is asserted
+		 */
+		if ((vioapic->rtbl[pin].reg & IOART_INTMASK) == IOART_INTMCLR &&
+		    (vioapic->rtbl[pin].reg & IOART_REM_IRR) == 0 &&
+		    (vioapic->rtbl[pin].acnt > 0)) {
+			VIOAPIC_CTR2(vioapic, "ioapic pin%d: asserted at rtbl "
+			    "write, acnt %d", pin, vioapic->rtbl[pin].acnt);
+			vioapic_send_intr(vioapic, pin);
 		}
 	}
 }
@@ -366,6 +410,38 @@ vioapic_mmio_write(void *vm, int vcpuid,
 	return (error);
 }
 
+void
+vioapic_process_eoi(struct vm *vm, int vcpuid, int vector)
+{
+	struct vioapic *vioapic;
+	int pin;
+
+	KASSERT(vector >= 0 && vector < 256,
+	    ("vioapic_process_eoi: invalid vector %d", vector));
+
+	vioapic = vm_ioapic(vm);
+	VIOAPIC_CTR1(vioapic, "ioapic processing eoi for vector %d", vector);
+
+	/*
+	 * XXX keep track of the pins associated with this vector instead
+	 * of iterating on every single pin each time.
+	 */
+	VIOAPIC_LOCK(vioapic);
+	for (pin = 0; pin < REDIR_ENTRIES; pin++) {
+		if ((vioapic->rtbl[pin].reg & IOART_REM_IRR) == 0)
+			continue;
+		if ((vioapic->rtbl[pin].reg & IOART_INTVEC) != vector)
+			continue;
+		vioapic->rtbl[pin].reg &= ~IOART_REM_IRR;
+		if (vioapic->rtbl[pin].acnt > 0) {
+			VIOAPIC_CTR2(vioapic, "ioapic pin%d: asserted at eoi, "
+			    "acnt %d", pin, vioapic->rtbl[pin].acnt);
+			vioapic_send_intr(vioapic, pin);
+		}
+	}
+	VIOAPIC_UNLOCK(vioapic);
+}
+
 struct vioapic *
 vioapic_init(struct vm *vm)
 {
@@ -390,3 +466,10 @@ vioapic_cleanup(struct vioapic *vioapic)
 
 	free(vioapic, M_VIOAPIC);
 }
+
+int
+vioapic_pincount(struct vm *vm)
+{
+
+	return (REDIR_ENTRIES);
+}

Modified: head/sys/amd64/vmm/io/vioapic.h
==============================================================================
--- head/sys/amd64/vmm/io/vioapic.h	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/io/vioapic.h	Wed Nov 27 22:18:08 2013	(r258699)
@@ -44,4 +44,7 @@ int	vioapic_mmio_write(void *vm, int vcp
 	    uint64_t wval, int size, void *arg);
 int	vioapic_mmio_read(void *vm, int vcpuid, uint64_t gpa,
 	    uint64_t *rval, int size, void *arg);
+
+int	vioapic_pincount(struct vm *vm);
+void	vioapic_process_eoi(struct vm *vm, int vcpuid, int vector);
 #endif

Modified: head/sys/amd64/vmm/io/vlapic.c
==============================================================================
--- head/sys/amd64/vmm/io/vlapic.c	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/io/vlapic.c	Wed Nov 27 22:18:08 2013	(r258699)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
 #include "vmm_lapic.h"
 #include "vmm_ktr.h"
 #include "vlapic.h"
+#include "vioapic.h"
 
 #define	VLAPIC_CTR0(vlapic, format)					\
 	VCPU_CTR0((vlapic)->vm, (vlapic)->vcpuid, format)
@@ -211,18 +212,32 @@ vlapic_reset(struct vlapic *vlapic)
 }
 
 void
-vlapic_set_intr_ready(struct vlapic *vlapic, int vector)
+vlapic_set_intr_ready(struct vlapic *vlapic, int vector, bool level)
 {
 	struct LAPIC	*lapic = &vlapic->apic;
-	uint32_t	*irrptr;
+	uint32_t	*irrptr, *tmrptr, mask;
 	int		idx;
 
 	if (vector < 0 || vector >= 256)
 		panic("vlapic_set_intr_ready: invalid vector %d\n", vector);
 
 	idx = (vector / 32) * 4;
+	mask = 1 << (vector % 32);
+
 	irrptr = &lapic->irr0;
-	atomic_set_int(&irrptr[idx], 1 << (vector % 32));
+	atomic_set_int(&irrptr[idx], mask);
+
+	/*
+	 * Upon acceptance of an interrupt into the IRR the corresponding
+	 * TMR bit is cleared for edge-triggered interrupts and set for
+	 * level-triggered interrupts.
+	 */
+	tmrptr = &lapic->tmr0;
+	if (level)
+		atomic_set_int(&tmrptr[idx], mask);
+	else
+		atomic_clear_int(&tmrptr[idx], mask);
+
 	VLAPIC_CTR_IRR(vlapic, "vlapic_set_intr_ready");
 }
 
@@ -350,10 +365,11 @@ static void
 vlapic_process_eoi(struct vlapic *vlapic)
 {
 	struct LAPIC	*lapic = &vlapic->apic;
-	uint32_t	*isrptr;
-	int		i, idx, bitpos;
+	uint32_t	*isrptr, *tmrptr;
+	int		i, idx, bitpos, vector;
 
 	isrptr = &lapic->isr0;
+	tmrptr = &lapic->tmr0;
 
 	/*
 	 * The x86 architecture reserves the the first 32 vectors for use
@@ -362,15 +378,20 @@ vlapic_process_eoi(struct vlapic *vlapic
 	for (i = 7; i > 0; i--) {
 		idx = i * 4;
 		bitpos = fls(isrptr[idx]);
-		if (bitpos != 0) {
+		if (bitpos-- != 0) {
 			if (vlapic->isrvec_stk_top <= 0) {
 				panic("invalid vlapic isrvec_stk_top %d",
 				      vlapic->isrvec_stk_top);
 			}
-			isrptr[idx] &= ~(1 << (bitpos - 1));
+			isrptr[idx] &= ~(1 << bitpos);
 			VLAPIC_CTR_ISR(vlapic, "vlapic_process_eoi");
 			vlapic->isrvec_stk_top--;
 			vlapic_update_ppr(vlapic);
+			if ((tmrptr[idx] & (1 << bitpos)) != 0) {
+				vector = i * 32 + bitpos;
+				vioapic_process_eoi(vlapic->vm, vlapic->vcpuid,
+				    vector);
+			}
 			return;
 		}
 	}
@@ -405,7 +426,7 @@ vlapic_fire_timer(struct vlapic *vlapic)
 	if (!vlapic_get_lvt_field(lvt, APIC_LVTT_M)) {
 		vmm_stat_incr(vlapic->vm, vlapic->vcpuid, VLAPIC_INTR_TIMER, 1);
 		vector = vlapic_get_lvt_field(lvt,APIC_LVTT_VECTOR);
-		vlapic_set_intr_ready(vlapic, vector);
+		vlapic_set_intr_ready(vlapic, vector, false);
 	}
 }
 
@@ -451,7 +472,7 @@ lapic_process_icr(struct vlapic *vlapic,
 			i--;
 			CPU_CLR(i, &dmask);
 			if (mode == APIC_DELMODE_FIXED) {
-				lapic_set_intr(vlapic->vm, i, vec);
+				lapic_intr_edge(vlapic->vm, i, vec);
 				vmm_stat_array_incr(vlapic->vm, vlapic->vcpuid,
 						    IPIS_SENT, i, 1);
 			} else

Modified: head/sys/amd64/vmm/io/vlapic.h
==============================================================================
--- head/sys/amd64/vmm/io/vlapic.h	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/io/vlapic.h	Wed Nov 27 22:18:08 2013	(r258699)
@@ -94,7 +94,7 @@ int vlapic_write(struct vlapic *vlapic, 
 int vlapic_read(struct vlapic *vlapic, uint64_t offset, uint64_t *data);
 int vlapic_pending_intr(struct vlapic *vlapic);
 void vlapic_intr_accepted(struct vlapic *vlapic, int vector);
-void vlapic_set_intr_ready(struct vlapic *vlapic, int vector);
+void vlapic_set_intr_ready(struct vlapic *vlapic, int vector, bool level);
 int vlapic_timer_tick(struct vlapic *vlapic);
 
 uint64_t vlapic_get_apicbase(struct vlapic *vlapic);

Modified: head/sys/amd64/vmm/vmm_dev.c
==============================================================================
--- head/sys/amd64/vmm/vmm_dev.c	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/vmm_dev.c	Wed Nov 27 22:18:08 2013	(r258699)
@@ -294,7 +294,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long c
 		break;
 	case VM_LAPIC_IRQ:
 		vmirq = (struct vm_lapic_irq *)data;
-		error = lapic_set_intr(sc->vm, vmirq->cpuid, vmirq->vector);
+		error = lapic_intr_edge(sc->vm, vmirq->cpuid, vmirq->vector);
 		break;
 	case VM_IOAPIC_ASSERT_IRQ:
 		ioapic_irq = (struct vm_ioapic_irq *)data;

Modified: head/sys/amd64/vmm/vmm_ktr.h
==============================================================================
--- head/sys/amd64/vmm/vmm_ktr.h	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/vmm_ktr.h	Wed Nov 27 22:18:08 2013	(r258699)
@@ -59,4 +59,7 @@ CTR3(KTR_VMM, "vm %s: " format, vm_name(
 
 #define	VM_CTR3(vm, format, p1, p2, p3)					\
 CTR4(KTR_VMM, "vm %s: " format, vm_name((vm)), (p1), (p2), (p3))
+
+#define	VM_CTR4(vm, format, p1, p2, p3, p4)				\
+CTR5(KTR_VMM, "vm %s: " format, vm_name((vm)), (p1), (p2), (p3), (p4))
 #endif

Modified: head/sys/amd64/vmm/vmm_lapic.c
==============================================================================
--- head/sys/amd64/vmm/vmm_lapic.c	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/vmm_lapic.c	Wed Nov 27 22:18:08 2013	(r258699)
@@ -62,7 +62,7 @@ lapic_intr_accepted(struct vm *vm, int c
 }
 
 int
-lapic_set_intr(struct vm *vm, int cpu, int vector)
+lapic_set_intr(struct vm *vm, int cpu, int vector, bool level)
 {
 	struct vlapic *vlapic;
 
@@ -73,7 +73,7 @@ lapic_set_intr(struct vm *vm, int cpu, i
 		return (EINVAL);
 
 	vlapic = vm_lapic(vm, cpu);
-	vlapic_set_intr_ready(vlapic, vector);
+	vlapic_set_intr_ready(vlapic, vector, level);
 
 	vm_interrupt_hostcpu(vm, cpu);
 

Modified: head/sys/amd64/vmm/vmm_lapic.h
==============================================================================
--- head/sys/amd64/vmm/vmm_lapic.h	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/sys/amd64/vmm/vmm_lapic.h	Wed Nov 27 22:18:08 2013	(r258699)
@@ -66,6 +66,22 @@ void	lapic_intr_accepted(struct vm *vm, 
  * Signals to the LAPIC that an interrupt at 'vector' needs to be generated
  * to the 'cpu', the state is recorded in IRR.
  */
-int	lapic_set_intr(struct vm *vm, int cpu, int vector);
+int	lapic_set_intr(struct vm *vm, int cpu, int vector, bool trig);
+
+#define	LAPIC_TRIG_LEVEL	true
+#define	LAPIC_TRIG_EDGE		false
+static __inline int
+lapic_intr_level(struct vm *vm, int cpu, int vector)
+{
+
+	return (lapic_set_intr(vm, cpu, vector, LAPIC_TRIG_LEVEL));
+}
+
+static __inline int
+lapic_intr_edge(struct vm *vm, int cpu, int vector)
+{
+
+	return (lapic_set_intr(vm, cpu, vector, LAPIC_TRIG_EDGE));
+}
 
 #endif

Modified: head/usr.sbin/bhyve/acpi.c
==============================================================================
--- head/usr.sbin/bhyve/acpi.c	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/usr.sbin/bhyve/acpi.c	Wed Nov 27 22:18:08 2013	(r258699)
@@ -259,7 +259,7 @@ basl_fwrite_madt(FILE *fp)
 		EFPRINTF(fp, "\n");
 	}
 
-	/* Always a single IOAPIC entry, with ID ncpu+1 */
+	/* Always a single IOAPIC entry, with ID 0 */
 	EFPRINTF(fp, "[0001]\t\tSubtable Type : 01\n");
 	EFPRINTF(fp, "[0001]\t\tLength : 0C\n");
 	/* iasl expects a hex value for the i/o apic id */

Modified: head/usr.sbin/bhyve/mptbl.c
==============================================================================
--- head/usr.sbin/bhyve/mptbl.c	Wed Nov 27 22:17:00 2013	(r258698)
+++ head/usr.sbin/bhyve/mptbl.c	Wed Nov 27 22:18:08 2013	(r258699)
@@ -72,7 +72,7 @@ __FBSDID("$FreeBSD$");
 #define MPEP_FEATURES           (0xBFEBFBFF) /* XXX Intel i7 */
 
 /* Number of i/o intr entries */
-#define	MPEII_MAX_IRQ		16
+#define	MPEII_MAX_IRQ		24
 
 /* Define processor entry struct since <x86/mptable.h> gets it wrong */
 typedef struct BPROCENTRY {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201311272218.rARMI9Y1065386>