从 QEMU GICv3 上的 EL2 访问系统寄存器时出现异常
Exception when accessing system registers from EL2 on QEMU GICv3
我在 QEMU 中有一些裸机 AARCH64 软件 运行。我正在尝试从 EL2 访问 GICv3 系统寄存器 ICH_*,但是当我 read/write 访问它时我一直遇到异常。
ESR 0x2000000: ec 0x0, il 0x2000000, iss 0x0
x0 0xffffffff000bd2c0 x1 0x3 x2 0xffff00004808cd50 x3 0xffff00004808cd20
x4 0x77616974 x5 0x65766e74 x6 0x74696d72 x7 0
x8 0 x9 0xffffffff x10 0xffff0000401fc870 x11 0x4a49524200000000
x12 0 x13 0xffffffff00131000 x14 0xffff000042290000 x15 0xffff0000401fc730
x16 0xffffffff00117100 x17 0xffff0000401feb80 x18 0xffffffff00117100 x19 0xffff00004808ccb0
x20 0 x21 0xffff0083dd174db8 x22 0xffff00004808cd38 x23 0xffff00004806eba8
x24 0xffff00004806f028 x25 0xffff00004808ccc8 x26 0xffff0083dd174e18 x27 0x80000
x28 0x1 x29 0xffff0083dd174d50 lr 0xffffffff000bc5a0 usp 0
elr 0xffffffff000bd2c0
spsr 0x20000305
我已通过设置 ICC_SRE_EL2 寄存器启用 SRE
我是不是漏掉了什么?
-金
以下是您的用例的最小、完整且可验证的示例:
a) 在 /tmp
:
中创建一个 ich_hcr_l2.S
文件
#define ICH_HCR_EL2 S3_4_C12_C11_0
.arch armv8-a
.globl _start
.text
_start:
#ifdef __RETURN_CURRENT_EL__
// test only - returning CurrentEL
mrs x0, CurrentEL
ubfx x0, x0,2,2
#else
mrs x0, ICH_HCR_EL2
#endif
// exiting/returning w0 using Angel/Semihosting interface
adr x1, status
str w0, [x1]
mov w0, #0x18
adr x1, code
hlt #0xf000
.data
.balign 8
code: .dword 0x00020026
status: .dword 0x00000000
.end
b) 在 /tmp
中创建名为 ich_hcr_l2.sh
的可执行 shell 脚本:
#!/bin/bash
# Absolute path to this script. /home/user/bin/foo.sh
SCRIPT=$(readlink -f $BASH_SOURCE)
# Absolute path this script is in. /home/user/bin
SCRIPTPATH=$(dirname $SCRIPT)
set -e
QEMU_VERSION=2.11.0
QEMU_SYSTEM_ARM=${SCRIPTPATH}/qemu/bin/qemu-system-aarch64
build_qemu()
{
if [ ! -f ${SCRIPTPATH}/qemu/bin/qemu-system-aarch64 ]
then
if [ ! -f ${SCRIPTPATH}/qemu-${QEMU_VERSION}.tar.xz ]
then
wget https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz
fi
rm -rf ${SCRIPTPATH}/qemu-${QEMU_VERSION}
tar Jxf ${SCRIPTPATH}/qemu-${QEMU_VERSION}.tar.xz -C ${SCRIPTPATH}
pushd qemu-${QEMU_VERSION}
./configure --target-list="aarch64-softmmu" --prefix=${SCRIPTPATH}/qemu
make all install
popd
fi
}
build_example()
{
aarch64-linux-gnu-gcc ${CFLAGS} -nostartfiles -nodefaultlibs -Wl,-Ttext=0x0000000042000000 -o ${SCRIPTPATH}/ich_hcr_l2.elf ${SCRIPTPATH}/ich_hcr_l2.S
aarch64-linux-gnu-objdump -D ${SCRIPTPATH}/ich_hcr_l2.elf > ${SCRIPTPATH}/ich_hcr_l2.lst
}
run_example()
{
# exit code will be the context at w0 register.
${QEMU_SYSTEM_ARM} -m 256M -semihosting -machine virt,gic-version=3,virtualization=on,secure=${SECURE} -monitor telnet:127.0.0.1:1235,server,nowait -cpu cortex-a53 -nographic -kernel ${SCRIPTPATH}/ich_hcr_l2.elf
printf "Program returned with w0=%d\n" $?
}
# main
build_example
build_qemu
set +e
# testing program - should return CurrentEL=2
CFLAGS="-D__RETURN_CURRENT_EL__"
SECURE=off
build_example
run_example
# testing program - should return CurrentEL=3
CFLAGS="-D__RETURN_CURRENT_EL__"
SECURE=on
build_example
run_example
# actual test case: retrieving ICH_HCR_L2 at EL2:
CFLAGS=""
SECURE=off
build_example
run_example
c) 将 /tmp 设为当前工作目录,并执行 ich_hcr_l2.sh,然后耐心等待:脚本将下载,然后从其源代码构建 qemu-system-aarch64 2.11.0。
过一会儿,您应该会看到显示以下两个三个:
Program returned with w0=2
Program returned with w0=3
Program returned with w0=0
和 /tmp/ich_hcr_l2.lst 应包含:
/home/eperie/aarch64/ich_hcr_l2.elf: file format elf64-littleaarch64
Disassembly of section .text:
0000000042000000 <_start>:
42000000: d53ccb00 mrs x0, s3_4_c12_c11_0
42000004: 100800e1 adr x1, 42010020 <status>
42000008: b9000020 str w0, [x1]
4200000c: 52800300 mov w0, #0x18 // #24
42000010: 10080041 adr x1, 42010018 <code>
42000014: d45e0000 hlt #0xf000
Disassembly of section .note.gnu.build-id:
0000000000400120 <.note.gnu.build-id>:
400120: 00000004 .inst 0x00000004 ; undefined
400124: 00000014 .inst 0x00000014 ; undefined
400128: 00000003 .inst 0x00000003 ; undefined
40012c: 00554e47 .inst 0x00554e47 ; undefined
400130: e7c953ee .inst 0xe7c953ee ; undefined
400134: d3437b0f ubfx x15, x24, #3, #28
400138: 2edb19d4 .inst 0x2edb19d4 ; undefined
40013c: 9350921e sbfx x30, x16, #16, #21
400140: ea5adf9d ands x29, x28, x26, lsr #55
Disassembly of section .data:
0000000042010018 <code>:
42010018: 00020026 .word 0x00020026
4201001c: 00000000 .word 0x00000000
0000000042010020 <status>:
...
我在 QEMU 中有一些裸机 AARCH64 软件 运行。我正在尝试从 EL2 访问 GICv3 系统寄存器 ICH_*,但是当我 read/write 访问它时我一直遇到异常。
ESR 0x2000000: ec 0x0, il 0x2000000, iss 0x0
x0 0xffffffff000bd2c0 x1 0x3 x2 0xffff00004808cd50 x3 0xffff00004808cd20
x4 0x77616974 x5 0x65766e74 x6 0x74696d72 x7 0
x8 0 x9 0xffffffff x10 0xffff0000401fc870 x11 0x4a49524200000000
x12 0 x13 0xffffffff00131000 x14 0xffff000042290000 x15 0xffff0000401fc730
x16 0xffffffff00117100 x17 0xffff0000401feb80 x18 0xffffffff00117100 x19 0xffff00004808ccb0
x20 0 x21 0xffff0083dd174db8 x22 0xffff00004808cd38 x23 0xffff00004806eba8
x24 0xffff00004806f028 x25 0xffff00004808ccc8 x26 0xffff0083dd174e18 x27 0x80000
x28 0x1 x29 0xffff0083dd174d50 lr 0xffffffff000bc5a0 usp 0
elr 0xffffffff000bd2c0
spsr 0x20000305
我已通过设置 ICC_SRE_EL2 寄存器启用 SRE
我是不是漏掉了什么?
-金
以下是您的用例的最小、完整且可验证的示例:
a) 在 /tmp
:
ich_hcr_l2.S
文件
#define ICH_HCR_EL2 S3_4_C12_C11_0
.arch armv8-a
.globl _start
.text
_start:
#ifdef __RETURN_CURRENT_EL__
// test only - returning CurrentEL
mrs x0, CurrentEL
ubfx x0, x0,2,2
#else
mrs x0, ICH_HCR_EL2
#endif
// exiting/returning w0 using Angel/Semihosting interface
adr x1, status
str w0, [x1]
mov w0, #0x18
adr x1, code
hlt #0xf000
.data
.balign 8
code: .dword 0x00020026
status: .dword 0x00000000
.end
b) 在 /tmp
中创建名为 ich_hcr_l2.sh
的可执行 shell 脚本:
#!/bin/bash
# Absolute path to this script. /home/user/bin/foo.sh
SCRIPT=$(readlink -f $BASH_SOURCE)
# Absolute path this script is in. /home/user/bin
SCRIPTPATH=$(dirname $SCRIPT)
set -e
QEMU_VERSION=2.11.0
QEMU_SYSTEM_ARM=${SCRIPTPATH}/qemu/bin/qemu-system-aarch64
build_qemu()
{
if [ ! -f ${SCRIPTPATH}/qemu/bin/qemu-system-aarch64 ]
then
if [ ! -f ${SCRIPTPATH}/qemu-${QEMU_VERSION}.tar.xz ]
then
wget https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz
fi
rm -rf ${SCRIPTPATH}/qemu-${QEMU_VERSION}
tar Jxf ${SCRIPTPATH}/qemu-${QEMU_VERSION}.tar.xz -C ${SCRIPTPATH}
pushd qemu-${QEMU_VERSION}
./configure --target-list="aarch64-softmmu" --prefix=${SCRIPTPATH}/qemu
make all install
popd
fi
}
build_example()
{
aarch64-linux-gnu-gcc ${CFLAGS} -nostartfiles -nodefaultlibs -Wl,-Ttext=0x0000000042000000 -o ${SCRIPTPATH}/ich_hcr_l2.elf ${SCRIPTPATH}/ich_hcr_l2.S
aarch64-linux-gnu-objdump -D ${SCRIPTPATH}/ich_hcr_l2.elf > ${SCRIPTPATH}/ich_hcr_l2.lst
}
run_example()
{
# exit code will be the context at w0 register.
${QEMU_SYSTEM_ARM} -m 256M -semihosting -machine virt,gic-version=3,virtualization=on,secure=${SECURE} -monitor telnet:127.0.0.1:1235,server,nowait -cpu cortex-a53 -nographic -kernel ${SCRIPTPATH}/ich_hcr_l2.elf
printf "Program returned with w0=%d\n" $?
}
# main
build_example
build_qemu
set +e
# testing program - should return CurrentEL=2
CFLAGS="-D__RETURN_CURRENT_EL__"
SECURE=off
build_example
run_example
# testing program - should return CurrentEL=3
CFLAGS="-D__RETURN_CURRENT_EL__"
SECURE=on
build_example
run_example
# actual test case: retrieving ICH_HCR_L2 at EL2:
CFLAGS=""
SECURE=off
build_example
run_example
c) 将 /tmp 设为当前工作目录,并执行 ich_hcr_l2.sh,然后耐心等待:脚本将下载,然后从其源代码构建 qemu-system-aarch64 2.11.0。
过一会儿,您应该会看到显示以下两个三个:
Program returned with w0=2
Program returned with w0=3
Program returned with w0=0
和 /tmp/ich_hcr_l2.lst 应包含:
/home/eperie/aarch64/ich_hcr_l2.elf: file format elf64-littleaarch64
Disassembly of section .text:
0000000042000000 <_start>:
42000000: d53ccb00 mrs x0, s3_4_c12_c11_0
42000004: 100800e1 adr x1, 42010020 <status>
42000008: b9000020 str w0, [x1]
4200000c: 52800300 mov w0, #0x18 // #24
42000010: 10080041 adr x1, 42010018 <code>
42000014: d45e0000 hlt #0xf000
Disassembly of section .note.gnu.build-id:
0000000000400120 <.note.gnu.build-id>:
400120: 00000004 .inst 0x00000004 ; undefined
400124: 00000014 .inst 0x00000014 ; undefined
400128: 00000003 .inst 0x00000003 ; undefined
40012c: 00554e47 .inst 0x00554e47 ; undefined
400130: e7c953ee .inst 0xe7c953ee ; undefined
400134: d3437b0f ubfx x15, x24, #3, #28
400138: 2edb19d4 .inst 0x2edb19d4 ; undefined
40013c: 9350921e sbfx x30, x16, #16, #21
400140: ea5adf9d ands x29, x28, x26, lsr #55
Disassembly of section .data:
0000000042010018 <code>:
42010018: 00020026 .word 0x00020026
4201001c: 00000000 .word 0x00000000
0000000042010020 <status>:
...