Re: [PATCH v1 3/3] target/i386: Raise the highest index value used for any VMCS encoding

2024-08-09 Thread Xin Li

On 8/8/2024 11:27 PM, Xin Li wrote:

+    if (f[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+    /* FRED injected-event data (0x2052).  */
+    kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x52);


HMM, I have the questions when I check the FRED spec.

Section 9.3.4 said, (for injected-event data) "This field has uses the
encoding pair 2052H/2053H."

So why adjust the highest index to 0x52 other than 0x53?


Okay, found it in the Intel SDM:

Index. Bits 9:1 distinguish components with the same field width and type.

Bit 0 is not included in the index field.




Re: [PATCH v1 2/3] target/i386: Add VMX control bits for nested FRED support

2024-08-08 Thread Xin Li

@@ -1450,7 +1450,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
   NULL, "vmx-entry-ia32e-mode", NULL, NULL,
   NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", 
"vmx-entry-load-efer",
   "vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
-NULL, NULL, "vmx-entry-load-pkrs", NULL,
+NULL, NULL, "vmx-entry-load-pkrs", "vmx-entry-load-fred",


Should we also define VMX_VM_ENTRY_LOAD_FRED? "vmx-entry-load-rtit-ctl"
and "vmx-entry-load-pkrs" have their corresponding bit definitions, even
if they are not used.


I'm not sure, but why add something that is not being used (thus not
tested)?


Yes, the use of macros is a factor. My another consideration is the
integrity of the feature definitions. When the such feature definitions
were first introduced in commit 704798add83b (”target/i386: add VMX
definitions”), I understand thay were mainly used to enumerate and
reflect hardware support and not all defs are used directly.

The feat word name and the feature definition should essentially be
bound, and it might be possible to generate the feature definition
from the feat word via some script without having to add it manually,
but right now there is no work on this, and no additional constraints,
so we have to manually add and manually check it to make sure that the
two correspond to each other. When a feature word is added, it means
that Host supports the corresponding feature, and from an integrity
perspective, so it is natural to continue adding definition (just like
the commit 52a44ad2b92b ("target/i386: Expose VMX entry/exit load pkrs
control bits")), right?

Though I found that there are still some mismatches between the feature
word and the corresponding definition, but ideally they should coexist.

About the test, if it's just enumerated and not added to a specific CPU
model or involved by other logic, it's harmless?


Unless tests are ready, such code are literally dead code, and could get
broken w/o being noticed for a long time.

I think we should add it only when tests are also added.  Otherwise we 
added burden to maintainers, hoping test will be added soon, which often

never happen.



Thanks,
Zhao







Re: [PATCH v1 3/3] target/i386: Raise the highest index value used for any VMCS encoding

2024-08-08 Thread Xin Li

+if (f[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+/* FRED injected-event data (0x2052).  */
+kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x52);


HMM, I have the questions when I check the FRED spec.

Section 9.3.4 said, (for injected-event data) "This field has uses the
encoding pair 2052H/2053H."

So why adjust the highest index to 0x52 other than 0x53?


For 16-bit, 32-bit, and natural-width fields, they must be read/write
as a whole, thus the lowest bit of their encoding must be 0.

A 64-bit VMCS field can be accessed as two 32-bit fields, with the
higher order half using an odd VMCS encoding.  But conceptually they
should be treated as a whole 64-bit field.

Better to refer to Intel SDM 25.11.2 VMREAD, VMWRITE, and Encodings of
VMCS Fields.



And it seems FRED introduces another field "original-event data"
(0x2404/0x2405), why not consider this field here as well?


+} else if (f[FEAT_VMX_EXIT_CTLS] &
+   VMX_VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) {
+/* Secondary VM-exit controls (0x2044).  */
+kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x44);
+} else if (f[FEAT_VMX_SECONDARY_CTLS] & VMX_SECONDARY_EXEC_TSC_SCALING) {
  /* TSC multiplier (0x2032).  */
  kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x32);
  } else {


Maybe we could adjust the index in a cleaner way like
x86_cpu_adjust_level(), but the current case-by-case is ok for me as
well.


Yeah, that sounds a good idea.  But the code hasn't gone wild...



Re: [PATCH v1 2/3] target/i386: Add VMX control bits for nested FRED support

2024-08-08 Thread Xin Li

On 8/7/2024 8:58 AM, Zhao Liu wrote:

On Wed, Aug 07, 2024 at 01:18:11AM -0700, Xin Li (Intel) wrote:

@@ -1435,7 +1435,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  "vmx-exit-save-efer", "vmx-exit-load-efer",
  "vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
  NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
-NULL, "vmx-exit-load-pkrs", NULL, NULL,
+NULL, "vmx-exit-load-pkrs", NULL, "vmx-exit-secondary-ctls",


Oh, the order of my reviews is mixed up.
It's better to move VMX_VM_EXIT_ACTIVATE_SECONDARY_CONTROLS into this patch.


Usually a simple definition is added in a patch where it is used, not in
qemu?


  },
  .msr = {
  .index = MSR_IA32_VMX_TRUE_EXIT_CTLS,
@@ -1450,7 +1450,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  NULL, "vmx-entry-ia32e-mode", NULL, NULL,
  NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", 
"vmx-entry-load-efer",
  "vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
-NULL, NULL, "vmx-entry-load-pkrs", NULL,
+NULL, NULL, "vmx-entry-load-pkrs", "vmx-entry-load-fred",


Should we also define VMX_VM_ENTRY_LOAD_FRED? "vmx-entry-load-rtit-ctl"
and "vmx-entry-load-pkrs" have their corresponding bit definitions, even
if they are not used.


I'm not sure, but why add something that is not being used (thus not
tested)?





[PATCH v1 0/3] target/i386: Add nested FRED support

2024-08-07 Thread Xin Li (Intel)
This patch set adds nested FRED support to allow KVM to run a nested
guest with FRED enabled.


Lei Wang (1):
  target/i386: Raise the highest index value used for any VMCS encoding

Xin Li (Intel) (2):
  target/i386: Delete duplicated macro definition CR4_FRED_MASK
  target/i386: Add VMX control bits for nested FRED support

 target/i386/cpu.c | 4 ++--
 target/i386/cpu.h | 7 +--
 target/i386/kvm/kvm.c | 9 -
 3 files changed, 11 insertions(+), 9 deletions(-)


base-commit: 6d00c6f98256adbd0613966285792125abe5
-- 
2.45.2




[PATCH v1 3/3] target/i386: Raise the highest index value used for any VMCS encoding

2024-08-07 Thread Xin Li (Intel)
From: Lei Wang 

Because the index value of the VMCS field encoding of FRED injected-event
data (one of the newly added VMCS fields for FRED transitions), 0x52, is
larger than any existing index value, raise the highest index value used
for any VMCS encoding to 0x52.

Because the index value of the VMCS field encoding of Secondary VM-exit
controls, 0x44, is larger than any existing index value, raise the highest
index value used for any VMCS encoding to 0x44.

Co-developed-by: Xin Li 
Signed-off-by: Xin Li 
Signed-off-by: Lei Wang 
Signed-off-by: Xin Li (Intel) 
---
 target/i386/cpu.h | 1 +
 target/i386/kvm/kvm.c | 9 -
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 118ef9cb68..62324c3dcd 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1186,6 +1186,7 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, 
FeatureWord w);
 #define VMX_VM_EXIT_PT_CONCEAL_PIP  0x0100
 #define VMX_VM_EXIT_CLEAR_IA32_RTIT_CTL 0x0200
 #define VMX_VM_EXIT_LOAD_IA32_PKRS  0x2000
