Machine and x86 queue, 2021-02-18

Feature:
 * i386: Add the support for AMD EPYC 3rd generation processors
   (Babu Moger)
 
 Bug fix:
 * hostmem: Don't report pmem attribute if unsupported
   (Michal Privoznik)
 
 Cleanup:
 * device-crash-test: Remove problematic language
   (Eduardo Habkost)
 -----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCAAyFiEEWjIv1avE09usz9GqKAeTb5hNxaYFAmAu+aIUHGVoYWJrb3N0
 QHJlZGhhdC5jb20ACgkQKAeTb5hNxaZNoA/+Mq/etOPYqYLWhTZj2tMPeOtatFUx
 IgBM6Jq1TLI2CGuENl/xC4r54yhbskLTrNnXgYQwGcedbtgdWIGMAzYtbu8hgA5L
 rX390DBzI/HYGJtbGB3sj4xQ4jDhTSMUOscBiWuSBksJ6wc+KCZ37h7aHYMAu37Q
 zsDpYpTeayj8gkUm5X9aV4D8w1Y0qn79QubOUaLq3L+jRz1Tyvs3u8e6os+8oX9u
 GxRISieKHFbwO8tWJTU10XqZ2K0pAYXdMBESdkU0Rf4k2LiiaEVpVA6vXjD5eGXG
 UPJeO1/jBxOX284suh33i0MisPXJeHef002vEuY00zeeY62l6ot1U7qdFub+rYpK
 Zl0LA6ATzmFJJ3hxx4pvrdaCQ5MiauDcOiLWP3MB2MBQ1MQxOEV5RTzQbjc6OHW7
 66aw/1FBuLyhzssZsb3hwM46P2TmBGNbNKnKA6G/MLQnG58GZHYlF6ic6FFMFXj7
 dDL62a5rxkR4/bwfoOLXg0CX5ZdjBmQ4xiOR137tRVo2uJ6WQQs/DMDgN+2pRZNR
 JKx56hSQ7yVfo+fYrrY+zzlntnMFaGKsCftPgL69LXyR47yYPFc42ToGExDLN3Fo
 3kUvf+tkecRxaqYQjSze85kJrAEHXGxhmNu5pe0O2kAsNPeYR74d8MweMRnw6t+C
 nHgiRm3cxOL1mxU=
 =K6mm
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/ehabkost-gl/tags/machine-next-pull-request' into staging

Machine and x86 queue, 2021-02-18

Feature:
* i386: Add the support for AMD EPYC 3rd generation processors
  (Babu Moger)

Bug fix:
* hostmem: Don't report pmem attribute if unsupported
  (Michal Privoznik)

Cleanup:
* device-crash-test: Remove problematic language
  (Eduardo Habkost)

# gpg: Signature made Thu 18 Feb 2021 23:34:58 GMT
# gpg:                using RSA key 5A322FD5ABC4D3DBACCFD1AA2807936F984DC5A6
# gpg:                issuer "ehabkost@redhat.com"
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>" [full]
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost-gl/tags/machine-next-pull-request:
  hostmem: Don't report pmem attribute if unsupported
  device-crash-test: Remove problematic language
  i386: Add the support for AMD EPYC 3rd generation processors

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-02-19 10:59:04 +00:00
commit 6de76c5f32
4 changed files with 162 additions and 58 deletions

View File

@ -124,6 +124,7 @@ static void file_memory_backend_set_align(Object *o, Visitor *v,
fb->align = val; fb->align = val;
} }
#ifdef CONFIG_LIBPMEM
static bool file_memory_backend_get_pmem(Object *o, Error **errp) static bool file_memory_backend_get_pmem(Object *o, Error **errp)
{ {
return MEMORY_BACKEND_FILE(o)->is_pmem; 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; 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; fb->is_pmem = value;
} }
#endif /* CONFIG_LIBPMEM */
static bool file_memory_backend_get_readonly(Object *obj, Error **errp) 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_get_align,
file_memory_backend_set_align, file_memory_backend_set_align,
NULL, NULL); NULL, NULL);
#ifdef CONFIG_LIBPMEM
object_class_property_add_bool(oc, "pmem", object_class_property_add_bool(oc, "pmem",
file_memory_backend_get_pmem, file_memory_backend_set_pmem); file_memory_backend_get_pmem, file_memory_backend_set_pmem);
#endif
object_class_property_add_bool(oc, "readonly", object_class_property_add_bool(oc, "readonly",
file_memory_backend_get_readonly, file_memory_backend_get_readonly,
file_memory_backend_set_readonly); file_memory_backend_set_readonly);

