mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210119-1' into staging
target-arm queue: * Implement IMPDEF pauth algorithm * Support ARMv8.4-SEL2 * Fix bug where we were truncating predicate vector lengths in SVE insns * npcm7xx_adc-test: Fix memleak in adc_qom_set * target/arm/m_helper: Silence GCC 10 maybe-uninitialized error * docs: Build and install all the docs in a single manual # gpg: Signature made Tue 19 Jan 2021 15:46:34 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20210119-1: (29 commits) docs: Build and install all the docs in a single manual target/arm/m_helper: Silence GCC 10 maybe-uninitialized error npcm7xx_adc-test: Fix memleak in adc_qom_set target/arm: Update REV, PUNPK for pred_desc target/arm: Update ZIP, UZP, TRN for pred_desc target/arm: Update PFIRST, PNEXT for pred_desc target/arm: Introduce PREDDESC field definitions target/arm: refactor vae1_tlbmask() target/arm: enable Secure EL2 in max CPU target/arm: Implement SCR_EL2.EEL2 target/arm: revector to run-time pick target EL target/arm: set HPFAR_EL2.NS on secure stage 2 faults target/arm: secure stage 2 translation regime target/arm: generalize 2-stage page-walk condition target/arm: translate NS bit in page-walks target/arm: do S1_ptw_translate() before address space lookup target/arm: handle VMID change in secure state target/arm: add ARMv8.4-SEL2 system registers target/arm: add MMU stage 1 for Secure EL2 target/arm: add 64-bit S-EL2 to EL exception table ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+2
-2
@@ -622,8 +622,8 @@ pages:
|
||||
-t "Welcome to the QEMU sourcecode"
|
||||
- mv HTML public/src
|
||||
# Project documentation
|
||||
- mv build/docs/index.html public/
|
||||
- for i in devel interop specs system tools user ; do mv build/docs/$i public/ ; done
|
||||
- make -C build install DESTDIR=$(pwd)/temp-install
|
||||
- mv temp-install/usr/local/share/doc/qemu/* public/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
|
||||
+45
-1
@@ -224,7 +224,51 @@ latex_documents = [
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
# Individual manual/conf.py can override this to create man pages
|
||||
man_pages = []
|
||||
man_pages = [
|
||||
('interop/qemu-ga', 'qemu-ga',
|
||||
'QEMU Guest Agent',
|
||||
['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8),
|
||||
('interop/qemu-ga-ref', 'qemu-ga-ref',
|
||||
'QEMU Guest Agent Protocol Reference',
|
||||
[], 7),
|
||||
('interop/qemu-qmp-ref', 'qemu-qmp-ref',
|
||||
'QEMU QMP Reference Manual',
|
||||
[], 7),
|
||||
('interop/qemu-storage-daemon-qmp-ref', 'qemu-storage-daemon-qmp-ref',
|
||||
'QEMU Storage Daemon QMP Reference Manual',
|
||||
[], 7),
|
||||
('system/qemu-manpage', 'qemu',
|
||||
'QEMU User Documentation',
|
||||
['Fabrice Bellard'], 1),
|
||||
('system/qemu-block-drivers', 'qemu-block-drivers',
|
||||
'QEMU block drivers reference',
|
||||
['Fabrice Bellard and the QEMU Project developers'], 7),
|
||||
('system/qemu-cpu-models', 'qemu-cpu-models',
|
||||
'QEMU CPU Models',
|
||||
['The QEMU Project developers'], 7),
|
||||
('tools/qemu-img', 'qemu-img',
|
||||
'QEMU disk image utility',
|
||||
['Fabrice Bellard'], 1),
|
||||
('tools/qemu-nbd', 'qemu-nbd',
|
||||
'QEMU Disk Network Block Device Server',
|
||||
['Anthony Liguori <anthony@codemonkey.ws>'], 8),
|
||||
('tools/qemu-pr-helper', 'qemu-pr-helper',
|
||||
'QEMU persistent reservation helper',
|
||||
[], 8),
|
||||
('tools/qemu-storage-daemon', 'qemu-storage-daemon',
|
||||
'QEMU storage daemon',
|
||||
[], 1),
|
||||
('tools/qemu-trace-stap', 'qemu-trace-stap',
|
||||
'QEMU SystemTap trace tool',
|
||||
[], 1),
|
||||
('tools/virtfs-proxy-helper', 'virtfs-proxy-helper',
|
||||
'QEMU 9p virtfs proxy filesystem helper',
|
||||
['M. Mohan Kumar'], 1),
|
||||
('tools/virtiofsd', 'virtiofsd',
|
||||
'QEMU virtio-fs shared file system daemon',
|
||||
['Stefan Hajnoczi <stefanha@redhat.com>',
|
||||
'Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>'], 1),
|
||||
]
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file for the 'devel' manual.
|
||||
#
|
||||
# This includes the top level conf file and then makes any necessary tweaks.
|
||||
import sys
|
||||
import os
|
||||
|
||||
qemu_docdir = os.path.abspath("..")
|
||||
parent_config = os.path.join(qemu_docdir, "conf.py")
|
||||
exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
|
||||
|
||||
# This slightly misuses the 'description', but is the best way to get
|
||||
# the manual title to appear in the sidebar.
|
||||
html_theme_options['description'] = u'Developer''s Guide'
|
||||
@@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>QEMU @VERSION@ Documentation</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>QEMU @VERSION@ Documentation</h1>
|
||||
<ul>
|
||||
<li><a href="system/index.html">System Emulation User's Guide</a></li>
|
||||
<li><a href="user/index.html">User Mode Emulation User's Guide</a></li>
|
||||
<li><a href="tools/index.html">Tools Guide</a></li>
|
||||
<li><a href="interop/index.html">System Emulation Management and Interoperability Guide</a></li>
|
||||
<li><a href="specs/index.html">System Emulation Guest Hardware Specifications</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,28 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file for the 'interop' manual.
|
||||
#
|
||||
# This includes the top level conf file and then makes any necessary tweaks.
|
||||
import sys
|
||||
import os
|
||||
|
||||
qemu_docdir = os.path.abspath("..")
|
||||
parent_config = os.path.join(qemu_docdir, "conf.py")
|
||||
exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
|
||||
|
||||
# This slightly misuses the 'description', but is the best way to get
|
||||
# the manual title to appear in the sidebar.
|
||||
html_theme_options['description'] = u'System Emulation Management and Interoperability Guide'
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('qemu-ga', 'qemu-ga', u'QEMU Guest Agent',
|
||||
['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8),
|
||||
('qemu-ga-ref', 'qemu-ga-ref', 'QEMU Guest Agent Protocol Reference',
|
||||
[], 7),
|
||||
('qemu-qmp-ref', 'qemu-qmp-ref', 'QEMU QMP Reference Manual',
|
||||
[], 7),
|
||||
('qemu-storage-daemon-qmp-ref', 'qemu-storage-daemon-qmp-ref',
|
||||
'QEMU Storage Daemon QMP Reference Manual', [], 7),
|
||||
]
|
||||
+25
-39
@@ -46,19 +46,11 @@ if build_docs
|
||||
meson.source_root() / 'docs/sphinx/qmp_lexer.py',
|
||||
qapi_gen_depends ]
|
||||
|
||||
configure_file(output: 'index.html',
|
||||
input: files('index.html.in'),
|
||||
configuration: {'VERSION': meson.project_version()},
|
||||
install_dir: qemu_docdir)
|
||||
manuals = [ 'devel', 'interop', 'tools', 'specs', 'system', 'user' ]
|
||||
man_pages = {
|
||||
'interop' : {
|
||||
'qemu-ga.8': (have_tools ? 'man8' : ''),
|
||||
'qemu-ga-ref.7': 'man7',
|
||||
'qemu-qmp-ref.7': 'man7',
|
||||
'qemu-storage-daemon-qmp-ref.7': (have_tools ? 'man7' : ''),
|
||||
},
|
||||
'tools': {
|
||||
'qemu-img.1': (have_tools ? 'man1' : ''),
|
||||
'qemu-nbd.8': (have_tools ? 'man8' : ''),
|
||||
'qemu-pr-helper.8': (have_tools ? 'man8' : ''),
|
||||
@@ -66,53 +58,47 @@ if build_docs
|
||||
'qemu-trace-stap.1': (config_host.has_key('CONFIG_TRACE_SYSTEMTAP') ? 'man1' : ''),
|
||||
'virtfs-proxy-helper.1': (have_virtfs_proxy_helper ? 'man1' : ''),
|
||||
'virtiofsd.1': (have_virtiofsd ? 'man1' : ''),
|
||||
},
|
||||
'system': {
|
||||
'qemu.1': 'man1',
|
||||
'qemu-block-drivers.7': 'man7',
|
||||
'qemu-cpu-models.7': 'man7'
|
||||
},
|
||||
}
|
||||
|
||||
sphinxdocs = []
|
||||
sphinxmans = []
|
||||
foreach manual : manuals
|
||||
private_dir = meson.current_build_dir() / (manual + '.p')
|
||||
output_dir = meson.current_build_dir() / manual
|
||||
input_dir = meson.current_source_dir() / manual
|
||||
|
||||
this_manual = custom_target(manual + ' manual',
|
||||
private_dir = meson.current_build_dir() / 'manual.p'
|
||||
output_dir = meson.current_build_dir() / 'manual'
|
||||
input_dir = meson.current_source_dir()
|
||||
|
||||
this_manual = custom_target('QEMU manual',
|
||||
build_by_default: build_docs,
|
||||
output: [manual + '.stamp'],
|
||||
input: [files('conf.py'), files(manual / 'conf.py')],
|
||||
depfile: manual + '.d',
|
||||
output: 'docs.stamp',
|
||||
input: files('conf.py'),
|
||||
depfile: 'docs.d',
|
||||
depend_files: sphinx_extn_depends,
|
||||
command: [SPHINX_ARGS, '-Ddepfile=@DEPFILE@',
|
||||
'-Ddepfile_stamp=@OUTPUT0@',
|
||||
'-b', 'html', '-d', private_dir,
|
||||
input_dir, output_dir])
|
||||
sphinxdocs += this_manual
|
||||
if build_docs and manual != 'devel'
|
||||
install_subdir(output_dir, install_dir: qemu_docdir)
|
||||
endif
|
||||
sphinxdocs += this_manual
|
||||
install_subdir(output_dir, install_dir: qemu_docdir, strip_directory: true)
|
||||
|
||||
these_man_pages = []
|
||||
install_dirs = []
|
||||
foreach page, section : man_pages.get(manual, {})
|
||||
these_man_pages += page
|
||||
install_dirs += section == '' ? false : get_option('mandir') / section
|
||||
endforeach
|
||||
if these_man_pages.length() > 0
|
||||
sphinxmans += custom_target(manual + ' man pages',
|
||||
build_by_default: build_docs,
|
||||
output: these_man_pages,
|
||||
input: this_manual,
|
||||
install: build_docs,
|
||||
install_dir: install_dirs,
|
||||
command: [SPHINX_ARGS, '-b', 'man', '-d', private_dir,
|
||||
input_dir, meson.current_build_dir()])
|
||||
endif
|
||||
these_man_pages = []
|
||||
install_dirs = []
|
||||
foreach page, section : man_pages
|
||||
these_man_pages += page
|
||||
install_dirs += section == '' ? false : get_option('mandir') / section
|
||||
endforeach
|
||||
|
||||
sphinxmans += custom_target('QEMU man pages',
|
||||
build_by_default: build_docs,
|
||||
output: these_man_pages,
|
||||
input: this_manual,
|
||||
install: build_docs,
|
||||
install_dir: install_dirs,
|
||||
command: [SPHINX_ARGS, '-b', 'man', '-d', private_dir,
|
||||
input_dir, meson.current_build_dir()])
|
||||
|
||||
alias_target('sphinxdocs', sphinxdocs)
|
||||
alias_target('html', sphinxdocs)
|
||||
alias_target('man', sphinxmans)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file for the 'specs' manual.
|
||||
#
|
||||
# This includes the top level conf file and then makes any necessary tweaks.
|
||||
import sys
|
||||
import os
|
||||
|
||||
qemu_docdir = os.path.abspath("..")
|
||||
parent_config = os.path.join(qemu_docdir, "conf.py")
|
||||
exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
|
||||
|
||||
# This slightly misuses the 'description', but is the best way to get
|
||||
# the manual title to appear in the sidebar.
|
||||
html_theme_options['description'] = \
|
||||
u'System Emulation Guest Hardware Specifications'
|
||||
@@ -211,6 +211,27 @@ the list of KVM VCPU features and their descriptions.
|
||||
influence the guest scheduler behavior and/or be
|
||||
exposed to the guest userspace.
|
||||
|
||||
TCG VCPU Features
|
||||
=================
|
||||
|
||||
TCG VCPU features are CPU features that are specific to TCG.
|
||||
Below is the list of TCG VCPU features and their descriptions.
|
||||
|
||||
pauth Enable or disable `FEAT_Pauth`, pointer
|
||||
authentication. By default, the feature is
|
||||
enabled with `-cpu max`.
|
||||
|
||||
pauth-impdef When `FEAT_Pauth` is enabled, either the
|
||||
*impdef* (Implementation Defined) algorithm
|
||||
is enabled or the *architected* QARMA algorithm
|
||||
is enabled. By default the impdef algorithm
|
||||
is disabled, and QARMA is enabled.
|
||||
|
||||
The architected QARMA algorithm has good
|
||||
cryptographic properties, but can be quite slow
|
||||
to emulate. The impdef algorithm used by QEMU
|
||||
is non-cryptographic but significantly faster.
|
||||
|
||||
SVE CPU Properties
|
||||
==================
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file for the 'system' manual.
|
||||
#
|
||||
# This includes the top level conf file and then makes any necessary tweaks.
|
||||
import sys
|
||||
import os
|
||||
|
||||
qemu_docdir = os.path.abspath("..")
|
||||
parent_config = os.path.join(qemu_docdir, "conf.py")
|
||||
exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
|
||||
|
||||
# This slightly misuses the 'description', but is the best way to get
|
||||
# the manual title to appear in the sidebar.
|
||||
html_theme_options['description'] = u'System Emulation User''s Guide'
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('qemu-manpage', 'qemu', u'QEMU User Documentation',
|
||||
['Fabrice Bellard'], 1),
|
||||
('qemu-block-drivers', 'qemu-block-drivers',
|
||||
u'QEMU block drivers reference',
|
||||
['Fabrice Bellard and the QEMU Project developers'], 7),
|
||||
('qemu-cpu-models', 'qemu-cpu-models',
|
||||
u'QEMU CPU Models',
|
||||
['The QEMU Project developers'], 7)
|
||||
]
|
||||
@@ -1,37 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file for the 'tools' manual.
|
||||
#
|
||||
# This includes the top level conf file and then makes any necessary tweaks.
|
||||
import sys
|
||||
import os
|
||||
|
||||
qemu_docdir = os.path.abspath("..")
|
||||
parent_config = os.path.join(qemu_docdir, "conf.py")
|
||||
exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
|
||||
|
||||
# This slightly misuses the 'description', but is the best way to get
|
||||
# the manual title to appear in the sidebar.
|
||||
html_theme_options['description'] = \
|
||||
u'Tools Guide'
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('qemu-img', 'qemu-img', u'QEMU disk image utility',
|
||||
['Fabrice Bellard'], 1),
|
||||
('qemu-storage-daemon', 'qemu-storage-daemon', u'QEMU storage daemon',
|
||||
[], 1),
|
||||
('qemu-nbd', 'qemu-nbd', u'QEMU Disk Network Block Device Server',
|
||||
['Anthony Liguori <anthony@codemonkey.ws>'], 8),
|
||||
('qemu-pr-helper', 'qemu-pr-helper', 'QEMU persistent reservation helper',
|
||||
[], 8),
|
||||
('qemu-trace-stap', 'qemu-trace-stap', u'QEMU SystemTap trace tool',
|
||||
[], 1),
|
||||
('virtfs-proxy-helper', 'virtfs-proxy-helper',
|
||||
u'QEMU 9p virtfs proxy filesystem helper',
|
||||
['M. Mohan Kumar'], 1),
|
||||
('virtiofsd', 'virtiofsd', u'QEMU virtio-fs shared file system daemon',
|
||||
['Stefan Hajnoczi <stefanha@redhat.com>',
|
||||
'Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>'], 1),
|
||||
]
|
||||
@@ -1,15 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# QEMU documentation build configuration file for the 'user' manual.
|
||||
#
|
||||
# This includes the top level conf file and then makes any necessary tweaks.
|
||||
import sys
|
||||
import os
|
||||
|
||||
qemu_docdir = os.path.abspath("..")
|
||||
parent_config = os.path.join(qemu_docdir, "conf.py")
|
||||
exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
|
||||
|
||||
# This slightly misuses the 'description', but is the best way to get
|
||||
# the manual title to appear in the sidebar.
|
||||
html_theme_options['description'] = u'User Mode Emulation User''s Guide'
|
||||
@@ -119,4 +119,102 @@ static inline uint32_t qemu_xxhash6(uint64_t ab, uint64_t cd, uint32_t e,
|
||||
return qemu_xxhash7(ab, cd, e, f, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Component parts of the XXH64 algorithm from
|
||||
* https://github.com/Cyan4973/xxHash/blob/v0.8.0/xxhash.h
|
||||
*
|
||||
* The complete algorithm looks like
|
||||
*
|
||||
* i = 0;
|
||||
* if (len >= 32) {
|
||||
* v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
|
||||
* v2 = seed + XXH_PRIME64_2;
|
||||
* v3 = seed + 0;
|
||||
* v4 = seed - XXH_PRIME64_1;
|
||||
* do {
|
||||
* v1 = XXH64_round(v1, get64bits(input + i));
|
||||
* v2 = XXH64_round(v2, get64bits(input + i + 8));
|
||||
* v3 = XXH64_round(v3, get64bits(input + i + 16));
|
||||
* v4 = XXH64_round(v4, get64bits(input + i + 24));
|
||||
* } while ((i += 32) <= len);
|
||||
* h64 = XXH64_mergerounds(v1, v2, v3, v4);
|
||||
* } else {
|
||||
* h64 = seed + XXH_PRIME64_5;
|
||||
* }
|
||||
* h64 += len;
|
||||
*
|
||||
* for (; i + 8 <= len; i += 8) {
|
||||
* h64 ^= XXH64_round(0, get64bits(input + i));
|
||||
* h64 = rol64(h64, 27) * XXH_PRIME64_1 + XXH_PRIME64_4;
|
||||
* }
|
||||
* for (; i + 4 <= len; i += 4) {
|
||||
* h64 ^= get32bits(input + i) * PRIME64_1;
|
||||
* h64 = rol64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
|
||||
* }
|
||||
* for (; i < len; i += 1) {
|
||||
* h64 ^= get8bits(input + i) * XXH_PRIME64_5;
|
||||
* h64 = rol64(h64, 11) * XXH_PRIME64_1;
|
||||
* }
|
||||
*
|
||||
* return XXH64_avalanche(h64)
|
||||
*
|
||||
* Exposing the pieces instead allows for simplified usage when
|
||||
* the length is a known constant and the inputs are in registers.
|
||||
*/
|
||||
#define XXH_PRIME64_1 0x9E3779B185EBCA87ULL
|
||||
#define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL
|
||||
#define XXH_PRIME64_3 0x165667B19E3779F9ULL
|
||||
#define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL
|
||||
#define XXH_PRIME64_5 0x27D4EB2F165667C5ULL
|
||||
|
||||
static inline uint64_t XXH64_round(uint64_t acc, uint64_t input)
|
||||
{
|
||||
return rol64(acc + input * XXH_PRIME64_2, 31) * XXH_PRIME64_1;
|
||||
}
|
||||
|
||||
static inline uint64_t XXH64_mergeround(uint64_t acc, uint64_t val)
|
||||
{
|
||||
return (acc ^ XXH64_round(0, val)) * XXH_PRIME64_1 + XXH_PRIME64_4;
|
||||
}
|
||||
|
||||
static inline uint64_t XXH64_mergerounds(uint64_t v1, uint64_t v2,
|
||||
uint64_t v3, uint64_t v4)
|
||||
{
|
||||
uint64_t h64;
|
||||
|
||||
h64 = rol64(v1, 1) + rol64(v2, 7) + rol64(v3, 12) + rol64(v4, 18);
|
||||
h64 = XXH64_mergeround(h64, v1);
|
||||
h64 = XXH64_mergeround(h64, v2);
|
||||
h64 = XXH64_mergeround(h64, v3);
|
||||
h64 = XXH64_mergeround(h64, v4);
|
||||
|
||||
return h64;
|
||||
}
|
||||
|
||||
static inline uint64_t XXH64_avalanche(uint64_t h64)
|
||||
{
|
||||
h64 ^= h64 >> 33;
|
||||
h64 *= XXH_PRIME64_2;
|
||||
h64 ^= h64 >> 29;
|
||||
h64 *= XXH_PRIME64_3;
|
||||
h64 ^= h64 >> 32;
|
||||
return h64;
|
||||
}
|
||||
|
||||
static inline uint64_t qemu_xxhash64_4(uint64_t a, uint64_t b,
|
||||
uint64_t c, uint64_t d)
|
||||
{
|
||||
uint64_t v1 = QEMU_XXHASH_SEED + XXH_PRIME64_1 + XXH_PRIME64_2;
|
||||
uint64_t v2 = QEMU_XXHASH_SEED + XXH_PRIME64_2;
|
||||
uint64_t v3 = QEMU_XXHASH_SEED + 0;
|
||||
uint64_t v4 = QEMU_XXHASH_SEED - XXH_PRIME64_1;
|
||||
|
||||
v1 = XXH64_round(v1, a);
|
||||
v2 = XXH64_round(v2, b);
|
||||
v3 = XXH64_round(v3, c);
|
||||
v4 = XXH64_round(v4, d);
|
||||
|
||||
return XXH64_avalanche(XXH64_mergerounds(v1, v2, v3, v4));
|
||||
}
|
||||
|
||||
#endif /* QEMU_XXHASH_H */
|
||||
|
||||
@@ -29,6 +29,6 @@
|
||||
# define TARGET_PAGE_BITS_MIN 10
|
||||
#endif
|
||||
|
||||
#define NB_MMU_MODES 11
|
||||
#define NB_MMU_MODES 15
|
||||
|
||||
#endif
|
||||
|
||||
+18
-5
@@ -451,14 +451,14 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
break;
|
||||
|
||||
case EXCP_VFIQ:
|
||||
if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VFIQs are only taken when hypervized and non-secure. */
|
||||
if (!(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VFIQs are only taken when hypervized. */
|
||||
return false;
|
||||
}
|
||||
return !(env->daif & PSTATE_F);
|
||||
case EXCP_VIRQ:
|
||||
if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VIRQs are only taken when hypervized and non-secure. */
|
||||
if (!(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VIRQs are only taken when hypervized. */
|
||||
return false;
|
||||
}
|
||||
return !(env->daif & PSTATE_I);
|
||||
@@ -480,7 +480,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
* masked from Secure state. The HCR and SCR settings
|
||||
* don't affect the masking logic, only the interrupt routing.
|
||||
*/
|
||||
if (target_el == 3 || !secure) {
|
||||
if (target_el == 3 || !secure || (env->cp15.scr_el3 & SCR_EEL2)) {
|
||||
unmasked = true;
|
||||
}
|
||||
} else {
|
||||
@@ -1320,6 +1320,19 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* KVM does not support modifications to this feature.
|
||||
* We have not registered the cpu properties when KVM
|
||||
* is in use, so the user will not be able to set them.
|
||||
*/
|
||||
if (!kvm_enabled()) {
|
||||
arm_cpu_pauth_finalize(cpu, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kvm_enabled()) {
|
||||
|
||||
+86
-21
@@ -168,6 +168,11 @@ typedef struct {
|
||||
uint32_t base_mask;
|
||||
} TCR;
|
||||
|
||||
#define VTCR_NSW (1u << 29)
|
||||
#define VTCR_NSA (1u << 30)
|
||||
#define VSTCR_SW VTCR_NSW
|
||||
#define VSTCR_SA VTCR_NSA
|
||||
|
||||
/* Define a maximum sized vector register.
|
||||
* For 32-bit, this is a 128-bit NEON/AdvSIMD register.
|
||||
* For 64-bit, this is a 2048-bit SVE register.
|
||||
@@ -197,9 +202,11 @@ typedef struct {
|
||||
#ifdef TARGET_AARCH64
|
||||
# define ARM_MAX_VQ 16
|
||||
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
|
||||
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
|
||||
#else
|
||||
# define ARM_MAX_VQ 1
|
||||
static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
|
||||
static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
|
||||
#endif
|
||||
|
||||
typedef struct ARMVectorReg {
|
||||
@@ -323,9 +330,11 @@ typedef struct CPUARMState {
|
||||
uint64_t ttbr1_el[4];
|
||||
};
|
||||
uint64_t vttbr_el2; /* Virtualization Translation Table Base. */
|
||||
uint64_t vsttbr_el2; /* Secure Virtualization Translation Table. */
|
||||
/* MMU translation table base control. */
|
||||
TCR tcr_el[4];
|
||||
TCR vtcr_el2; /* Virtualization Translation Control. */
|
||||
TCR vstcr_el2; /* Secure Virtualization Translation Control. */
|
||||
uint32_t c2_data; /* MPU data cacheable bits. */
|
||||
uint32_t c2_insn; /* MPU instruction cacheable bits. */
|
||||
union { /* MMU domain access control register
|
||||
@@ -947,6 +956,14 @@ struct ARMCPU {
|
||||
uint64_t reset_cbar;
|
||||
uint32_t reset_auxcr;
|
||||
bool reset_hivecs;
|
||||
|
||||
/*
|
||||
* Intermediate values used during property parsing.
|
||||
* Once finalized, the values should be read from ID_AA64ISAR1.
|
||||
*/
|
||||
bool prop_pauth;
|
||||
bool prop_pauth_impdef;
|
||||
|
||||
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
|
||||
uint32_t dcz_blocksize;
|
||||
uint64_t rvbar;
|
||||
@@ -1467,6 +1484,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
#define HCR_TWEDEN (1ULL << 59)
|
||||
#define HCR_TWEDEL MAKE_64BIT_MASK(60, 4)
|
||||
|
||||
#define HPFAR_NS (1ULL << 63)
|
||||
|
||||
#define SCR_NS (1U << 0)
|
||||
#define SCR_IRQ (1U << 1)
|
||||
#define SCR_FIQ (1U << 2)
|
||||
@@ -2138,6 +2157,21 @@ static inline bool arm_is_secure(CPUARMState *env)
|
||||
return arm_is_secure_below_el3(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the current security state has AArch64 EL2 or AArch32 Hyp.
|
||||
* This corresponds to the pseudocode EL2Enabled()
|
||||
*/
|
||||
static inline bool arm_is_el2_enabled(CPUARMState *env)
|
||||
{
|
||||
if (arm_feature(env, ARM_FEATURE_EL2)) {
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
return (env->cp15.scr_el3 & SCR_EEL2) != 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline bool arm_is_secure_below_el3(CPUARMState *env)
|
||||
{
|
||||
@@ -2148,6 +2182,11 @@ static inline bool arm_is_secure(CPUARMState *env)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool arm_is_el2_enabled(CPUARMState *env)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -2175,7 +2214,8 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
|
||||
return aa64;
|
||||
}
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_EL3)) {
|
||||
if (arm_feature(env, ARM_FEATURE_EL3) &&
|
||||
((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) {
|
||||
aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
|
||||
}
|
||||
|
||||
@@ -2183,7 +2223,7 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
|
||||
return aa64;
|
||||
}
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_EL2) && !arm_is_secure_below_el3(env)) {
|
||||
if (arm_is_el2_enabled(env)) {
|
||||
aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
|
||||
}
|
||||
|
||||
@@ -3022,6 +3062,9 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
|
||||
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
|
||||
#define ARM_MMU_IDX_M 0x40 /* M profile */
|
||||
|
||||
/* Meanings of the bits for A profile mmu idx values */
|
||||
#define ARM_MMU_IDX_A_NS 0x8
|
||||
|
||||
/* Meanings of the bits for M profile mmu idx values */
|
||||
#define ARM_MMU_IDX_M_PRIV 0x1
|
||||
#define ARM_MMU_IDX_M_NEGPRI 0x2
|
||||
@@ -3035,20 +3078,22 @@ typedef enum ARMMMUIdx {
|
||||
/*
|
||||
* A-profile.
|
||||
*/
|
||||
ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE10_0 = 0 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE20_0 = 1 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE10_1 = 2 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE20_2 = 3 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE10_1_PAN = 4 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE20_2_PAN = 5 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE2 = 6 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE3 = 7 | ARM_MMU_IDX_A,
|
||||
|
||||
ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E10_1_PAN = 3 | ARM_MMU_IDX_A,
|
||||
|
||||
ARMMMUIdx_E2 = 4 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E20_2 = 5 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E20_2_PAN = 6 | ARM_MMU_IDX_A,
|
||||
|
||||
ARMMMUIdx_SE10_0 = 7 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE10_1 = 8 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E10_0 = ARMMMUIdx_SE10_0 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E20_0 = ARMMMUIdx_SE20_0 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E10_1 = ARMMMUIdx_SE10_1 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E20_2 = ARMMMUIdx_SE20_2 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E10_1_PAN = ARMMMUIdx_SE10_1_PAN | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E20_2_PAN = ARMMMUIdx_SE20_2_PAN | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E2 = ARMMMUIdx_SE2 | ARM_MMU_IDX_A_NS,
|
||||
|
||||
/*
|
||||
* These are not allocated TLBs and are used only for AT system
|
||||
@@ -3057,6 +3102,9 @@ typedef enum ARMMMUIdx {
|
||||
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_SE0 = 3 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_SE1 = 4 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_SE1_PAN = 5 | ARM_MMU_IDX_NOTLB,
|
||||
/*
|
||||
* Not allocated a TLB: used only for second stage of an S12 page
|
||||
* table walk, or for descriptor loads during first stage of an S1
|
||||
@@ -3064,7 +3112,8 @@ typedef enum ARMMMUIdx {
|
||||
* then various TLB flush insns which currently are no-ops or flush
|
||||
* only stage 1 MMU indexes will need to change to flush stage 2.
|
||||
*/
|
||||
ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage2 = 6 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage2_S = 7 | ARM_MMU_IDX_NOTLB,
|
||||
|
||||
/*
|
||||
* M-profile.
|
||||
@@ -3095,8 +3144,12 @@ typedef enum ARMMMUIdxBit {
|
||||
TO_CORE_BIT(E20_2),
|
||||
TO_CORE_BIT(E20_2_PAN),
|
||||
TO_CORE_BIT(SE10_0),
|
||||
TO_CORE_BIT(SE20_0),
|
||||
TO_CORE_BIT(SE10_1),
|
||||
TO_CORE_BIT(SE20_2),
|
||||
TO_CORE_BIT(SE10_1_PAN),
|
||||
TO_CORE_BIT(SE20_2_PAN),
|
||||
TO_CORE_BIT(SE2),
|
||||
TO_CORE_BIT(SE3),
|
||||
|
||||
TO_CORE_BIT(MUser),
|
||||
@@ -3127,7 +3180,7 @@ static inline int arm_debug_target_el(CPUARMState *env)
|
||||
bool secure = arm_is_secure(env);
|
||||
bool route_to_el2 = false;
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_EL2) && !secure) {
|
||||
if (arm_is_el2_enabled(env)) {
|
||||
route_to_el2 = env->cp15.hcr_el2 & HCR_TGE ||
|
||||
env->cp15.mdcr_el2 & MDCR_TDE;
|
||||
}
|
||||
@@ -3918,10 +3971,8 @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
|
||||
static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
|
||||
{
|
||||
/*
|
||||
* Note that while QEMU will only implement the architected algorithm
|
||||
* QARMA, and thus APA+GPA, the host cpu for kvm may use implementation
|
||||
* defined algorithms, and thus API+GPI, and this predicate controls
|
||||
* migration of the 128-bit keys.
|
||||
* Return true if any form of pauth is enabled, as this
|
||||
* predicate controls migration of the 128-bit keys.
|
||||
*/
|
||||
return (id->id_aa64isar1 &
|
||||
(FIELD_DP64(0, ID_AA64ISAR1, APA, 0xf) |
|
||||
@@ -3930,6 +3981,15 @@ static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
|
||||
FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_pauth_arch(const ARMISARegisters *id)
|
||||
{
|
||||
/*
|
||||
* Return true if pauth is enabled with the architected QARMA algorithm.
|
||||
* QEMU will always set APA+GPA to the same value.
|
||||
*/
|
||||
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
|
||||
@@ -3977,6 +4037,11 @@ static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
|
||||
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
|
||||
|
||||
+47
-18
@@ -28,6 +28,8 @@
|
||||
#include "sysemu/kvm.h"
|
||||
#include "kvm_arm.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
@@ -486,6 +488,12 @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
|
||||
cpu->sve_max_vq = max_vq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that cpu_arm_get/set_sve_vq cannot use the simpler
|
||||
* object_property_add_bool interface because they make use
|
||||
* of the contents of "name" to determine which bit on which
|
||||
* to operate.
|
||||
*/
|
||||
static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
@@ -527,26 +535,17 @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
|
||||
set_bit(vq - 1, cpu->sve_vq_init);
|
||||
}
|
||||
|
||||
static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
static bool cpu_arm_get_sve(Object *obj, Error **errp)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
bool value = cpu_isar_feature(aa64_sve, cpu);
|
||||
|
||||
visit_type_bool(v, name, &value, errp);
|
||||
return cpu_isar_feature(aa64_sve, cpu);
|
||||
}
|
||||
|
||||
static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
bool value;
|
||||
uint64_t t;
|
||||
|
||||
if (!visit_type_bool(v, name, &value, errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
|
||||
error_setg(errp, "'sve' feature not supported by KVM on this host");
|
||||
return;
|
||||
@@ -561,8 +560,7 @@ void aarch64_add_sve_properties(Object *obj)
|
||||
{
|
||||
uint32_t vq;
|
||||
|
||||
object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
|
||||
cpu_arm_set_sve, NULL, NULL);
|
||||
object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve);
|
||||
|
||||
for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
|
||||
char name[8];
|
||||
@@ -572,6 +570,36 @@ void aarch64_add_sve_properties(Object *obj)
|
||||
}
|
||||
}
|
||||
|
||||
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
|
||||
{
|
||||
int arch_val = 0, impdef_val = 0;
|
||||
uint64_t t;
|
||||
|
||||
/* TODO: Handle HaveEnhancedPAC, HaveEnhancedPAC2, HaveFPAC. */
|
||||
if (cpu->prop_pauth) {
|
||||
if (cpu->prop_pauth_impdef) {
|
||||
impdef_val = 1;
|
||||
} else {
|
||||
arch_val = 1;
|
||||
}
|
||||
} else if (cpu->prop_pauth_impdef) {
|
||||
error_setg(errp, "cannot enable pauth-impdef without pauth");
|
||||
error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
|
||||
}
|
||||
|
||||
t = cpu->isar.id_aa64isar1;
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, APA, arch_val);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, arch_val);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, API, impdef_val);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, impdef_val);
|
||||
cpu->isar.id_aa64isar1 = t;
|
||||
}
|
||||
|
||||
static Property arm_cpu_pauth_property =
|
||||
DEFINE_PROP_BOOL("pauth", ARMCPU, prop_pauth, true);
|
||||
static Property arm_cpu_pauth_impdef_property =
|
||||
DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
|
||||
|
||||
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
|
||||
* otherwise, a CPU with as many features enabled as our emulation supports.
|
||||
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
|
||||
@@ -627,10 +655,6 @@ static void aarch64_max_initfn(Object *obj)
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
|
||||
@@ -641,6 +665,7 @@ static void aarch64_max_initfn(Object *obj)
|
||||
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
|
||||
t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
|
||||
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
|
||||
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1);
|
||||
cpu->isar.id_aa64pfr0 = t;
|
||||
|
||||
t = cpu->isar.id_aa64pfr1;
|
||||
@@ -721,6 +746,10 @@ static void aarch64_max_initfn(Object *obj)
|
||||
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
|
||||
cpu->dcz_blocksize = 7; /* 512 bytes */
|
||||
#endif
|
||||
|
||||
/* Default to PAUTH on, with the architected algorithm. */
|
||||
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_property);
|
||||
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
|
||||
}
|
||||
|
||||
aarch64_add_sve_properties(obj);
|
||||
|
||||
@@ -972,8 +972,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
|
||||
if (new_el == -1) {
|
||||
goto illegal_return;
|
||||
}
|
||||
if (new_el > cur_el
|
||||
|| (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
|
||||
if (new_el > cur_el || (new_el == 2 && !arm_is_el2_enabled(env))) {
|
||||
/* Disallow return to an EL which is unimplemented or higher
|
||||
* than the current one.
|
||||
*/
|
||||
@@ -985,11 +984,6 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
|
||||
goto illegal_return;
|
||||
}
|
||||
|
||||
if (new_el == 2 && arm_is_secure_below_el3(env)) {
|
||||
/* Return to the non-existent secure-EL2 */
|
||||
goto illegal_return;
|
||||
}
|
||||
|
||||
if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
|
||||
goto illegal_return;
|
||||
}
|
||||
|
||||
+273
-141
File diff suppressed because it is too large
Load Diff
@@ -593,6 +593,7 @@ typedef enum ARMFaultType {
|
||||
* @s2addr: Address that caused a fault at stage 2
|
||||
* @stage2: True if we faulted at stage 2
|
||||
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
|
||||
* @s1ns: True if we faulted on a non-secure IPA while in secure state
|
||||
* @ea: True if we should set the EA (external abort type) bit in syndrome
|
||||
*/
|
||||
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
|
||||
@@ -603,6 +604,7 @@ struct ARMMMUFaultInfo {
|
||||
int domain;
|
||||
bool stage2;
|
||||
bool s1ptw;
|
||||
bool s1ns;
|
||||
bool ea;
|
||||
};
|
||||
|
||||
@@ -851,6 +853,9 @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
|
||||
case ARMMMUIdx_Stage1_E0:
|
||||
case ARMMMUIdx_Stage1_E1:
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_Stage1_SE0:
|
||||
case ARMMMUIdx_Stage1_SE1:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
case ARMMMUIdx_E10_0:
|
||||
case ARMMMUIdx_E10_1:
|
||||
case ARMMMUIdx_E10_1_PAN:
|
||||
@@ -860,6 +865,9 @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
|
||||
case ARMMMUIdx_SE10_0:
|
||||
case ARMMMUIdx_SE10_1:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
case ARMMMUIdx_SE20_0:
|
||||
case ARMMMUIdx_SE20_2:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -890,6 +898,14 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
case ARMMMUIdx_SE10_0:
|
||||
case ARMMMUIdx_SE10_1:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
case ARMMMUIdx_SE20_0:
|
||||
case ARMMMUIdx_SE20_2:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
case ARMMMUIdx_Stage1_SE0:
|
||||
case ARMMMUIdx_Stage1_SE1:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
case ARMMMUIdx_SE2:
|
||||
case ARMMMUIdx_Stage2_S:
|
||||
case ARMMMUIdx_MSPrivNegPri:
|
||||
case ARMMMUIdx_MSUserNegPri:
|
||||
case ARMMMUIdx_MSPriv:
|
||||
@@ -904,9 +920,11 @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
{
|
||||
switch (mmu_idx) {
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
case ARMMMUIdx_E10_1_PAN:
|
||||
case ARMMMUIdx_E20_2_PAN:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -917,21 +935,29 @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
{
|
||||
switch (mmu_idx) {
|
||||
case ARMMMUIdx_SE20_0:
|
||||
case ARMMMUIdx_SE20_2:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
case ARMMMUIdx_E20_0:
|
||||
case ARMMMUIdx_E20_2:
|
||||
case ARMMMUIdx_E20_2_PAN:
|
||||
case ARMMMUIdx_Stage2:
|
||||
case ARMMMUIdx_Stage2_S:
|
||||
case ARMMMUIdx_SE2:
|
||||
case ARMMMUIdx_E2:
|
||||
return 2;
|
||||
case ARMMMUIdx_SE3:
|
||||
return 3;
|
||||
case ARMMMUIdx_SE10_0:
|
||||
case ARMMMUIdx_Stage1_SE0:
|
||||
return arm_el_is_aa64(env, 3) ? 1 : 3;
|
||||
case ARMMMUIdx_SE10_1:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
case ARMMMUIdx_Stage1_E0:
|
||||
case ARMMMUIdx_Stage1_E1:
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_Stage1_SE1:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
case ARMMMUIdx_E10_0:
|
||||
case ARMMMUIdx_E10_1:
|
||||
case ARMMMUIdx_E10_1_PAN:
|
||||
@@ -955,6 +981,13 @@ static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
if (mmu_idx == ARMMMUIdx_Stage2) {
|
||||
return &env->cp15.vtcr_el2;
|
||||
}
|
||||
if (mmu_idx == ARMMMUIdx_Stage2_S) {
|
||||
/*
|
||||
* Note: Secure stage 2 nominally shares fields from VTCR_EL2, but
|
||||
* those are not currently used by QEMU, so just return VSTCR_EL2.
|
||||
*/
|
||||
return &env->cp15.vstcr_el2;
|
||||
}
|
||||
return &env->cp15.tcr_el[regime_el(env, mmu_idx)];
|
||||
}
|
||||
|
||||
@@ -1157,6 +1190,9 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
|
||||
case ARMMMUIdx_Stage1_E0:
|
||||
case ARMMMUIdx_Stage1_E1:
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_Stage1_SE0:
|
||||
case ARMMMUIdx_Stage1_SE1:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -1312,6 +1348,15 @@ void arm_log_exception(int idx);
|
||||
#define LOG2_TAG_GRANULE 4
|
||||
#define TAG_GRANULE (1 << LOG2_TAG_GRANULE)
|
||||
|
||||
/*
|
||||
* SVE predicates are 1/8 the size of SVE vectors, and cannot use
|
||||
* the same simd_desc() encoding due to restrictions on size.
|
||||
* Use these instead.
|
||||
*/
|
||||
FIELD(PREDDESC, OPRSZ, 0, 6)
|
||||
FIELD(PREDDESC, ESZ, 6, 2)
|
||||
FIELD(PREDDESC, DATA, 8, 24)
|
||||
|
||||
/*
|
||||
* The SVE simd_data field, for memory ops, contains either
|
||||
* rd (5 bits) or a shift count (2 bits).
|
||||
|
||||
@@ -1347,7 +1347,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
|
||||
bool exc_secure = false;
|
||||
bool return_to_secure;
|
||||
bool ftype;
|
||||
bool restore_s16_s31;
|
||||
bool restore_s16_s31 = false;
|
||||
|
||||
/*
|
||||
* If we're not in Handler mode then jumps to magic exception-exit
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user