+#define VMX_VM_EXIT_ACTIVATE_SECONDARY_CONTROLS 0x8000
 
 #define VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS0x0004
 #define VMX_VM_ENTRY_IA32E_MODE 0x0200
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 31f149c990..fac5990274 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -3694,7 +3694,14 @@ static void kvm_msr_entry_add_vmx(X86CPU *cpu, 
FeatureWordArray f)
 kvm_msr_entry_add(cpu, MSR_IA32_VMX_CR4_FIXED0,
   CR4_VMXE_MASK);
 
-if (f[FEAT_VMX_SECONDARY_CTLS] & VMX_SECONDARY_EXEC_TSC_SCALING) {
+if (f[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+/* FRED injected-event data (0x2052).  */
+kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x52);
+} else if (f[FEAT_VMX_EXIT_CTLS] &
+   VMX_VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) {
+/* Secondary VM-exit controls (0x2044).  */
+kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x44);
+} else if (f[FEAT_VMX_SECONDARY_CTLS] & VMX_SECONDARY_EXEC_TSC_SCALING) {
 /* TSC multiplier (0x2032).  */
 kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x32);
 } else {
-- 
2.45.2




[PATCH v1 1/3] target/i386: Delete duplicated macro definition CR4_FRED_MASK

2024-08-07 Thread Xin Li (Intel)
Macro CR4_FRED_MASK is defined twice, delete one.

Signed-off-by: Xin Li (Intel) 
---
 target/i386/cpu.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c6cc035df3..118ef9cb68 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -267,12 +267,6 @@ typedef enum X86Seg {
 #define CR4_FRED_MASK   0
 #endif
 
-#ifdef TARGET_X86_64
-#define CR4_FRED_MASK   (1ULL << 32)
-#else
-#define CR4_FRED_MASK   0
-#endif
-
 #define CR4_RESERVED_MASK \
 (~(target_ulong)(CR4_VME_MASK | CR4_PVI_MASK | CR4_TSD_MASK \
 | CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \
-- 
2.45.2




[PATCH v1 2/3] target/i386: Add VMX control bits for nested FRED support

2024-08-07 Thread Xin Li (Intel)
Add definitions of
  1) VM-exit activate secondary controls bit
  2) VM-entry load FRED bit
which are required to enable nested FRED.

Reviewed-by: Zhao Liu 
Signed-off-by: Xin Li (Intel) 
---
 target/i386/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 85ef7452c0..31f287cae0 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1435,7 +1435,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "vmx-exit-save-efer", "vmx-exit-load-efer",
 "vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
 NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
-NULL, "vmx-exit-load-pkrs", NULL, NULL,
+NULL, "vmx-exit-load-pkrs", NULL, "vmx-exit-secondary-ctls",
 },
 .msr = {
 .index = MSR_IA32_VMX_TRUE_EXIT_CTLS,
@@ -1450,7 +1450,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, "vmx-entry-ia32e-mode", NULL, NULL,
 NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", 
"vmx-entry-load-efer",
 "vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
-NULL, NULL, "vmx-entry-load-pkrs", NULL,
+NULL, NULL, "vmx-entry-load-pkrs", "vmx-entry-load-fred",
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 },
-- 
2.45.2




[PATCH v1 1/1] target/i386: Add VMX entry load FRED control name to VMX feature words

2024-07-07 Thread Xin Li (Intel)
As VMX entry load FRED control is required to enable FRED in nested VMX,
add it to VMX feature words.

Signed-off-by: Xin Li (Intel) 
---
 target/i386/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c05765eeaf..84a09c19cf 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1450,7 +1450,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, "vmx-entry-ia32e-mode", NULL, NULL,
 NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", 
"vmx-entry-load-efer",
 "vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
-NULL, NULL, "vmx-entry-load-pkrs", NULL,
+NULL, NULL, "vmx-entry-load-pkrs", "vmx-entry-load-fred",
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 },

base-commit: f2cb4026fccfe073f84a4b440e41d3ed0c3134f6
-- 
2.45.2




[PATCH v1 1/1] target/i386: Delete a duplicated macro definition CR4_FRED_MASK

2024-07-02 Thread Xin Li (Intel)
Macro CR4_FRED_MASK is defined twice due to a merge incident, delete one.

