--- sys/amd64/vmm/amd/svm.c.orig
+++ sys/amd64/vmm/amd/svm.c
@@ -488,10 +488,23 @@
 	svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_SHUTDOWN);
 	svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT,
 	    VMCB_INTCPT_FERR_FREEZE);
+	svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_INVD);
+	svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_INVLPGA);
 
 	svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_MONITOR);
 	svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_MWAIT);
 
+	/*
+	 * Intercept SVM instructions since AMD enables them in guests otherwise.
+	 * Non-intercepted VMMCALL causes #UD, skip it.
+	 */
+	svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_VMLOAD);
+	svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_VMSAVE);
+	svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_STGI);
+	svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_CLGI);
+	svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_SKINIT);
+	svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_ICEBP);
+
 	/*
 	 * From section "Canonicalization and Consistency Checks" in APMv2
 	 * the VMRUN intercept bit must be set to pass the consistency check.
@@ -1236,43 +1249,45 @@
 static const char *
 exit_reason_to_str(uint64_t reason)
 {
+	int i;
 	static char reasonbuf[32];
-
-	switch (reason) {
-	case VMCB_EXIT_INVALID:
-		return ("invalvmcb");
-	case VMCB_EXIT_SHUTDOWN:
-		return ("shutdown");
-	case VMCB_EXIT_NPF:
-		return ("nptfault");
-	case VMCB_EXIT_PAUSE:
-		return ("pause");
-	case VMCB_EXIT_HLT:
-		return ("hlt");
-	case VMCB_EXIT_CPUID:
-		return ("cpuid");
-	case VMCB_EXIT_IO:
-		return ("inout");
-	case VMCB_EXIT_MC:
-		return ("mchk");
-	case VMCB_EXIT_INTR:
-		return ("extintr");
-	case VMCB_EXIT_NMI:
-		return ("nmi");
-	case VMCB_EXIT_VINTR:
-		return ("vintr");
-	case VMCB_EXIT_MSR:
-		return ("msr");
-	case VMCB_EXIT_IRET:
-		return ("iret");
-	case VMCB_EXIT_MONITOR:
-		return ("monitor");
-	case VMCB_EXIT_MWAIT:
-		return ("mwait");
-	default:
-		snprintf(reasonbuf, sizeof(reasonbuf), "%#lx", reason);
-		return (reasonbuf);
+	static const struct {
+		int reason;
+		const char *str;
+	} reasons[] = {
+		{ .reason = VMCB_EXIT_INVALID,	.str = "invalvmcb" },
+		{ .reason = VMCB_EXIT_SHUTDOWN,	.str = "shutdown" },
+		{ .reason = VMCB_EXIT_NPF, 	.str = "nptfault" },
+		{ .reason = VMCB_EXIT_PAUSE,	.str = "pause" },
+		{ .reason = VMCB_EXIT_HLT,	.str = "hlt" },
+		{ .reason = VMCB_EXIT_CPUID,	.str = "cpuid" },
+		{ .reason = VMCB_EXIT_IO,	.str = "inout" },
+		{ .reason = VMCB_EXIT_MC,	.str = "mchk" },
+		{ .reason = VMCB_EXIT_INTR,	.str = "extintr" },
+		{ .reason = VMCB_EXIT_NMI,	.str = "nmi" },
+		{ .reason = VMCB_EXIT_VINTR,	.str = "vintr" },
+		{ .reason = VMCB_EXIT_MSR,	.str = "msr" },
+		{ .reason = VMCB_EXIT_IRET,	.str = "iret" },
+		{ .reason = VMCB_EXIT_MONITOR,	.str = "monitor" },
+		{ .reason = VMCB_EXIT_MWAIT,	.str = "mwait" },
+		{ .reason = VMCB_EXIT_VMRUN,	.str = "vmrun" },
+		{ .reason = VMCB_EXIT_VMMCALL,	.str = "vmmcall" },
+		{ .reason = VMCB_EXIT_VMLOAD,	.str = "vmload" },
+		{ .reason = VMCB_EXIT_VMSAVE,	.str = "vmsave" },
+		{ .reason = VMCB_EXIT_STGI,	.str = "stgi" },
+		{ .reason = VMCB_EXIT_CLGI,	.str = "clgi" },
+		{ .reason = VMCB_EXIT_SKINIT,	.str = "skinit" },
+		{ .reason = VMCB_EXIT_ICEBP,	.str = "icebp" },
+		{ .reason = VMCB_EXIT_INVD,	.str = "invd" },
+		{ .reason = VMCB_EXIT_INVLPGA,	.str = "invlpga" },
+	};
+
+	for (i = 0; i < nitems(reasons); i++) {
+		if (reasons[i].reason == reason)
+			return (reasons[i].str);
 	}
+	snprintf(reasonbuf, sizeof(reasonbuf), "%#lx", reason);
+	return (reasonbuf);
 }
 #endif	/* KTR */
 
