changeset 21495:80001d779f72

Merge pull request #497 from hadfl/joyent_merge/2019061201 Joyent merge/2019061201
author Tobias Oetiker <tobi@oetiker.ch>
date Thu, 13 Jun 2019 10:53:23 +0200
parents fd839de25b5f (current diff) 7f6c16965285 (diff)
children c4ed0980aecd dd4db089303c
files
diffstat 4 files changed, 33 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/README.OmniOS	Wed Jun 12 22:57:18 2019 +0200
+++ b/README.OmniOS	Thu Jun 13 10:53:23 2019 +0200
@@ -1,5 +1,5 @@
 This README is here to keep track of merges from Joyent (a massive and
 continuing side-pull).
 
-Last illumos-joyent commit: 9240ea30ee29d2a499bcf3eed9e12dd9921f39f8
+Last illumos-joyent commit: e6de8afafa8b73b0636044f094ba810178b0a271
 
--- a/usr/src/uts/i86pc/io/vmm/io/vlapic.c	Wed Jun 12 22:57:18 2019 +0200
+++ b/usr/src/uts/i86pc/io/vmm/io/vlapic.c	Thu Jun 13 10:53:23 2019 +0200
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2011 NetApp, Inc.
  * All rights reserved.
+ * Copyright (c) 2019 Joyent, Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -91,6 +92,8 @@
  */
 #define VLAPIC_BUS_FREQ		(128 * 1024 * 1024)
 
+static void vlapic_set_error(struct vlapic *, uint32_t, bool);
+
 static __inline uint32_t
 vlapic_get_id(struct vlapic *vlapic)
 {
@@ -293,7 +296,8 @@
 	}
 
 	if (vector < 16) {
-		vlapic_set_error(vlapic, APIC_ESR_RECEIVE_ILLEGAL_VECTOR);
+		vlapic_set_error(vlapic, APIC_ESR_RECEIVE_ILLEGAL_VECTOR,
+		    false);
 		VLAPIC_CTR1(vlapic, "vlapic ignoring interrupt to vector %d",
 		    vector);
 		return (1);
@@ -455,20 +459,22 @@
 }
 
 static int