Signed-off-by: Xin Li (Intel) 
---
 target/i386/cpu.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 29daf37048..b73685a745 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -267,12 +267,6 @@ typedef enum X86Seg {
 #define CR4_FRED_MASK   0
 #endif
 
-#ifdef TARGET_X86_64
-#define CR4_FRED_MASK   (1ULL << 32)
-#else
-#define CR4_FRED_MASK   0
-#endif
-
 #define CR4_RESERVED_MASK \
 (~(target_ulong)(CR4_VME_MASK | CR4_PVI_MASK | CR4_TSD_MASK \
 | CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \

base-commit: ff6d8490e33acf44ed8afd549e203a42d6f813b5
-- 
2.45.2




[PATCH v3A 1/6] target/i386: add support for FRED in CPUID enumeration

2023-12-21 Thread Xin Li
FRED, i.e., the Intel flexible return and event delivery architecture,
defines simple new transitions that change privilege level (ring
transitions).

The new transitions defined by the FRED architecture are FRED event
delivery and, for returning from events, two FRED return instructions.
FRED event delivery can effect a transition from ring 3 to ring 0, but
it is used also to deliver events incident to ring 0.  One FRED
instruction (ERETU) effects a return from ring 0 to ring 3, while the
other (ERETS) returns while remaining in ring 0.  Collectively, FRED
event delivery and the FRED return instructions are FRED transitions.

In addition to these transitions, the FRED architecture defines a new
instruction (LKGS) for managing the state of the GS segment register.
The LKGS instruction can be used by 64-bit operating systems that do
not use the new FRED transitions.

WRMSRNS is an instruction that behaves exactly like WRMSR, with the
only difference being that it is not a serializing instruction by
default.  Under certain conditions, WRMSRNS may replace WRMSR to improve
performance.  FRED uses it to switch RSP0 in a faster manner.

Search for the latest FRED spec in most search engines with this search
pattern:

  site:intel.com FRED (flexible return and event delivery) specification

The CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[17] enumerates FRED, and
the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[18] enumerates LKGS, and
the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[19] enumerates WRMSRNS.

Add CPUID definitions for FRED/LKGS/WRMSRNS, and expose them to KVM guests.

Because FRED relies on LKGS and WRMSRNS, add that to feature dependency
map.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---

Changelog
v3A:
- Fix reversed dependency (Wu Dan1).
---
 target/i386/cpu.c | 10 +-
 target/i386/cpu.h |  6 ++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 358d9c0a65..66551c7eae 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -965,7 +965,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "avx-vnni", "avx512-bf16", NULL, "cmpccxadd",
 NULL, NULL, "fzrm", "fsrs",
 "fsrc", NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, "fred", "lkgs", "wrmsrns",
 NULL, "amx-fp16", NULL, "avx-ifma",
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
@@ -1552,6 +1552,14 @@ static FeatureDep feature_dependencies[] = {
 .from = { FEAT_VMX_SECONDARY_CTLS,  
VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE },
 .to = { FEAT_7_0_ECX,   CPUID_7_0_ECX_WAITPKG },
 },
+{
+.from = { FEAT_7_1_EAX, CPUID_7_1_EAX_LKGS },
+.to = { FEAT_7_1_EAX,   CPUID_7_1_EAX_FRED },
+},
+{
+.from = { FEAT_7_1_EAX, CPUID_7_1_EAX_WRMSRNS },
+.to = { FEAT_7_1_EAX,   CPUID_7_1_EAX_FRED },
+},
 };
 
 typedef struct X86RegisterInfo32 {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index cd2e295bd6..5faf00551d 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -934,6 +934,12 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define CPUID_7_1_EDX_AMX_COMPLEX   (1U << 8)
 /* PREFETCHIT0/1 Instructions */
 #define CPUID_7_1_EDX_PREFETCHITI   (1U << 14)
+/* Flexible return and event delivery (FRED) */
+#define CPUID_7_1_EAX_FRED  (1U << 17)
+/* Load into IA32_KERNEL_GS_BASE (LKGS) */
+#define CPUID_7_1_EAX_LKGS  (1U << 18)
+/* Non-Serializing Write to Model Specific Register (WRMSRNS) */
+#define CPUID_7_1_EAX_WRMSRNS   (1U << 19)
 
 /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
 #define CPUID_7_2_EDX_MCDT_NO   (1U << 5)
-- 
2.43.0




[PATCH v3 5/6] target/i386: enumerate VMX nested-exception support

2023-11-08 Thread Xin Li
Allow VMX nested-exception support to be exposed in KVM guests, thus
nested KVM guests can enumerate it.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 scripts/kvm/vmxcap | 1 +
 target/i386/cpu.c  | 1 +
 target/i386/cpu.h  | 1 +
 3 files changed, 3 insertions(+)

diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap
index 44898d73c2..508be19c75 100755
--- a/scripts/kvm/vmxcap
+++ b/scripts/kvm/vmxcap
@@ -117,6 +117,7 @@ controls = [
 54: 'INS/OUTS instruction information',
 55: 'IA32_VMX_TRUE_*_CTLS support',
 56: 'Skip checks on event error code',
+58: 'VMX nested exception support',
 },
 msr = MSR_IA32_VMX_BASIC,
 ),
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index dcf914a7ec..f7556621a5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1343,6 +1343,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 [54] = "vmx-ins-outs",
 [55] = "vmx-true-ctls",
 [56] = "vmx-any-errcode",
+[58] = "vmx-nested-exception",
 },
 .msr = {
 .index = MSR_IA32_VMX_BASIC,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index a4d3702621..cc3b4fefb8 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1054,6 +1054,7 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define MSR_VMX_BASIC_INS_OUTS   (1ULL << 54)
 #define MSR_VMX_BASIC_TRUE_CTLS  (1ULL << 55)
 #define MSR_VMX_BASIC_ANY_ERRCODE(1ULL << 56)
+#define MSR_VMX_BASIC_NESTED_EXCEPTION   (1ULL << 58)
 
 #define MSR_VMX_MISC_PREEMPTION_TIMER_SHIFT_MASK 0x1Full
 #define MSR_VMX_MISC_STORE_LMA   (1ULL << 5)
-- 
2.42.0




[PATCH v3 6/6] target/i386: Add get/set/migrate support for FRED MSRs

2023-11-08 Thread Xin Li
FRED CPU states are managed in 9 new FRED MSRs, in addtion to a few
existing CPU registers and MSRs, e.g., CR4.FRED and MSR_IA32_PL0_SSP.

Save/restore/migrate FRED MSRs if FRED is exposed to the guest.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.h | 22 +++
 target/i386/kvm/kvm.c | 49 +++
 target/i386/machine.c | 28 +
 3 files changed, 99 insertions(+)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index cc3b4fefb8..3b13eceffe 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -529,6 +529,17 @@ typedef enum X86Seg {
 #define MSR_IA32_XFD0x01c4
 #define MSR_IA32_XFD_ERR0x01c5
 
+/* FRED MSRs */
+#define MSR_IA32_FRED_RSP0  0x01cc   /* Stack level 0 
regular stack pointer */
+#define MSR_IA32_FRED_RSP1  0x01cd   /* Stack level 1 
regular stack pointer */
+#define MSR_IA32_FRED_RSP2  0x01ce   /* Stack level 2 
regular stack pointer */
+#define MSR_IA32_FRED_RSP3  0x01cf   /* Stack level 3 
regular stack pointer */
+#define MSR_IA32_FRED_STKLVLS   0x01d0   /* FRED exception 
stack levels */
+#define MSR_IA32_FRED_SSP1  0x01d1   /* Stack level 1 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP2  0x01d2   /* Stack level 2 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP3  0x01d3   /* Stack level 3 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_CONFIG0x01d4   /* FRED Entrypoint 
and interrupt stack level */
+
 #define MSR_IA32_BNDCFGS0x0d90
 #define MSR_IA32_XSS0x0da0
 #define MSR_IA32_UMWAIT_CONTROL 0xe1
@@ -1687,6 +1698,17 @@ typedef struct CPUArchState {
 target_ulong cstar;
 target_ulong fmask;
 target_ulong kernelgsbase;
+
+/* FRED MSRs */
+uint64_t fred_rsp0;
+uint64_t fred_rsp1;
+uint64_t fred_rsp2;
+uint64_t fred_rsp3;
+uint64_t fred_stklvls;
+uint64_t fred_ssp1;
+uint64_t fred_ssp2;
+uint64_t fred_ssp3;
+uint64_t fred_config;
 #endif
 
 uint64_t tsc_adjust;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 11b8177eff..101ff63805 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -3309,6 +3309,17 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
 kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, env->kernelgsbase);
 kvm_msr_entry_add(cpu, MSR_FMASK, env->fmask);
 kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar);
+if (env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP0, env->fred_rsp0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP1, env->fred_rsp1);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP2, env->fred_rsp2);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP3, env->fred_rsp3);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_STKLVLS, env->fred_stklvls);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP1, env->fred_ssp1);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, env->fred_ssp2);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, env->fred_ssp3);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, env->fred_config);
+}
 }
 #endif
 
@@ -3773,6 +3784,17 @@ static int kvm_get_msrs(X86CPU *cpu)
 kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, 0);
 kvm_msr_entry_add(cpu, MSR_FMASK, 0);
 kvm_msr_entry_add(cpu, MSR_LSTAR, 0);
+if (env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP0, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP1, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP2, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP3, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_STKLVLS, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP1, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, 0);
+}
 }
 #endif
 kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, 0);
@@ -3994,6 +4016,33 @@ static int kvm_get_msrs(X86CPU *cpu)
 case MSR_LSTAR:
 env->lstar = msrs[i].data;
 break;
+case MSR_IA32_FRED_RSP0:
+env->fred_rsp0 = msrs[i].data;
+break;
+case MSR_IA32_FRED_RSP1:
+env->fred_rsp1 = msrs[i].data;
+break;
+case MSR_IA32_FRED_RSP2:
+env->fred_rsp2 = msrs[i].data;
+break;
+case MSR_IA32_FRED_RSP3:
+env->fred_rsp3 = msrs[i].data;
+break;
+case MSR_IA32_FRED_STKLVLS:
+en

[PATCH v3 3/6] target/i386: add the secondary VM exit controls MSR

2023-11-08 Thread Xin Li
Add the secondary VM exit controls MSR to prepare for KVM FRED enabling.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 scripts/kvm/vmxcap | 9 +
 target/i386/cpu.c  | 2 +-
 target/i386/cpu.h  | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap
index 3fb4d5b342..7da1e00ca8 100755
--- a/scripts/kvm/vmxcap
+++ b/scripts/kvm/vmxcap
@@ -24,6 +24,7 @@ MSR_IA32_VMX_TRUE_EXIT_CTLS = 0x48F
 MSR_IA32_VMX_TRUE_ENTRY_CTLS = 0x490
 MSR_IA32_VMX_VMFUNC = 0x491
 MSR_IA32_VMX_PROCBASED_CTLS3 = 0x492
+MSR_IA32_VMX_EXIT_CTLS2 = 0x493
 
 class msr(object):
 def __init__(self):
@@ -219,11 +220,19 @@ controls = [
 23: 'Clear IA32_BNDCFGS',
 24: 'Conceal VM exits from PT',
 25: 'Clear IA32_RTIT_CTL',
+31: 'Activate secondary VM-exit controls',
 },
 cap_msr = MSR_IA32_VMX_EXIT_CTLS,
 true_cap_msr = MSR_IA32_VMX_TRUE_EXIT_CTLS,
 ),
 