@@ -1524,6 +1539,20 @@
 	case VMCB_EXIT_MWAIT:
 		vmexit->exitcode = VM_EXITCODE_MWAIT;
 		break;
+	case VMCB_EXIT_SHUTDOWN:
+	case VMCB_EXIT_VMRUN:
+	case VMCB_EXIT_VMMCALL:
+	case VMCB_EXIT_VMLOAD:
+	case VMCB_EXIT_VMSAVE:
+	case VMCB_EXIT_STGI:
+	case VMCB_EXIT_CLGI:
+	case VMCB_EXIT_SKINIT:
+	case VMCB_EXIT_ICEBP:
+	case VMCB_EXIT_INVD:
+	case VMCB_EXIT_INVLPGA:
+		vm_inject_ud(svm_sc->vm, vcpu);
+		handled = 1;
+		break;
 	default:
 		vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_UNKNOWN, 1);
 		break;
--- sys/amd64/vmm/amd/vmcb.h.orig
+++ sys/amd64/vmm/amd/vmcb.h
@@ -71,8 +71,8 @@
 #define	VMCB_INTCPT_INVD		BIT(22)
 #define	VMCB_INTCPT_PAUSE		BIT(23)
 #define	VMCB_INTCPT_HLT			BIT(24)
-#define	VMCB_INTCPT_INVPG		BIT(25)
-#define	VMCB_INTCPT_INVPGA		BIT(26)
+#define	VMCB_INTCPT_INVLPG		BIT(25)
+#define	VMCB_INTCPT_INVLPGA		BIT(26)
 #define	VMCB_INTCPT_IO			BIT(27)
 #define	VMCB_INTCPT_MSR			BIT(28)
 #define	VMCB_INTCPT_TASK_SWITCH		BIT(29)
@@ -134,12 +134,21 @@
 #define	VMCB_EXIT_POPF			0x71
 #define	VMCB_EXIT_CPUID			0x72
 #define	VMCB_EXIT_IRET			0x74
+#define	VMCB_EXIT_INVD			0x76
 #define	VMCB_EXIT_PAUSE			0x77
 #define	VMCB_EXIT_HLT			0x78
+#define	VMCB_EXIT_INVLPGA		0x7A
 #define	VMCB_EXIT_IO			0x7B
 #define	VMCB_EXIT_MSR			0x7C
 #define	VMCB_EXIT_SHUTDOWN		0x7F
+#define	VMCB_EXIT_VMRUN			0x80
+#define	VMCB_EXIT_VMMCALL		0x81
+#define	VMCB_EXIT_VMLOAD		0x82
 #define	VMCB_EXIT_VMSAVE		0x83
+#define	VMCB_EXIT_STGI			0x84
+#define	VMCB_EXIT_CLGI			0x85
+#define	VMCB_EXIT_SKINIT		0x86
+#define	VMCB_EXIT_ICEBP			0x88
 #define	VMCB_EXIT_MONITOR		0x8A
 #define	VMCB_EXIT_MWAIT			0x8B
 #define	VMCB_EXIT_NPF			0x400