View File

@ -41,18 +41,18 @@ logger = logging.getLogger('device-crash-test')
dbg = logger.debug dbg = logger.debug
# Purposes of the following whitelist: # Purposes of the following rule list:
# * Avoiding verbose log messages when we find known non-fatal # * Avoiding verbose log messages when we find known non-fatal
# (exitcode=1) errors # (exitcode=1) errors
# * Avoiding fatal errors when we find known crashes # * Avoiding fatal errors when we find known crashes
# * Skipping machines/devices that are known not to work out of # * Skipping machines/devices that are known not to work out of
# the box, when running in --quick mode # 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 # because unexpected cases where QEMU exits with exitcode=1 will
# just trigger a INFO message. # just trigger a INFO message.
# Valid whitelist entry keys: # Valid error rule keys:
# * accel: regexp, full match only # * accel: regexp, full match only
# * machine: regexp, full match only # * machine: regexp, full match only
# * device: 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 # * expected: if True, QEMU is expected to always fail every time
# when testing the corresponding test case # when testing the corresponding test case
# * loglevel: log level of log output when there's a match. # * 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: # Machines that won't work out of the box:
# MACHINE | ERROR MESSAGE # MACHINE | ERROR MESSAGE
{'machine':'niagara', 'expected':True}, # Unable to load a firmware for -M niagara {'machine':'niagara', 'expected':True}, # Unable to load a firmware for -M niagara
@ -186,65 +186,65 @@ ERROR_WHITELIST = [
] ]
def whitelistTestCaseMatch(wl, t): def errorRuleTestCaseMatch(rule, t):
"""Check if a test case specification can match a whitelist entry """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 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 'machine' not in t or
re.match(wl['machine'] + '$', t['machine'])) and re.match(rule['machine'] + '$', t['machine'])) and
('accel' not in wl or ('accel' not in rule or
'accel' not in t or 'accel' not in t or
re.match(wl['accel'] + '$', t['accel'])) and re.match(rule['accel'] + '$', t['accel'])) and
('device' not in wl or ('device' not in rule or
'device' not in t 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""" """Generate the list of candidates that can match a test case"""
for i, wl in enumerate(ERROR_WHITELIST): for i, rule in enumerate(ERROR_RULE_LIST):
if whitelistTestCaseMatch(wl, t): if errorRuleTestCaseMatch(rule, t):
yield (i, wl) yield (i, rule)
def findExpectedResult(t): 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 Returns (i, rule) tuple, where i is the index in
ERROR_WHITELIST and wl is the whitelist entry itself. ERROR_RULE_LIST and rule is the error rule itself.
""" """
for i, wl in whitelistCandidates(t): for i, rule in ruleListCandidates(t):
if wl.get('expected'): if rule.get('expected'):
return (i, wl) return (i, rule)
def whitelistResultMatch(wl, r): def ruleListResultMatch(rule, r):
"""Check if test case results/output match a whitelist entry """Check if test case results/output match a error rule
It is valid to call this function only if It is valid to call this function only if
whitelistTestCaseMatch() is True for the entry (e.g. on errorRuleTestCaseMatch() is True for the rule (e.g. on
entries returned by whitelistCandidates()) rules returned by ruleListCandidates())
""" """
assert whitelistTestCaseMatch(wl, r['testcase']) assert errorRuleTestCaseMatch(rule, r['testcase'])
return ((wl.get('exitcode', 1) is None or return ((rule.get('exitcode', 1) is None or
r['exitcode'] == wl.get('exitcode', 1)) and r['exitcode'] == rule.get('exitcode', 1)) and
('log' not in wl or ('log' not in rule or
re.search(wl['log'], r['log'], re.MULTILINE))) re.search(rule['log'], r['log'], re.MULTILINE)))
def checkResultWhitelist(r): def checkResultRuleList(r):
"""Look up whitelist entry for a given test case result """Look up error rule for a given test case result
Returns (i, wl) tuple, where i is the index in Returns (i, rule) tuple, where i is the index in
ERROR_WHITELIST and wl is the whitelist entry itself. ERROR_RULE_LIST and rule is the error rule itself.
""" """
for i, wl in whitelistCandidates(r['testcase']): for i, rule in ruleListCandidates(r['testcase']):
if whitelistResultMatch(wl, r): if ruleListResultMatch(rule, r):
return i, wl return i, rule
raise Exception("this should never happen") raise Exception("this should never happen")
@ -543,12 +543,12 @@ def main():
break break
if f: if f:
i, wl = checkResultWhitelist(f) i, rule = checkResultRuleList(f)
dbg("testcase: %r, whitelist match: %r", t, wl) dbg("testcase: %r, rule list match: %r", t, rule)
wl_stats.setdefault(i, []).append(f) wl_stats.setdefault(i, []).append(f)
level = wl.get('loglevel', logging.DEBUG) level = rule.get('loglevel', logging.DEBUG)
logFailure(f, level) 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) fatal_failures.append(f)
else: else:
dbg("success: %s", formatTestCase(t)) dbg("success: %s", formatTestCase(t))
@ -560,10 +560,10 @@ def main():
logger.info("Skipped %d test cases", skipped) logger.info("Skipped %d test cases", skipped)
if args.debug: if args.debug:
stats = sorted([(len(wl_stats.get(i, [])), wl) for i, wl in stats = sorted([(len(wl_stats.get(i, [])), rule) for i, rule in
enumerate(ERROR_WHITELIST)], key=lambda x: x[0]) enumerate(ERROR_RULE_LIST)], key=lambda x: x[0])
for count, wl in stats: for count, rule in stats:
dbg("whitelist entry stats: %d: %r", count, wl) dbg("error rule stats: %d: %r", count, rule)
if fatal_failures: if fatal_failures:
for f in fatal_failures: for f in fatal_failures:

View File

@ -1033,7 +1033,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"clzero", NULL, "xsaveerptr", NULL, "clzero", NULL, "xsaveerptr", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, "wbnoinvd", NULL, NULL, NULL, "wbnoinvd", NULL, NULL,
"ibpb", NULL, NULL, "amd-stibp", "ibpb", NULL, "ibrs", "amd-stibp",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"amd-ssbd", "virt-ssbd", "amd-no-ssb", 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 /* The following VMX features are not supported by KVM and are left out in the
* CPU definitions: * CPU definitions:
* *
@ -4130,6 +4180,61 @@ static X86CPUDefinition builtin_x86_defs[] = {
.model_id = "AMD EPYC-Rome Processor", .model_id = "AMD EPYC-Rome Processor",
.cache_info = &epyc_rome_cache_info, .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 /* KVM-specific features that are automatically added/removed

View File

@ -817,8 +817,12 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_8000_0008_EBX_WBNOINVD (1U << 9) #define CPUID_8000_0008_EBX_WBNOINVD (1U << 9)
/* Indirect Branch Prediction Barrier */ /* Indirect Branch Prediction Barrier */
#define CPUID_8000_0008_EBX_IBPB (1U << 12) #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 */ /* Single Thread Indirect Branch Predictors */
#define CPUID_8000_0008_EBX_STIBP (1U << 15) #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_XSAVEOPT (1U << 0)
#define CPUID_XSAVE_XSAVEC (1U << 1) #define CPUID_XSAVE_XSAVEC (1U << 1)