+Allowed1Control(
+name = 'secondary VM-Exit controls',
+bits = {
+},
+cap_msr = MSR_IA32_VMX_EXIT_CTLS2,
+),
+
 Control(
 name = 'VM-Entry controls',
 bits = {
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 403c84177a..227ee1c759 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1270,7 +1270,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "vmx-exit-save-efer", "vmx-exit-load-efer",
 "vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
 NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
-NULL, "vmx-exit-load-pkrs", NULL, NULL,
+NULL, "vmx-exit-load-pkrs", NULL, "vmx-exit-secondary-ctls",
 },
 .msr = {
 .index = MSR_IA32_VMX_TRUE_EXIT_CTLS,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e210957cba..a4d3702621 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -551,6 +551,7 @@ typedef enum X86Seg {
 #define MSR_IA32_VMX_TRUE_EXIT_CTLS  0x048f
 #define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x0490
 #define MSR_IA32_VMX_VMFUNC 0x0491
+#define MSR_IA32_VMX_EXIT_CTLS2 0x0493
 
 #define XSTATE_FP_BIT   0
 #define XSTATE_SSE_BIT  1
-- 
2.42.0




[PATCH v3 4/6] target/i386: add support for VMX FRED controls

2023-11-08 Thread Xin Li
Add VMX FRED controls used to enable save/load of FRED MSRs.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 scripts/kvm/vmxcap | 3 +++
 target/i386/cpu.c  | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap
index 7da1e00ca8..44898d73c2 100755
--- a/scripts/kvm/vmxcap
+++ b/scripts/kvm/vmxcap
@@ -229,6 +229,8 @@ controls = [
 Allowed1Control(
 name = 'secondary VM-Exit controls',
 bits = {
+0: 'Save IA32 FRED MSRs',
+1: 'Load IA32 FRED MSRs',
 },
 cap_msr = MSR_IA32_VMX_EXIT_CTLS2,
 ),
@@ -246,6 +248,7 @@ controls = [
 16: 'Load IA32_BNDCFGS',
 17: 'Conceal VM entries from PT',
 18: 'Load IA32_RTIT_CTL',
+23: 'Load IA32 FRED MSRs',
 },
 cap_msr = MSR_IA32_VMX_ENTRY_CTLS,
 true_cap_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 227ee1c759..dcf914a7ec 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1285,7 +1285,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, "vmx-entry-ia32e-mode", NULL, NULL,
 NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", 
"vmx-entry-load-efer",
 "vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
-NULL, NULL, "vmx-entry-load-pkrs", NULL,
+NULL, NULL, "vmx-entry-load-pkrs", "vmx-entry-load-fred",
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 },
-- 
2.42.0




[PATCH v3 0/6] target/i386: add support for FRED

2023-11-08 Thread Xin Li
This patch set adds support for the Intel flexible return and event delivery
(FRED) architecture to allow Qemu to run KVM guests with FRED enabled.

The FRED architecture defines simple new transitions that change privilege
level (ring transitions). The FRED architecture was designed with the
following goals:
1) Improve overall performance and response time by replacing event delivery
   through the interrupt descriptor table (IDT event delivery) and event
   return by the IRET instruction with lower latency transitions.
2) Improve software robustness by ensuring that event delivery establishes
   the full supervisor context and that event return establishes the full
   user context.

Intel VMX architecture is extended to run FRED guests, and the changes
are majorly:
1) New VMCS fields for FRED context management, which includes two new
   event data VMCS fields, eight new guest FRED context VMCS fields and
   eight new host FRED context VMCS fields.
2) VMX nested-Exception support for proper virtualization of stack
   levels introduced with FRED architecture.

Search for the latest FRED spec in most search engines with this search pattern:

  site:intel.com FRED (flexible return and event delivery) specification

The counterpart KVM patch set is at:
https://lore.kernel.org/kvm/20231108183003.5981-1-xin3...@intel.com/T/#m77876e22876f41c5ec677c0834a46113a4987d31


---
Changelog
v3:
- Add WRMSRNS as a baseline feature for FRED.
- Add the secondary VM exit controls MSR.
- Add FRED VMX controls to VM exit/entry feature words and
  scripts/kvm/vmxcap.
- Do not set/get FRED SSP0 MSR, i.e. PL0_SSP MSR, with FRED, leave it to
  KVM CET.

v2:
- Add VMX nested-exception support to scripts/kvm/vmxcap (Paolo Bonzini).
- Move FRED MSRs from basic x86_cpu part to .subsections part (Weijiang Yang).


Xin Li (6):
  target/i386: add support for FRED in CPUID enumeration
  target/i386: mark CR4.FRED not reserved
  target/i386: add the secondary VM exit controls MSR
  target/i386: add support for VMX FRED controls
  target/i386: enumerate VMX nested-exception support
  target/i386: Add get/set/migrate support for FRED MSRs

 scripts/kvm/vmxcap| 13 
 target/i386/cpu.c | 15 ++---
 target/i386/cpu.h | 42 -
 target/i386/kvm/kvm.c | 49 +++
 target/i386/machine.c | 28 +
 5 files changed, 143 insertions(+), 4 deletions(-)


base-commit: a3c3aaa846ad61b801e7196482dcf4afb8ba34e4
-- 
2.42.0




[PATCH v3 1/6] target/i386: add support for FRED in CPUID enumeration

2023-11-08 Thread Xin Li
FRED, i.e., the Intel flexible return and event delivery architecture,
defines simple new transitions that change privilege level (ring
transitions).

The new transitions defined by the FRED architecture are FRED event
delivery and, for returning from events, two FRED return instructions.
FRED event delivery can effect a transition from ring 3 to ring 0, but
it is used also to deliver events incident to ring 0.  One FRED
instruction (ERETU) effects a return from ring 0 to ring 3, while the
other (ERETS) returns while remaining in ring 0.  Collectively, FRED
event delivery and the FRED return instructions are FRED transitions.

In addition to these transitions, the FRED architecture defines a new
instruction (LKGS) for managing the state of the GS segment register.
The LKGS instruction can be used by 64-bit operating systems that do
not use the new FRED transitions.

WRMSRNS is an instruction that behaves exactly like WRMSR, with the
only difference being that it is not a serializing instruction by
default.  Under certain conditions, WRMSRNS may replace WRMSR to improve
performance.  FRED uses it to switch RSP0 in a faster manner.

Search for the latest FRED spec in most search engines with this search
pattern:

  site:intel.com FRED (flexible return and event delivery) specification

The CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[17] enumerates FRED, and
the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[18] enumerates LKGS, and
the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[19] enumerates WRMSRNS.

Add CPUID definitions for FRED/LKGS/WRMSRNS, and expose them to KVM guests.

Because FRED relies on LKGS and WRMSRNS, add that to feature dependency
map.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.c | 10 +-
 target/i386/cpu.h |  6 ++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 358d9c0a65..403c84177a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -965,7 +965,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "avx-vnni", "avx512-bf16", NULL, "cmpccxadd",
 NULL, NULL, "fzrm", "fsrs",
 "fsrc", NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, "fred", "lkgs", "wrmsrns",
 NULL, "amx-fp16", NULL, "avx-ifma",
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
@@ -1552,6 +1552,14 @@ static FeatureDep feature_dependencies[] = {
 .from = { FEAT_VMX_SECONDARY_CTLS,  
VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE },
 .to = { FEAT_7_0_ECX,   CPUID_7_0_ECX_WAITPKG },
 },
