* [PATCH 0/3] x86/svm: Make various details private
@ 2025-11-28 20:19 Andrew Cooper
2025-11-28 20:19 ` [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/ Andrew Cooper
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Andrew Cooper @ 2025-11-28 20:19 UTC (permalink / raw)
To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monné
Lots of this does not need to be included into all translation units.
Andrew Cooper (3):
x86/svm: Make vmcb_struct private to svm/
x86/svm: Drop svmdebug.c
x86/svm: Drop svmdebug.h
xen/arch/x86/hvm/svm/Makefile | 1 -
xen/arch/x86/hvm/svm/asid.c | 1 +
xen/arch/x86/hvm/svm/emulate.c | 1 +
xen/arch/x86/hvm/svm/intr.c | 1 +
xen/arch/x86/hvm/svm/nestedsvm.c | 2 +-
xen/arch/x86/hvm/svm/svm.c | 2 +-
xen/arch/x86/hvm/svm/svm.h | 17 +
xen/arch/x86/hvm/svm/svmdebug.c | 179 ------
xen/arch/x86/hvm/svm/vmcb.c | 163 ++++-
xen/arch/x86/hvm/svm/vmcb.h | 620 +++++++++++++++++++
xen/arch/x86/include/asm/hvm/svm/svmdebug.h | 19 -
xen/arch/x86/include/asm/hvm/svm/vmcb.h | 621 --------------------
12 files changed, 804 insertions(+), 823 deletions(-)
delete mode 100644 xen/arch/x86/hvm/svm/svmdebug.c
create mode 100644 xen/arch/x86/hvm/svm/vmcb.h
delete mode 100644 xen/arch/x86/include/asm/hvm/svm/svmdebug.h
base-commit: 486c7f79c0032cbd210af8f3f1d204f8eabfdbde
--
2.39.5
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/
2025-11-28 20:19 [PATCH 0/3] x86/svm: Make various details private Andrew Cooper
@ 2025-11-28 20:19 ` Andrew Cooper
2025-12-01 15:23 ` Alejandro Vallejo
2025-12-08 9:05 ` Jan Beulich
2025-11-28 20:19 ` [PATCH 2/3] x86/svm: Drop svmdebug.c Andrew Cooper
2025-11-28 20:19 ` [PATCH 3/3] x86/svm: Drop svmdebug.h Andrew Cooper
2 siblings, 2 replies; 12+ messages in thread
From: Andrew Cooper @ 2025-11-28 20:19 UTC (permalink / raw)
To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monné
The rest of Xen has no buisness knowing this structure, and it is currently
included via xen/sched.h into most code. Create a new private svm/vmcb.h.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
---
xen/arch/x86/hvm/svm/asid.c | 1 +
xen/arch/x86/hvm/svm/emulate.c | 1 +
xen/arch/x86/hvm/svm/intr.c | 1 +
xen/arch/x86/hvm/svm/nestedsvm.c | 1 +
xen/arch/x86/hvm/svm/svm.c | 1 +
xen/arch/x86/hvm/svm/svmdebug.c | 2 +
xen/arch/x86/hvm/svm/vmcb.c | 2 +
xen/arch/x86/hvm/svm/vmcb.h | 617 ++++++++++++++++++++++++
xen/arch/x86/include/asm/hvm/svm/vmcb.h | 606 -----------------------
9 files changed, 626 insertions(+), 606 deletions(-)
create mode 100644 xen/arch/x86/hvm/svm/vmcb.h
diff --git a/xen/arch/x86/hvm/svm/asid.c b/xen/arch/x86/hvm/svm/asid.c
index 03f98b7a8b89..0e115243a3af 100644
--- a/xen/arch/x86/hvm/svm/asid.c
+++ b/xen/arch/x86/hvm/svm/asid.c
@@ -9,6 +9,7 @@
#include <asm/hvm/svm/svm.h>
#include "svm.h"
+#include "vmcb.h"
void svm_asid_init(const struct cpuinfo_x86 *c)
{
diff --git a/xen/arch/x86/hvm/svm/emulate.c b/xen/arch/x86/hvm/svm/emulate.c
index 93ac1d3435f9..d8aa45590885 100644
--- a/xen/arch/x86/hvm/svm/emulate.c
+++ b/xen/arch/x86/hvm/svm/emulate.c
@@ -15,6 +15,7 @@
#include <asm/hvm/svm/vmcb.h>
#include "svm.h"
+#include "vmcb.h"
static unsigned long svm_nextrip_insn_length(struct vcpu *v)
{
diff --git a/xen/arch/x86/hvm/svm/intr.c b/xen/arch/x86/hvm/svm/intr.c
index 46186a110261..931973a9fad4 100644
--- a/xen/arch/x86/hvm/svm/intr.c
+++ b/xen/arch/x86/hvm/svm/intr.c
@@ -26,6 +26,7 @@
#include <xen/domain_page.h>
#include "nestedhvm.h"
+#include "vmcb.h"
static void svm_inject_nmi(struct vcpu *v)
{
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index 1813692ffb03..191466755148 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -16,6 +16,7 @@
#include "nestedhvm.h"
#include "svm.h"
+#include "vmcb.h"
#define NSVM_ERROR_VVMCB 1
#define NSVM_ERROR_VMENTRY 2
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 2d7c598ffe99..14b3a427e642 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -44,6 +44,7 @@
#include "nestedhvm.h"
#include "svm.h"
+#include "vmcb.h"
void noreturn svm_asm_do_resume(void);
diff --git a/xen/arch/x86/hvm/svm/svmdebug.c b/xen/arch/x86/hvm/svm/svmdebug.c
index 9d3badcf5da0..bdb9ea3583ee 100644
--- a/xen/arch/x86/hvm/svm/svmdebug.c
+++ b/xen/arch/x86/hvm/svm/svmdebug.c
@@ -10,6 +10,8 @@
#include <asm/msr-index.h>
#include <asm/hvm/svm/svmdebug.h>
+#include "vmcb.h"
+
static void svm_dump_sel(const char *name, const struct segment_register *s)
{
printk("%s: %04x %04x %08x %016"PRIx64"\n",
diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c
index c57d314a2486..44fa76bf0228 100644
--- a/xen/arch/x86/hvm/svm/vmcb.c
+++ b/xen/arch/x86/hvm/svm/vmcb.c
@@ -22,6 +22,8 @@
#include <asm/p2m.h>
#include <asm/spec_ctrl.h>
+#include "vmcb.h"
+
struct vmcb_struct *alloc_vmcb(void)
{
struct vmcb_struct *vmcb;
diff --git a/xen/arch/x86/hvm/svm/vmcb.h b/xen/arch/x86/hvm/svm/vmcb.h
new file mode 100644
index 000000000000..68012948a9e3
--- /dev/null
+++ b/xen/arch/x86/hvm/svm/vmcb.h
@@ -0,0 +1,617 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef SVM_PRIVATE_VMCB_H
+#define SVM_PRIVATE_VMCB_H
+
+#include <xen/types.h>
+
+#include <asm/x86_emulate.h>
+
+struct vcpu;
+
+/* general 1 intercepts */
+enum GenericIntercept1bits
+{
+ GENERAL1_INTERCEPT_INTR = 1 << 0,
+ GENERAL1_INTERCEPT_NMI = 1 << 1,
+ GENERAL1_INTERCEPT_SMI = 1 << 2,
+ GENERAL1_INTERCEPT_INIT = 1 << 3,
+ GENERAL1_INTERCEPT_VINTR = 1 << 4,
+ GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5,
+ GENERAL1_INTERCEPT_IDTR_READ = 1 << 6,
+ GENERAL1_INTERCEPT_GDTR_READ = 1 << 7,
+ GENERAL1_INTERCEPT_LDTR_READ = 1 << 8,
+ GENERAL1_INTERCEPT_TR_READ = 1 << 9,
+ GENERAL1_INTERCEPT_IDTR_WRITE = 1 << 10,
+ GENERAL1_INTERCEPT_GDTR_WRITE = 1 << 11,
+ GENERAL1_INTERCEPT_LDTR_WRITE = 1 << 12,
+ GENERAL1_INTERCEPT_TR_WRITE = 1 << 13,
+ GENERAL1_INTERCEPT_RDTSC = 1 << 14,
+ GENERAL1_INTERCEPT_RDPMC = 1 << 15,
+ GENERAL1_INTERCEPT_PUSHF = 1 << 16,
+ GENERAL1_INTERCEPT_POPF = 1 << 17,
+ GENERAL1_INTERCEPT_CPUID = 1 << 18,
+ GENERAL1_INTERCEPT_RSM = 1 << 19,
+ GENERAL1_INTERCEPT_IRET = 1 << 20,
+ GENERAL1_INTERCEPT_SWINT = 1 << 21,
+ GENERAL1_INTERCEPT_INVD = 1 << 22,
+ GENERAL1_INTERCEPT_PAUSE = 1 << 23,
+ GENERAL1_INTERCEPT_HLT = 1 << 24,
+ GENERAL1_INTERCEPT_INVLPG = 1 << 25,
+ GENERAL1_INTERCEPT_INVLPGA = 1 << 26,
+ GENERAL1_INTERCEPT_IOIO_PROT = 1 << 27,
+ GENERAL1_INTERCEPT_MSR_PROT = 1 << 28,
+ GENERAL1_INTERCEPT_TASK_SWITCH = 1 << 29,
+ GENERAL1_INTERCEPT_FERR_FREEZE = 1 << 30,
+ GENERAL1_INTERCEPT_SHUTDOWN_EVT = 1u << 31
+};
+
+/* general 2 intercepts */
+enum GenericIntercept2bits
+{
+ GENERAL2_INTERCEPT_VMRUN = 1 << 0,
+ GENERAL2_INTERCEPT_VMMCALL = 1 << 1,
+ GENERAL2_INTERCEPT_VMLOAD = 1 << 2,
+ GENERAL2_INTERCEPT_VMSAVE = 1 << 3,
+ GENERAL2_INTERCEPT_STGI = 1 << 4,
+ GENERAL2_INTERCEPT_CLGI = 1 << 5,
+ GENERAL2_INTERCEPT_SKINIT = 1 << 6,
+ GENERAL2_INTERCEPT_RDTSCP = 1 << 7,
+ GENERAL2_INTERCEPT_ICEBP = 1 << 8,
+ GENERAL2_INTERCEPT_WBINVD = 1 << 9,
+ GENERAL2_INTERCEPT_MONITOR = 1 << 10,
+ GENERAL2_INTERCEPT_MWAIT = 1 << 11,
+ GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12,
+ GENERAL2_INTERCEPT_XSETBV = 1 << 13,
+ GENERAL2_INTERCEPT_RDPRU = 1 << 14,
+};
+
+
+/* control register intercepts */
+enum CRInterceptBits
+{
+ CR_INTERCEPT_CR0_READ = 1 << 0,
+ CR_INTERCEPT_CR1_READ = 1 << 1,
+ CR_INTERCEPT_CR2_READ = 1 << 2,
+ CR_INTERCEPT_CR3_READ = 1 << 3,
+ CR_INTERCEPT_CR4_READ = 1 << 4,
+ CR_INTERCEPT_CR5_READ = 1 << 5,
+ CR_INTERCEPT_CR6_READ = 1 << 6,
+ CR_INTERCEPT_CR7_READ = 1 << 7,
+ CR_INTERCEPT_CR8_READ = 1 << 8,
+ CR_INTERCEPT_CR9_READ = 1 << 9,
+ CR_INTERCEPT_CR10_READ = 1 << 10,
+ CR_INTERCEPT_CR11_READ = 1 << 11,
+ CR_INTERCEPT_CR12_READ = 1 << 12,
+ CR_INTERCEPT_CR13_READ = 1 << 13,
+ CR_INTERCEPT_CR14_READ = 1 << 14,
+ CR_INTERCEPT_CR15_READ = 1 << 15,
+ CR_INTERCEPT_CR0_WRITE = 1 << 16,
+ CR_INTERCEPT_CR1_WRITE = 1 << 17,
+ CR_INTERCEPT_CR2_WRITE = 1 << 18,
+ CR_INTERCEPT_CR3_WRITE = 1 << 19,
+ CR_INTERCEPT_CR4_WRITE = 1 << 20,
+ CR_INTERCEPT_CR5_WRITE = 1 << 21,
+ CR_INTERCEPT_CR6_WRITE = 1 << 22,
+ CR_INTERCEPT_CR7_WRITE = 1 << 23,
+ CR_INTERCEPT_CR8_WRITE = 1 << 24,
+ CR_INTERCEPT_CR9_WRITE = 1 << 25,
+ CR_INTERCEPT_CR10_WRITE = 1 << 26,
+ CR_INTERCEPT_CR11_WRITE = 1 << 27,
+ CR_INTERCEPT_CR12_WRITE = 1 << 28,
+ CR_INTERCEPT_CR13_WRITE = 1 << 29,
+ CR_INTERCEPT_CR14_WRITE = 1 << 30,
+ CR_INTERCEPT_CR15_WRITE = 1u << 31,
+};
+
+
+/* debug register intercepts */
+enum DRInterceptBits
+{
+ DR_INTERCEPT_DR0_READ = 1 << 0,
+ DR_INTERCEPT_DR1_READ = 1 << 1,
+ DR_INTERCEPT_DR2_READ = 1 << 2,
+ DR_INTERCEPT_DR3_READ = 1 << 3,
+ DR_INTERCEPT_DR4_READ = 1 << 4,
+ DR_INTERCEPT_DR5_READ = 1 << 5,
+ DR_INTERCEPT_DR6_READ = 1 << 6,
+ DR_INTERCEPT_DR7_READ = 1 << 7,
+ DR_INTERCEPT_DR8_READ = 1 << 8,
+ DR_INTERCEPT_DR9_READ = 1 << 9,
+ DR_INTERCEPT_DR10_READ = 1 << 10,
+ DR_INTERCEPT_DR11_READ = 1 << 11,
+ DR_INTERCEPT_DR12_READ = 1 << 12,
+ DR_INTERCEPT_DR13_READ = 1 << 13,
+ DR_INTERCEPT_DR14_READ = 1 << 14,
+ DR_INTERCEPT_DR15_READ = 1 << 15,
+ DR_INTERCEPT_DR0_WRITE = 1 << 16,
+ DR_INTERCEPT_DR1_WRITE = 1 << 17,
+ DR_INTERCEPT_DR2_WRITE = 1 << 18,
+ DR_INTERCEPT_DR3_WRITE = 1 << 19,
+ DR_INTERCEPT_DR4_WRITE = 1 << 20,
+ DR_INTERCEPT_DR5_WRITE = 1 << 21,
+ DR_INTERCEPT_DR6_WRITE = 1 << 22,
+ DR_INTERCEPT_DR7_WRITE = 1 << 23,
+ DR_INTERCEPT_DR8_WRITE = 1 << 24,
+ DR_INTERCEPT_DR9_WRITE = 1 << 25,
+ DR_INTERCEPT_DR10_WRITE = 1 << 26,
+ DR_INTERCEPT_DR11_WRITE = 1 << 27,
+ DR_INTERCEPT_DR12_WRITE = 1 << 28,
+ DR_INTERCEPT_DR13_WRITE = 1 << 29,
+ DR_INTERCEPT_DR14_WRITE = 1 << 30,
+ DR_INTERCEPT_DR15_WRITE = 1u << 31,
+};
+
+enum VMEXIT_EXITCODE
+{
+ /* control register read exitcodes */
+ VMEXIT_CR0_READ = 0, /* 0x0 */
+ VMEXIT_CR1_READ = 1, /* 0x1 */
+ VMEXIT_CR2_READ = 2, /* 0x2 */
+ VMEXIT_CR3_READ = 3, /* 0x3 */
+ VMEXIT_CR4_READ = 4, /* 0x4 */
+ VMEXIT_CR5_READ = 5, /* 0x5 */
+ VMEXIT_CR6_READ = 6, /* 0x6 */
+ VMEXIT_CR7_READ = 7, /* 0x7 */
+ VMEXIT_CR8_READ = 8, /* 0x8 */
+ VMEXIT_CR9_READ = 9, /* 0x9 */
+ VMEXIT_CR10_READ = 10, /* 0xa */
+ VMEXIT_CR11_READ = 11, /* 0xb */
+ VMEXIT_CR12_READ = 12, /* 0xc */
+ VMEXIT_CR13_READ = 13, /* 0xd */
+ VMEXIT_CR14_READ = 14, /* 0xe */
+ VMEXIT_CR15_READ = 15, /* 0xf */
+
+ /* control register write exitcodes */
+ VMEXIT_CR0_WRITE = 16, /* 0x10 */
+ VMEXIT_CR1_WRITE = 17, /* 0x11 */
+ VMEXIT_CR2_WRITE = 18, /* 0x12 */
+ VMEXIT_CR3_WRITE = 19, /* 0x13 */
+ VMEXIT_CR4_WRITE = 20, /* 0x14 */
+ VMEXIT_CR5_WRITE = 21, /* 0x15 */
+ VMEXIT_CR6_WRITE = 22, /* 0x16 */
+ VMEXIT_CR7_WRITE = 23, /* 0x17 */
+ VMEXIT_CR8_WRITE = 24, /* 0x18 */
+ VMEXIT_CR9_WRITE = 25, /* 0x19 */
+ VMEXIT_CR10_WRITE = 26, /* 0x1a */
+ VMEXIT_CR11_WRITE = 27, /* 0x1b */
+ VMEXIT_CR12_WRITE = 28, /* 0x1c */
+ VMEXIT_CR13_WRITE = 29, /* 0x1d */
+ VMEXIT_CR14_WRITE = 30, /* 0x1e */
+ VMEXIT_CR15_WRITE = 31, /* 0x1f */
+
+ /* debug register read exitcodes */
+ VMEXIT_DR0_READ = 32, /* 0x20 */
+ VMEXIT_DR1_READ = 33, /* 0x21 */
+ VMEXIT_DR2_READ = 34, /* 0x22 */
+ VMEXIT_DR3_READ = 35, /* 0x23 */
+ VMEXIT_DR4_READ = 36, /* 0x24 */
+ VMEXIT_DR5_READ = 37, /* 0x25 */
+ VMEXIT_DR6_READ = 38, /* 0x26 */
+ VMEXIT_DR7_READ = 39, /* 0x27 */
+ VMEXIT_DR8_READ = 40, /* 0x28 */
+ VMEXIT_DR9_READ = 41, /* 0x29 */
+ VMEXIT_DR10_READ = 42, /* 0x2a */
+ VMEXIT_DR11_READ = 43, /* 0x2b */
+ VMEXIT_DR12_READ = 44, /* 0x2c */
+ VMEXIT_DR13_READ = 45, /* 0x2d */
+ VMEXIT_DR14_READ = 46, /* 0x2e */
+ VMEXIT_DR15_READ = 47, /* 0x2f */
+
+ /* debug register write exitcodes */
+ VMEXIT_DR0_WRITE = 48, /* 0x30 */
+ VMEXIT_DR1_WRITE = 49, /* 0x31 */
+ VMEXIT_DR2_WRITE = 50, /* 0x32 */
+ VMEXIT_DR3_WRITE = 51, /* 0x33 */
+ VMEXIT_DR4_WRITE = 52, /* 0x34 */
+ VMEXIT_DR5_WRITE = 53, /* 0x35 */
+ VMEXIT_DR6_WRITE = 54, /* 0x36 */
+ VMEXIT_DR7_WRITE = 55, /* 0x37 */
+ VMEXIT_DR8_WRITE = 56, /* 0x38 */
+ VMEXIT_DR9_WRITE = 57, /* 0x39 */
+ VMEXIT_DR10_WRITE = 58, /* 0x3a */
+ VMEXIT_DR11_WRITE = 59, /* 0x3b */
+ VMEXIT_DR12_WRITE = 60, /* 0x3c */
+ VMEXIT_DR13_WRITE = 61, /* 0x3d */
+ VMEXIT_DR14_WRITE = 62, /* 0x3e */
+ VMEXIT_DR15_WRITE = 63, /* 0x3f */
+
+ /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
+ VMEXIT_EXCEPTION_DE = 64, /* 0x40, divide-by-zero-error */
+ VMEXIT_EXCEPTION_DB = 65, /* 0x41, debug */
+ VMEXIT_EXCEPTION_NMI = 66, /* 0x42, non-maskable-interrupt */
+ VMEXIT_EXCEPTION_BP = 67, /* 0x43, breakpoint */
+ VMEXIT_EXCEPTION_OF = 68, /* 0x44, overflow */
+ VMEXIT_EXCEPTION_BR = 69, /* 0x45, bound-range */
+ VMEXIT_EXCEPTION_UD = 70, /* 0x46, invalid-opcode*/
+ VMEXIT_EXCEPTION_NM = 71, /* 0x47, device-not-available */
+ VMEXIT_EXCEPTION_DF = 72, /* 0x48, double-fault */
+ VMEXIT_EXCEPTION_09 = 73, /* 0x49, unsupported (reserved) */
+ VMEXIT_EXCEPTION_TS = 74, /* 0x4a, invalid-tss */
+ VMEXIT_EXCEPTION_NP = 75, /* 0x4b, segment-not-present */
+ VMEXIT_EXCEPTION_SS = 76, /* 0x4c, stack */
+ VMEXIT_EXCEPTION_GP = 77, /* 0x4d, general-protection */
+ VMEXIT_EXCEPTION_PF = 78, /* 0x4e, page-fault */
+ VMEXIT_EXCEPTION_15 = 79, /* 0x4f, reserved */
+ VMEXIT_EXCEPTION_MF = 80, /* 0x50, x87 floating-point exception-pending */
+ VMEXIT_EXCEPTION_AC = 81, /* 0x51, alignment-check */
+ VMEXIT_EXCEPTION_MC = 82, /* 0x52, machine-check */
+ VMEXIT_EXCEPTION_XF = 83, /* 0x53, simd floating-point */
+/* VMEXIT_EXCEPTION_20 = 84, 0x54, #VE (Intel specific) */
+ VMEXIT_EXCEPTION_CP = 85, /* 0x55, controlflow protection */
+
+ /* exceptions 20-31 (exitcodes 84-95) are reserved */
+
+ /* ...and the rest of the #VMEXITs */
+ VMEXIT_INTR = 96, /* 0x60 */
+ VMEXIT_NMI = 97, /* 0x61 */
+ VMEXIT_SMI = 98, /* 0x62 */
+ VMEXIT_INIT = 99, /* 0x63 */
+ VMEXIT_VINTR = 100, /* 0x64 */
+ VMEXIT_CR0_SEL_WRITE = 101, /* 0x65 */
+ VMEXIT_IDTR_READ = 102, /* 0x66 */
+ VMEXIT_GDTR_READ = 103, /* 0x67 */
+ VMEXIT_LDTR_READ = 104, /* 0x68 */
+ VMEXIT_TR_READ = 105, /* 0x69 */
+ VMEXIT_IDTR_WRITE = 106, /* 0x6a */
+ VMEXIT_GDTR_WRITE = 107, /* 0x6b */
+ VMEXIT_LDTR_WRITE = 108, /* 0x6c */
+ VMEXIT_TR_WRITE = 109, /* 0x6d */
+ VMEXIT_RDTSC = 110, /* 0x6e */
+ VMEXIT_RDPMC = 111, /* 0x6f */
+ VMEXIT_PUSHF = 112, /* 0x70 */
+ VMEXIT_POPF = 113, /* 0x71 */
+ VMEXIT_CPUID = 114, /* 0x72 */
+ VMEXIT_RSM = 115, /* 0x73 */
+ VMEXIT_IRET = 116, /* 0x74 */
+ VMEXIT_SWINT = 117, /* 0x75 */
+ VMEXIT_INVD = 118, /* 0x76 */
+ VMEXIT_PAUSE = 119, /* 0x77 */
+ VMEXIT_HLT = 120, /* 0x78 */
+ VMEXIT_INVLPG = 121, /* 0x79 */
+ VMEXIT_INVLPGA = 122, /* 0x7a */
+ VMEXIT_IOIO = 123, /* 0x7b */
+ VMEXIT_MSR = 124, /* 0x7c */
+ VMEXIT_TASK_SWITCH = 125, /* 0x7d */
+ VMEXIT_FERR_FREEZE = 126, /* 0x7e */
+ VMEXIT_SHUTDOWN = 127, /* 0x7f */
+ VMEXIT_VMRUN = 128, /* 0x80 */
+ VMEXIT_VMMCALL = 129, /* 0x81 */
+ VMEXIT_VMLOAD = 130, /* 0x82 */
+ VMEXIT_VMSAVE = 131, /* 0x83 */
+ VMEXIT_STGI = 132, /* 0x84 */
+ VMEXIT_CLGI = 133, /* 0x85 */
+ VMEXIT_SKINIT = 134, /* 0x86 */
+ VMEXIT_RDTSCP = 135, /* 0x87 */
+ VMEXIT_ICEBP = 136, /* 0x88 */
+ VMEXIT_WBINVD = 137, /* 0x89 */
+ VMEXIT_MONITOR = 138, /* 0x8a */
+ VMEXIT_MWAIT = 139, /* 0x8b */
+ VMEXIT_MWAIT_CONDITIONAL= 140, /* 0x8c */
+ VMEXIT_XSETBV = 141, /* 0x8d */
+ VMEXIT_RDPRU = 142, /* 0x8e */
+ /* Remember to also update VMEXIT_NPF_PERFC! */
+ VMEXIT_NPF = 1024, /* 0x400, nested paging fault */
+ /* Remember to also update SVM_PERF_EXIT_REASON_SIZE! */
+ VMEXIT_INVALID = -1
+};
+
+enum
+{
+ /* Available on all SVM-capable hardware. */
+ TLB_CTRL_NO_FLUSH = 0,
+ TLB_CTRL_FLUSH_ALL = 1,
+
+ /* Available with the FlushByASID feature. */
+ TLB_CTRL_FLUSH_ASID = 3,
+ TLB_CTRL_FLUSH_ASID_NONGLOBAL = 7,
+};
+
+typedef union
+{
+ struct
+ {
+ uint8_t vector;
+ uint8_t type:3;
+ bool ev:1;
+ uint32_t resvd1:19;
+ bool v:1;
+ uint32_t ec;
+ };
+ uint64_t raw;
+} intinfo_t;
+
+typedef union {
+ struct {
+ bool intr_shadow: 1;
+ bool guest_intr_mask:1;
+ };
+ uint64_t raw;
+} intstat_t;
+
+typedef union
+{
+ u64 bytes;
+ struct
+ {
+ u64 tpr: 8;
+ u64 irq: 1;
+ u64 vgif: 1;
+ u64 rsvd0: 6;
+ u64 prio: 4;
+ u64 ign_tpr: 1;
+ u64 rsvd1: 3;
+ u64 intr_masking: 1;
+ u64 vgif_enable: 1;
+ u64 rsvd2: 6;
+ u64 vector: 8;
+ u64 rsvd3: 24;
+ } fields;
+} vintr_t;
+
+typedef union
+{
+ u64 bytes;
+ struct
+ {
+ u64 type: 1;
+ u64 rsv0: 1;
+ u64 str: 1;
+ u64 rep: 1;
+ u64 sz8: 1;
+ u64 sz16: 1;
+ u64 sz32: 1;
+ u64 rsv1: 9;
+ u64 port: 16;
+ } fields;
+} ioio_info_t;
+
+typedef union
+{
+ u64 bytes;
+ struct
+ {
+ u64 lbr_enable:1;
+ u64 vloadsave_enable:1;
+ } fields;
+} virt_ext_t;
+
+typedef union
+{
+ struct {
+ bool intercepts:1; /* 0: cr/dr/exception/general intercepts,
+ * pause_filter_count, tsc_offset */
+ bool iopm:1; /* 1: iopm_base_pa, msrpm_base_pa */
+ bool asid:1; /* 2: asid */
+ bool tpr:1; /* 3: vintr */
+ bool np:1; /* 4: np, h_cr3, g_pat */
+ bool cr:1; /* 5: cr0, cr3, cr4, efer */
+ bool dr:1; /* 6: dr6, dr7 */
+ bool dt:1; /* 7: gdtr, idtr */
+ bool seg:1; /* 8: cs, ds, es, ss, cpl */
+ bool cr2:1; /* 9: cr2 */
+ bool lbr:1; /* 10: debugctlmsr, last{branch,int}{to,from}ip */
+ bool :1;
+ bool cet:1; /* 12: msr_s_set, ssp, msr_isst */
+ };
+ uint32_t raw;
+} vmcbcleanbits_t;
+
+#define IOPM_SIZE (12 * 1024)
+#define MSRPM_SIZE (8 * 1024)
+
+struct vmcb_struct {
+ u32 _cr_intercepts; /* offset 0x00 - cleanbit 0 */
+ u32 _dr_intercepts; /* offset 0x04 - cleanbit 0 */
+ u32 _exception_intercepts; /* offset 0x08 - cleanbit 0 */
+ u32 _general1_intercepts; /* offset 0x0C - cleanbit 0 */
+ u32 _general2_intercepts; /* offset 0x10 - cleanbit 0 */
+ u32 res01[10];
+ u16 _pause_filter_thresh; /* offset 0x3C - cleanbit 0 */
+ u16 _pause_filter_count; /* offset 0x3E - cleanbit 0 */
+ u64 _iopm_base_pa; /* offset 0x40 - cleanbit 1 */
+ u64 _msrpm_base_pa; /* offset 0x48 - cleanbit 1 */
+ u64 _tsc_offset; /* offset 0x50 - cleanbit 0 */
+ u32 _asid; /* offset 0x58 - cleanbit 2 */
+ u8 tlb_control; /* offset 0x5C - TLB_CTRL_* */
+ u8 res07[3];
+ vintr_t _vintr; /* offset 0x60 - cleanbit 3 */
+ intstat_t int_stat; /* offset 0x68 */
+ u64 exitcode; /* offset 0x70 */
+ union {
+ struct {
+ uint64_t exitinfo1; /* offset 0x78 */
+ uint64_t exitinfo2; /* offset 0x80 */
+ };
+ union {
+ struct {
+ uint32_t ec; /* #NP, #SS, #GP, #PF, #AC */
+ uint32_t :32;
+
+ uint64_t cr2; /* #PF */
+ } exc;
+ struct {
+ bool in:1;
+ bool :1;
+ bool str:1;
+ bool rep:1;
+ uint16_t bytes:3;
+ uint16_t /* asz */:3;
+ uint16_t seg:3;
+ uint16_t :3;
+ uint16_t port;
+ uint32_t :32;
+
+ uint64_t nrip;
+ } io;
+ struct {
+ uint64_t gpr:4;
+ uint64_t :59;
+ bool mov_insn:1; /* MOV, as opposed to LMSW, CLTS, etc */
+ } mov_cr;
+ struct {
+ uint64_t ec;
+ uint64_t gpa;
+ } npf;
+ struct {
+ uint16_t sel;
+ uint64_t :48;
+
+ uint32_t ec;
+ uint32_t :4;
+ bool iret:1;
+ uint32_t :1;
+ bool jmp:1;
+ uint32_t :5;
+ bool ev:1;
+ uint32_t :3;
+ bool rf:1;
+ } task_switch;
+ } ei;
+ };
+ intinfo_t exit_int_info; /* offset 0x88 */
+ union { /* offset 0x90 - cleanbit 4 */
+ struct {
+ bool _np :1;
+ bool _sev :1;
+ bool _sev_es :1;
+ bool _gmet :1;
+ bool _np_sss :1;
+ bool _vte :1;
+ };
+ uint64_t _np_ctrl;
+ };
+ u64 res08[2];
+ intinfo_t event_inj; /* offset 0xA8 */
+ u64 _h_cr3; /* offset 0xB0 - cleanbit 4 */
+ virt_ext_t virt_ext; /* offset 0xB8 */
+ vmcbcleanbits_t cleanbits; /* offset 0xC0 */
+ u32 res09; /* offset 0xC4 */
+ u64 nextrip; /* offset 0xC8 */
+ u8 guest_ins_len; /* offset 0xD0 */
+ u8 guest_ins[15]; /* offset 0xD1 */
+ u64 res10a[100]; /* offset 0xE0 pad to save area */
+
+ union {
+ struct segment_register sreg[6];
+ struct {
+ struct segment_register es; /* offset 0x400 - cleanbit 8 */
+ struct segment_register cs; /* cleanbit 8 */
+ struct segment_register ss; /* cleanbit 8 */
+ struct segment_register ds; /* cleanbit 8 */
+ struct segment_register fs;
+ struct segment_register gs;
+ };
+ };
+ struct segment_register gdtr; /* cleanbit 7 */
+ struct segment_register ldtr;
+ struct segment_register idtr; /* cleanbit 7 */
+ struct segment_register tr;
+ u64 res10[5];
+ u8 res11[3];
+ u8 _cpl; /* cleanbit 8 */
+ u32 res12;
+ u64 _efer; /* offset 0x400 + 0xD0 - cleanbit 5 */
+ u64 res13[14];
+ u64 _cr4; /* offset 0x400 + 0x148 - cleanbit 5 */
+ u64 _cr3; /* cleanbit 5 */
+ u64 _cr0; /* cleanbit 5 */
+ u64 _dr7; /* cleanbit 6 */
+ u64 _dr6; /* cleanbit 6 */
+ u64 rflags;
+ u64 rip;
+ u64 res14[11];
+ u64 rsp;
+ u64 _msr_s_cet; /* offset 0x400 + 0x1E0 - cleanbit 12 */
+ u64 _ssp; /* offset 0x400 + 0x1E8 | */
+ u64 _msr_isst; /* offset 0x400 + 0x1F0 v */
+ u64 rax;
+ u64 star;
+ u64 lstar;
+ u64 cstar;
+ u64 sfmask;
+ u64 kerngsbase;
+ u64 sysenter_cs;
+ u64 sysenter_esp;
+ u64 sysenter_eip;
+ u64 _cr2; /* cleanbit 9 */
+ u64 res16[4];
+ u64 _g_pat; /* cleanbit 4 */
+ u64 _debugctlmsr; /* cleanbit 10 */
+ u64 _lastbranchfromip; /* cleanbit 10 */
+ u64 _lastbranchtoip; /* cleanbit 10 */
+ u64 _lastintfromip; /* cleanbit 10 */
+ u64 _lastinttoip; /* cleanbit 10 */
+ u64 res17[9];
+ u64 spec_ctrl;
+ u64 res18[291];
+};
+
+struct vmcb_struct *alloc_vmcb(void);
+void free_vmcb(struct vmcb_struct *vmcb);
+
+int svm_create_vmcb(struct vcpu *v);
+void svm_destroy_vmcb(struct vcpu *v);
+
+void setup_vmcb_dump(void);
+
+/*
+ * VMCB accessor functions.
+ */
+
+#define VMCB_ACCESSORS_(name, type, cleanbit) \
+static inline void \
+vmcb_set_ ## name(struct vmcb_struct *vmcb, \
+ type value) \
+{ \
+ vmcb->_ ## name = value; \
+ vmcb->cleanbits.cleanbit = false; \
+} \
+static inline type \
+vmcb_get_ ## name(const struct vmcb_struct *vmcb) \
+{ \
+ return vmcb->_ ## name; \
+}
+
+#define VMCB_ACCESSORS(name, cleanbit) \
+ VMCB_ACCESSORS_(name, typeof(((struct vmcb_struct){})._ ## name), cleanbit)
+
+VMCB_ACCESSORS(cr_intercepts, intercepts)
+VMCB_ACCESSORS(dr_intercepts, intercepts)
+VMCB_ACCESSORS(exception_intercepts, intercepts)
+VMCB_ACCESSORS(general1_intercepts, intercepts)
+VMCB_ACCESSORS(general2_intercepts, intercepts)
+VMCB_ACCESSORS(pause_filter_count, intercepts)
+VMCB_ACCESSORS(pause_filter_thresh, intercepts)
+VMCB_ACCESSORS(tsc_offset, intercepts)
+VMCB_ACCESSORS(iopm_base_pa, iopm)
+VMCB_ACCESSORS(msrpm_base_pa, iopm)
+VMCB_ACCESSORS(asid, asid)
+VMCB_ACCESSORS(vintr, tpr)
+VMCB_ACCESSORS(np_ctrl, np)
+VMCB_ACCESSORS_(np, bool, np)
+VMCB_ACCESSORS_(sev, bool, np)
+VMCB_ACCESSORS_(sev_es, bool, np)
+VMCB_ACCESSORS_(gmet, bool, np)
+VMCB_ACCESSORS_(vte, bool, np)
+VMCB_ACCESSORS(h_cr3, np)
+VMCB_ACCESSORS(g_pat, np)
+VMCB_ACCESSORS(cr0, cr)
+VMCB_ACCESSORS(cr3, cr)
+VMCB_ACCESSORS(cr4, cr)
+VMCB_ACCESSORS(efer, cr)
+VMCB_ACCESSORS(dr6, dr)
+VMCB_ACCESSORS(dr7, dr)
+VMCB_ACCESSORS(cpl, seg)
+VMCB_ACCESSORS(cr2, cr2)
+VMCB_ACCESSORS(debugctlmsr, lbr)
+VMCB_ACCESSORS(lastbranchfromip, lbr)
+VMCB_ACCESSORS(lastbranchtoip, lbr)
+VMCB_ACCESSORS(lastintfromip, lbr)
+VMCB_ACCESSORS(lastinttoip, lbr)
+VMCB_ACCESSORS(msr_s_cet, cet)
+VMCB_ACCESSORS(ssp, cet)
+VMCB_ACCESSORS(msr_isst, cet)
+
+#undef VMCB_ACCESSORS
+
+#endif /* SVM_PRIVATE_VMCB_H */
diff --git a/xen/arch/x86/include/asm/hvm/svm/vmcb.h b/xen/arch/x86/include/asm/hvm/svm/vmcb.h
index 28f715e37692..717215ff969b 100644
--- a/xen/arch/x86/include/asm/hvm/svm/vmcb.h
+++ b/xen/arch/x86/include/asm/hvm/svm/vmcb.h
@@ -10,544 +10,6 @@
#include <xen/types.h>
-/* general 1 intercepts */
-enum GenericIntercept1bits
-{
- GENERAL1_INTERCEPT_INTR = 1 << 0,
- GENERAL1_INTERCEPT_NMI = 1 << 1,
- GENERAL1_INTERCEPT_SMI = 1 << 2,
- GENERAL1_INTERCEPT_INIT = 1 << 3,
- GENERAL1_INTERCEPT_VINTR = 1 << 4,
- GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5,
- GENERAL1_INTERCEPT_IDTR_READ = 1 << 6,
- GENERAL1_INTERCEPT_GDTR_READ = 1 << 7,
- GENERAL1_INTERCEPT_LDTR_READ = 1 << 8,
- GENERAL1_INTERCEPT_TR_READ = 1 << 9,
- GENERAL1_INTERCEPT_IDTR_WRITE = 1 << 10,
- GENERAL1_INTERCEPT_GDTR_WRITE = 1 << 11,
- GENERAL1_INTERCEPT_LDTR_WRITE = 1 << 12,
- GENERAL1_INTERCEPT_TR_WRITE = 1 << 13,
- GENERAL1_INTERCEPT_RDTSC = 1 << 14,
- GENERAL1_INTERCEPT_RDPMC = 1 << 15,
- GENERAL1_INTERCEPT_PUSHF = 1 << 16,
- GENERAL1_INTERCEPT_POPF = 1 << 17,
- GENERAL1_INTERCEPT_CPUID = 1 << 18,
- GENERAL1_INTERCEPT_RSM = 1 << 19,
- GENERAL1_INTERCEPT_IRET = 1 << 20,
- GENERAL1_INTERCEPT_SWINT = 1 << 21,
- GENERAL1_INTERCEPT_INVD = 1 << 22,
- GENERAL1_INTERCEPT_PAUSE = 1 << 23,
- GENERAL1_INTERCEPT_HLT = 1 << 24,
- GENERAL1_INTERCEPT_INVLPG = 1 << 25,
- GENERAL1_INTERCEPT_INVLPGA = 1 << 26,
- GENERAL1_INTERCEPT_IOIO_PROT = 1 << 27,
- GENERAL1_INTERCEPT_MSR_PROT = 1 << 28,
- GENERAL1_INTERCEPT_TASK_SWITCH = 1 << 29,
- GENERAL1_INTERCEPT_FERR_FREEZE = 1 << 30,
- GENERAL1_INTERCEPT_SHUTDOWN_EVT = 1u << 31
-};
-
-/* general 2 intercepts */
-enum GenericIntercept2bits
-{
- GENERAL2_INTERCEPT_VMRUN = 1 << 0,
- GENERAL2_INTERCEPT_VMMCALL = 1 << 1,
- GENERAL2_INTERCEPT_VMLOAD = 1 << 2,
- GENERAL2_INTERCEPT_VMSAVE = 1 << 3,
- GENERAL2_INTERCEPT_STGI = 1 << 4,
- GENERAL2_INTERCEPT_CLGI = 1 << 5,
- GENERAL2_INTERCEPT_SKINIT = 1 << 6,
- GENERAL2_INTERCEPT_RDTSCP = 1 << 7,
- GENERAL2_INTERCEPT_ICEBP = 1 << 8,
- GENERAL2_INTERCEPT_WBINVD = 1 << 9,
- GENERAL2_INTERCEPT_MONITOR = 1 << 10,
- GENERAL2_INTERCEPT_MWAIT = 1 << 11,
- GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12,
- GENERAL2_INTERCEPT_XSETBV = 1 << 13,
- GENERAL2_INTERCEPT_RDPRU = 1 << 14,
-};
-
-
-/* control register intercepts */
-enum CRInterceptBits
-{
- CR_INTERCEPT_CR0_READ = 1 << 0,
- CR_INTERCEPT_CR1_READ = 1 << 1,
- CR_INTERCEPT_CR2_READ = 1 << 2,
- CR_INTERCEPT_CR3_READ = 1 << 3,
- CR_INTERCEPT_CR4_READ = 1 << 4,
- CR_INTERCEPT_CR5_READ = 1 << 5,
- CR_INTERCEPT_CR6_READ = 1 << 6,
- CR_INTERCEPT_CR7_READ = 1 << 7,
- CR_INTERCEPT_CR8_READ = 1 << 8,
- CR_INTERCEPT_CR9_READ = 1 << 9,
- CR_INTERCEPT_CR10_READ = 1 << 10,
- CR_INTERCEPT_CR11_READ = 1 << 11,
- CR_INTERCEPT_CR12_READ = 1 << 12,
- CR_INTERCEPT_CR13_READ = 1 << 13,
- CR_INTERCEPT_CR14_READ = 1 << 14,
- CR_INTERCEPT_CR15_READ = 1 << 15,
- CR_INTERCEPT_CR0_WRITE = 1 << 16,
- CR_INTERCEPT_CR1_WRITE = 1 << 17,
- CR_INTERCEPT_CR2_WRITE = 1 << 18,
- CR_INTERCEPT_CR3_WRITE = 1 << 19,
- CR_INTERCEPT_CR4_WRITE = 1 << 20,
- CR_INTERCEPT_CR5_WRITE = 1 << 21,
- CR_INTERCEPT_CR6_WRITE = 1 << 22,
- CR_INTERCEPT_CR7_WRITE = 1 << 23,
- CR_INTERCEPT_CR8_WRITE = 1 << 24,
- CR_INTERCEPT_CR9_WRITE = 1 << 25,
- CR_INTERCEPT_CR10_WRITE = 1 << 26,
- CR_INTERCEPT_CR11_WRITE = 1 << 27,
- CR_INTERCEPT_CR12_WRITE = 1 << 28,
- CR_INTERCEPT_CR13_WRITE = 1 << 29,
- CR_INTERCEPT_CR14_WRITE = 1 << 30,
- CR_INTERCEPT_CR15_WRITE = 1u << 31,
-};
-
-
-/* debug register intercepts */
-enum DRInterceptBits
-{
- DR_INTERCEPT_DR0_READ = 1 << 0,
- DR_INTERCEPT_DR1_READ = 1 << 1,
- DR_INTERCEPT_DR2_READ = 1 << 2,
- DR_INTERCEPT_DR3_READ = 1 << 3,
- DR_INTERCEPT_DR4_READ = 1 << 4,
- DR_INTERCEPT_DR5_READ = 1 << 5,
- DR_INTERCEPT_DR6_READ = 1 << 6,
- DR_INTERCEPT_DR7_READ = 1 << 7,
- DR_INTERCEPT_DR8_READ = 1 << 8,
- DR_INTERCEPT_DR9_READ = 1 << 9,
- DR_INTERCEPT_DR10_READ = 1 << 10,
- DR_INTERCEPT_DR11_READ = 1 << 11,
- DR_INTERCEPT_DR12_READ = 1 << 12,
- DR_INTERCEPT_DR13_READ = 1 << 13,
- DR_INTERCEPT_DR14_READ = 1 << 14,
- DR_INTERCEPT_DR15_READ = 1 << 15,
- DR_INTERCEPT_DR0_WRITE = 1 << 16,
- DR_INTERCEPT_DR1_WRITE = 1 << 17,
- DR_INTERCEPT_DR2_WRITE = 1 << 18,
- DR_INTERCEPT_DR3_WRITE = 1 << 19,
- DR_INTERCEPT_DR4_WRITE = 1 << 20,
- DR_INTERCEPT_DR5_WRITE = 1 << 21,
- DR_INTERCEPT_DR6_WRITE = 1 << 22,
- DR_INTERCEPT_DR7_WRITE = 1 << 23,
- DR_INTERCEPT_DR8_WRITE = 1 << 24,
- DR_INTERCEPT_DR9_WRITE = 1 << 25,
- DR_INTERCEPT_DR10_WRITE = 1 << 26,
- DR_INTERCEPT_DR11_WRITE = 1 << 27,
- DR_INTERCEPT_DR12_WRITE = 1 << 28,
- DR_INTERCEPT_DR13_WRITE = 1 << 29,
- DR_INTERCEPT_DR14_WRITE = 1 << 30,
- DR_INTERCEPT_DR15_WRITE = 1u << 31,
-};
-
-enum VMEXIT_EXITCODE
-{
- /* control register read exitcodes */
- VMEXIT_CR0_READ = 0, /* 0x0 */
- VMEXIT_CR1_READ = 1, /* 0x1 */
- VMEXIT_CR2_READ = 2, /* 0x2 */
- VMEXIT_CR3_READ = 3, /* 0x3 */
- VMEXIT_CR4_READ = 4, /* 0x4 */
- VMEXIT_CR5_READ = 5, /* 0x5 */
- VMEXIT_CR6_READ = 6, /* 0x6 */
- VMEXIT_CR7_READ = 7, /* 0x7 */
- VMEXIT_CR8_READ = 8, /* 0x8 */
- VMEXIT_CR9_READ = 9, /* 0x9 */
- VMEXIT_CR10_READ = 10, /* 0xa */
- VMEXIT_CR11_READ = 11, /* 0xb */
- VMEXIT_CR12_READ = 12, /* 0xc */
- VMEXIT_CR13_READ = 13, /* 0xd */
- VMEXIT_CR14_READ = 14, /* 0xe */
- VMEXIT_CR15_READ = 15, /* 0xf */
-
- /* control register write exitcodes */
- VMEXIT_CR0_WRITE = 16, /* 0x10 */
- VMEXIT_CR1_WRITE = 17, /* 0x11 */
- VMEXIT_CR2_WRITE = 18, /* 0x12 */
- VMEXIT_CR3_WRITE = 19, /* 0x13 */
- VMEXIT_CR4_WRITE = 20, /* 0x14 */
- VMEXIT_CR5_WRITE = 21, /* 0x15 */
- VMEXIT_CR6_WRITE = 22, /* 0x16 */
- VMEXIT_CR7_WRITE = 23, /* 0x17 */
- VMEXIT_CR8_WRITE = 24, /* 0x18 */
- VMEXIT_CR9_WRITE = 25, /* 0x19 */
- VMEXIT_CR10_WRITE = 26, /* 0x1a */
- VMEXIT_CR11_WRITE = 27, /* 0x1b */
- VMEXIT_CR12_WRITE = 28, /* 0x1c */
- VMEXIT_CR13_WRITE = 29, /* 0x1d */
- VMEXIT_CR14_WRITE = 30, /* 0x1e */
- VMEXIT_CR15_WRITE = 31, /* 0x1f */
-
- /* debug register read exitcodes */
- VMEXIT_DR0_READ = 32, /* 0x20 */
- VMEXIT_DR1_READ = 33, /* 0x21 */
- VMEXIT_DR2_READ = 34, /* 0x22 */
- VMEXIT_DR3_READ = 35, /* 0x23 */
- VMEXIT_DR4_READ = 36, /* 0x24 */
- VMEXIT_DR5_READ = 37, /* 0x25 */
- VMEXIT_DR6_READ = 38, /* 0x26 */
- VMEXIT_DR7_READ = 39, /* 0x27 */
- VMEXIT_DR8_READ = 40, /* 0x28 */
- VMEXIT_DR9_READ = 41, /* 0x29 */
- VMEXIT_DR10_READ = 42, /* 0x2a */
- VMEXIT_DR11_READ = 43, /* 0x2b */
- VMEXIT_DR12_READ = 44, /* 0x2c */
- VMEXIT_DR13_READ = 45, /* 0x2d */
- VMEXIT_DR14_READ = 46, /* 0x2e */
- VMEXIT_DR15_READ = 47, /* 0x2f */
-
- /* debug register write exitcodes */
- VMEXIT_DR0_WRITE = 48, /* 0x30 */
- VMEXIT_DR1_WRITE = 49, /* 0x31 */
- VMEXIT_DR2_WRITE = 50, /* 0x32 */
- VMEXIT_DR3_WRITE = 51, /* 0x33 */
- VMEXIT_DR4_WRITE = 52, /* 0x34 */
- VMEXIT_DR5_WRITE = 53, /* 0x35 */
- VMEXIT_DR6_WRITE = 54, /* 0x36 */
- VMEXIT_DR7_WRITE = 55, /* 0x37 */
- VMEXIT_DR8_WRITE = 56, /* 0x38 */
- VMEXIT_DR9_WRITE = 57, /* 0x39 */
- VMEXIT_DR10_WRITE = 58, /* 0x3a */
- VMEXIT_DR11_WRITE = 59, /* 0x3b */
- VMEXIT_DR12_WRITE = 60, /* 0x3c */
- VMEXIT_DR13_WRITE = 61, /* 0x3d */
- VMEXIT_DR14_WRITE = 62, /* 0x3e */
- VMEXIT_DR15_WRITE = 63, /* 0x3f */
-
- /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
- VMEXIT_EXCEPTION_DE = 64, /* 0x40, divide-by-zero-error */
- VMEXIT_EXCEPTION_DB = 65, /* 0x41, debug */
- VMEXIT_EXCEPTION_NMI = 66, /* 0x42, non-maskable-interrupt */
- VMEXIT_EXCEPTION_BP = 67, /* 0x43, breakpoint */
- VMEXIT_EXCEPTION_OF = 68, /* 0x44, overflow */
- VMEXIT_EXCEPTION_BR = 69, /* 0x45, bound-range */
- VMEXIT_EXCEPTION_UD = 70, /* 0x46, invalid-opcode*/
- VMEXIT_EXCEPTION_NM = 71, /* 0x47, device-not-available */
- VMEXIT_EXCEPTION_DF = 72, /* 0x48, double-fault */
- VMEXIT_EXCEPTION_09 = 73, /* 0x49, unsupported (reserved) */
- VMEXIT_EXCEPTION_TS = 74, /* 0x4a, invalid-tss */
- VMEXIT_EXCEPTION_NP = 75, /* 0x4b, segment-not-present */
- VMEXIT_EXCEPTION_SS = 76, /* 0x4c, stack */
- VMEXIT_EXCEPTION_GP = 77, /* 0x4d, general-protection */
- VMEXIT_EXCEPTION_PF = 78, /* 0x4e, page-fault */
- VMEXIT_EXCEPTION_15 = 79, /* 0x4f, reserved */
- VMEXIT_EXCEPTION_MF = 80, /* 0x50, x87 floating-point exception-pending */
- VMEXIT_EXCEPTION_AC = 81, /* 0x51, alignment-check */
- VMEXIT_EXCEPTION_MC = 82, /* 0x52, machine-check */
- VMEXIT_EXCEPTION_XF = 83, /* 0x53, simd floating-point */
-/* VMEXIT_EXCEPTION_20 = 84, 0x54, #VE (Intel specific) */
- VMEXIT_EXCEPTION_CP = 85, /* 0x55, controlflow protection */
-
- /* exceptions 20-31 (exitcodes 84-95) are reserved */
-
- /* ...and the rest of the #VMEXITs */
- VMEXIT_INTR = 96, /* 0x60 */
- VMEXIT_NMI = 97, /* 0x61 */
- VMEXIT_SMI = 98, /* 0x62 */
- VMEXIT_INIT = 99, /* 0x63 */
- VMEXIT_VINTR = 100, /* 0x64 */
- VMEXIT_CR0_SEL_WRITE = 101, /* 0x65 */
- VMEXIT_IDTR_READ = 102, /* 0x66 */
- VMEXIT_GDTR_READ = 103, /* 0x67 */
- VMEXIT_LDTR_READ = 104, /* 0x68 */
- VMEXIT_TR_READ = 105, /* 0x69 */
- VMEXIT_IDTR_WRITE = 106, /* 0x6a */
- VMEXIT_GDTR_WRITE = 107, /* 0x6b */
- VMEXIT_LDTR_WRITE = 108, /* 0x6c */
- VMEXIT_TR_WRITE = 109, /* 0x6d */
- VMEXIT_RDTSC = 110, /* 0x6e */
- VMEXIT_RDPMC = 111, /* 0x6f */
- VMEXIT_PUSHF = 112, /* 0x70 */
- VMEXIT_POPF = 113, /* 0x71 */
- VMEXIT_CPUID = 114, /* 0x72 */
- VMEXIT_RSM = 115, /* 0x73 */
- VMEXIT_IRET = 116, /* 0x74 */
- VMEXIT_SWINT = 117, /* 0x75 */
- VMEXIT_INVD = 118, /* 0x76 */
- VMEXIT_PAUSE = 119, /* 0x77 */
- VMEXIT_HLT = 120, /* 0x78 */
- VMEXIT_INVLPG = 121, /* 0x79 */
- VMEXIT_INVLPGA = 122, /* 0x7a */
- VMEXIT_IOIO = 123, /* 0x7b */
- VMEXIT_MSR = 124, /* 0x7c */
- VMEXIT_TASK_SWITCH = 125, /* 0x7d */
- VMEXIT_FERR_FREEZE = 126, /* 0x7e */
- VMEXIT_SHUTDOWN = 127, /* 0x7f */
- VMEXIT_VMRUN = 128, /* 0x80 */
- VMEXIT_VMMCALL = 129, /* 0x81 */
- VMEXIT_VMLOAD = 130, /* 0x82 */
- VMEXIT_VMSAVE = 131, /* 0x83 */
- VMEXIT_STGI = 132, /* 0x84 */
- VMEXIT_CLGI = 133, /* 0x85 */
- VMEXIT_SKINIT = 134, /* 0x86 */
- VMEXIT_RDTSCP = 135, /* 0x87 */
- VMEXIT_ICEBP = 136, /* 0x88 */
- VMEXIT_WBINVD = 137, /* 0x89 */
- VMEXIT_MONITOR = 138, /* 0x8a */
- VMEXIT_MWAIT = 139, /* 0x8b */
- VMEXIT_MWAIT_CONDITIONAL= 140, /* 0x8c */
- VMEXIT_XSETBV = 141, /* 0x8d */
- VMEXIT_RDPRU = 142, /* 0x8e */
- /* Remember to also update VMEXIT_NPF_PERFC! */
- VMEXIT_NPF = 1024, /* 0x400, nested paging fault */
- /* Remember to also update SVM_PERF_EXIT_REASON_SIZE! */
- VMEXIT_INVALID = -1
-};
-
-enum
-{
- /* Available on all SVM-capable hardware. */
- TLB_CTRL_NO_FLUSH = 0,
- TLB_CTRL_FLUSH_ALL = 1,
-
- /* Available with the FlushByASID feature. */
- TLB_CTRL_FLUSH_ASID = 3,
- TLB_CTRL_FLUSH_ASID_NONGLOBAL = 7,
-};
-
-typedef union
-{
- struct
- {
- uint8_t vector;
- uint8_t type:3;
- bool ev:1;
- uint32_t resvd1:19;
- bool v:1;
- uint32_t ec;
- };
- uint64_t raw;
-} intinfo_t;
-
-typedef union {
- struct {
- bool intr_shadow: 1;
- bool guest_intr_mask:1;
- };
- uint64_t raw;
-} intstat_t;
-
-typedef union
-{
- u64 bytes;
- struct
- {
- u64 tpr: 8;
- u64 irq: 1;
- u64 vgif: 1;
- u64 rsvd0: 6;
- u64 prio: 4;
- u64 ign_tpr: 1;
- u64 rsvd1: 3;
- u64 intr_masking: 1;
- u64 vgif_enable: 1;
- u64 rsvd2: 6;
- u64 vector: 8;
- u64 rsvd3: 24;
- } fields;
-} vintr_t;
-
-typedef union
-{
- u64 bytes;
- struct
- {
- u64 type: 1;
- u64 rsv0: 1;
- u64 str: 1;
- u64 rep: 1;
- u64 sz8: 1;
- u64 sz16: 1;
- u64 sz32: 1;
- u64 rsv1: 9;
- u64 port: 16;
- } fields;
-} ioio_info_t;
-
-typedef union
-{
- u64 bytes;
- struct
- {
- u64 lbr_enable:1;
- u64 vloadsave_enable:1;
- } fields;
-} virt_ext_t;
-
-typedef union
-{
- struct {
- bool intercepts:1; /* 0: cr/dr/exception/general intercepts,
- * pause_filter_count, tsc_offset */
- bool iopm:1; /* 1: iopm_base_pa, msrpm_base_pa */
- bool asid:1; /* 2: asid */
- bool tpr:1; /* 3: vintr */
- bool np:1; /* 4: np, h_cr3, g_pat */
- bool cr:1; /* 5: cr0, cr3, cr4, efer */
- bool dr:1; /* 6: dr6, dr7 */
- bool dt:1; /* 7: gdtr, idtr */
- bool seg:1; /* 8: cs, ds, es, ss, cpl */
- bool cr2:1; /* 9: cr2 */
- bool lbr:1; /* 10: debugctlmsr, last{branch,int}{to,from}ip */
- bool :1;
- bool cet:1; /* 12: msr_s_set, ssp, msr_isst */
- };
- uint32_t raw;
-} vmcbcleanbits_t;
-
-#define IOPM_SIZE (12 * 1024)
-#define MSRPM_SIZE (8 * 1024)
-
-struct vmcb_struct {
- u32 _cr_intercepts; /* offset 0x00 - cleanbit 0 */
- u32 _dr_intercepts; /* offset 0x04 - cleanbit 0 */
- u32 _exception_intercepts; /* offset 0x08 - cleanbit 0 */
- u32 _general1_intercepts; /* offset 0x0C - cleanbit 0 */
- u32 _general2_intercepts; /* offset 0x10 - cleanbit 0 */
- u32 res01[10];
- u16 _pause_filter_thresh; /* offset 0x3C - cleanbit 0 */
- u16 _pause_filter_count; /* offset 0x3E - cleanbit 0 */
- u64 _iopm_base_pa; /* offset 0x40 - cleanbit 1 */
- u64 _msrpm_base_pa; /* offset 0x48 - cleanbit 1 */
- u64 _tsc_offset; /* offset 0x50 - cleanbit 0 */
- u32 _asid; /* offset 0x58 - cleanbit 2 */
- u8 tlb_control; /* offset 0x5C - TLB_CTRL_* */
- u8 res07[3];
- vintr_t _vintr; /* offset 0x60 - cleanbit 3 */
- intstat_t int_stat; /* offset 0x68 */
- u64 exitcode; /* offset 0x70 */
- union {
- struct {
- uint64_t exitinfo1; /* offset 0x78 */
- uint64_t exitinfo2; /* offset 0x80 */
- };
- union {
- struct {
- uint32_t ec; /* #NP, #SS, #GP, #PF, #AC */
- uint32_t :32;
-
- uint64_t cr2; /* #PF */
- } exc;
- struct {
- bool in:1;
- bool :1;
- bool str:1;
- bool rep:1;
- uint16_t bytes:3;
- uint16_t /* asz */:3;
- uint16_t seg:3;
- uint16_t :3;
- uint16_t port;
- uint32_t :32;
-
- uint64_t nrip;
- } io;
- struct {
- uint64_t gpr:4;
- uint64_t :59;
- bool mov_insn:1; /* MOV, as opposed to LMSW, CLTS, etc */
- } mov_cr;
- struct {
- uint64_t ec;
- uint64_t gpa;
- } npf;
- struct {
- uint16_t sel;
- uint64_t :48;
-
- uint32_t ec;
- uint32_t :4;
- bool iret:1;
- uint32_t :1;
- bool jmp:1;
- uint32_t :5;
- bool ev:1;
- uint32_t :3;
- bool rf:1;
- } task_switch;
- } ei;
- };
- intinfo_t exit_int_info; /* offset 0x88 */
- union { /* offset 0x90 - cleanbit 4 */
- struct {
- bool _np :1;
- bool _sev :1;
- bool _sev_es :1;
- bool _gmet :1;
- bool _np_sss :1;
- bool _vte :1;
- };
- uint64_t _np_ctrl;
- };
- u64 res08[2];
- intinfo_t event_inj; /* offset 0xA8 */
- u64 _h_cr3; /* offset 0xB0 - cleanbit 4 */
- virt_ext_t virt_ext; /* offset 0xB8 */
- vmcbcleanbits_t cleanbits; /* offset 0xC0 */
- u32 res09; /* offset 0xC4 */
- u64 nextrip; /* offset 0xC8 */
- u8 guest_ins_len; /* offset 0xD0 */
- u8 guest_ins[15]; /* offset 0xD1 */
- u64 res10a[100]; /* offset 0xE0 pad to save area */
-
- union {
- struct segment_register sreg[6];
- struct {
- struct segment_register es; /* offset 0x400 - cleanbit 8 */
- struct segment_register cs; /* cleanbit 8 */
- struct segment_register ss; /* cleanbit 8 */
- struct segment_register ds; /* cleanbit 8 */
- struct segment_register fs;
- struct segment_register gs;
- };
- };
- struct segment_register gdtr; /* cleanbit 7 */
- struct segment_register ldtr;
- struct segment_register idtr; /* cleanbit 7 */
- struct segment_register tr;
- u64 res10[5];
- u8 res11[3];
- u8 _cpl; /* cleanbit 8 */
- u32 res12;
- u64 _efer; /* offset 0x400 + 0xD0 - cleanbit 5 */
- u64 res13[14];
- u64 _cr4; /* offset 0x400 + 0x148 - cleanbit 5 */
- u64 _cr3; /* cleanbit 5 */
- u64 _cr0; /* cleanbit 5 */
- u64 _dr7; /* cleanbit 6 */
- u64 _dr6; /* cleanbit 6 */
- u64 rflags;
- u64 rip;
- u64 res14[11];
- u64 rsp;
- u64 _msr_s_cet; /* offset 0x400 + 0x1E0 - cleanbit 12 */
- u64 _ssp; /* offset 0x400 + 0x1E8 | */
- u64 _msr_isst; /* offset 0x400 + 0x1F0 v */
- u64 rax;
- u64 star;
- u64 lstar;
- u64 cstar;
- u64 sfmask;
- u64 kerngsbase;
- u64 sysenter_cs;
- u64 sysenter_esp;
- u64 sysenter_eip;
- u64 _cr2; /* cleanbit 9 */
- u64 res16[4];
- u64 _g_pat; /* cleanbit 4 */
- u64 _debugctlmsr; /* cleanbit 10 */
- u64 _lastbranchfromip; /* cleanbit 10 */
- u64 _lastbranchtoip; /* cleanbit 10 */
- u64 _lastintfromip; /* cleanbit 10 */
- u64 _lastinttoip; /* cleanbit 10 */
- u64 res17[9];
- u64 spec_ctrl;
- u64 res18[291];
-};
-
struct svm_domain {
/* OSVW MSRs */
union {
@@ -595,14 +57,6 @@ struct svm_vcpu {
uint64_t guest_sysenter_eip;
};
-struct vmcb_struct *alloc_vmcb(void);
-void free_vmcb(struct vmcb_struct *vmcb);
-
-int svm_create_vmcb(struct vcpu *v);
-void svm_destroy_vmcb(struct vcpu *v);
-
-void setup_vmcb_dump(void);
-
#define MSR_INTERCEPT_NONE 0
#define MSR_INTERCEPT_READ 1
#define MSR_INTERCEPT_WRITE 2
@@ -611,66 +65,6 @@ void svm_intercept_msr(struct vcpu *v, uint32_t msr, int flags);
#define svm_disable_intercept_for_msr(v, msr) svm_intercept_msr((v), (msr), MSR_INTERCEPT_NONE)
#define svm_enable_intercept_for_msr(v, msr) svm_intercept_msr((v), (msr), MSR_INTERCEPT_RW)
-/*
- * VMCB accessor functions.
- */
-
-#define VMCB_ACCESSORS_(name, type, cleanbit) \
-static inline void \
-vmcb_set_ ## name(struct vmcb_struct *vmcb, \
- type value) \
-{ \
- vmcb->_ ## name = value; \
- vmcb->cleanbits.cleanbit = false; \
-} \
-static inline type \
-vmcb_get_ ## name(const struct vmcb_struct *vmcb) \
-{ \
- return vmcb->_ ## name; \
-}
-
-#define VMCB_ACCESSORS(name, cleanbit) \
- VMCB_ACCESSORS_(name, typeof(((struct vmcb_struct){})._ ## name), cleanbit)
-
-VMCB_ACCESSORS(cr_intercepts, intercepts)
-VMCB_ACCESSORS(dr_intercepts, intercepts)
-VMCB_ACCESSORS(exception_intercepts, intercepts)
-VMCB_ACCESSORS(general1_intercepts, intercepts)
-VMCB_ACCESSORS(general2_intercepts, intercepts)
-VMCB_ACCESSORS(pause_filter_count, intercepts)
-VMCB_ACCESSORS(pause_filter_thresh, intercepts)
-VMCB_ACCESSORS(tsc_offset, intercepts)
-VMCB_ACCESSORS(iopm_base_pa, iopm)
-VMCB_ACCESSORS(msrpm_base_pa, iopm)
-VMCB_ACCESSORS(asid, asid)
-VMCB_ACCESSORS(vintr, tpr)
-VMCB_ACCESSORS(np_ctrl, np)
-VMCB_ACCESSORS_(np, bool, np)
-VMCB_ACCESSORS_(sev, bool, np)
-VMCB_ACCESSORS_(sev_es, bool, np)
-VMCB_ACCESSORS_(gmet, bool, np)
-VMCB_ACCESSORS_(vte, bool, np)
-VMCB_ACCESSORS(h_cr3, np)
-VMCB_ACCESSORS(g_pat, np)
-VMCB_ACCESSORS(cr0, cr)
-VMCB_ACCESSORS(cr3, cr)
-VMCB_ACCESSORS(cr4, cr)
-VMCB_ACCESSORS(efer, cr)
-VMCB_ACCESSORS(dr6, dr)
-VMCB_ACCESSORS(dr7, dr)
-VMCB_ACCESSORS(cpl, seg)
-VMCB_ACCESSORS(cr2, cr2)
-VMCB_ACCESSORS(debugctlmsr, lbr)
-VMCB_ACCESSORS(lastbranchfromip, lbr)
-VMCB_ACCESSORS(lastbranchtoip, lbr)
-VMCB_ACCESSORS(lastintfromip, lbr)
-VMCB_ACCESSORS(lastinttoip, lbr)
-VMCB_ACCESSORS(msr_s_cet, cet)
-VMCB_ACCESSORS(ssp, cet)
-VMCB_ACCESSORS(msr_isst, cet)
-
-#undef VMCB_ACCESSORS
-
#endif /* ASM_X86_HVM_SVM_VMCS_H__ */
/*
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/3] x86/svm: Drop svmdebug.c
2025-11-28 20:19 [PATCH 0/3] x86/svm: Make various details private Andrew Cooper
2025-11-28 20:19 ` [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/ Andrew Cooper
@ 2025-11-28 20:19 ` Andrew Cooper
2025-12-01 15:33 ` Alejandro Vallejo
2025-12-08 9:06 ` Jan Beulich
2025-11-28 20:19 ` [PATCH 3/3] x86/svm: Drop svmdebug.h Andrew Cooper
2 siblings, 2 replies; 12+ messages in thread
From: Andrew Cooper @ 2025-11-28 20:19 UTC (permalink / raw)
To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monné
Everything here is really VMCB functionality, so merge it into vmcb.c. Move
the declarations from the global svmdebug.h to the logical vmcb.h.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
---
xen/arch/x86/hvm/svm/Makefile | 1 -
xen/arch/x86/hvm/svm/nestedsvm.c | 1 -
xen/arch/x86/hvm/svm/svmdebug.c | 181 --------------------
xen/arch/x86/hvm/svm/vmcb.c | 159 +++++++++++++++++
xen/arch/x86/hvm/svm/vmcb.h | 3 +
xen/arch/x86/include/asm/hvm/svm/svmdebug.h | 3 -
6 files changed, 162 insertions(+), 186 deletions(-)
delete mode 100644 xen/arch/x86/hvm/svm/svmdebug.c
diff --git a/xen/arch/x86/hvm/svm/Makefile b/xen/arch/x86/hvm/svm/Makefile
index 760d2954da83..8a072cafd572 100644
--- a/xen/arch/x86/hvm/svm/Makefile
+++ b/xen/arch/x86/hvm/svm/Makefile
@@ -4,5 +4,4 @@ obj-bin-y += entry.o
obj-y += intr.o
obj-y += nestedsvm.o
obj-y += svm.o
-obj-y += svmdebug.o
obj-y += vmcb.o
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index 191466755148..63ed6c86b775 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -9,7 +9,6 @@
#include <asm/hvm/svm/svm.h>
#include <asm/hvm/svm/vmcb.h>
#include <asm/hvm/nestedhvm.h>
-#include <asm/hvm/svm/svmdebug.h>
#include <asm/paging.h> /* paging_mode_hap */
#include <asm/event.h> /* for local_event_delivery_(en|dis)able */
#include <asm/p2m.h> /* p2m_get_pagetable, p2m_get_nestedp2m */
diff --git a/xen/arch/x86/hvm/svm/svmdebug.c b/xen/arch/x86/hvm/svm/svmdebug.c
deleted file mode 100644
index bdb9ea3583ee..000000000000
--- a/xen/arch/x86/hvm/svm/svmdebug.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * svmdebug.c: debug functions
- * Copyright (c) 2011, Advanced Micro Devices, Inc.
- *
- */
-
-#include <xen/sched.h>
-#include <asm/processor.h>
-#include <asm/msr-index.h>
-#include <asm/hvm/svm/svmdebug.h>
-
-#include "vmcb.h"
-
-static void svm_dump_sel(const char *name, const struct segment_register *s)
-{
- printk("%s: %04x %04x %08x %016"PRIx64"\n",
- name, s->sel, s->attr, s->limit, s->base);
-}
-
-void svm_vmcb_dump(const char *from, const struct vmcb_struct *vmcb)
-{
- struct vcpu *curr = current;
-
- /*
- * If we are dumping the VMCB currently in context, some guest state may
- * still be cached in hardware. Retrieve it.
- */
- if ( vmcb == curr->arch.hvm.svm.vmcb )
- svm_sync_vmcb(curr, vmcb_in_sync);
-
- printk("Dumping guest's current state at %s...\n", from);
- printk("Size of VMCB = %zu, paddr = %"PRIpaddr", vaddr = %p\n",
- sizeof(struct vmcb_struct), virt_to_maddr(vmcb), vmcb);
-
- printk("cr_intercepts = %#x dr_intercepts = %#x "
- "exception_intercepts = %#x\n",
- vmcb_get_cr_intercepts(vmcb), vmcb_get_dr_intercepts(vmcb),
- vmcb_get_exception_intercepts(vmcb));
- printk("general1_intercepts = %#x general2_intercepts = %#x\n",
- vmcb_get_general1_intercepts(vmcb), vmcb_get_general2_intercepts(vmcb));
- printk("iopm_base_pa = %#"PRIx64" msrpm_base_pa = %#"PRIx64" tsc_offset = %#"PRIx64"\n",
- vmcb_get_iopm_base_pa(vmcb), vmcb_get_msrpm_base_pa(vmcb),
- vmcb_get_tsc_offset(vmcb));
- printk("tlb_control = %#x vintr = %#"PRIx64" int_stat = %#"PRIx64"\n",
- vmcb->tlb_control, vmcb_get_vintr(vmcb).bytes,
- vmcb->int_stat.raw);
- printk("event_inj %016"PRIx64", valid? %d, ec? %d, type %u, vector %#x\n",
- vmcb->event_inj.raw, vmcb->event_inj.v,
- vmcb->event_inj.ev, vmcb->event_inj.type,
- vmcb->event_inj.vector);
- printk("exitcode = %#"PRIx64" exit_int_info = %#"PRIx64"\n",
- vmcb->exitcode, vmcb->exit_int_info.raw);
- printk("exitinfo1 = %#"PRIx64" exitinfo2 = %#"PRIx64"\n",
- vmcb->exitinfo1, vmcb->exitinfo2);
- printk("asid = %#x np_ctrl = %#"PRIx64":%s%s%s\n",
- vmcb_get_asid(vmcb), vmcb_get_np_ctrl(vmcb),
- vmcb_get_np(vmcb) ? " NP" : "",
- vmcb_get_sev(vmcb) ? " SEV" : "",
- vmcb_get_sev_es(vmcb) ? " SEV_ES" : "");
- printk("virtual vmload/vmsave = %d, virt_ext = %#"PRIx64"\n",
- vmcb->virt_ext.fields.vloadsave_enable, vmcb->virt_ext.bytes);
- printk("cpl = %d efer = %#"PRIx64" star = %#"PRIx64" lstar = %#"PRIx64"\n",
- vmcb_get_cpl(vmcb), vmcb_get_efer(vmcb), vmcb->star, vmcb->lstar);
- printk("CR0 = 0x%016"PRIx64" CR2 = 0x%016"PRIx64"\n",
- vmcb_get_cr0(vmcb), vmcb_get_cr2(vmcb));
- printk("CR3 = 0x%016"PRIx64" CR4 = 0x%016"PRIx64"\n",
- vmcb_get_cr3(vmcb), vmcb_get_cr4(vmcb));
- printk("RSP = 0x%016"PRIx64" RIP = 0x%016"PRIx64"\n",
- vmcb->rsp, vmcb->rip);
- printk("RAX = 0x%016"PRIx64" RFLAGS=0x%016"PRIx64"\n",
- vmcb->rax, vmcb->rflags);
- printk("DR6 = 0x%016"PRIx64", DR7 = 0x%016"PRIx64"\n",
- vmcb_get_dr6(vmcb), vmcb_get_dr7(vmcb));
- printk("CSTAR = 0x%016"PRIx64" SFMask = 0x%016"PRIx64"\n",
- vmcb->cstar, vmcb->sfmask);
- printk("KernGSBase = 0x%016"PRIx64" PAT = 0x%016"PRIx64"\n",
- vmcb->kerngsbase, vmcb_get_g_pat(vmcb));
- printk("SSP = 0x%016"PRIx64" S_CET = 0x%016"PRIx64" ISST = 0x%016"PRIx64"\n",
- vmcb->_ssp, vmcb->_msr_s_cet, vmcb->_msr_isst);
- printk("H_CR3 = 0x%016"PRIx64" CleanBits = %#x\n",
- vmcb_get_h_cr3(vmcb), vmcb->cleanbits.raw);
-
- /* print out all the selectors */
- printk(" sel attr limit base\n");
- svm_dump_sel(" CS", &vmcb->cs);
- svm_dump_sel(" DS", &vmcb->ds);
- svm_dump_sel(" SS", &vmcb->ss);
- svm_dump_sel(" ES", &vmcb->es);
- svm_dump_sel(" FS", &vmcb->fs);
- svm_dump_sel(" GS", &vmcb->gs);
- svm_dump_sel("GDTR", &vmcb->gdtr);
- svm_dump_sel("LDTR", &vmcb->ldtr);
- svm_dump_sel("IDTR", &vmcb->idtr);
- svm_dump_sel(" TR", &vmcb->tr);
-}
-
-bool svm_vmcb_isvalid(const char *from, const struct vmcb_struct *vmcb,
- const struct vcpu *v, bool verbose)
-{
- bool ret = false; /* ok */
- unsigned long cr0 = vmcb_get_cr0(vmcb);
- unsigned long cr3 = vmcb_get_cr3(vmcb);
- unsigned long cr4 = vmcb_get_cr4(vmcb);
- unsigned long valid;
- uint64_t efer = vmcb_get_efer(vmcb);
-
-#define PRINTF(fmt, args...) do { \
- if ( !verbose ) return true; \
- ret = true; \
- printk(XENLOG_GUEST "%pv[%s]: " fmt, v, from, ## args); \
-} while (0)
-
- if ( !(efer & EFER_SVME) )
- PRINTF("EFER: SVME bit not set (%#"PRIx64")\n", efer);
-
- if ( !(cr0 & X86_CR0_CD) && (cr0 & X86_CR0_NW) )
- PRINTF("CR0: CD bit is zero and NW bit set (%#"PRIx64")\n", cr0);
-
- if ( cr0 >> 32 )
- PRINTF("CR0: bits [63:32] are not zero (%#"PRIx64")\n", cr0);
-
- if ( (cr0 & X86_CR0_PG) &&
- ((cr3 & 7) ||
- ((!(cr4 & X86_CR4_PAE) || (efer & EFER_LMA)) && (cr3 & 0xfe0)) ||
- ((efer & EFER_LMA) &&
- (cr3 >> v->domain->arch.cpuid->extd.maxphysaddr))) )
- PRINTF("CR3: MBZ bits are set (%#"PRIx64")\n", cr3);
-
- valid = hvm_cr4_guest_valid_bits(v->domain);
- if ( cr4 & ~valid )
- PRINTF("CR4: invalid value %#lx (valid %#lx, rejected %#lx)\n",
- cr4, valid, cr4 & ~valid);
-
- if ( vmcb_get_dr6(vmcb) >> 32 )
- PRINTF("DR6: bits [63:32] are not zero (%#"PRIx64")\n",
- vmcb_get_dr6(vmcb));
-
- if ( vmcb_get_dr7(vmcb) >> 32 )
- PRINTF("DR7: bits [63:32] are not zero (%#"PRIx64")\n",
- vmcb_get_dr7(vmcb));
-
- if ( efer & ~EFER_KNOWN_MASK )
- PRINTF("EFER: unknown bits are not zero (%#"PRIx64")\n", efer);
-
- if ( hvm_efer_valid(v, efer, -1) )
- PRINTF("EFER: %s (%"PRIx64")\n", hvm_efer_valid(v, efer, -1), efer);
-
- if ( (efer & EFER_LME) && (cr0 & X86_CR0_PG) )
- {
- if ( !(cr4 & X86_CR4_PAE) )
- PRINTF("EFER_LME and CR0.PG are both set and CR4.PAE is zero\n");
- if ( !(cr0 & X86_CR0_PE) )
- PRINTF("EFER_LME and CR0.PG are both set and CR0.PE is zero\n");
- }
-
- if ( (efer & EFER_LME) && (cr0 & X86_CR0_PG) && (cr4 & X86_CR4_PAE) &&
- vmcb->cs.l && vmcb->cs.db )
- PRINTF("EFER_LME, CR0.PG, CR4.PAE, CS.L and CS.D are all non-zero\n");
-
- if ( !(vmcb_get_general2_intercepts(vmcb) & GENERAL2_INTERCEPT_VMRUN) )
- PRINTF("GENERAL2_INTERCEPT: VMRUN intercept bit is clear (%#"PRIx32")\n",
- vmcb_get_general2_intercepts(vmcb));
-
- if ( vmcb->event_inj.resvd1 )
- PRINTF("eventinj: MBZ bits are set (%#"PRIx64")\n",
- vmcb->event_inj.raw);
-
-#undef PRINTF
- return ret;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c
index 44fa76bf0228..b1a79d515143 100644
--- a/xen/arch/x86/hvm/svm/vmcb.c
+++ b/xen/arch/x86/hvm/svm/vmcb.c
@@ -228,6 +228,165 @@ void svm_destroy_vmcb(struct vcpu *v)
svm->vmcb = NULL;
}
+static void svm_dump_sel(const char *name, const struct segment_register *s)
+{
+ printk("%s: %04x %04x %08x %016"PRIx64"\n",
+ name, s->sel, s->attr, s->limit, s->base);
+}
+
+void svm_vmcb_dump(const char *from, const struct vmcb_struct *vmcb)
+{
+ struct vcpu *curr = current;
+
+ /*
+ * If we are dumping the VMCB currently in context, some guest state may
+ * still be cached in hardware. Retrieve it.
+ */
+ if ( vmcb == curr->arch.hvm.svm.vmcb )
+ svm_sync_vmcb(curr, vmcb_in_sync);
+
+ printk("Dumping guest's current state at %s...\n", from);
+ printk("Size of VMCB = %zu, paddr = %"PRIpaddr", vaddr = %p\n",
+ sizeof(struct vmcb_struct), virt_to_maddr(vmcb), vmcb);
+
+ printk("cr_intercepts = %#x dr_intercepts = %#x "
+ "exception_intercepts = %#x\n",
+ vmcb_get_cr_intercepts(vmcb), vmcb_get_dr_intercepts(vmcb),
+ vmcb_get_exception_intercepts(vmcb));
+ printk("general1_intercepts = %#x general2_intercepts = %#x\n",
+ vmcb_get_general1_intercepts(vmcb), vmcb_get_general2_intercepts(vmcb));
+ printk("iopm_base_pa = %#"PRIx64" msrpm_base_pa = %#"PRIx64" tsc_offset = %#"PRIx64"\n",
+ vmcb_get_iopm_base_pa(vmcb), vmcb_get_msrpm_base_pa(vmcb),
+ vmcb_get_tsc_offset(vmcb));
+ printk("tlb_control = %#x vintr = %#"PRIx64" int_stat = %#"PRIx64"\n",
+ vmcb->tlb_control, vmcb_get_vintr(vmcb).bytes,
+ vmcb->int_stat.raw);
+ printk("event_inj %016"PRIx64", valid? %d, ec? %d, type %u, vector %#x\n",
+ vmcb->event_inj.raw, vmcb->event_inj.v,
+ vmcb->event_inj.ev, vmcb->event_inj.type,
+ vmcb->event_inj.vector);
+ printk("exitcode = %#"PRIx64" exit_int_info = %#"PRIx64"\n",
+ vmcb->exitcode, vmcb->exit_int_info.raw);
+ printk("exitinfo1 = %#"PRIx64" exitinfo2 = %#"PRIx64"\n",
+ vmcb->exitinfo1, vmcb->exitinfo2);
+ printk("asid = %#x np_ctrl = %#"PRIx64":%s%s%s\n",
+ vmcb_get_asid(vmcb), vmcb_get_np_ctrl(vmcb),
+ vmcb_get_np(vmcb) ? " NP" : "",
+ vmcb_get_sev(vmcb) ? " SEV" : "",
+ vmcb_get_sev_es(vmcb) ? " SEV_ES" : "");
+ printk("virtual vmload/vmsave = %d, virt_ext = %#"PRIx64"\n",
+ vmcb->virt_ext.fields.vloadsave_enable, vmcb->virt_ext.bytes);
+ printk("cpl = %d efer = %#"PRIx64" star = %#"PRIx64" lstar = %#"PRIx64"\n",
+ vmcb_get_cpl(vmcb), vmcb_get_efer(vmcb), vmcb->star, vmcb->lstar);
+ printk("CR0 = 0x%016"PRIx64" CR2 = 0x%016"PRIx64"\n",
+ vmcb_get_cr0(vmcb), vmcb_get_cr2(vmcb));
+ printk("CR3 = 0x%016"PRIx64" CR4 = 0x%016"PRIx64"\n",
+ vmcb_get_cr3(vmcb), vmcb_get_cr4(vmcb));
+ printk("RSP = 0x%016"PRIx64" RIP = 0x%016"PRIx64"\n",
+ vmcb->rsp, vmcb->rip);
+ printk("RAX = 0x%016"PRIx64" RFLAGS=0x%016"PRIx64"\n",
+ vmcb->rax, vmcb->rflags);
+ printk("DR6 = 0x%016"PRIx64", DR7 = 0x%016"PRIx64"\n",
+ vmcb_get_dr6(vmcb), vmcb_get_dr7(vmcb));
+ printk("CSTAR = 0x%016"PRIx64" SFMask = 0x%016"PRIx64"\n",
+ vmcb->cstar, vmcb->sfmask);
+ printk("KernGSBase = 0x%016"PRIx64" PAT = 0x%016"PRIx64"\n",
+ vmcb->kerngsbase, vmcb_get_g_pat(vmcb));
+ printk("SSP = 0x%016"PRIx64" S_CET = 0x%016"PRIx64" ISST = 0x%016"PRIx64"\n",
+ vmcb->_ssp, vmcb->_msr_s_cet, vmcb->_msr_isst);
+ printk("H_CR3 = 0x%016"PRIx64" CleanBits = %#x\n",
+ vmcb_get_h_cr3(vmcb), vmcb->cleanbits.raw);
+
+ /* print out all the selectors */
+ printk(" sel attr limit base\n");
+ svm_dump_sel(" CS", &vmcb->cs);
+ svm_dump_sel(" DS", &vmcb->ds);
+ svm_dump_sel(" SS", &vmcb->ss);
+ svm_dump_sel(" ES", &vmcb->es);
+ svm_dump_sel(" FS", &vmcb->fs);
+ svm_dump_sel(" GS", &vmcb->gs);
+ svm_dump_sel("GDTR", &vmcb->gdtr);
+ svm_dump_sel("LDTR", &vmcb->ldtr);
+ svm_dump_sel("IDTR", &vmcb->idtr);
+ svm_dump_sel(" TR", &vmcb->tr);
+}
+
+bool svm_vmcb_isvalid(
+ const char *from, const struct vmcb_struct *vmcb, const struct vcpu *v,
+ bool verbose)
+{
+ bool ret = false; /* ok */
+ unsigned long cr0 = vmcb_get_cr0(vmcb);
+ unsigned long cr3 = vmcb_get_cr3(vmcb);
+ unsigned long cr4 = vmcb_get_cr4(vmcb);
+ unsigned long valid;
+ uint64_t efer = vmcb_get_efer(vmcb);
+
+#define PRINTF(fmt, args...) do { \
+ if ( !verbose ) return true; \
+ ret = true; \
+ printk(XENLOG_GUEST "%pv[%s]: " fmt, v, from, ## args); \
+} while (0)
+
+ if ( !(efer & EFER_SVME) )
+ PRINTF("EFER: SVME bit not set (%#"PRIx64")\n", efer);
+
+ if ( !(cr0 & X86_CR0_CD) && (cr0 & X86_CR0_NW) )
+ PRINTF("CR0: CD bit is zero and NW bit set (%#"PRIx64")\n", cr0);
+
+ if ( cr0 >> 32 )
+ PRINTF("CR0: bits [63:32] are not zero (%#"PRIx64")\n", cr0);
+
+ if ( (cr0 & X86_CR0_PG) &&
+ ((cr3 & 7) ||
+ ((!(cr4 & X86_CR4_PAE) || (efer & EFER_LMA)) && (cr3 & 0xfe0)) ||
+ ((efer & EFER_LMA) &&
+ (cr3 >> v->domain->arch.cpuid->extd.maxphysaddr))) )
+ PRINTF("CR3: MBZ bits are set (%#"PRIx64")\n", cr3);
+
+ valid = hvm_cr4_guest_valid_bits(v->domain);
+ if ( cr4 & ~valid )
+ PRINTF("CR4: invalid value %#lx (valid %#lx, rejected %#lx)\n",
+ cr4, valid, cr4 & ~valid);
+
+ if ( vmcb_get_dr6(vmcb) >> 32 )
+ PRINTF("DR6: bits [63:32] are not zero (%#"PRIx64")\n",
+ vmcb_get_dr6(vmcb));
+
+ if ( vmcb_get_dr7(vmcb) >> 32 )
+ PRINTF("DR7: bits [63:32] are not zero (%#"PRIx64")\n",
+ vmcb_get_dr7(vmcb));
+
+ if ( efer & ~EFER_KNOWN_MASK )
+ PRINTF("EFER: unknown bits are not zero (%#"PRIx64")\n", efer);
+
+ if ( hvm_efer_valid(v, efer, -1) )
+ PRINTF("EFER: %s (%"PRIx64")\n", hvm_efer_valid(v, efer, -1), efer);
+
+ if ( (efer & EFER_LME) && (cr0 & X86_CR0_PG) )
+ {
+ if ( !(cr4 & X86_CR4_PAE) )
+ PRINTF("EFER_LME and CR0.PG are both set and CR4.PAE is zero\n");
+ if ( !(cr0 & X86_CR0_PE) )
+ PRINTF("EFER_LME and CR0.PG are both set and CR0.PE is zero\n");
+ }
+
+ if ( (efer & EFER_LME) && (cr0 & X86_CR0_PG) && (cr4 & X86_CR4_PAE) &&
+ vmcb->cs.l && vmcb->cs.db )
+ PRINTF("EFER_LME, CR0.PG, CR4.PAE, CS.L and CS.D are all non-zero\n");
+
+ if ( !(vmcb_get_general2_intercepts(vmcb) & GENERAL2_INTERCEPT_VMRUN) )
+ PRINTF("GENERAL2_INTERCEPT: VMRUN intercept bit is clear (%#"PRIx32")\n",
+ vmcb_get_general2_intercepts(vmcb));
+
+ if ( vmcb->event_inj.resvd1 )
+ PRINTF("eventinj: MBZ bits are set (%#"PRIx64")\n",
+ vmcb->event_inj.raw);
+
+#undef PRINTF
+ return ret;
+}
+
static void cf_check vmcb_dump(unsigned char ch)
{
struct domain *d;
diff --git a/xen/arch/x86/hvm/svm/vmcb.h b/xen/arch/x86/hvm/svm/vmcb.h
index 68012948a9e3..ba554a964487 100644
--- a/xen/arch/x86/hvm/svm/vmcb.h
+++ b/xen/arch/x86/hvm/svm/vmcb.h
@@ -553,6 +553,9 @@ int svm_create_vmcb(struct vcpu *v);
void svm_destroy_vmcb(struct vcpu *v);
void setup_vmcb_dump(void);
+void svm_vmcb_dump(const char *from, const struct vmcb_struct *vmcb);
+bool svm_vmcb_isvalid(const char *from, const struct vmcb_struct *vmcb,
+ const struct vcpu *v, bool verbose);
/*
* VMCB accessor functions.
diff --git a/xen/arch/x86/include/asm/hvm/svm/svmdebug.h b/xen/arch/x86/include/asm/hvm/svm/svmdebug.h
index 2fb76ec24c76..ede13bd34048 100644
--- a/xen/arch/x86/include/asm/hvm/svm/svmdebug.h
+++ b/xen/arch/x86/include/asm/hvm/svm/svmdebug.h
@@ -12,8 +12,5 @@
#include <asm/hvm/svm/vmcb.h>
void svm_sync_vmcb(struct vcpu *v, enum vmcb_sync_state new_state);
-void svm_vmcb_dump(const char *from, const struct vmcb_struct *vmcb);
-bool svm_vmcb_isvalid(const char *from, const struct vmcb_struct *vmcb,
- const struct vcpu *v, bool verbose);
#endif /* __ASM_X86_HVM_SVM_SVMDEBUG_H__ */
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/3] x86/svm: Drop svmdebug.h
2025-11-28 20:19 [PATCH 0/3] x86/svm: Make various details private Andrew Cooper
2025-11-28 20:19 ` [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/ Andrew Cooper
2025-11-28 20:19 ` [PATCH 2/3] x86/svm: Drop svmdebug.c Andrew Cooper
@ 2025-11-28 20:19 ` Andrew Cooper
2025-12-01 15:39 ` Alejandro Vallejo
2025-12-08 9:10 ` Jan Beulich
2 siblings, 2 replies; 12+ messages in thread
From: Andrew Cooper @ 2025-11-28 20:19 UTC (permalink / raw)
To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monné
svmdebug.h now only contains the declaration for svm_sync_vmcb(), despite the
function being implemented in svm.c. Move the declaration into svm.h
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
---
xen/arch/x86/hvm/svm/svm.c | 1 -
xen/arch/x86/hvm/svm/svm.h | 17 +++++++++++++++++
xen/arch/x86/hvm/svm/vmcb.c | 2 +-
xen/arch/x86/include/asm/hvm/svm/svmdebug.h | 16 ----------------
xen/arch/x86/include/asm/hvm/svm/vmcb.h | 15 ---------------
5 files changed, 18 insertions(+), 33 deletions(-)
delete mode 100644 xen/arch/x86/include/asm/hvm/svm/svmdebug.h
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 14b3a427e642..15d45cbb57c5 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -27,7 +27,6 @@
#include <asm/hvm/nestedhvm.h>
#include <asm/hvm/support.h>
#include <asm/hvm/svm/svm.h>
-#include <asm/hvm/svm/svmdebug.h>
#include <asm/hvm/svm/vmcb.h>
#include <asm/i387.h>
#include <asm/idt.h>
diff --git a/xen/arch/x86/hvm/svm/svm.h b/xen/arch/x86/hvm/svm/svm.h
index f5b0312d2dcf..cfa411ad5ae1 100644
--- a/xen/arch/x86/hvm/svm/svm.h
+++ b/xen/arch/x86/hvm/svm/svm.h
@@ -78,6 +78,23 @@ unsigned int svm_get_task_switch_insn_len(void);
#define _NPT_PFEC_in_gpt 33
#define NPT_PFEC_in_gpt (1UL<<_NPT_PFEC_in_gpt)
+/*
+ * VMRUN doesn't switch fs/gs/tr/ldtr and SHADOWGS/SYSCALL/SYSENTER state.
+ * Therefore, guest state is in the hardware registers when servicing a
+ * VMExit.
+ *
+ * Immediately after a VMExit, the vmcb is stale, and needs to be brought
+ * into sync by VMSAVE. If state in the vmcb is modified, a VMLOAD is
+ * needed before the following VMRUN.
+ */
+enum vmcb_sync_state {
+ vmcb_in_sync,
+ vmcb_needs_vmsave, /* VMCB out of sync (VMSAVE needed)? */
+ vmcb_needs_vmload, /* VMCB dirty (VMLOAD needed)? */
+};
+
+void svm_sync_vmcb(struct vcpu *v, enum vmcb_sync_state new_state);
+
#endif /* __X86_HVM_SVM_SVM_PRIV_H__ */
/*
diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c
index b1a79d515143..7bde6e98ce03 100644
--- a/xen/arch/x86/hvm/svm/vmcb.c
+++ b/xen/arch/x86/hvm/svm/vmcb.c
@@ -16,12 +16,12 @@
#include <asm/guest-msr.h>
#include <asm/hvm/svm/svm.h>
-#include <asm/hvm/svm/svmdebug.h>
#include <asm/hvm/svm/vmcb.h>
#include <asm/msr-index.h>
#include <asm/p2m.h>
#include <asm/spec_ctrl.h>
+#include "svm.h"
#include "vmcb.h"
struct vmcb_struct *alloc_vmcb(void)
diff --git a/xen/arch/x86/include/asm/hvm/svm/svmdebug.h b/xen/arch/x86/include/asm/hvm/svm/svmdebug.h
deleted file mode 100644
index ede13bd34048..000000000000
--- a/xen/arch/x86/include/asm/hvm/svm/svmdebug.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * svmdebug.h: SVM related debug defintions
- * Copyright (c) 2011, AMD Corporation.
- *
- */
-
-#ifndef __ASM_X86_HVM_SVM_SVMDEBUG_H__
-#define __ASM_X86_HVM_SVM_SVMDEBUG_H__
-
-#include <xen/types.h>
-#include <asm/hvm/svm/vmcb.h>
-
-void svm_sync_vmcb(struct vcpu *v, enum vmcb_sync_state new_state);
-
-#endif /* __ASM_X86_HVM_SVM_SVMDEBUG_H__ */
diff --git a/xen/arch/x86/include/asm/hvm/svm/vmcb.h b/xen/arch/x86/include/asm/hvm/svm/vmcb.h
index 717215ff969b..41bcc9f0d862 100644
--- a/xen/arch/x86/include/asm/hvm/svm/vmcb.h
+++ b/xen/arch/x86/include/asm/hvm/svm/vmcb.h
@@ -21,21 +21,6 @@ struct svm_domain {
} osvw;
};
-/*
- * VMRUN doesn't switch fs/gs/tr/ldtr and SHADOWGS/SYSCALL/SYSENTER state.
- * Therefore, guest state is in the hardware registers when servicing a
- * VMExit.
- *
- * Immediately after a VMExit, the vmcb is stale, and needs to be brought
- * into sync by VMSAVE. If state in the vmcb is modified, a VMLOAD is
- * needed before the following VMRUN.
- */
-enum vmcb_sync_state {
- vmcb_in_sync,
- vmcb_needs_vmsave, /* VMCB out of sync (VMSAVE needed)? */
- vmcb_needs_vmload /* VMCB dirty (VMLOAD needed)? */
-};
-
struct svm_vcpu {
struct vmcb_struct *vmcb;
u64 vmcb_pa;
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/
2025-11-28 20:19 ` [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/ Andrew Cooper
@ 2025-12-01 15:23 ` Alejandro Vallejo
2025-12-08 9:05 ` Jan Beulich
1 sibling, 0 replies; 12+ messages in thread
From: Alejandro Vallejo @ 2025-12-01 15:23 UTC (permalink / raw)
To: Andrew Cooper, Xen-devel; +Cc: Jan Beulich, Roger Pau Monné, Xen-devel
Hi,
Code motion is correct according to my scripts. A nit though...
On Fri Nov 28, 2025 at 9:19 PM CET, Andrew Cooper wrote:
> The rest of Xen has no buisness knowing this structure, and it is currently
> included via xen/sched.h into most code. Create a new private svm/vmcb.h.
>
> No functional change.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> ---
> xen/arch/x86/hvm/svm/asid.c | 1 +
> xen/arch/x86/hvm/svm/emulate.c | 1 +
> xen/arch/x86/hvm/svm/intr.c | 1 +
> xen/arch/x86/hvm/svm/nestedsvm.c | 1 +
> xen/arch/x86/hvm/svm/svm.c | 1 +
> xen/arch/x86/hvm/svm/svmdebug.c | 2 +
> xen/arch/x86/hvm/svm/vmcb.c | 2 +
> xen/arch/x86/hvm/svm/vmcb.h | 617 ++++++++++++++++++++++++
> xen/arch/x86/include/asm/hvm/svm/vmcb.h | 606 -----------------------
> 9 files changed, 626 insertions(+), 606 deletions(-)
> create mode 100644 xen/arch/x86/hvm/svm/vmcb.h
>
[snip]
> diff --git a/xen/arch/x86/hvm/svm/vmcb.h b/xen/arch/x86/hvm/svm/vmcb.h
> new file mode 100644
> index 000000000000..68012948a9e3
> --- /dev/null
> +++ b/xen/arch/x86/hvm/svm/vmcb.h
> @@ -0,0 +1,617 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef SVM_PRIVATE_VMCB_H
> +#define SVM_PRIVATE_VMCB_H
> +
> +#include <xen/types.h>
> +
> +#include <asm/x86_emulate.h>
Worth commenting here that this exists because the segment selector struct lives
as part of the x86 emulator even though it's part of the SVM ABI.
In an ideal world this wouldn't exist. Otherwise everything looks fine.
With or without the nit addressed
Reviewed-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/3] x86/svm: Drop svmdebug.c
2025-11-28 20:19 ` [PATCH 2/3] x86/svm: Drop svmdebug.c Andrew Cooper
@ 2025-12-01 15:33 ` Alejandro Vallejo
2025-12-08 9:06 ` Jan Beulich
1 sibling, 0 replies; 12+ messages in thread
From: Alejandro Vallejo @ 2025-12-01 15:33 UTC (permalink / raw)
To: Andrew Cooper, Xen-devel; +Cc: Jan Beulich, Roger Pau Monné, Xen-devel
Hi,
On Fri Nov 28, 2025 at 9:19 PM CET, Andrew Cooper wrote:
> Everything here is really VMCB functionality, so merge it into vmcb.c. Move
> the declarations from the global svmdebug.h to the logical vmcb.h.
>
> No functional change.
Not functional, but there's a single instance of style adjustment on move...
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> ---
> xen/arch/x86/hvm/svm/Makefile | 1 -
> xen/arch/x86/hvm/svm/nestedsvm.c | 1 -
> xen/arch/x86/hvm/svm/svmdebug.c | 181 --------------------
> xen/arch/x86/hvm/svm/vmcb.c | 159 +++++++++++++++++
> xen/arch/x86/hvm/svm/vmcb.h | 3 +
> xen/arch/x86/include/asm/hvm/svm/svmdebug.h | 3 -
> 6 files changed, 162 insertions(+), 186 deletions(-)
> delete mode 100644 xen/arch/x86/hvm/svm/svmdebug.c
>
> diff --git a/xen/arch/x86/hvm/svm/Makefile b/xen/arch/x86/hvm/svm/Makefile
> index 760d2954da83..8a072cafd572 100644
> --- a/xen/arch/x86/hvm/svm/Makefile
> +++ b/xen/arch/x86/hvm/svm/Makefile
> @@ -4,5 +4,4 @@ obj-bin-y += entry.o
> obj-y += intr.o
> obj-y += nestedsvm.o
> obj-y += svm.o
> -obj-y += svmdebug.o
> obj-y += vmcb.o
> diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
> index 191466755148..63ed6c86b775 100644
> --- a/xen/arch/x86/hvm/svm/nestedsvm.c
> +++ b/xen/arch/x86/hvm/svm/nestedsvm.c
> @@ -9,7 +9,6 @@
> #include <asm/hvm/svm/svm.h>
> #include <asm/hvm/svm/vmcb.h>
> #include <asm/hvm/nestedhvm.h>
> -#include <asm/hvm/svm/svmdebug.h>
> #include <asm/paging.h> /* paging_mode_hap */
> #include <asm/event.h> /* for local_event_delivery_(en|dis)able */
> #include <asm/p2m.h> /* p2m_get_pagetable, p2m_get_nestedp2m */
> diff --git a/xen/arch/x86/hvm/svm/svmdebug.c b/xen/arch/x86/hvm/svm/svmdebug.c
> deleted file mode 100644
> index bdb9ea3583ee..000000000000
> --- a/xen/arch/x86/hvm/svm/svmdebug.c
> +++ /dev/null
> @@ -1,181 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * svmdebug.c: debug functions
> - * Copyright (c) 2011, Advanced Micro Devices, Inc.
> - *
> - */
> -
> -#include <xen/sched.h>
> -#include <asm/processor.h>
> -#include <asm/msr-index.h>
> -#include <asm/hvm/svm/svmdebug.h>
> -
> -#include "vmcb.h"
> -
> -static void svm_dump_sel(const char *name, const struct segment_register *s)
> -{
> - printk("%s: %04x %04x %08x %016"PRIx64"\n",
> - name, s->sel, s->attr, s->limit, s->base);
> -}
> -
> -void svm_vmcb_dump(const char *from, const struct vmcb_struct *vmcb)
> -{
> - struct vcpu *curr = current;
> -
> - /*
> - * If we are dumping the VMCB currently in context, some guest state may
> - * still be cached in hardware. Retrieve it.
> - */
> - if ( vmcb == curr->arch.hvm.svm.vmcb )
> - svm_sync_vmcb(curr, vmcb_in_sync);
> -
> - printk("Dumping guest's current state at %s...\n", from);
> - printk("Size of VMCB = %zu, paddr = %"PRIpaddr", vaddr = %p\n",
> - sizeof(struct vmcb_struct), virt_to_maddr(vmcb), vmcb);
> -
> - printk("cr_intercepts = %#x dr_intercepts = %#x "
> - "exception_intercepts = %#x\n",
> - vmcb_get_cr_intercepts(vmcb), vmcb_get_dr_intercepts(vmcb),
> - vmcb_get_exception_intercepts(vmcb));
> - printk("general1_intercepts = %#x general2_intercepts = %#x\n",
> - vmcb_get_general1_intercepts(vmcb), vmcb_get_general2_intercepts(vmcb));
> - printk("iopm_base_pa = %#"PRIx64" msrpm_base_pa = %#"PRIx64" tsc_offset = %#"PRIx64"\n",
> - vmcb_get_iopm_base_pa(vmcb), vmcb_get_msrpm_base_pa(vmcb),
> - vmcb_get_tsc_offset(vmcb));
> - printk("tlb_control = %#x vintr = %#"PRIx64" int_stat = %#"PRIx64"\n",
> - vmcb->tlb_control, vmcb_get_vintr(vmcb).bytes,
> - vmcb->int_stat.raw);
> - printk("event_inj %016"PRIx64", valid? %d, ec? %d, type %u, vector %#x\n",
> - vmcb->event_inj.raw, vmcb->event_inj.v,
> - vmcb->event_inj.ev, vmcb->event_inj.type,
> - vmcb->event_inj.vector);
> - printk("exitcode = %#"PRIx64" exit_int_info = %#"PRIx64"\n",
> - vmcb->exitcode, vmcb->exit_int_info.raw);
> - printk("exitinfo1 = %#"PRIx64" exitinfo2 = %#"PRIx64"\n",
> - vmcb->exitinfo1, vmcb->exitinfo2);
> - printk("asid = %#x np_ctrl = %#"PRIx64":%s%s%s\n",
> - vmcb_get_asid(vmcb), vmcb_get_np_ctrl(vmcb),
> - vmcb_get_np(vmcb) ? " NP" : "",
> - vmcb_get_sev(vmcb) ? " SEV" : "",
> - vmcb_get_sev_es(vmcb) ? " SEV_ES" : "");
> - printk("virtual vmload/vmsave = %d, virt_ext = %#"PRIx64"\n",
> - vmcb->virt_ext.fields.vloadsave_enable, vmcb->virt_ext.bytes);
> - printk("cpl = %d efer = %#"PRIx64" star = %#"PRIx64" lstar = %#"PRIx64"\n",
> - vmcb_get_cpl(vmcb), vmcb_get_efer(vmcb), vmcb->star, vmcb->lstar);
> - printk("CR0 = 0x%016"PRIx64" CR2 = 0x%016"PRIx64"\n",
> - vmcb_get_cr0(vmcb), vmcb_get_cr2(vmcb));
> - printk("CR3 = 0x%016"PRIx64" CR4 = 0x%016"PRIx64"\n",
> - vmcb_get_cr3(vmcb), vmcb_get_cr4(vmcb));
> - printk("RSP = 0x%016"PRIx64" RIP = 0x%016"PRIx64"\n",
> - vmcb->rsp, vmcb->rip);
> - printk("RAX = 0x%016"PRIx64" RFLAGS=0x%016"PRIx64"\n",
> - vmcb->rax, vmcb->rflags);
> - printk("DR6 = 0x%016"PRIx64", DR7 = 0x%016"PRIx64"\n",
> - vmcb_get_dr6(vmcb), vmcb_get_dr7(vmcb));
> - printk("CSTAR = 0x%016"PRIx64" SFMask = 0x%016"PRIx64"\n",
> - vmcb->cstar, vmcb->sfmask);
> - printk("KernGSBase = 0x%016"PRIx64" PAT = 0x%016"PRIx64"\n",
> - vmcb->kerngsbase, vmcb_get_g_pat(vmcb));
> - printk("SSP = 0x%016"PRIx64" S_CET = 0x%016"PRIx64" ISST = 0x%016"PRIx64"\n",
> - vmcb->_ssp, vmcb->_msr_s_cet, vmcb->_msr_isst);
> - printk("H_CR3 = 0x%016"PRIx64" CleanBits = %#x\n",
> - vmcb_get_h_cr3(vmcb), vmcb->cleanbits.raw);
> -
> - /* print out all the selectors */
> - printk(" sel attr limit base\n");
> - svm_dump_sel(" CS", &vmcb->cs);
> - svm_dump_sel(" DS", &vmcb->ds);
> - svm_dump_sel(" SS", &vmcb->ss);
> - svm_dump_sel(" ES", &vmcb->es);
> - svm_dump_sel(" FS", &vmcb->fs);
> - svm_dump_sel(" GS", &vmcb->gs);
> - svm_dump_sel("GDTR", &vmcb->gdtr);
> - svm_dump_sel("LDTR", &vmcb->ldtr);
> - svm_dump_sel("IDTR", &vmcb->idtr);
> - svm_dump_sel(" TR", &vmcb->tr);
> -}
> -
> -bool svm_vmcb_isvalid(const char *from, const struct vmcb_struct *vmcb,
> - const struct vcpu *v, bool verbose)
> -{
> - bool ret = false; /* ok */
> - unsigned long cr0 = vmcb_get_cr0(vmcb);
> - unsigned long cr3 = vmcb_get_cr3(vmcb);
> - unsigned long cr4 = vmcb_get_cr4(vmcb);
> - unsigned long valid;
> - uint64_t efer = vmcb_get_efer(vmcb);
> -
> -#define PRINTF(fmt, args...) do { \
> - if ( !verbose ) return true; \
> - ret = true; \
> - printk(XENLOG_GUEST "%pv[%s]: " fmt, v, from, ## args); \
> -} while (0)
> -
> - if ( !(efer & EFER_SVME) )
> - PRINTF("EFER: SVME bit not set (%#"PRIx64")\n", efer);
> -
> - if ( !(cr0 & X86_CR0_CD) && (cr0 & X86_CR0_NW) )
> - PRINTF("CR0: CD bit is zero and NW bit set (%#"PRIx64")\n", cr0);
> -
> - if ( cr0 >> 32 )
> - PRINTF("CR0: bits [63:32] are not zero (%#"PRIx64")\n", cr0);
> -
> - if ( (cr0 & X86_CR0_PG) &&
> - ((cr3 & 7) ||
> - ((!(cr4 & X86_CR4_PAE) || (efer & EFER_LMA)) && (cr3 & 0xfe0)) ||
> - ((efer & EFER_LMA) &&
> - (cr3 >> v->domain->arch.cpuid->extd.maxphysaddr))) )
> - PRINTF("CR3: MBZ bits are set (%#"PRIx64")\n", cr3);
> -
> - valid = hvm_cr4_guest_valid_bits(v->domain);
> - if ( cr4 & ~valid )
> - PRINTF("CR4: invalid value %#lx (valid %#lx, rejected %#lx)\n",
> - cr4, valid, cr4 & ~valid);
> -
> - if ( vmcb_get_dr6(vmcb) >> 32 )
> - PRINTF("DR6: bits [63:32] are not zero (%#"PRIx64")\n",
> - vmcb_get_dr6(vmcb));
> -
> - if ( vmcb_get_dr7(vmcb) >> 32 )
> - PRINTF("DR7: bits [63:32] are not zero (%#"PRIx64")\n",
> - vmcb_get_dr7(vmcb));
> -
> - if ( efer & ~EFER_KNOWN_MASK )
> - PRINTF("EFER: unknown bits are not zero (%#"PRIx64")\n", efer);
> -
> - if ( hvm_efer_valid(v, efer, -1) )
> - PRINTF("EFER: %s (%"PRIx64")\n", hvm_efer_valid(v, efer, -1), efer);
> -
> - if ( (efer & EFER_LME) && (cr0 & X86_CR0_PG) )
> - {
> - if ( !(cr4 & X86_CR4_PAE) )
> - PRINTF("EFER_LME and CR0.PG are both set and CR4.PAE is zero\n");
> - if ( !(cr0 & X86_CR0_PE) )
> - PRINTF("EFER_LME and CR0.PG are both set and CR0.PE is zero\n");
> - }
> -
> - if ( (efer & EFER_LME) && (cr0 & X86_CR0_PG) && (cr4 & X86_CR4_PAE) &&
> - vmcb->cs.l && vmcb->cs.db )
> - PRINTF("EFER_LME, CR0.PG, CR4.PAE, CS.L and CS.D are all non-zero\n");
> -
> - if ( !(vmcb_get_general2_intercepts(vmcb) & GENERAL2_INTERCEPT_VMRUN) )
> - PRINTF("GENERAL2_INTERCEPT: VMRUN intercept bit is clear (%#"PRIx32")\n",
> - vmcb_get_general2_intercepts(vmcb));
> -
> - if ( vmcb->event_inj.resvd1 )
> - PRINTF("eventinj: MBZ bits are set (%#"PRIx64")\n",
> - vmcb->event_inj.raw);
> -
> -#undef PRINTF
> - return ret;
> -}
> -
> -/*
> - * Local variables:
> - * mode: C
> - * c-file-style: "BSD"
> - * c-basic-offset: 4
> - * tab-width: 4
> - * indent-tabs-mode: nil
> - * End:
> - */
> diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c
> index 44fa76bf0228..b1a79d515143 100644
> --- a/xen/arch/x86/hvm/svm/vmcb.c
> +++ b/xen/arch/x86/hvm/svm/vmcb.c
> @@ -228,6 +228,165 @@ void svm_destroy_vmcb(struct vcpu *v)
> svm->vmcb = NULL;
> }
>
> +static void svm_dump_sel(const char *name, const struct segment_register *s)
> +{
> + printk("%s: %04x %04x %08x %016"PRIx64"\n",
> + name, s->sel, s->attr, s->limit, s->base);
> +}
> +
> +void svm_vmcb_dump(const char *from, const struct vmcb_struct *vmcb)
> +{
> + struct vcpu *curr = current;
> +
> + /*
> + * If we are dumping the VMCB currently in context, some guest state may
> + * still be cached in hardware. Retrieve it.
> + */
> + if ( vmcb == curr->arch.hvm.svm.vmcb )
> + svm_sync_vmcb(curr, vmcb_in_sync);
> +
> + printk("Dumping guest's current state at %s...\n", from);
> + printk("Size of VMCB = %zu, paddr = %"PRIpaddr", vaddr = %p\n",
> + sizeof(struct vmcb_struct), virt_to_maddr(vmcb), vmcb);
> +
> + printk("cr_intercepts = %#x dr_intercepts = %#x "
> + "exception_intercepts = %#x\n",
> + vmcb_get_cr_intercepts(vmcb), vmcb_get_dr_intercepts(vmcb),
> + vmcb_get_exception_intercepts(vmcb));
> + printk("general1_intercepts = %#x general2_intercepts = %#x\n",
> + vmcb_get_general1_intercepts(vmcb), vmcb_get_general2_intercepts(vmcb));
> + printk("iopm_base_pa = %#"PRIx64" msrpm_base_pa = %#"PRIx64" tsc_offset = %#"PRIx64"\n",
> + vmcb_get_iopm_base_pa(vmcb), vmcb_get_msrpm_base_pa(vmcb),
> + vmcb_get_tsc_offset(vmcb));
> + printk("tlb_control = %#x vintr = %#"PRIx64" int_stat = %#"PRIx64"\n",
> + vmcb->tlb_control, vmcb_get_vintr(vmcb).bytes,
> + vmcb->int_stat.raw);
> + printk("event_inj %016"PRIx64", valid? %d, ec? %d, type %u, vector %#x\n",
> + vmcb->event_inj.raw, vmcb->event_inj.v,
> + vmcb->event_inj.ev, vmcb->event_inj.type,
> + vmcb->event_inj.vector);
> + printk("exitcode = %#"PRIx64" exit_int_info = %#"PRIx64"\n",
> + vmcb->exitcode, vmcb->exit_int_info.raw);
> + printk("exitinfo1 = %#"PRIx64" exitinfo2 = %#"PRIx64"\n",
> + vmcb->exitinfo1, vmcb->exitinfo2);
> + printk("asid = %#x np_ctrl = %#"PRIx64":%s%s%s\n",
> + vmcb_get_asid(vmcb), vmcb_get_np_ctrl(vmcb),
> + vmcb_get_np(vmcb) ? " NP" : "",
> + vmcb_get_sev(vmcb) ? " SEV" : "",
> + vmcb_get_sev_es(vmcb) ? " SEV_ES" : "");
> + printk("virtual vmload/vmsave = %d, virt_ext = %#"PRIx64"\n",
> + vmcb->virt_ext.fields.vloadsave_enable, vmcb->virt_ext.bytes);
> + printk("cpl = %d efer = %#"PRIx64" star = %#"PRIx64" lstar = %#"PRIx64"\n",
> + vmcb_get_cpl(vmcb), vmcb_get_efer(vmcb), vmcb->star, vmcb->lstar);
> + printk("CR0 = 0x%016"PRIx64" CR2 = 0x%016"PRIx64"\n",
> + vmcb_get_cr0(vmcb), vmcb_get_cr2(vmcb));
> + printk("CR3 = 0x%016"PRIx64" CR4 = 0x%016"PRIx64"\n",
> + vmcb_get_cr3(vmcb), vmcb_get_cr4(vmcb));
> + printk("RSP = 0x%016"PRIx64" RIP = 0x%016"PRIx64"\n",
> + vmcb->rsp, vmcb->rip);
> + printk("RAX = 0x%016"PRIx64" RFLAGS=0x%016"PRIx64"\n",
> + vmcb->rax, vmcb->rflags);
> + printk("DR6 = 0x%016"PRIx64", DR7 = 0x%016"PRIx64"\n",
> + vmcb_get_dr6(vmcb), vmcb_get_dr7(vmcb));
> + printk("CSTAR = 0x%016"PRIx64" SFMask = 0x%016"PRIx64"\n",
> + vmcb->cstar, vmcb->sfmask);
> + printk("KernGSBase = 0x%016"PRIx64" PAT = 0x%016"PRIx64"\n",
> + vmcb->kerngsbase, vmcb_get_g_pat(vmcb));
> + printk("SSP = 0x%016"PRIx64" S_CET = 0x%016"PRIx64" ISST = 0x%016"PRIx64"\n",
> + vmcb->_ssp, vmcb->_msr_s_cet, vmcb->_msr_isst);
> + printk("H_CR3 = 0x%016"PRIx64" CleanBits = %#x\n",
> + vmcb_get_h_cr3(vmcb), vmcb->cleanbits.raw);
> +
> + /* print out all the selectors */
> + printk(" sel attr limit base\n");
> + svm_dump_sel(" CS", &vmcb->cs);
> + svm_dump_sel(" DS", &vmcb->ds);
> + svm_dump_sel(" SS", &vmcb->ss);
> + svm_dump_sel(" ES", &vmcb->es);
> + svm_dump_sel(" FS", &vmcb->fs);
> + svm_dump_sel(" GS", &vmcb->gs);
> + svm_dump_sel("GDTR", &vmcb->gdtr);
> + svm_dump_sel("LDTR", &vmcb->ldtr);
> + svm_dump_sel("IDTR", &vmcb->idtr);
> + svm_dump_sel(" TR", &vmcb->tr);
> +}
> +
> +bool svm_vmcb_isvalid(
> + const char *from, const struct vmcb_struct *vmcb, const struct vcpu *v,
> + bool verbose)
... here, which is probably unintentional. If intentional it's worth mentioning
in the commit message and worth keeping in sync with the form in the prototype.
I personally prefer the former style rather than this one, FWIW.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] x86/svm: Drop svmdebug.h
2025-11-28 20:19 ` [PATCH 3/3] x86/svm: Drop svmdebug.h Andrew Cooper
@ 2025-12-01 15:39 ` Alejandro Vallejo
2025-12-08 9:10 ` Jan Beulich
1 sibling, 0 replies; 12+ messages in thread
From: Alejandro Vallejo @ 2025-12-01 15:39 UTC (permalink / raw)
To: Andrew Cooper, Xen-devel; +Cc: Jan Beulich, Roger Pau Monné, Xen-devel
On Fri Nov 28, 2025 at 9:19 PM CET, Andrew Cooper wrote:
> svmdebug.h now only contains the declaration for svm_sync_vmcb(), despite the
> function being implemented in svm.c. Move the declaration into svm.h
>
> No functional change.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> ---
> xen/arch/x86/hvm/svm/svm.c | 1 -
> xen/arch/x86/hvm/svm/svm.h | 17 +++++++++++++++++
> xen/arch/x86/hvm/svm/vmcb.c | 2 +-
> xen/arch/x86/include/asm/hvm/svm/svmdebug.h | 16 ----------------
> xen/arch/x86/include/asm/hvm/svm/vmcb.h | 15 ---------------
> 5 files changed, 18 insertions(+), 33 deletions(-)
> delete mode 100644 xen/arch/x86/include/asm/hvm/svm/svmdebug.h
>
> diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
> index 14b3a427e642..15d45cbb57c5 100644
> --- a/xen/arch/x86/hvm/svm/svm.c
> +++ b/xen/arch/x86/hvm/svm/svm.c
> @@ -27,7 +27,6 @@
> #include <asm/hvm/nestedhvm.h>
> #include <asm/hvm/support.h>
> #include <asm/hvm/svm/svm.h>
> -#include <asm/hvm/svm/svmdebug.h>
> #include <asm/hvm/svm/vmcb.h>
> #include <asm/i387.h>
> #include <asm/idt.h>
> diff --git a/xen/arch/x86/hvm/svm/svm.h b/xen/arch/x86/hvm/svm/svm.h
> index f5b0312d2dcf..cfa411ad5ae1 100644
> --- a/xen/arch/x86/hvm/svm/svm.h
> +++ b/xen/arch/x86/hvm/svm/svm.h
> @@ -78,6 +78,23 @@ unsigned int svm_get_task_switch_insn_len(void);
> #define _NPT_PFEC_in_gpt 33
> #define NPT_PFEC_in_gpt (1UL<<_NPT_PFEC_in_gpt)
>
> +/*
> + * VMRUN doesn't switch fs/gs/tr/ldtr and SHADOWGS/SYSCALL/SYSENTER state.
> + * Therefore, guest state is in the hardware registers when servicing a
> + * VMExit.
> + *
> + * Immediately after a VMExit, the vmcb is stale, and needs to be brought
> + * into sync by VMSAVE. If state in the vmcb is modified, a VMLOAD is
> + * needed before the following VMRUN.
> + */
> +enum vmcb_sync_state {
> + vmcb_in_sync,
> + vmcb_needs_vmsave, /* VMCB out of sync (VMSAVE needed)? */
> + vmcb_needs_vmload, /* VMCB dirty (VMLOAD needed)? */
extra comma on move, but this is better, IMO.
Reviewed-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/
2025-11-28 20:19 ` [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/ Andrew Cooper
2025-12-01 15:23 ` Alejandro Vallejo
@ 2025-12-08 9:05 ` Jan Beulich
2025-12-10 14:25 ` Andrew Cooper
1 sibling, 1 reply; 12+ messages in thread
From: Jan Beulich @ 2025-12-08 9:05 UTC (permalink / raw)
To: Andrew Cooper; +Cc: Roger Pau Monné, Xen-devel
On 28.11.2025 21:19, Andrew Cooper wrote:
> The rest of Xen has no buisness knowing this structure, and it is currently
> included via xen/sched.h into most code. Create a new private svm/vmcb.h.
>
> No functional change.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> ---
> xen/arch/x86/hvm/svm/asid.c | 1 +
> xen/arch/x86/hvm/svm/emulate.c | 1 +
> xen/arch/x86/hvm/svm/intr.c | 1 +
> xen/arch/x86/hvm/svm/nestedsvm.c | 1 +
> xen/arch/x86/hvm/svm/svm.c | 1 +
> xen/arch/x86/hvm/svm/svmdebug.c | 2 +
> xen/arch/x86/hvm/svm/vmcb.c | 2 +
> xen/arch/x86/hvm/svm/vmcb.h | 617 ++++++++++++++++++++++++
> xen/arch/x86/include/asm/hvm/svm/vmcb.h | 606 -----------------------
> 9 files changed, 626 insertions(+), 606 deletions(-)
> create mode 100644 xen/arch/x86/hvm/svm/vmcb.h
I was actually hoping for the file to be moved. I notice that a few things are
left in the original file, and I wonder if they couldn't be moved elsewhere up
front. Yet I wouldn't insist; we can certainly do it this way round, accepting
that the file name then is pretty much wrong considering what remains there.
> --- a/xen/arch/x86/hvm/svm/asid.c
> +++ b/xen/arch/x86/hvm/svm/asid.c
> @@ -9,6 +9,7 @@
> #include <asm/hvm/svm/svm.h>
>
> #include "svm.h"
> +#include "vmcb.h"
Instead of repeating this in every .c file, couldn't svm.h include the new file?
Or are you foreseeing some of the .c files requiring svm.h to (later) not need
this include anymore?
Jan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/3] x86/svm: Drop svmdebug.c
2025-11-28 20:19 ` [PATCH 2/3] x86/svm: Drop svmdebug.c Andrew Cooper
2025-12-01 15:33 ` Alejandro Vallejo
@ 2025-12-08 9:06 ` Jan Beulich
1 sibling, 0 replies; 12+ messages in thread
From: Jan Beulich @ 2025-12-08 9:06 UTC (permalink / raw)
To: Andrew Cooper; +Cc: Roger Pau Monné, Xen-devel
On 28.11.2025 21:19, Andrew Cooper wrote:
> Everything here is really VMCB functionality, so merge it into vmcb.c. Move
> the declarations from the global svmdebug.h to the logical vmcb.h.
Nit: s/logical/local/ ?
> No functional change.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] x86/svm: Drop svmdebug.h
2025-11-28 20:19 ` [PATCH 3/3] x86/svm: Drop svmdebug.h Andrew Cooper
2025-12-01 15:39 ` Alejandro Vallejo
@ 2025-12-08 9:10 ` Jan Beulich
1 sibling, 0 replies; 12+ messages in thread
From: Jan Beulich @ 2025-12-08 9:10 UTC (permalink / raw)
To: Andrew Cooper; +Cc: Roger Pau Monné, Xen-devel
On 28.11.2025 21:19, Andrew Cooper wrote:
> svmdebug.h now only contains the declaration for svm_sync_vmcb(), despite the
> function being implemented in svm.c. Move the declaration into svm.h
Maybe again add "private" or "local", seeing that we have two svm.h?
> No functional change.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/
2025-12-08 9:05 ` Jan Beulich
@ 2025-12-10 14:25 ` Andrew Cooper
2025-12-11 7:10 ` Jan Beulich
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Cooper @ 2025-12-10 14:25 UTC (permalink / raw)
To: Jan Beulich; +Cc: Andrew Cooper, Roger Pau Monné, Xen-devel
On 08/12/2025 9:05 am, Jan Beulich wrote:
> On 28.11.2025 21:19, Andrew Cooper wrote:
>> The rest of Xen has no buisness knowing this structure, and it is currently
>> included via xen/sched.h into most code. Create a new private svm/vmcb.h.
>>
>> No functional change.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> CC: Jan Beulich <JBeulich@suse.com>
>> CC: Roger Pau Monné <roger.pau@citrix.com>
>> ---
>> xen/arch/x86/hvm/svm/asid.c | 1 +
>> xen/arch/x86/hvm/svm/emulate.c | 1 +
>> xen/arch/x86/hvm/svm/intr.c | 1 +
>> xen/arch/x86/hvm/svm/nestedsvm.c | 1 +
>> xen/arch/x86/hvm/svm/svm.c | 1 +
>> xen/arch/x86/hvm/svm/svmdebug.c | 2 +
>> xen/arch/x86/hvm/svm/vmcb.c | 2 +
>> xen/arch/x86/hvm/svm/vmcb.h | 617 ++++++++++++++++++++++++
>> xen/arch/x86/include/asm/hvm/svm/vmcb.h | 606 -----------------------
>> 9 files changed, 626 insertions(+), 606 deletions(-)
>> create mode 100644 xen/arch/x86/hvm/svm/vmcb.h
> I was actually hoping for the file to be moved. I notice that a few things are
> left in the original file, and I wonder if they couldn't be moved elsewhere up
> front.
No, they can't be moved yet. There's other cleanup on the list, and
more header dis-entangling needed first.
But I do agree the name is wrong and wants to go.
I intend to end up with svm-structs.h and svm.h only, dropping the subdir.
>> --- a/xen/arch/x86/hvm/svm/asid.c
>> +++ b/xen/arch/x86/hvm/svm/asid.c
>> @@ -9,6 +9,7 @@
>> #include <asm/hvm/svm/svm.h>
>>
>> #include "svm.h"
>> +#include "vmcb.h"
> Instead of repeating this in every .c file, couldn't svm.h include the new file?
> Or are you foreseeing some of the .c files requiring svm.h to (later) not need
> this include anymore?
The other option is to merge all the current header files into one
private.h first, before moving this.
~Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/
2025-12-10 14:25 ` Andrew Cooper
@ 2025-12-11 7:10 ` Jan Beulich
0 siblings, 0 replies; 12+ messages in thread
From: Jan Beulich @ 2025-12-11 7:10 UTC (permalink / raw)
To: Andrew Cooper; +Cc: Roger Pau Monné, Xen-devel
On 10.12.2025 15:25, Andrew Cooper wrote:
> On 08/12/2025 9:05 am, Jan Beulich wrote:
>> On 28.11.2025 21:19, Andrew Cooper wrote:
>>> The rest of Xen has no buisness knowing this structure, and it is currently
>>> included via xen/sched.h into most code. Create a new private svm/vmcb.h.
>>>
>>> No functional change.
>>>
>>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>>> ---
>>> CC: Jan Beulich <JBeulich@suse.com>
>>> CC: Roger Pau Monné <roger.pau@citrix.com>
>>> ---
>>> xen/arch/x86/hvm/svm/asid.c | 1 +
>>> xen/arch/x86/hvm/svm/emulate.c | 1 +
>>> xen/arch/x86/hvm/svm/intr.c | 1 +
>>> xen/arch/x86/hvm/svm/nestedsvm.c | 1 +
>>> xen/arch/x86/hvm/svm/svm.c | 1 +
>>> xen/arch/x86/hvm/svm/svmdebug.c | 2 +
>>> xen/arch/x86/hvm/svm/vmcb.c | 2 +
>>> xen/arch/x86/hvm/svm/vmcb.h | 617 ++++++++++++++++++++++++
>>> xen/arch/x86/include/asm/hvm/svm/vmcb.h | 606 -----------------------
>>> 9 files changed, 626 insertions(+), 606 deletions(-)
>>> create mode 100644 xen/arch/x86/hvm/svm/vmcb.h
>> I was actually hoping for the file to be moved. I notice that a few things are
>> left in the original file, and I wonder if they couldn't be moved elsewhere up
>> front.
>
> No, they can't be moved yet. There's other cleanup on the list, and
> more header dis-entangling needed first.
>
> But I do agree the name is wrong and wants to go.
Well, then let's go this route:
Acked-by: Jan Beulich <jbeulich@suse.com>
Jan
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-12-11 7:10 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-28 20:19 [PATCH 0/3] x86/svm: Make various details private Andrew Cooper
2025-11-28 20:19 ` [PATCH 1/3] x86/svm: Make vmcb_struct private to svm/ Andrew Cooper
2025-12-01 15:23 ` Alejandro Vallejo
2025-12-08 9:05 ` Jan Beulich
2025-12-10 14:25 ` Andrew Cooper
2025-12-11 7:10 ` Jan Beulich
2025-11-28 20:19 ` [PATCH 2/3] x86/svm: Drop svmdebug.c Andrew Cooper
2025-12-01 15:33 ` Alejandro Vallejo
2025-12-08 9:06 ` Jan Beulich
2025-11-28 20:19 ` [PATCH 3/3] x86/svm: Drop svmdebug.h Andrew Cooper
2025-12-01 15:39 ` Alejandro Vallejo
2025-12-08 9:10 ` Jan Beulich
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.