-vlapic_fire_lvt(struct vlapic *vlapic, uint32_t lvt)
+vlapic_fire_lvt(struct vlapic *vlapic, u_int lvt)
 {
-	uint32_t vec, mode;
+	uint32_t mode, reg, vec;
 
-	if (lvt & APIC_LVT_M)
-		return (0);
+	reg = atomic_load_acq_32(&vlapic->lvt_last[lvt]);
 
-	vec = lvt & APIC_LVT_VECTOR;
-	mode = lvt & APIC_LVT_DM;
+	if (reg & APIC_LVT_M)
+		return (0);
+	vec = reg & APIC_LVT_VECTOR;
+	mode = reg & APIC_LVT_DM;
 
 	switch (mode) {
 	case APIC_LVT_DM_FIXED:
 		if (vec < 16) {
-			vlapic_set_error(vlapic, APIC_ESR_SEND_ILLEGAL_VECTOR);
+			vlapic_set_error(vlapic, APIC_ESR_SEND_ILLEGAL_VECTOR,
+			    lvt == APIC_LVT_ERROR);
 			return (0);
 		}
 		if (vlapic_set_intr_ready(vlapic, vec, false))
@@ -629,22 +635,22 @@
 
 static VMM_STAT(VLAPIC_INTR_ERROR, "error interrupts generated by vlapic");
 
-void
-vlapic_set_error(struct vlapic *vlapic, uint32_t mask)
+static void
+vlapic_set_error(struct vlapic *vlapic, uint32_t mask, bool lvt_error)
 {
-	uint32_t lvt;
 
 	vlapic->esr_pending |= mask;
-	if (vlapic->esr_firing)
-		return;
-	vlapic->esr_firing = 1;
 
-	// The error LVT always uses the fixed delivery mode.
-	lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_ERROR_LVT);
-	if (vlapic_fire_lvt(vlapic, lvt | APIC_LVT_DM_FIXED)) {
+	/*
+	 * Avoid infinite recursion if the error LVT itself is configured with
+	 * an illegal vector.
+	 */
+	if (lvt_error)
+		return;
+
+	if (vlapic_fire_lvt(vlapic, APIC_LVT_ERROR)) {
 		vmm_stat_incr(vlapic->vm, vlapic->vcpuid, VLAPIC_INTR_ERROR, 1);
 	}
-	vlapic->esr_firing = 0;
 }
 
 static VMM_STAT(VLAPIC_INTR_TIMER, "timer interrupts generated by vlapic");
@@ -652,13 +658,10 @@
 static void
 vlapic_fire_timer(struct vlapic *vlapic)
 {
-	uint32_t lvt;
 
 	KASSERT(VLAPIC_TIMER_LOCKED(vlapic), ("vlapic_fire_timer not locked"));
-	
-	// The timer LVT always uses the fixed delivery mode.
-	lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_TIMER_LVT);
-	if (vlapic_fire_lvt(vlapic, lvt | APIC_LVT_DM_FIXED)) {
+
+	if (vlapic_fire_lvt(vlapic, APIC_LVT_TIMER)) {
 		VLAPIC_CTR0(vlapic, "vlapic timer fired");
 		vmm_stat_incr(vlapic->vm, vlapic->vcpuid, VLAPIC_INTR_TIMER, 1);
 	}
@@ -670,10 +673,8 @@
 void
 vlapic_fire_cmci(struct vlapic *vlapic)
 {
-	uint32_t lvt;
 
-	lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_CMCI_LVT);
-	if (vlapic_fire_lvt(vlapic, lvt)) {
+	if (vlapic_fire_lvt(vlapic, APIC_LVT_CMCI)) {
 		vmm_stat_incr(vlapic->vm, vlapic->vcpuid, VLAPIC_INTR_CMC, 1);
 	}
 }
@@ -684,7 +685,6 @@
 int
 vlapic_trigger_lvt(struct vlapic *vlapic, int vector)
 {
-	uint32_t lvt;
 
 	if (vlapic_enabled(vlapic) == false) {
 		/*
@@ -707,35 +707,20 @@
 
 	switch (vector) {
 	case APIC_LVT_LINT0:
-		lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_LINT0_LVT);
-		break;
 	case APIC_LVT_LINT1:
-		lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_LINT1_LVT);
-		break;
 	case APIC_LVT_TIMER:
-		lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_TIMER_LVT);
-		lvt |= APIC_LVT_DM_FIXED;
-		break;
 	case APIC_LVT_ERROR:
-		lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_ERROR_LVT);
-		lvt |= APIC_LVT_DM_FIXED;
-		break;
 	case APIC_LVT_PMC:
-		lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_PERF_LVT);
-		break;
 	case APIC_LVT_THERMAL:
-		lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_THERM_LVT);
-		break;
 	case APIC_LVT_CMCI:
-		lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_CMCI_LVT);
+		if (vlapic_fire_lvt(vlapic, vector)) {
+			vmm_stat_array_incr(vlapic->vm, vlapic->vcpuid,
+			    LVTS_TRIGGERRED, vector, 1);
+		}
 		break;
 	default:
 		return (EINVAL);
 	}
-	if (vlapic_fire_lvt(vlapic, lvt)) {
-		vmm_stat_array_incr(vlapic->vm, vlapic->vcpuid,
-		    LVTS_TRIGGERRED, vector, 1);
-	}
 	return (0);
 }
 
@@ -1008,7 +993,7 @@
 	mode = icrval & APIC_DELMODE_MASK;
 
 	if (mode == APIC_DELMODE_FIXED && vec < 16) {
-		vlapic_set_error(vlapic, APIC_ESR_SEND_ILLEGAL_VECTOR);
+		vlapic_set_error(vlapic, APIC_ESR_SEND_ILLEGAL_VECTOR, false);
 		VLAPIC_CTR1(vlapic, "Ignoring invalid IPI %d", vec);
 		return (0);
 	}
--- a/usr/src/uts/i86pc/io/vmm/io/vlapic.h	Wed Jun 12 22:57:18 2019 +0200
+++ b/usr/src/uts/i86pc/io/vmm/io/vlapic.h	Thu Jun 13 10:53:23 2019 +0200
@@ -75,7 +75,6 @@
  */
 void vlapic_post_intr(struct vlapic *vlapic, int hostcpu, int ipinum);
 
-void vlapic_set_error(struct vlapic *vlapic, uint32_t mask);
 void vlapic_fire_cmci(struct vlapic *vlapic);
 int vlapic_trigger_lvt(struct vlapic *vlapic, int vector);
 
--- a/usr/src/uts/i86pc/io/vmm/io/vlapic_priv.h	Wed Jun 12 22:57:18 2019 +0200
+++ b/usr/src/uts/i86pc/io/vmm/io/vlapic_priv.h	Thu Jun 13 10:53:23 2019 +0200
@@ -156,7 +156,6 @@
 	struct vlapic_ops	ops;
 
 	uint32_t		esr_pending;
-	int			esr_firing;
 
 	struct callout	callout;	/* vlapic timer */
 	struct bintime	timer_fire_bt;	/* callout expiry time */