+{
+.from = { FEAT_7_1_EAX, CPUID_7_1_EAX_FRED },
+.to = { FEAT_7_1_EAX,   CPUID_7_1_EAX_LKGS },
+},
+{
+.from = { FEAT_7_1_EAX, CPUID_7_1_EAX_FRED },
+.to = { FEAT_7_1_EAX,   CPUID_7_1_EAX_WRMSRNS },
+},
 };
 
 typedef struct X86RegisterInfo32 {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index cd2e295bd6..5faf00551d 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -934,6 +934,12 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define CPUID_7_1_EDX_AMX_COMPLEX   (1U << 8)
 /* PREFETCHIT0/1 Instructions */
 #define CPUID_7_1_EDX_PREFETCHITI   (1U << 14)
+/* Flexible return and event delivery (FRED) */
+#define CPUID_7_1_EAX_FRED  (1U << 17)
+/* Load into IA32_KERNEL_GS_BASE (LKGS) */
+#define CPUID_7_1_EAX_LKGS  (1U << 18)
+/* Non-Serializing Write to Model Specific Register (WRMSRNS) */
+#define CPUID_7_1_EAX_WRMSRNS   (1U << 19)
 
 /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
 #define CPUID_7_2_EDX_MCDT_NO   (1U << 5)
-- 
2.42.0




[PATCH v3 2/6] target/i386: mark CR4.FRED not reserved

2023-11-08 Thread Xin Li
The CR4.FRED bit, i.e., CR4[32], is no longer a reserved bit when FRED
is exposed to guests, otherwise it is still a reserved bit.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.h | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 5faf00551d..e210957cba 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -262,6 +262,12 @@ typedef enum X86Seg {
 #define CR4_PKE_MASK   (1U << 22)
 #define CR4_PKS_MASK   (1U << 24)
 
+#ifdef TARGET_X86_64
+#define CR4_FRED_MASK   (1ULL << 32)
+#else
+#define CR4_FRED_MASK   0
+#endif
+
 #define CR4_RESERVED_MASK \
 (~(target_ulong)(CR4_VME_MASK | CR4_PVI_MASK | CR4_TSD_MASK \
 | CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \
@@ -269,7 +275,8 @@ typedef enum X86Seg {
 | CR4_OSFXSR_MASK | CR4_OSXMMEXCPT_MASK | CR4_UMIP_MASK \
 | CR4_LA57_MASK \
 | CR4_FSGSBASE_MASK | CR4_PCIDE_MASK | CR4_OSXSAVE_MASK \
-| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK))
+| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK \
+| CR4_FRED_MASK))
 
 #define DR6_BD  (1 << 13)
 #define DR6_BS  (1 << 14)
@@ -2520,6 +2527,9 @@ static inline uint64_t cr4_reserved_bits(CPUX86State *env)
 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS)) {
 reserved_bits |= CR4_PKS_MASK;
 }
+if (!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED)) {
+reserved_bits |= CR4_FRED_MASK;
+}
 return reserved_bits;
 }
 
-- 
2.42.0




[PATCH v2 3/4] target/i386: enumerate VMX nested-exception support

2023-10-02 Thread Xin Li
Allow VMX nested-exception support to be exposed in KVM guests, thus
nested KVM guests can enumerate it.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 scripts/kvm/vmxcap | 1 +
 target/i386/cpu.c  | 1 +
 target/i386/cpu.h  | 1 +
 3 files changed, 3 insertions(+)

diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap
index 3fb4d5b342..97097518a8 100755
--- a/scripts/kvm/vmxcap
+++ b/scripts/kvm/vmxcap
@@ -116,6 +116,7 @@ controls = [
 54: 'INS/OUTS instruction information',
 55: 'IA32_VMX_TRUE_*_CTLS support',
 56: 'Skip checks on event error code',
+58: 'VMX nested exception support',
 },
 msr = MSR_IA32_VMX_BASIC,
 ),
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 59fdb2a01a..da0876842f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1341,6 +1341,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 [54] = "vmx-ins-outs",
 [55] = "vmx-true-ctls",
 [56] = "vmx-any-errcode",
+[58] = "vmx-nested-exception",
 },
 .msr = {
 .index = MSR_IA32_VMX_BASIC,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 322547aa49..f4f0c57574 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1051,6 +1051,7 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define MSR_VMX_BASIC_INS_OUTS   (1ULL << 54)
 #define MSR_VMX_BASIC_TRUE_CTLS  (1ULL << 55)
 #define MSR_VMX_BASIC_ANY_ERRCODE(1ULL << 56)
+#define MSR_VMX_BASIC_NESTED_EXCEPTION   (1ULL << 58)
 
 #define MSR_VMX_MISC_PREEMPTION_TIMER_SHIFT_MASK 0x1Full
 #define MSR_VMX_MISC_STORE_LMA   (1ULL << 5)
-- 
2.34.1




[PATCH v2 4/4] target/i386: Add get/set/migrate support for FRED MSRs

2023-10-02 Thread Xin Li
FRED CPU states are managed in 9 new FRED MSRs, in addtion to a few
existing CPU registers and MSRs, e.g., CR4.FRED and MSR_IA32_PL0_SSP.

Save/restore/migrate FRED MSRs if FRED is exposed to the guest.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.h | 26 +
 target/i386/kvm/kvm.c | 54 +++
 target/i386/machine.c | 29 +++
 3 files changed, 109 insertions(+)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index f4f0c57574..48e713ecc1 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -529,6 +529,20 @@ typedef enum X86Seg {
 #define MSR_IA32_XFD0x01c4
 #define MSR_IA32_XFD_ERR0x01c5
 
+#define MSR_IA32_PL0_SSP0x06a4   /* Stack level 0 
shadow stack pointer in ring 0 */
+
+/* FRED MSRs */
+#define MSR_IA32_FRED_RSP0  0x01cc   /* Stack level 0 
regular stack pointer */
+#define MSR_IA32_FRED_RSP1  0x01cd   /* Stack level 1 
regular stack pointer */
+#define MSR_IA32_FRED_RSP2  0x01ce   /* Stack level 2 
regular stack pointer */
+#define MSR_IA32_FRED_RSP3  0x01cf   /* Stack level 3 
regular stack pointer */
+#define MSR_IA32_FRED_STKLVLS   0x01d0   /* FRED exception 
stack levels */
+#define MSR_IA32_FRED_SSP0  MSR_IA32_PL0_SSP /* Stack level 0 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP1  0x01d1   /* Stack level 1 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP2  0x01d2   /* Stack level 2 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP3  0x01d3   /* Stack level 3 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_CONFIG0x01d4   /* FRED Entrypoint 
and interrupt stack level */
+
 #define MSR_IA32_BNDCFGS0x0d90
 #define MSR_IA32_XSS0x0da0
 #define MSR_IA32_UMWAIT_CONTROL 0xe1
@@ -1684,6 +1698,18 @@ typedef struct CPUArchState {
 target_ulong cstar;
 target_ulong fmask;
 target_ulong kernelgsbase;
+
+/* FRED MSRs */
+uint64_t fred_rsp0;
+uint64_t fred_rsp1;
+uint64_t fred_rsp2;
+uint64_t fred_rsp3;
+uint64_t fred_stklvls;
+uint64_t fred_ssp0;
+uint64_t fred_ssp1;
+uint64_t fred_ssp2;
+uint64_t fred_ssp3;
+uint64_t fred_config;
 #endif
 
 uint64_t tsc_adjust;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index f6c7f7e268..6ee3369a93 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -3399,6 +3399,18 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
 kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, env->kernelgsbase);
 kvm_msr_entry_add(cpu, MSR_FMASK, env->fmask);
 kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar);
+if (env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP0, env->fred_rsp0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP1, env->fred_rsp1);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP2, env->fred_rsp2);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP3, env->fred_rsp3);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_STKLVLS, env->fred_stklvls);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP0, env->fred_ssp0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP1, env->fred_ssp1);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, env->fred_ssp2);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, env->fred_ssp3);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, env->fred_config);
+}
 }
 #endif
 
@@ -3897,6 +3909,18 @@ static int kvm_get_msrs(X86CPU *cpu)
 kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, 0);
 kvm_msr_entry_add(cpu, MSR_FMASK, 0);
 kvm_msr_entry_add(cpu, MSR_LSTAR, 0);
