summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backends/hostmem-file.c13
-rwxr-xr-xscripts/device-crash-test96
-rw-r--r--target/i386/cpu.c107
-rw-r--r--target/i386/cpu.h4
4 files changed, 162 insertions, 58 deletions
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 733408e076..b683da9daf 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -124,6 +124,7 @@ static void file_memory_backend_set_align(Object *o, Visitor *v,
fb->align = val;
}
+#ifdef CONFIG_LIBPMEM
static bool file_memory_backend_get_pmem(Object *o, Error **errp)
{
return MEMORY_BACKEND_FILE(o)->is_pmem;
@@ -140,17 +141,9 @@ static void file_memory_backend_set_pmem(Object *o, bool value, Error **errp)
return;
}
-#ifndef CONFIG_LIBPMEM
- if (value) {
- error_setg(errp, "Lack of libpmem support while setting the 'pmem=on'"
- " of %s. We can't ensure data persistence.",
- object_get_typename(o));
- return;
- }
-#endif
-
fb->is_pmem = value;
}
+#endif /* CONFIG_LIBPMEM */
static bool file_memory_backend_get_readonly(Object *obj, Error **errp)
{
@@ -203,8 +196,10 @@ file_backend_class_init(ObjectClass *oc, void *data)
file_memory_backend_get_align,
file_memory_backend_set_align,
NULL, NULL);
+#ifdef CONFIG_LIBPMEM
object_class_property_add_bool(oc, "pmem",
file_memory_backend_get_pmem, file_memory_backend_set_pmem);
+#endif
object_class_property_add_bool(oc, "readonly",
file_memory_backend_get_readonly,
file_memory_backend_set_readonly);
diff --git a/scripts/device-crash-test b/scripts/device-crash-test
index 04118669ba..ef1412ca59 100755
--- a/scripts/device-crash-test
+++ b/scripts/device-crash-test
@@ -41,18 +41,18 @@ logger = logging.getLogger('device-crash-test')
dbg = logger.debug
-# Purposes of the following whitelist:
+# Purposes of the following rule list:
# * Avoiding verbose log messages when we find known non-fatal
# (exitcode=1) errors
# * Avoiding fatal errors when we find known crashes
# * Skipping machines/devices that are known not to work out of
# the box, when running in --quick mode
#
-# Keeping the whitelist updated is desirable, but not required,
+# Keeping the rule list updated is desirable, but not required,
# because unexpected cases where QEMU exits with exitcode=1 will
# just trigger a INFO message.
-# Valid whitelist entry keys:
+# Valid error rule keys:
# * accel: regexp, full match only
# * machine: regexp, full match only
# * device: regexp, full match only
@@ -62,7 +62,7 @@ dbg = logger.debug
# * expected: if True, QEMU is expected to always fail every time
# when testing the corresponding test case
# * loglevel: log level of log output when there's a match.
-ERROR_WHITELIST = [
+ERROR_RULE_LIST = [
# Machines that won't work out of the box:
# MACHINE | ERROR MESSAGE
{'machine':'niagara', 'expected':True}, # Unable to load a firmware for -M niagara
@@ -186,65 +186,65 @@ ERROR_WHITELIST = [
]
-def whitelistTestCaseMatch(wl, t):
- """Check if a test case specification can match a whitelist entry
+def errorRuleTestCaseMatch(rule, t):
+ """Check if a test case specification can match a error rule
- This only checks if a whitelist entry is a candidate match
+ This only checks if a error rule is a candidate match
for a given test case, it won't check if the test case
- results/output match the entry. See whitelistResultMatch().
+ results/output match the rule. See ruleListResultMatch().
"""
- return (('machine' not in wl or
+ return (('machine' not in rule or
'machine' not in t or
- re.match(wl['machine'] + '$', t['machine'])) and
- ('accel' not in wl or
+ re.match(rule['machine'] + '$', t['machine'])) and
+ ('accel' not in rule or
'accel' not in t or
- re.match(wl['accel'] + '$', t['accel'])) and
- ('device' not in wl or
+ re.match(rule['accel'] + '$', t['accel'])) and
+ ('device' not in rule or
'device' not in t or
- re.match(wl['device'] + '$', t['device'])))
+ re.match(rule['device'] + '$', t['device'])))
-def whitelistCandidates(t):
+def ruleListCandidates(t):
"""Generate the list of candidates that can match a test case"""
- for i, wl in enumerate(ERROR_WHITELIST):
- if whitelistTestCaseMatch(wl, t):
- yield (i, wl)
+ for i, rule in enumerate(ERROR_RULE_LIST):
+ if errorRuleTestCaseMatch(rule, t):
+ yield (i, rule)
def findExpectedResult(t):
- """Check if there's an expected=True whitelist entry for a test case
+ """Check if there's an expected=True error rule for a test case
- Returns (i, wl) tuple, where i is the index in
- ERROR_WHITELIST and wl is the whitelist entry itself.
+ Returns (i, rule) tuple, where i is the index in
+ ERROR_RULE_LIST and rule is the error rule itself.
"""
- for i, wl in whitelistCandidates(t):
- if wl.get('expected'):
- return (i, wl)
+ for i, rule in ruleListCandidates(t):
+ if rule.get('expected'):
+ return (i, rule)
-def whitelistResultMatch(wl, r):
- """Check if test case results/output match a whitelist entry
+def ruleListResultMatch(rule, r):
+ """Check if test case results/output match a error rule
It is valid to call this function only if
- whitelistTestCaseMatch() is True for the entry (e.g. on
- entries returned by whitelistCandidates())
+ errorRuleTestCaseMatch() is True for the rule (e.g. on
+ rules returned by ruleListCandidates())
"""
- assert whitelistTestCaseMatch(wl, r['testcase'])
- return ((wl.get('exitcode', 1) is None or
- r['exitcode'] == wl.get('exitcode', 1)) and
- ('log' not in wl or
- re.search(wl['log'], r['log'], re.MULTILINE)))
+ assert errorRuleTestCaseMatch(rule, r['testcase'])
+ return ((rule.get('exitcode', 1) is None or
+ r['exitcode'] == rule.get('exitcode', 1)) and
+ ('log' not in rule or
+ re.search(rule['log'], r['log'], re.MULTILINE)))
-def checkResultWhitelist(r):
- """Look up whitelist entry for a given test case result
+def checkResultRuleList(r):
+ """Look up error rule for a given test case result
- Returns (i, wl) tuple, where i is the index in
- ERROR_WHITELIST and wl is the whitelist entry itself.
+ Returns (i, rule) tuple, where i is the index in
+ ERROR_RULE_LIST and rule is the error rule itself.
"""
- for i, wl in whitelistCandidates(r['testcase']):
- if whitelistResultMatch(wl, r):
- return i, wl
+ for i, rule in ruleListCandidates(r['testcase']):
+ if ruleListResultMatch(rule, r):
+ return i, rule
raise Exception("this should never happen")
@@ -543,12 +543,12 @@ def main():
break
if f:
- i, wl = checkResultWhitelist(f)
- dbg("testcase: %r, whitelist match: %r", t, wl)
+ i, rule = checkResultRuleList(f)
+ dbg("testcase: %r, rule list match: %r", t, rule)
wl_stats.setdefault(i, []).append(f)
- level = wl.get('loglevel', logging.DEBUG)
+ level = rule.get('loglevel', logging.DEBUG)
logFailure(f, level)
- if wl.get('fatal') or (args.strict and level >= logging.WARN):
+ if rule.get('fatal') or (args.strict and level >= logging.WARN):
fatal_failures.append(f)
else:
dbg("success: %s", formatTestCase(t))
@@ -560,10 +560,10 @@ def main():
logger.info("Skipped %d test cases", skipped)
if args.debug:
- stats = sorted([(len(wl_stats.get(i, [])), wl) for i, wl in
- enumerate(ERROR_WHITELIST)], key=lambda x: x[0])
- for count, wl in stats:
- dbg("whitelist entry stats: %d: %r", count, wl)
+ stats = sorted([(len(wl_stats.get(i, [])), rule) for i, rule in
+ enumerate(ERROR_RULE_LIST)], key=lambda x: x[0])
+ for count, rule in stats:
+ dbg("error rule stats: %d: %r", count, rule)
if fatal_failures:
for f in fatal_failures:
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 20c3a5af3f..6a53446e6a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1033,7 +1033,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"clzero", NULL, "xsaveerptr", NULL,
NULL, NULL, NULL, NULL,
NULL, "wbnoinvd", NULL, NULL,
- "ibpb", NULL, NULL, "amd-stibp",
+ "ibpb", NULL, "ibrs", "amd-stibp",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
"amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL,
@@ -1798,6 +1798,56 @@ static CPUCaches epyc_rome_cache_info = {
},
};
+static CPUCaches epyc_milan_cache_info = {
+ .l1d_cache = &(CPUCacheInfo) {
+ .type = DATA_CACHE,
+ .level = 1,
+ .size = 32 * KiB,
+ .line_size = 64,
+ .associativity = 8,
+ .partitions = 1,
+ .sets = 64,
+ .lines_per_tag = 1,
+ .self_init = 1,
+ .no_invd_sharing = true,
+ },
+ .l1i_cache = &(CPUCacheInfo) {
+ .type = INSTRUCTION_CACHE,
+ .level = 1,
+ .size = 32 * KiB,
+ .line_size = 64,
+ .associativity = 8,
+ .partitions = 1,
+ .sets = 64,
+ .lines_per_tag = 1,
+ .self_init = 1,
+ .no_invd_sharing = true,
+ },
+ .l2_cache = &(CPUCacheInfo) {
+ .type = UNIFIED_CACHE,
+ .level = 2,
+ .size = 512 * KiB,
+ .line_size = 64,
+ .associativity = 8,
+ .partitions = 1,
+ .sets = 1024,
+ .lines_per_tag = 1,
+ },
+ .l3_cache = &(CPUCacheInfo) {
+ .type = UNIFIED_CACHE,
+ .level = 3,
+ .size = 32 * MiB,
+ .line_size = 64,
+ .associativity = 16,
+ .partitions = 1,
+ .sets = 32768,
+ .lines_per_tag = 1,
+ .self_init = true,
+ .inclusive = true,
+ .complex_indexing = true,
+ },
+};
+
/* The following VMX features are not supported by KVM and are left out in the
* CPU definitions:
*
@@ -4130,6 +4180,61 @@ static X86CPUDefinition builtin_x86_defs[] = {
.model_id = "AMD EPYC-Rome Processor",
.cache_info = &epyc_rome_cache_info,
},
+ {
+ .name = "EPYC-Milan",
+ .level = 0xd,
+ .vendor = CPUID_VENDOR_AMD,
+ .family = 25,
+ .model = 1,
+ .stepping = 1,
+ .features[FEAT_1_EDX] =
+ CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
+ CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
+ CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
+ CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
+ CPUID_VME | CPUID_FP87,
+ .features[FEAT_1_ECX] =
+ CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
+ CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
+ CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
+ CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
+ CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
+ CPUID_EXT_PCID,
+ .features[FEAT_8000_0001_EDX] =
+ CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
+ CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
+ CPUID_EXT2_SYSCALL,
+ .features[FEAT_8000_0001_ECX] =
+ CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
+ CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
+ CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
+ CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE,
+ .features[FEAT_8000_0008_EBX] =
+ CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR |
+ CPUID_8000_0008_EBX_WBNOINVD | CPUID_8000_0008_EBX_IBPB |
+ CPUID_8000_0008_EBX_IBRS | CPUID_8000_0008_EBX_STIBP |
+ CPUID_8000_0008_EBX_AMD_SSBD,
+ .features[FEAT_7_0_EBX] =
+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
+ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
+ CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
+ CPUID_7_0_EBX_SHA_NI | CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_ERMS |
+ CPUID_7_0_EBX_INVPCID,
+ .features[FEAT_7_0_ECX] =
+ CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_PKU,
+ .features[FEAT_7_0_EDX] =
+ CPUID_7_0_EDX_FSRM,
+ .features[FEAT_XSAVE] =
+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
+ .features[FEAT_SVM] =
+ CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE | CPUID_SVM_SVME_ADDR_CHK,
+ .xlevel = 0x8000001E,
+ .model_id = "AMD EPYC-Milan Processor",
+ .cache_info = &epyc_milan_cache_info,
+ },
};
/* KVM-specific features that are automatically added/removed
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 82c1ac00ef..8be39cfb62 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -817,8 +817,12 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_8000_0008_EBX_WBNOINVD (1U << 9)
/* Indirect Branch Prediction Barrier */
#define CPUID_8000_0008_EBX_IBPB (1U << 12)
+/* Indirect Branch Restricted Speculation */
+#define CPUID_8000_0008_EBX_IBRS (1U << 14)
/* Single Thread Indirect Branch Predictors */
#define CPUID_8000_0008_EBX_STIBP (1U << 15)
+/* Speculative Store Bypass Disable */
+#define CPUID_8000_0008_EBX_AMD_SSBD (1U << 24)
#define CPUID_XSAVE_XSAVEOPT (1U << 0)
#define CPUID_XSAVE_XSAVEC (1U << 1)