target/arm: Add isar_feature tests for PAN + ATS1E1
target/arm: Add ID_AA64MMFR2_EL1
target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
target/arm: Define an aa32_pmu_8_1 isar feature test function
target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
target/arm: Stop assuming DBGDIDR always exists
target/arm: Move DBGDIDR into ARMISARegisters
target/arm: Enable ARMv8.2-ATS1E1 in -cpu max
target/arm: Test correct register in aa32_pan and aa32_ats1e1 checks
target/arm: Read debug-related ID registers from KVM
target/arm/monitor: Introduce qmp_query_cpu_model_expansion
target/arm/monitor: query-cpu-model-expansion crashed qemu when using machine type none
target/arm: convert isar regs to array
target/arm: parse cpu feature related options
target/arm: register CPU features for property
target/arm: Allow ID registers to synchronize to KVM
target/arm: introduce CPU feature dependency mechanism
target/arm: introduce KVM_CAP_ARM_CPU_FEATURE
target/arm: Add CPU features to query-cpu-model-expansion
target/arm: Update ID fields
target/arm: Add more CPU features
target/arm: ignore evtstrm and cpuid CPU features
target/arm: Update the ID registers of Kunpeng-920
target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest
target/arm: clear EL2 and EL3 only when kvm is not enabled
Signed-off-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Liang Yan <lyan@suse.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
When has_el2 and has_el3 are disabled, which is the default value for
virt machine, QEMU will clear the corresponding field in ID_PFR1_EL1 and
ID_AA64PFR0_EL1 to not expose EL3 and EL2 to guest. Because KVM doesn't
support to emulate ID registers in AArch64 before, it will not take
effect. Hence, clear EL2 and EL3 only when kvm is not enabled for
backwards compatibility.
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit ad6ce039cab07b6a99ccaa36fbb0043ae85a74c9)
Some AArch64 CPU doesn't support AArch32 mode, and the values of AArch32
registers are all 0. Hence, We'd better not to modify AArch32 registers
in AArch64 mode.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit 88e3146118230de8b99280db219a6a6c47bebce1)
The values of some ID registers in Kunpeng-920 are not exactly correct.
Let's update them. The values are read from Kunpeng-920 by calling
read_sysreg_s.
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit b54ca94f19a9b22537712638ae05d2095258eb80)
evtstrm and cpuid cann't be controlled by VMM:
1. evtstrm: The generic timer is configured to generate events at a
frequency of approximately 100KHz. It's controlled by the linux
kernel config CONFIG_ARM_ARCH_TIMER_EVTSTREAM.
2. cpuid: EL0 access to certain ID registers is available. It's always
set by linux kernel after 77c97b4ee2129 ("arm64: cpufeature: Expose
CPUID registers by emulation").
However, they are exposed by getauxval() and /proc/cpuinfo. Hence,
let's report and ignore the CPU features if someone set them.
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit 02f8ee8f420e62aff233748c7e848a1c1197b741)
Add i8mm, bf16, and dgh CPU features for AArch64.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit 8acf8dd1a20c53453d028a7b86f593019329d8c1)
Update definitions for ID fields, up to ARMv8.6.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit f87ed4385cdadf4af38b76385d2aa581b7ade6c9)
Add CPU features to the result of query-cpu-model-expansion so that
other applications (such as libvirt) can know the supported CPU
features.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit e39f3e8e4d945a87a936388204b3125041da4032)
Introduce KVM_CAP_ARM_CPU_FEATURE to check whether KVM supports to set
CPU features in ARM.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit e55671b1d033f8815316407e0274fd85f48bc4df)
Some CPU features are dependent on other CPU features. For example,
ID_AA64PFR0_EL1.FP field and ID_AA64PFR0_EL1.AdvSIMD must have the same
value, which means FP and ADVSIMD are dependent on each other, FPHP and
ADVSIMDHP are dependent on each other.
This commit introduces a mechanism for CPU feature dependency in
AArch64. We build a directed graph from the CPU feature dependency
relationship, each edge from->to means the `to` CPU feature is dependent
on the `from` CPU feature. And we will automatically enable/disable CPU
feature according to the directed graph.
For example, a, b, and c CPU features are in relationship a->b->c, which
means c is dependent on b and b is dependent on a. If c is enabled by
user, then a and b is enabled automatically. And if a is disabled by
user, then b and c is disabled automatically.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit 9a16d2b2389664aa50e63c33af0ea94afb45185b)
There are 2 steps to synchronize the values of system registers from
CPU state to KVM:
1. write to the values of system registers from CPU state to
(index,value) list by write_cpustate_to_list;
2. write the values in (index,value) list to KVM by
write_list_to_kvmstate;
In step 1, the values of constant system registers are not allowed to
write to (index,value) list. However, a constant system register is
CONSTANT for guest but not for QEMU, which means, QEMU can set/modify
the value of constant system registers that is different from phsical
registers when startup. But if KVM is enabled, guest can not read the
values of the system registers which QEMU set unless they can be written
to (index,value) list. And why not try to write to KVM if kvm_sync is
true?
At the moment we call write_cpustate_to_list, all ID registers are
contant, including ID_PFR1_EL1 and ID_AA64PFR0_EL1 because GIC has been
initialized. Hence, let's give all ID registers a chance to write to
KVM. If the write is successful, then write to (index,value) list.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit f4e592d1235bbb1290b8bc3684cb57c4304d63dc)
The Arm architecture specifies a number of ID registers that are
characterized as comprising a set of 4-bit ID fields. Each ID field
identifies the presence, and possibly the level of support for, a
particular feature in an implementation of the architecture. [1]
For most of the ID fields, there is a minimum presence value, equal to
or higher than which means the corresponding CPU feature is implemented.
Hence, we can use the minimum presence value to determine whether a CPU
feature is enabled and enable a CPU feature.
To disable a CPU feature, setting the corresponding ID field to 0x0/0xf
(for unsigned/signed field) seems as a good idea. However, it maybe
lead to some problems. For example, ID_AA64PFR0_EL1.FP is a signed ID
field. ID_AA64PFR0_EL1.FP == 0x0 represents the implementation of FP
(floating-point) and ID_AA64PFR0_EL1.FP == 0x1 represents the
implementation of FPHP (half-precision floating-point). If
ID_AA64PFR0_EL1.FP is set to 0xf when FPHP is disabled (which is also
disable FP), guest kernel maybe stuck. Hence, we add a ni_value (means
not-implemented value) to disable a CPU feature safely.
[1] D13.1.3 Principles of the ID scheme for fields in ID registers in
DDI.0487
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit 234f15e02b3b6e7195cc2cba0de3b7053dc9da09)
The implementation of CPUClass::parse_features only supports CPU
features in "feature=value" format. However, libvirt maybe send us a
CPU feature string in "+feature/-feature" format. Hence, we need to
override CPUClass::parse_features to support CPU feature string in both
"feature=value" and "+feature/-feature" format.
The logic of AArch64CPUClass::parse_features is similar to that of
X86CPUClass::parse_features.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit d7d6c711c44f18d34c7d5e730dd66da3664e02d5)
The isar in ARMCPU is a struct, each field of which represents an ID
register. It's not convenient for us to support CPU feature in AArch64.
So let's change it to an array first and add an enum as the index of the
array for convenience. Since we will never access high 32-bits of ID
registers in AArch32, it's harmless to change the ID registers in
AArch32 to 64-bits.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
(cherry-picked from commit 5b5976d6d99a55bdaf0f1596c8b0706366d0df92)
Commit e19afd566781 mentioned that target-arm only supports queryable
cpu models 'max', 'host', and the current type when KVM is in use.
The logic works well until using machine type none.
For machine type none, cpu_type will be null if cpu option is not
set by command line, strlen(cpu_type) will terminate process.
So We add a check above it.
This won't affect i386 and s390x since they do not use current_cpu.
Signed-off-by: Liang Yan <lyan@suse.com>
Message-id: 20200203134251.12986-1-lyan@suse.com
Reviewed-by: Andrew Jones <drjones@redhat.com>
Tested-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry-picked from commit 0999a4ba8718aa96105b978d3567fc7e90244c7e)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Add support for the query-cpu-model-expansion QMP command to Arm. We
do this selectively, only exposing CPU properties which represent
optional CPU features which the user may want to enable/disable.
Additionally we restrict the list of queryable cpu models to 'max',
'host', or the current type when KVM is in use. And, finally, we only
implement expansion type 'full', as Arm does not yet have a "base"
CPU type. More details and example queries are described in a new
document (docs/arm-cpu-features.rst).
Note, certainly more features may be added to the list of advertised
features, e.g. 'vfp' and 'neon'. The only requirement is that we can
detect invalid configurations and emit failures at QMP query time.
For 'vfp' and 'neon' this will require some refactoring to share a
validation function between the QMP query and the CPU realize
functions.
Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
Message-id: 20191031142734.8590-2-drjones@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry-picked from commit e19afd5667819d74ab25d1a1171efe7b5002c6ee)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Now we have isar_feature test functions that look at fields in the
ID_AA64DFR0_EL1 and ID_DFR0 ID registers, add the code that reads
these register values from KVM so that the checks behave correctly
when we're using KVM.
No isar_feature function tests ID_AA64DFR1_EL1 or DBGDIDR yet, but we
add it to maintain the invariant that every field in the
ARMISARegisters struct is populated for a KVM CPU and can be relied
on. This requirement isn't actually written down yet, so add a note
to the relevant comment.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200214175116.9164-13-peter.maydell@linaro.org
(cherry-picked from commit 1548a7b2ad621a31b4216ed703b6d658a2ecf0d0)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
The isar_feature_aa32_pan and isar_feature_aa32_ats1e1 functions
are supposed to be testing fields in ID_MMFR3; but a cut-and-paste
error meant we were looking at MVFR0 instead.
Fix the functions to look at the right register; this requires
us to move at least id_mmfr3 to the ARMISARegisters struct; we
choose to move all the ID_MMFRn registers for consistency.
Fixes: 3d6ad6bb466f
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200214175116.9164-19-peter.maydell@linaro.org
(cherry-picked from commit 10054016eda1b13bdd8340d100fd029cc8b58f36)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
This includes enablement of ARMv8.1-PAN.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200208125816.14954-17-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry-picked from commit e0fe7309a7c21ef2386de50d37c86aea0d671c08)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
We're going to want to read the DBGDIDR register from KVM in
a subsequent commit, which means it needs to be in the
ARMISARegisters sub-struct. Move it.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200214175116.9164-12-peter.maydell@linaro.org
(cherry-picked from commit 4426d3617d64922d97b74ed22e67e33b6fb7de0a)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
The AArch32 DBGDIDR defines properties like the number of
breakpoints, watchpoints and context-matching comparators. On an
AArch64 CPU, the register may not even exist if AArch32 is not
supported at EL1.
Currently we hard-code use of DBGDIDR to identify the number of
breakpoints etc; this works for all our TCG CPUs, but will break if
we ever add an AArch64-only CPU. We also have an assert() that the
AArch32 and AArch64 registers match, which currently works only by
luck for KVM because we don't populate either of these ID registers
from the KVM vCPU and so they are both zero.
Clean this up so we have functions for finding the number
of breakpoints, watchpoints and context comparators which look
in the appropriate ID register.
This allows us to drop the "check that AArch64 and AArch32 agree
on the number of breakpoints etc" asserts:
* we no longer look at the AArch32 versions unless that's the
right place to be looking
* it's valid to have a CPU (eg AArch64-only) where they don't match
* we shouldn't have been asserting the validity of ID registers
in a codepath used with KVM anyway
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200214175116.9164-11-peter.maydell@linaro.org
(cherry-picked from commit 88ce6c6ee85d902f59dc65afc3ca86b34f02b9ed)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Add the 64-bit version of the "is this a v8.1 PMUv3?"
ID register check function, and the _any_ version that
checks for either AArch32 or AArch64 support. We'll use
this in a later commit.
We don't (yet) do any isar_feature checks on ID_AA64DFR1_EL1,
but we move id_aa64dfr1 into the ARMISARegisters struct with
id_aa64dfr0, for consistency.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20200214175116.9164-10-peter.maydell@linaro.org
(cherry-picked from commit 2a609df87d9b886fd38a190a754dbc241ff707e8)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Instead of open-coding a check on the ID_DFR0 PerfMon ID register
field, create a standardly-named isar_feature for "does AArch32 have
a v8.1 PMUv3" and use it.
This entails moving the id_dfr0 field into the ARMISARegisters struct.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20200214175116.9164-9-peter.maydell@linaro.org
(cherry-picked from commit a617953855b65a602d36364b9643f7e5bc31288e)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
We already define FIELD macros for ID_DFR0, so use them in the
one place where we're doing direct bit value manipulation.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20200214175116.9164-8-peter.maydell@linaro.org
(cherry-picked from commit d52c061e541982a3663ad5c65bd3b518dbe85b87)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Add FIELD() definitions for the ID_AA64DFR0_EL1 and use them
where we currently have hard-coded bit values.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20200214175116.9164-7-peter.maydell@linaro.org
(cherry-picked from commit ceb2744b47a1ef4184dca56a158eb3156b6eba36)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Add definitions for all of the fields, up to ARMv8.5.
Convert the existing RESERVED register to a full register.
Query KVM for the value of the register for the host.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200208125816.14954-18-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry-picked from commit 64761e10af2742a916c08271828890274137b9e8)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Include definitions for all of the bits in ID_MMFR3.
We already have a definition for ID_AA64MMFR1.PAN.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200208125816.14954-4-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry-picked from commit 3d6ad6bb466f487bcc861f99e2c9054230df1076)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
fix CVE-2020-25742
patch link: https://lists.nongnu.org/archive/html/qemu-devel/2020-09/msg05294.html
While mapping IRQ level in pci_change_irq_level() routine,
it does not check if pci_get_bus() returned a valid pointer.
It may lead to a NULL pointer dereference issue. Add check to
avoid it.
-> https://ruhr-uni-bochum.sciebo.de/s/NNWP2GfwzYKeKwE?path=%2Flsi_nullptr1
==1183858==Hint: address points to the zero page.
#0 pci_change_irq_level hw/pci/pci.c:259
#1 pci_irq_handler hw/pci/pci.c:1445
#2 pci_set_irq hw/pci/pci.c:1463
#3 lsi_set_irq hw/scsi/lsi53c895a.c:488
#4 lsi_update_irq hw/scsi/lsi53c895a.c:523
#5 lsi_script_scsi_interrupt hw/scsi/lsi53c895a.c:554
#6 lsi_execute_script hw/scsi/lsi53c895a.c:1149
#7 lsi_reg_writeb hw/scsi/lsi53c895a.c:1984
#8 lsi_io_write hw/scsi/lsi53c895a.c:2146
...
Reported-by: Ruhr-University <bugs-syssec@rub.de>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
hw/net/xgmac: Fix buffer overflow in xgmac_enet_send()
hw/net/net_tx_pkt: fix assertion failure in net_tx_pkt_add_raw_fragment()
sm501: Convert printf + abort to qemu_log_mask
sm501: Shorten long variable names in sm501_2d_operation
sm501: Use BIT(x) macro to shorten constant
sm501: Clean up local variables in sm501_2d_operation
sm501: Replace hand written implementation with pixman where possible
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com>
Besides being faster this should also prevent malicious guests to
abuse 2D engine to overwrite data or cause a crash.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Message-id: 58666389b6cae256e4e972a32c05cf8aa51bffc0.1590089984.git.balaton@eik.bme.hu
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Make variables local to the block they are used in to make it clearer
which operation they are needed for.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: ae59f8138afe7f6a5a4a82539d0f61496a906b06.1590089984.git.balaton@eik.bme.hu
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Some places already use qemu_log_mask() to log unimplemented features
or errors but some others have printf() then abort(). Convert these to
qemu_log_mask() and avoid aborting to prevent guests to easily cause
denial of service.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 305af87f59d81e92f2aaff09eb8a3603b8baa322.1590089984.git.balaton@eik.bme.hu
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
An assertion failure issue was found in the code that processes network packets
while adding data fragments into the packet context. It could be abused by a
malicious guest to abort the QEMU process on the host. This patch replaces the
affected assert() with a conditional statement, returning false if the current
data fragment exceeds max_raw_frags.
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
Reviewed-by: Dmitry Fleytman <dmitry.fleytman@gmail.com>
Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
A buffer overflow issue was reported by Mr. Ziming Zhang, CC'd here. It
occurs while sending an Ethernet frame due to missing break statements
and improper checking of the buffer size.
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Drop IPv6 message shorter than what's mentioned in the payload
length header (+ the size of the IPv6 header). They're invalid and could
lead to data leakage in icmp6_send_echoreply().
Store calculated setup_len in a local variable, verify it, and only
write it to the struct(USBDevice->setup_len)in case it passed the
sanity checks.
This prevent other code (do_token_{in,out}function specifically)
from working with invalid USBDevice->setup_len values and overruning
the USBDevice->setup_buf[] buffer.
Fixes: CVE-2020-14364