+if (env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP0, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP1, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP2, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP3, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_STKLVLS, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP0, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP1, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, 0);
+}
 }
 #endif
 kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, 0);
@@ -4118,6 +4142,36 @@ static int kvm_get_msrs(X86CPU *cpu)
 case MSR_LSTAR:
 env->lstar = msrs[i].data;
 break;
+case MSR_IA32_FRED_RSP0:
+env->fred_rsp0 = msrs[i]

[PATCH v2 1/4] target/i386: add support for FRED in CPUID enumeration

2023-10-02 Thread Xin Li
FRED, i.e., the Intel flexible return and event delivery architecture,
defines simple new transitions that change privilege level (ring
transitions).

The new transitions defined by the FRED architecture are FRED event
delivery and, for returning from events, two FRED return instructions.
FRED event delivery can effect a transition from ring 3 to ring 0, but
it is used also to deliver events incident to ring 0. One FRED
instruction (ERETU) effects a return from ring 0 to ring 3, while the
other (ERETS) returns while remaining in ring 0. Collectively, FRED
event delivery and the FRED return instructions are FRED transitions.

In addition to these transitions, the FRED architecture defines a new
instruction (LKGS) for managing the state of the GS segment register.
The LKGS instruction can be used by 64-bit operating systems that do
not use the new FRED transitions.

Search for the latest FRED spec in most search engines with this search
pattern:

  site:intel.com FRED (flexible return and event delivery) specification

The CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[17] enumerates FRED, and
the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[18] enumerates LKGS.

Add CPUID definitions for FRED/LKGS, and expose them to KVM guests only.

Because FRED relies on LKGS, add it to feature dependency map.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.c | 6 +-
 target/i386/cpu.h | 4 
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ed72883bf3..59fdb2a01a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -963,7 +963,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "avx-vnni", "avx512-bf16", NULL, "cmpccxadd",
 NULL, NULL, "fzrm", "fsrs",
 "fsrc", NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, "fred", "lkgs", NULL,
 NULL, "amx-fp16", NULL, "avx-ifma",
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
@@ -1550,6 +1550,10 @@ static FeatureDep feature_dependencies[] = {
 .from = { FEAT_VMX_SECONDARY_CTLS,  
VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE },
 .to = { FEAT_7_0_ECX,   CPUID_7_0_ECX_WAITPKG },
 },
+{
+.from = { FEAT_7_1_EAX, CPUID_7_1_EAX_LKGS },
+.to = { FEAT_7_1_EAX,   CPUID_7_1_EAX_FRED },
+},
 };
 
 typedef struct X86RegisterInfo32 {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d3f377d48a..e2946f1d6b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -934,6 +934,10 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define CPUID_7_1_EDX_AMX_COMPLEX   (1U << 8)
 /* PREFETCHIT0/1 Instructions */
 #define CPUID_7_1_EDX_PREFETCHITI   (1U << 14)
+/* Flexible return and event delivery (FRED) */
+#define CPUID_7_1_EAX_FRED  (1U << 17)
+/* Load into IA32_KERNEL_GS_BASE (LKGS) */
+#define CPUID_7_1_EAX_LKGS  (1U << 18)
 
 /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
 #define CPUID_7_2_EDX_MCDT_NO   (1U << 5)
-- 
2.34.1




[PATCH v2 0/4] target/i386: add support for FRED

2023-10-02 Thread Xin Li
This patch set adds support for the Intel flexible return and event delivery
(FRED) architecture to allow Qemu to run KVM guests with FRED enabled.

The FRED architecture defines simple new transitions that change privilege
level (ring transitions). The FRED architecture was designed with the
following goals:
1) Improve overall performance and response time by replacing event delivery
   through the interrupt descriptor table (IDT event delivery) and event
   return by the IRET instruction with lower latency transitions.
2) Improve software robustness by ensuring that event delivery establishes
   the full supervisor context and that event return establishes the full
   user context.

Search for the latest FRED spec in most search engines with this search pattern:

  site:intel.com FRED (flexible return and event delivery) specification


---
Changelog
v2:
- Add VMX nested-exception support to scripts/kvm/vmxcap (Paolo Bonzini).
- Move FRED MSRs from basic x86_cpu part to .subsections part (Weijiang Yang).


Xin Li (4):
  target/i386: add support for FRED in CPUID enumeration
  target/i386: mark CR4.FRED not reserved
  target/i386: enumerate VMX nested-exception support
  target/i386: Add get/set/migrate support for FRED MSRs

 scripts/kvm/vmxcap|  1 +
 target/i386/cpu.c |  7 +-
 target/i386/cpu.h | 43 +-
 target/i386/kvm/kvm.c | 54 +++
 target/i386/machine.c | 29 +++
 5 files changed, 132 insertions(+), 2 deletions(-)

-- 
2.34.1




[PATCH v2 2/4] target/i386: mark CR4.FRED not reserved

2023-10-02 Thread Xin Li
The CR4.FRED bit, i.e., CR4[32], is no longer a reserved bit when FRED
is exposed to guests, otherwise it is still a reserved bit.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.h | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e2946f1d6b..322547aa49 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -262,6 +262,12 @@ typedef enum X86Seg {
 #define CR4_PKE_MASK   (1U << 22)
 #define CR4_PKS_MASK   (1U << 24)
 
+#ifdef TARGET_X86_64
+#define CR4_FRED_MASK   (1ULL << 32)
+#else
+#define CR4_FRED_MASK   0
+#endif
+
 #define CR4_RESERVED_MASK \
 (~(target_ulong)(CR4_VME_MASK | CR4_PVI_MASK | CR4_TSD_MASK \
 | CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \
@@ -269,7 +275,8 @@ typedef enum X86Seg {
 | CR4_OSFXSR_MASK | CR4_OSXMMEXCPT_MASK | CR4_UMIP_MASK \
 | CR4_LA57_MASK \
 | CR4_FSGSBASE_MASK | CR4_PCIDE_MASK | CR4_OSXSAVE_MASK \
-| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK))
+| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK \
+| CR4_FRED_MASK))
 
 #define DR6_BD  (1 << 13)
 #define DR6_BS  (1 << 14)
@@ -2484,6 +2491,9 @@ static inline uint64_t cr4_reserved_bits(CPUX86State *env)
 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS)) {
 reserved_bits |= CR4_PKS_MASK;
 }
+if (!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED)) {
+reserved_bits |= CR4_FRED_MASK;
+}
 return reserved_bits;
 }
 
-- 
2.34.1




[PATCH 4/4] target/i386: add live migration support for FRED

2023-08-31 Thread Xin Li
FRED CPU states are managed in 10 FRED MSRs, in addtion to a few existing
CPU registers and MSRs, e.g., the CR4.FRED bit.

Add the 10 new FRED MSRs to x86 CPUArchState for live migration support.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.h | 24 +++
 target/i386/kvm/kvm.c | 54 +++
 target/i386/machine.c | 10 
 3 files changed, 88 insertions(+)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 924819a64c..a36a1a58c4 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -529,6 +529,20 @@ typedef enum X86Seg {
 #define MSR_IA32_XFD0x01c4
 #define MSR_IA32_XFD_ERR0x01c5
 
+#define MSR_IA32_PL0_SSP0x06a4   /* Stack level 0 
shadow stack pointer in ring 0 */
+
+/* FRED MSRs */
+#define MSR_IA32_FRED_RSP0  0x01cc   /* Stack level 0 
regular stack pointer */
+#define MSR_IA32_FRED_RSP1  0x01cd   /* Stack level 1 
regular stack pointer */
+#define MSR_IA32_FRED_RSP2  0x01ce   /* Stack level 2 
regular stack pointer */
+#define MSR_IA32_FRED_RSP3  0x01cf   /* Stack level 3 
regular stack pointer */
+#define MSR_IA32_FRED_STKLVLS   0x01d0   /* FRED exception 
stack levels */
+#define MSR_IA32_FRED_SSP0  MSR_IA32_PL0_SSP /* Stack level 0 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP1  0x01d1   /* Stack level 1 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP2  0x01d2   /* Stack level 2 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP3  0x01d3   /* Stack level 3 
shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_CONFIG0x01d4   /* FRED Entrypoint 
and interrupt stack level */
+
 #define MSR_IA32_BNDCFGS0x0d90
 #define MSR_IA32_XSS0x0da0
 #define MSR_IA32_UMWAIT_CONTROL 0xe1
@@ -1680,6 +1694,16 @@ typedef struct CPUArchState {
 target_ulong cstar;
 target_ulong fmask;
 target_ulong kernelgsbase;
+target_ulong fred_rsp0;
+target_ulong fred_rsp1;
+target_ulong fred_rsp2;
+target_ulong fred_rsp3;
+target_ulong fred_stklvls;
+target_ulong fred_ssp0;
+target_ulong fred_ssp1;
+target_ulong fred_ssp2;
+target_ulong fred_ssp3;
+target_ulong fred_config;
 #endif
 
 uint64_t tsc_adjust;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 639a242ad8..4b241c82d8 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -3401,6 +3401,18 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
 kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, env->kernelgsbase);
 kvm_msr_entry_add(cpu, MSR_FMASK, env->fmask);
 kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar);
+if (env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP0, env->fred_rsp0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP1, env->fred_rsp1);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP2, env->fred_rsp2);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP3, env->fred_rsp3);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_STKLVLS, env->fred_stklvls);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP0, env->fred_ssp0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP1, env->fred_ssp1);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, env->fred_ssp2);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, env->fred_ssp3);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, env->fred_config);
+}
 }
 #endif
 
@@ -3901,6 +3913,18 @@ static int kvm_get_msrs(X86CPU *cpu)
 kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, 0);
 kvm_msr_entry_add(cpu, MSR_FMASK, 0);
 kvm_msr_entry_add(cpu, MSR_LSTAR, 0);
+if (env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP0, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP1, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP2, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP3, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_STKLVLS, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP0, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP1, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, 0);
+}
 }
 #endif
 kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, 0);
@@ -4123,6 +4147,36 @@ static int kvm_get_msrs(X86CPU *cpu)
 case MSR_LSTAR:
 env->lstar = msrs[i].data;
 break;
+case MSR_IA32_FRED_RSP0:
+env->fred_rsp0 = msrs[i]

[PATCH 3/4] target/i386: enumerate VMX nested-exception support

2023-08-31 Thread Xin Li
Allow VMX nested-exception support to be exposed in KVM guests, thus
nested KVM guests can enumerate it.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 3dba6b46d9..ba579e1fb7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1340,6 +1340,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 .feat_names = {
 [54] = "vmx-ins-outs",
 [55] = "vmx-true-ctls",
+[58] = "vmx-nested-exception",
 },
 .msr = {
 .index = MSR_IA32_VMX_BASIC,
-- 
2.34.1




[PATCH 0/4] target/i386: add support for FRED

2023-08-31 Thread Xin Li
This patch set adds support for the Intel flexible return and event delivery
(FRED) architecture to allow Qemu to run KVM guests with FRED enabled.

The FRED architecture defines simple new transitions that change privilege
level (ring transitions). The FRED architecture was designed with the
following goals:
1) Improve overall performance and response time by replacing event delivery
   through the interrupt descriptor table (IDT event delivery) and event
   return by the IRET instruction with lower latency transitions.
2) Improve software robustness by ensuring that event delivery establishes
   the full supervisor context and that event return establishes the full
   user context.

Search for the latest FRED spec in most search engines with this search pattern:

  site:intel.com FRED (flexible return and event delivery) specification


Xin Li (4):
  target/i386: add support for FRED in CPUID enumeration
  target/i386: mark CR4.FRED not reserved
  target/i386: enumerate VMX nested-exception support
  target/i386: add live migration support for FRED

 target/i386/cpu.c |  7 +-
 target/i386/cpu.h | 40 +++-
 target/i386/kvm/kvm.c | 54 +++
 target/i386/machine.c | 10 
 4 files changed, 109 insertions(+), 2 deletions(-)

-- 
2.34.1




[PATCH 2/4] target/i386: mark CR4.FRED not reserved

2023-08-31 Thread Xin Li
The CR4.FRED bit, i.e., CR4[32], is no longer a reserved bit when FRED
is exposed to guests, otherwise it is still a reserved bit.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.h | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 064decbc85..924819a64c 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -262,6 +262,12 @@ typedef enum X86Seg {
 #define CR4_PKE_MASK   (1U << 22)
 #define CR4_PKS_MASK   (1U << 24)
 
+#ifdef TARGET_X86_64
+#define CR4_FRED_MASK   (1ULL << 32)
+#else
+#define CR4_FRED_MASK   0
+#endif
+
 #define CR4_RESERVED_MASK \
 (~(target_ulong)(CR4_VME_MASK | CR4_PVI_MASK | CR4_TSD_MASK \
 | CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \
@@ -269,7 +275,8 @@ typedef enum X86Seg {
 | CR4_OSFXSR_MASK | CR4_OSXMMEXCPT_MASK | CR4_UMIP_MASK \
 | CR4_LA57_MASK \
 | CR4_FSGSBASE_MASK | CR4_PCIDE_MASK | CR4_OSXSAVE_MASK \
-| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK))
+| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK \
+| CR4_FRED_MASK))
 
 #define DR6_BD  (1 << 13)
 #define DR6_BS  (1 << 14)
@@ -2481,6 +2488,9 @@ static inline uint64_t cr4_reserved_bits(CPUX86State *env)
 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS)) {
 reserved_bits |= CR4_PKS_MASK;
 }
+if (!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED)) {
+reserved_bits |= CR4_FRED_MASK;
+}
 return reserved_bits;
 }
 
-- 
2.34.1




[PATCH 1/4] target/i386: add support for FRED in CPUID enumeration

2023-08-31 Thread Xin Li
FRED, i.e., the Intel flexible return and event delivery architecture,
defines simple new transitions that change privilege level (ring
transitions).

In addition to these transitions, the FRED architecture defines a new
instruction (LKGS) for managing the state of the GS segment register.
The LKGS instruction can be used by 64-bit operating systems that do
not use the new FRED transitions.

The CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[17] enumerates FRED, and
the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[18] enumerates LKGS.

Add CPUID definitions for FRED/LKGS, and expose them to KVM guests only.

Because FRED relies on LKGS, add it to feature dependency map.

Tested-by: Shan Kang 
Signed-off-by: Xin Li 
---
 target/i386/cpu.c | 6 +-
 target/i386/cpu.h | 4 
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 00f913b638..3dba6b46d9 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -963,7 +963,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "avx-vnni", "avx512-bf16", NULL, "cmpccxadd",
 NULL, NULL, "fzrm", "fsrs",
 "fsrc", NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, "fred", "lkgs", NULL,
 NULL, "amx-fp16", NULL, "avx-ifma",
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
@@ -1549,6 +1549,10 @@ static FeatureDep feature_dependencies[] = {
 .from = { FEAT_VMX_SECONDARY_CTLS,  
VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE },
 .to = { FEAT_7_0_ECX,   CPUID_7_0_ECX_WAITPKG },
 },
+{
+.from = { FEAT_7_1_EAX, CPUID_7_1_EAX_LKGS },
+.to = { FEAT_7_1_EAX,   CPUID_7_1_EAX_FRED },
+},
 };
 
 typedef struct X86RegisterInfo32 {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index a6000e93bd..064decbc85 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -932,6 +932,10 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define CPUID_7_1_EDX_AVX_NE_CONVERT(1U << 5)
 /* PREFETCHIT0/1 Instructions */
 #define CPUID_7_1_EDX_PREFETCHITI   (1U << 14)
+/* Flexible return and event delivery (FRED) */
+#define CPUID_7_1_EAX_FRED  (1U << 17)
+/* Load into IA32_KERNEL_GS_BASE (LKGS) */
+#define CPUID_7_1_EAX_LKGS  (1U << 18)
 
 /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
 #define CPUID_7_2_EDX_MCDT_NO   (1U << 5)
-- 
2.34.1




Re: [Qemu-devel] *BSD kernel crash at boot in qemu with seabios 1.7.4 (bisected)

2014-02-12 Thread Xin Li
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA512

On 2/6/14, 4:44 AM, Michael Tokarev wrote:
> [Changing subject to reflect reality]
> 
> I don't really understand what it is all about, as I initially
> said. But I've been told on freebsd IRC channels to post the issue
> to freebsd-emulation list, which I'm Cc'ing now, and if noone
> there answers, also to John Baldwin .
> 
> To bring some context back, here are a few pointers:
> 
> http://bugs.debian.org/737142 -- talking about pc-bsd, but it
> appears that the prob affects other BSD kernels too 
> http://thread.gmane.org/gmane.comp.emulators.qemu/254074 -- this
> thread 
> http://lists.gnu.org/archive/html/qemu-stable/2013-03/msg00037.html
> - a weird issue with freebsd reported last december
> 
> If it's a bug in *BSD kernels, maybe someone there will be glad to
> fix it.  And maybe together we can come out with a more elegant
> solution to this issue, or maybe to confirm (or deny) that the
> proposed patch is a right thing to do.

Yes it does look like a bug in FreeBSD kernel.  Is there a PR already
or should I create one and assign to myself?  I will try to fix this
when I have some free cycles.

I assume this also happens when running FreeBSD under qemu on FreeBSD,
right?

Cheers,

> Thanks,
> 
> /mjt
> 
> 06.02.2014 08:04, Kevin O'Connor wrote:
>> On Wed, Feb 05, 2014 at 12:44:06PM -0500, Kevin O'Connor wrote:
>>> On Tue, Feb 04, 2014 at 04:33:19PM +0400, Michael Tokarev
>>> wrote:
 We have a bugreport in debian,
 http://bugs.debian.org/737142, stating that PC-BSD does not
 work with seabios-1.7.4 anymore.
 
 I digged in, and found out that it fails only with -vga std 
 (cirrus works fine).  So I bisected the issue - only
 changing vgabios-stdvga.bin, and found this:
>> [...]
>>> This seems to be similar to the freebsd problem reported last
>>> year - see: 
>>> http://lists.gnu.org/archive/html/qemu-stable/2013-03/msg00037.html
>>
>>> 
[...]
>>> (*) The best I can think of is to try and construct some hand
>>> crafted assembler that can catch buggy x86emu emulators and
>>> force a failure..
>> 
>> I have put together some assember to try and run-time test for
>> known broken versions of x86emu.  This patch to SeaVGABIOS does
>> seem to catch the freebsd issue and in my tests it convinces
>> freebsd to take a different approach.  The patch is a bit ugly
>> though.
>> 
>> Comments welcome. -Kevin
>> 
>> 
>> commit e3caa553e940efb6184b30a5637134c4aa9f8b65 Author: Kevin
>> O'Connor  Date:   Wed Feb 5 22:47:29 2014
>> -0500
>> 
>> vgabios: Attempt to detect old x86emu and force a fault.
>> 
>> Check for cases where the leal instruction does not work.  This 
>> instruction is known to not be emulated properly on old versions
>> of x86emu.  If a broken version of x86emu is found, force a fault
>> that x86emu will easily detect.  This should help prevent soft
>> failures when running old software.
>> 
>> Signed-off-by: Kevin O'Connor 
>> 
>> diff --git a/vgasrc/vgaentry.S b/vgasrc/vgaentry.S index
>> 9854448..e246e7c 100644 --- a/vgasrc/vgaentry.S +++
>> b/vgasrc/vgaentry.S @@ -45,9 +45,27 @@ _rom_header_signature: *
>> Entry points 
>> /
>>
>>  -// This macro is the same as ENTRY_ARG except the
>> "calll" -// instruction is avoided to work around known
>> issues in the -// emulation of some versions of x86emu. +
>> // Force a fault if found to be running on broken x86emu
>> versions. +DECLFUNC x86emu_fault +x86emu_fault: +
>> int $0x03 +1:  hlt +jmp 1b + +// This macro
>> implements a call while avoiding instructions +// that
>> old versions of x86emu have problems with. +.macro
>> VGA_CALLL cfunc +// Make sure leal instruction works. +
>> movl $0x8000, %ecx +leal (%ecx, %ecx, 1), %ecx +
>> cmpl $0x1, %ecx +jne x86emu_fault +// Use
>> callw instead of calll +push %ax +callw \cfunc +
>> .endm + +// This macro is the same as ENTRY_ARG except
>> VGA_CALLL is used. .macro ENTRY_ARG_VGA cfunc cli cld @@ -57,7
>> +75,7 @@ _rom_header_signature: movl %esp, %ebx // Backup
>> %esp, then zero high bits movzwl %sp, %esp movl %esp, %eax
>> // First arg is pointer to struct bregs -pushw %ax ;
>> callw \cfunc +VGA_CALLL \cfunc movl %ebx, %esp //
>> Restore %esp (including high bits) POPBREGS .endm @@ -103,7
>> +121,7 @@ entry_10_extrastack: movw %ds, %dx   // Setup
>> %ss/%esp and call function movw %dx, %ss movl %eax, %esp -
>> pushw %ax ; callw handle_10 +VGA_CALLL handle_10
>> 
>> movl %esp, %eax // Restore registers and return movw
>> BREGS_size+4(%eax), %ss
>> 
> 
> ___ 
> freebsd-emulat...@freebsd.org mailing list 
> http://lists.freebsd.org/mailman/listinfo/freebsd-emulation To
> unsubscribe, send any mail to
> "freebsd-emulation-unsubscr...@freebsd.

[Qemu-devel] Bug: hpet timer hangs QEMU using icount

2010-03-01 Thread Xin Li
Hpet hangs QEMU when icount is present. I don't know if this is a 
universal problem. The cause is that for periodical timers, hpet_timer 
function tries to insert the timer back to the active timers queue, 
using an updated expire time. However, before the update, if the expire 
time is equal to the current time, this updating will be skipped. As a 
result, this timer will be inserted as is and goes off again and again, 
basically traps itself in a infinite loop, preventing any new 
instructions from being executed.


The patch tries to update the timer even when the current time equals 
the old expire time.


Thanks.

-Xin

--- hw/hpet.c   2010-03-01 23:58:08.815931235 -0500
+++ hw/new_hpet.c   2010-03-01 23:55:07.316704119 -0500
@@ -220,10 +220,10 @@

 if (timer_is_periodic(t) && period != 0) {
 if (t->config & HPET_TN_32BIT) {
-while (hpet_time_after(cur_tick, t->cmp))
+while (!hpet_time_after(t->cmp, cur_tick))
 t->cmp = (uint32_t)(t->cmp + t->period);
 } else
-while (hpet_time_after64(cur_tick, t->cmp))
+while (!hpet_time_after64(t->cmp, cur_tick))
 t->cmp += period;

 diff = hpet_calculate_diff(t, cur_tick);





[Qemu-devel] bug reporting procedure

2010-03-01 Thread Xin Li

Hello qemu devs,

I'm recently playing with QEMU for my research project. I think I've 
found a bug on my way, and I have my patch solving it. I wonder if there 
is a formal procedure to follow in order to file a bug report?


Thanks!

-Xin