[PATCH] doc: do not recommend -blockdev
Currently, documentation recommends to use -blockdev instead of -drive. This is quite a bit misleading, because -blockdev is "too" low-level, requires good knowlege of how to construct block device stack, esp. in context of various qcow2 layers, and requires too explicit configuration. More, quite some constructs does not work with -blockdev, - for example this is -snapshot. Instead of "recommended" word, use another construct here. Signed-off-by: Michael Tokarev --- qemu-options.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-options.hx b/qemu-options.hx index 59bdf67a2c..8fe31b465d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1143,7 +1143,7 @@ have gone through several iterations as the feature set and complexity of the block layer have grown. Many online guides to QEMU often reference older and deprecated options, which can lead to confusion. -The recommended modern way to describe disks is to use a combination of +The low-level detailed way to describe disks is to use a combination of ``-device`` to specify the hardware device and ``-blockdev`` to describe the backend. The device defines what the guest sees and the backend describes how QEMU handles the data. -- 2.30.2
Re: Question about TCG liveness_pass_1
On 2023/3/17 22:02, Richard Henderson wrote: On 3/16/23 19:57, LIU Zhiwei wrote: Hi Richard, When I read the tcg code, I find a corner case which may be a bug in liveness_pass_1. I see all TEMP_TBs or global temps are set to TS_DEAD | TS_MEM when enter liveness_pass_1. Think about the sequence. 1)Write_global_temp_0 // 0->TS_DEAD, but not recorded in arg_life Here TS_MEM->TS_DEAD, so *is* recorded in arg_life. 2)INDEX_op_qemu_st //trigger an exception here. Here TCG_OPF_SIDE_EFFECTS is set, so call la_global_sync, so 0->TS_MEM. Oops! I missed this. Thanks. 3)Ref_global_temp_0 // TS_DEAD->0 4)Write_global_temp_0 // TS_DEAD | TS_MEM -> TS_DEAD As 1) will not write to memory, its register will be reused by the 3). I think it may miss a write to global_temp_0 when enter an exception. Was there a specific test case that you find is miscompiled? No. Best Regards, Zhiwei r~
[PULL 09/31] tcg: Clear plugin_mem_cbs on TB exit
From: Richard Henderson Do this in cpu_tb_exec (normal exit) and cpu_loop_exit (exception), adjacent to where we reset can_do_io. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1381 Signed-off-by: Richard Henderson Message-Id: <20230310195252.210956-2-richard.hender...@linaro.org> Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-12-alex.ben...@linaro.org> diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c index c7bc8c6efa..176ea57281 100644 --- a/accel/tcg/cpu-exec-common.c +++ b/accel/tcg/cpu-exec-common.c @@ -65,6 +65,8 @@ void cpu_loop_exit(CPUState *cpu) { /* Undo the setting in cpu_tb_exec. */ cpu->can_do_io = 1; +/* Undo any setting in generated code. */ +qemu_plugin_disable_mem_helpers(cpu); siglongjmp(cpu->jmp_env, 1); } diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 56aaf58b9d..c815f2dbfd 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -459,6 +459,7 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit) qemu_thread_jit_execute(); ret = tcg_qemu_tb_exec(env, tb_ptr); cpu->can_do_io = 1; +qemu_plugin_disable_mem_helpers(cpu); /* * TODO: Delay swapping back to the read-write region of the TB * until we actually need to modify the TB. The read-only copy, @@ -526,7 +527,6 @@ static void cpu_exec_exit(CPUState *cpu) if (cc->tcg_ops->cpu_exec_exit) { cc->tcg_ops->cpu_exec_exit(cpu); } -QEMU_PLUGIN_ASSERT(cpu->plugin_mem_cbs == NULL); } void cpu_exec_step_atomic(CPUState *cpu) @@ -580,7 +580,6 @@ void cpu_exec_step_atomic(CPUState *cpu) qemu_mutex_unlock_iothread(); } assert_no_pages_locked(); -qemu_plugin_disable_mem_helpers(cpu); } /* @@ -1004,7 +1003,6 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc) cpu_loop_exec_tb(cpu, tb, pc, &last_tb, &tb_exit); -QEMU_PLUGIN_ASSERT(cpu->plugin_mem_cbs == NULL); /* Try to align the host and virtual clocks if the guest is in advance */ align_clocks(sc, cpu); @@ -1029,7 +1027,6 @@ static int cpu_exec_setjmp(CPUState *cpu, SyncClocks *sc) if (qemu_mutex_iothread_locked()) { qemu_mutex_unlock_iothread(); } -qemu_plugin_disable_mem_helpers(cpu); assert_no_pages_locked(); } -- 2.39.2
[PULL 03/31] scripts/ci: add libslirp-devel to build-environment
Without libslip enabled we won't have user networking which means the KVM tests won't run. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-4-alex.ben...@linaro.org> diff --git a/scripts/ci/org.centos/stream/8/build-environment.yml b/scripts/ci/org.centos/stream/8/build-environment.yml index 0d094d70c3..1ead77e2cb 100644 --- a/scripts/ci/org.centos/stream/8/build-environment.yml +++ b/scripts/ci/org.centos/stream/8/build-environment.yml @@ -55,6 +55,7 @@ - librados-devel - librbd-devel - libseccomp-devel + - libslirp-devel - libssh-devel - libxkbcommon-devel - lzo-devel -- 2.39.2
[PULL 11/31] include/qemu/plugin: Remove QEMU_PLUGIN_ASSERT
From: Richard Henderson This macro is no longer used. Signed-off-by: Richard Henderson Message-Id: <20230310195252.210956-4-richard.hender...@linaro.org> Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-14-alex.ben...@linaro.org> diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index fb338ba576..e0ebedef84 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -59,8 +59,6 @@ get_plugin_meminfo_rw(qemu_plugin_meminfo_t i) #ifdef CONFIG_PLUGIN extern QemuOptsList qemu_plugin_opts; -#define QEMU_PLUGIN_ASSERT(cond) g_assert(cond) - static inline void qemu_plugin_add_opts(void) { qemu_add_opts(&qemu_plugin_opts); @@ -252,8 +250,6 @@ void qemu_plugin_user_postfork(bool is_child); #else /* !CONFIG_PLUGIN */ -#define QEMU_PLUGIN_ASSERT(cond) - static inline void qemu_plugin_add_opts(void) { } -- 2.39.2
[PULL 06/31] include/qemu: add documentation for memory callbacks
Some API documentation was missed, rectify that. Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1497 Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Thomas Huth Message-Id: <20230315174331.2959-7-alex.ben...@linaro.org> diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index d0e9d03adf..50a9957279 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -481,17 +481,56 @@ uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr); */ const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h); -typedef void -(*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index, - qemu_plugin_meminfo_t info, uint64_t vaddr, - void *userdata); +/** + * typedef qemu_plugin_vcpu_mem_cb_t - memory callback function type + * @vcpu_index: the executing vCPU + * @info: an opaque handle for further queries about the memory + * @vaddr: the virtual address of the transaction + * @userdata: any user data attached to the callback + */ +typedef void (*qemu_plugin_vcpu_mem_cb_t) (unsigned int vcpu_index, + qemu_plugin_meminfo_t info, + uint64_t vaddr, + void *userdata); +/** + * qemu_plugin_register_vcpu_mem_cb() - register memory access callback + * @insn: handle for instruction to instrument + * @cb: callback of type qemu_plugin_vcpu_mem_cb_t + * @flags: (currently unused) callback flags + * @rw: monitor reads, writes or both + * @userdata: opaque pointer for userdata + * + * This registers a full callback for every memory access generated by + * an instruction. If the instruction doesn't access memory no + * callback will be made. + * + * The callback reports the vCPU the access took place on, the virtual + * address of the access and a handle for further queries. The user + * can attach some userdata to the callback for additional purposes. + * + * Other execution threads will continue to execute during the + * callback so the plugin is responsible for ensuring it doesn't get + * confused by making appropriate use of locking if required. + */ void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn, qemu_plugin_vcpu_mem_cb_t cb, enum qemu_plugin_cb_flags flags, enum qemu_plugin_mem_rw rw, void *userdata); +/** + * qemu_plugin_register_vcpu_mem_inline() - register an inline op to any memory access + * @insn: handle for instruction to instrument + * @rw: apply to reads, writes or both + * @op: the op, of type qemu_plugin_op + * @ptr: pointer memory for the op + * @imm: immediate data for @op + * + * This registers a inline op every memory access generated by the + * instruction. This provides for a lightweight but not thread-safe + * way of counting the number of operations done. + */ void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn, enum qemu_plugin_mem_rw rw, enum qemu_plugin_op op, void *ptr, -- 2.39.2
[PULL 10/31] tcg: Drop plugin_gen_disable_mem_helpers from tcg_gen_exit_tb
From: Richard Henderson Now that we call qemu_plugin_disable_mem_helpers in cpu_tb_exec, we don't need to do this in generated code as well. Signed-off-by: Richard Henderson Message-Id: <20230310195252.210956-3-richard.hender...@linaro.org> Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-13-alex.ben...@linaro.org> diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index ddab20a6a6..3136cef81a 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -2808,7 +2808,6 @@ void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx) tcg_debug_assert(idx == TB_EXIT_REQUESTED); } -plugin_gen_disable_mem_helpers(); tcg_gen_op1i(INDEX_op_exit_tb, val); } -- 2.39.2
[PULL 07/31] tests/tcg: add some help output for running individual tests
So you can do: cd tests/tcg/aarch64-linux-user make -f ../Makefile.target help To see the list of tests. You can then run each one individually. Signed-off-by: Alex Bennée Acked-by: Richard Henderson Reviewed-by: Thomas Huth Message-Id: <20230315174331.2959-8-alex.ben...@linaro.org> diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target index a3b0aaf8af..8318caf924 100644 --- a/tests/tcg/Makefile.target +++ b/tests/tcg/Makefile.target @@ -201,3 +201,10 @@ clean: distclean: rm -f config-cc.mak config-target.mak ../config-$(TARGET).mak + +.PHONY: help +help: + @echo "TCG tests help $(TARGET_NAME)" + @echo "Built with $(CC)" + @echo "Available tests:" + @$(foreach t,$(RUN_TESTS),echo " $t";) -- 2.39.2
[PULL 04/31] scripts/ci: update gitlab-runner playbook to handle CentOS
This was broken when we moved to using the pre-built packages as we didn't take care to ensure we used RPMs where required. NB: I could never get this to complete on my test setup but I suspect this was down to network connectivity and timeouts while downloading. Fixes: 69c4befba1 (scripts/ci: update gitlab-runner playbook to use latest runner) Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-5-alex.ben...@linaro.org> diff --git a/scripts/ci/setup/gitlab-runner.yml b/scripts/ci/setup/gitlab-runner.yml index 95d4199c03..1a1b270ff2 100644 --- a/scripts/ci/setup/gitlab-runner.yml +++ b/scripts/ci/setup/gitlab-runner.yml @@ -48,13 +48,29 @@ - debug: msg: gitlab-runner arch is {{ gitlab_runner_arch }} -- name: Download the matching gitlab-runner +- name: Download the matching gitlab-runner (DEB) get_url: dest: "/root/" url: "https://gitlab-runner-downloads.s3.amazonaws.com/latest/deb/gitlab-runner_{{ gitlab_runner_arch }}.deb" + when: +- ansible_facts['distribution'] == 'Ubuntu' + +- name: Download the matching gitlab-runner (RPM) + get_url: +dest: "/root/" +url: "https://gitlab-runner-downloads.s3.amazonaws.com/latest/rpm/gitlab-runner_{{ gitlab_runner_arch }}.rpm" + when: +- ansible_facts['distribution'] == 'CentOS' -- name: Install gitlab-runner via package manager +- name: Install gitlab-runner via package manager (DEB) apt: deb="/root/gitlab-runner_{{ gitlab_runner_arch }}.deb" + when: +- ansible_facts['distribution'] == 'Ubuntu' + +- name: Install gitlab-runner via package manager (RPM) + yum: name="/root/gitlab-runner_{{ gitlab_runner_arch }}.rpm" + when: +- ansible_facts['distribution'] == 'CentOS' - name: Register the gitlab-runner command: "/usr/bin/gitlab-runner register --non-interactive --url {{ gitlab_runner_server_url }} --registration-token {{ gitlab_runner_registration_token }} --executor shell --tag-list {{ ansible_facts[\"architecture\"] }},{{ ansible_facts[\"distribution\"]|lower }}_{{ ansible_facts[\"distribution_version\"] }} --description '{{ ansible_facts[\"distribution\"] }} {{ ansible_facts[\"distribution_version\"] }} {{ ansible_facts[\"architecture\"] }} ({{ ansible_facts[\"os_family\"] }})'" -- 2.39.2
[PULL 02/31] tests/docker: all add DOCKER_BUILDKIT to RUNC environment
It seems we also need to pass DOCKER_BUILDKIT as an argument to docker itself to get the full benefit of caching. Signed-off-by: Alex Bennée Suggested-by: Fabiano Rosas Tested-by: Richard Henderson Reviewed-by: Thomas Huth Message-Id: <20230315174331.2959-3-alex.ben...@linaro.org> diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index 54ed77f671..9401525325 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -39,7 +39,7 @@ docker-qemu-src: $(DOCKER_SRC_COPY) # General rule for building docker images. docker-image-%: $(DOCKER_FILES_DIR)/%.docker $(call quiet-command, \ - $(RUNC) build \ + DOCKER_BUILDKIT=1 $(RUNC) build \ $(if $V,,--quiet) \ $(if $(NOCACHE),--no-cache, \ $(if $(DOCKER_REGISTRY),--cache-from $(DOCKER_REGISTRY)/qemu/$*)) \ -- 2.39.2
[PULL 08/31] tests/avocado: don't use tags to define drive
We are abusing the avocado tags which are intended to provide test selection metadata to provide parameters to our test. This works OK up until the point you need to have ,'s in the field as this is the tag separator character which is the case for a number of the drive parameters. Fix this by making drive a parameter to the common helper function. Fixes: 267fe57c23 (tests: add tuxrun baseline test to avocado) Reviewed-by: David Woodhouse Signed-off-by: David Woodhouse Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-11-alex.ben...@linaro.org> diff --git a/tests/avocado/tuxrun_baselines.py b/tests/avocado/tuxrun_baselines.py index 30aaefc1d3..c3fb67f5dc 100644 --- a/tests/avocado/tuxrun_baselines.py +++ b/tests/avocado/tuxrun_baselines.py @@ -67,9 +67,6 @@ def setUp(self): # The name of the kernel Image file self.image = self.get_tag('image', "Image") -# The block device drive type -self.drive = self.get_tag('drive', "virtio-blk-device") - self.root = self.get_tag('root', "vda") # Occasionally we need extra devices to hook things up @@ -99,7 +96,7 @@ def fetch_tuxrun_assets(self, dt=None): return (kernel_image, self.workdir + "/rootfs.ext4", dtb) -def prepare_run(self, kernel, disk, dtb=None, console_index=0): +def prepare_run(self, kernel, disk, drive, dtb=None, console_index=0): """ Setup to run and add the common parameters to the system """ @@ -121,10 +118,8 @@ def prepare_run(self, kernel, disk, dtb=None, console_index=0): if self.extradev: self.vm.add_args('-device', self.extradev) -# Some machines already define a drive device -if self.drive != "none": -self.vm.add_args('-device', - f"{self.drive},drive=hd0") +self.vm.add_args('-device', + f"{drive},drive=hd0") # Some machines need an explicit DTB if dtb: @@ -154,7 +149,9 @@ def run_tuxtest_tests(self, haltmsg): else: self.vm.wait() -def common_tuxrun(self, dt=None, haltmsg="reboot: System halted", +def common_tuxrun(self, dt=None, + drive="virtio-blk-device", + haltmsg="reboot: System halted", console_index=0): """ Common path for LKFT tests. Unless we need to do something @@ -163,7 +160,7 @@ def common_tuxrun(self, dt=None, haltmsg="reboot: System halted", """ (kernel, disk, dtb) = self.fetch_tuxrun_assets(dt) -self.prepare_run(kernel, disk, dtb, console_index) +self.prepare_run(kernel, disk, drive, dtb, console_index) self.vm.launch() self.run_tuxtest_tests(haltmsg) @@ -206,11 +203,11 @@ def test_armv5(self): :avocado: tags=machine:versatilepb :avocado: tags=tuxboot:armv5 :avocado: tags=image:zImage -:avocado: tags=drive:virtio-blk-pci :avocado: tags=console:ttyAMA0 :avocado: tags=shutdown:nowait """ -self.common_tuxrun(dt="versatile-pb.dtb") +self.common_tuxrun(drive="virtio-blk-pci", + dt="versatile-pb.dtb") def test_armv7(self): """ @@ -244,10 +241,9 @@ def test_i386(self): :avocado: tags=machine:q35 :avocado: tags=tuxboot:i386 :avocado: tags=image:bzImage -:avocado: tags=drive:virtio-blk-pci :avocado: tags=shutdown:nowait """ -self.common_tuxrun() +self.common_tuxrun(drive="virtio-blk-pci") def test_mips32(self): """ @@ -257,11 +253,10 @@ def test_mips32(self): :avocado: tags=endian:big :avocado: tags=tuxboot:mips32 :avocado: tags=image:vmlinux -:avocado: tags=drive:driver=ide-hd,bus=ide.0,unit=0 :avocado: tags=root:sda :avocado: tags=shutdown:nowait """ -self.common_tuxrun() +self.common_tuxrun(drive="driver=ide-hd,bus=ide.0,unit=0") def test_mips32el(self): """ @@ -270,11 +265,10 @@ def test_mips32el(self): :avocado: tags=cpu:mips32r6-generic :avocado: tags=tuxboot:mips32el :avocado: tags=image:vmlinux -:avocado: tags=drive:driver=ide-hd,bus=ide.0,unit=0 :avocado: tags=root:sda :avocado: tags=shutdown:nowait """ -self.common_tuxrun() +self.common_tuxrun(drive="driver=ide-hd,bus=ide.0,unit=0") @skip("QEMU currently broken") # regression against stable QEMU def test_mips64(self): @@ -284,11 +278,10 @@ def test_mips64(self): :avocado: tags=tuxboot:mips64 :avocado: tags=endian:big :avocado: tags=image:vmlinux -:avocado: tags=drive:driver=ide-hd,bus=ide.0,unit=0 :avocado: tags=root:sda :avocado: tags=shutdown:nowait """ -self.common_tuxrun()
[PULL 00/31] various fixes (testing, plugins, gitdm)
The following changes since commit 74c581b6452394e591f13beba9fea2ec0688e2f5: Merge tag 'trivial-branch-for-8.0-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging (2023-03-17 14:22:01 +) are available in the Git repository at: https://gitlab.com/stsquad/qemu.git tags/pull-for-8.0-170323-4 for you to fetch changes up to 4f2c431acd43d0aa505494229d05fa343762f272: qtests: avoid printing comments before g_test_init() (2023-03-17 17:50:19 +) You can see my CI run on the branch here: https://gitlab.com/stsquad/qemu/-/pipelines/810271620 The failures: FreeBSD's time out on a migration test Centos8 Stream because my private runner needs more disk space Misc fixes for 8.0 (testing, plugins, gitdm) - update Alpine image used for testing images - include libslirp in custom runner build env - update gitlab-runner recipe for CentOS - update docker calls for better caching behaviour - document some plugin callbacks - don't use tags to define drives for lkft baseline tests - fix missing clear of plugin_mem_cbs - fix iotests to report individual results - update the gitdm metadata for contributors - avoid printing comments before g_test_init() Alex Bennée (14): tests/docker: all add DOCKER_BUILDKIT to RUNC environment scripts/ci: add libslirp-devel to build-environment scripts/ci: update gitlab-runner playbook to handle CentOS gitlab: update centos-8-stream job include/qemu: add documentation for memory callbacks tests/tcg: add some help output for running individual tests tests/avocado: don't use tags to define drive contrib/gitdm: Add ASPEED Technology to the domain map contrib/gitdm: Add SYRMIA to the domain map contrib/gitdm: add Amazon to the domain map contrib/gitdm: add Alibaba to the domain-map contrib/gitdm: add revng to domain map contrib/gitdm: add more individual contributors contrib/gitdm: add group map for AMD Daniel P. Berrangé (9): iotests: explicitly pass source/build dir to 'check' command iotests: allow test discovery before building iotests: strip subdir path when listing tests iotests: print TAP protocol version when reporting tests iotests: connect stdin to /dev/null when running tests iotests: always use a unique sub-directory per test iotests: register each I/O test separately with meson iotests: remove the check-block.sh script qtests: avoid printing comments before g_test_init() Marcin Juszkiewicz (1): tests/avocado: update AArch64 tests to Alpine 3.17.2 Richard Henderson (7): tcg: Clear plugin_mem_cbs on TB exit tcg: Drop plugin_gen_disable_mem_helpers from tcg_gen_exit_tb include/qemu/plugin: Remove QEMU_PLUGIN_ASSERT *: Add missing includes of qemu/error-report.h *: Add missing includes of qemu/plugin.h include/qemu: Split out plugin-event.h include/qemu/plugin: Inline qemu_plugin_disable_mem_helpers include/hw/core/cpu.h | 2 +- include/qemu/plugin-event.h| 26 ++ include/qemu/plugin.h | 27 +++--- include/qemu/qemu-plugin.h | 47 +++-- include/user/syscall-trace.h | 1 + accel/accel-softmmu.c | 2 +- accel/tcg/cpu-exec-common.c| 3 ++ accel/tcg/cpu-exec.c | 5 +- block/monitor/block-hmp-cmds.c | 1 + cpu.c | 1 + dump/dump.c| 1 + dump/win_dump.c| 1 + gdbstub/gdbstub.c | 1 + hw/arm/collie.c| 2 + hw/arm/cubieboard.c| 1 + hw/arm/musicpal.c | 2 + hw/arm/npcm7xx_boards.c| 2 + hw/arm/nseries.c | 2 + hw/arm/omap_sx1.c | 2 + hw/arm/orangepi.c | 1 + hw/arm/palm.c | 2 + hw/core/loader.c | 1 + hw/core/machine-smp.c | 2 + hw/i386/kvm/xen_evtchn.c | 1 + hw/i386/kvm/xen_xenstore.c | 1 + hw/i386/sgx.c | 1 + hw/intc/apic.c | 1 + hw/loongarch/acpi-build.c | 1 + hw/loongarch/virt.c| 2 + hw/m68k/next-cube.c| 1 + hw/m68k/q800.c
[PULL 01/31] tests/avocado: update AArch64 tests to Alpine 3.17.2
From: Marcin Juszkiewicz To test Alpine boot on SBSA-Ref target we need Alpine Linux 'standard' image as 'virt' one lacks kernel modules. So to minimalize Avocado cache I move test to 'standard' image. Signed-off-by: Marcin Juszkiewicz Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20230302191146.1790560-1-marcin.juszkiew...@linaro.org> Message-Id: <20230315174331.2959-2-alex.ben...@linaro.org> diff --git a/tests/avocado/machine_aarch64_virt.py b/tests/avocado/machine_aarch64_virt.py index 25dab8dc00..a90dc6ff4b 100644 --- a/tests/avocado/machine_aarch64_virt.py +++ b/tests/avocado/machine_aarch64_virt.py @@ -38,11 +38,11 @@ def test_alpine_virt_tcg_gic_max(self): :avocado: tags=accel:tcg """ iso_url = ('https://dl-cdn.alpinelinux.org/' - 'alpine/v3.16/releases/aarch64/' - 'alpine-virt-3.16.3-aarch64.iso') + 'alpine/v3.17/releases/aarch64/' + 'alpine-standard-3.17.2-aarch64.iso') # Alpine use sha256 so I recalculated this myself -iso_sha1 = '0683bc089486d55c91bf6607d5ecb93925769bc0' +iso_sha1 = '76284fcd7b41fe899b0c2375ceb8470803eea839' iso_path = self.fetch_asset(iso_url, asset_hash=iso_sha1) self.vm.set_console() @@ -65,7 +65,7 @@ def test_alpine_virt_tcg_gic_max(self): self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom') self.vm.launch() -self.wait_for_console_pattern('Welcome to Alpine Linux 3.16') +self.wait_for_console_pattern('Welcome to Alpine Linux 3.17') def common_aarch64_virt(self, machine): -- 2.39.2
[PULL 05/31] gitlab: update centos-8-stream job
A couple of clean-ups here: - inherit from the custom runners job for artefacts - call check-avocado directly - add some comments to the top about setup Signed-off-by: Alex Bennée Reviewed-by: Thomas Huth Message-Id: <20230315174331.2959-6-alex.ben...@linaro.org> diff --git a/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml b/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml index 068b0c4335..367424db78 100644 --- a/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml +++ b/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml @@ -1,4 +1,9 @@ +# All centos-stream-8 jobs should run successfully in an environment +# setup by the scripts/ci/setup/stream/8/build-environment.yml task +# "Installation of extra packages to build QEMU" + centos-stream-8-x86_64: + extends: .custom_runner_template allow_failure: true needs: [] stage: build @@ -8,15 +13,6 @@ centos-stream-8-x86_64: rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - if: "$CENTOS_STREAM_8_x86_64_RUNNER_AVAILABLE" - artifacts: - name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" - when: on_failure - expire_in: 7 days - paths: - - build/tests/results/latest/results.xml - - build/tests/results/latest/test-results - reports: - junit: build/tests/results/latest/results.xml before_script: - JOBS=$(expr $(nproc) + 1) script: @@ -25,6 +21,4 @@ centos-stream-8-x86_64: - ../scripts/ci/org.centos/stream/8/x86_64/configure || { cat config.log meson-logs/meson-log.txt; exit 1; } - make -j"$JOBS" - - make NINJA=":" check - || { cat meson-logs/testlog.txt; exit 1; } ; - - ../scripts/ci/org.centos/stream/8/x86_64/test-avocado + - make NINJA=":" check check-avocado -- 2.39.2
[RFC PATCH] metadata: add .git-blame-ignore-revs
Someone mentioned this on IRC so I thought I would try it out with a few commits that are pure code style fixes. Signed-off-by: Alex Bennée --- .git-blame-ignore-revs | 18 ++ 1 file changed, 18 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00..24208ece8c --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,18 @@ +# +# List of code-formatting clean ups the git blame can ignore +# +# git blame --ignore-revs-file .git-blame-ignore-revs +# +# or +# +# git config blame.ignoreRevsFile .git-blame-ignore-revs +# + +# gdbstub: clean-up indents +ad9e4585b3c7425759d3eea697afbca71d2c2082 + +# e1000e: fix code style +0eadd56bf53ab196a16d492d7dd31c62e1c24c32 + +# target/riscv: coding style fixes +8c7fed9218b407792120bcfda0347ed16205 -- 2.39.2
Re: [PATCH 1/4] util/iov: Make qiov_slice() public
On Fri, Mar 17, 2023 at 06:50:16PM +0100, Hanna Czenczek wrote: > We want to inline qemu_iovec_init_extended() in block/io.c for padding > requests, and having access to qiov_slice() is useful for this. > > (We will need to count the number of I/O vector elements of a slice > there, and then later process this slice. Without qiov_slice(), we > would need to call qemu_iovec_subvec_niov(), and all further > IOV-processing functions may need to skip prefixing elements to > accomodate for a qiov_offset. Because qemu_iovec_subvec_niov() > internally calls qiov_slice(), we can just have the block/io.c code call > qiov_slice() itself, thus get the number of elements, and also create an > iovec array with the superfluous prefixing elements stripped, so the > following processing functions no longer need to skip them.) Might be worth mentioning in the commit message that you also renamed it to qemu_iovec_slice() as part of exporting. > > Signed-off-by: Hanna Czenczek > --- > include/qemu/iov.h | 3 +++ > util/iov.c | 14 +++--- > 2 files changed, 10 insertions(+), 7 deletions(-) Reviewed-by: Eric Blake -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [PATCH 2/4] block: Split padded I/O vectors exceeding IOV_MAX
On Fri, Mar 17, 2023 at 06:50:17PM +0100, Hanna Czenczek wrote: > When processing vectored guest requests that are not aligned to the > storage request alignment, we pad them by adding head and/or tail > buffers for a read-modify-write cycle. > > > To do this, the use of qemu_iovec_init_extended() in bdrv_pad_request() > is effectively replaced by the new function bdrv_create_padded_qiov(), > which not only wraps the request IOV with padding head/tail, but also > ensures that the resulting vector will not have more than IOV_MAX > elements. Putting that functionality into qemu_iovec_init_extended() is > infeasible because it requires allocating a bounce buffer; doing so > would require many more parameters (buffer alignment, how to initialize > the buffer, and out parameters like the buffer, its length, and the > original elements), which is not reasonable. > > Conversely, it is not difficult to move qemu_iovec_init_extended()'s > functionality into bdrv_create_padded_qiov() by using public > qemu_iovec_* functions, so that is what this patch does. > > Because bdrv_pad_request() was the only "serious" user of > qemu_iovec_init_extended(), the next patch will remove the latter > function, so the functionality is not implemented twice. > > Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2141964 > Signed-off-by: Hanna Czenczek > --- > block/io.c | 153 + > 1 file changed, 143 insertions(+), 10 deletions(-) Reviewed-by: Eric Blake -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [PATCH 3/4] util/iov: Remove qemu_iovec_init_extended()
On Fri, Mar 17, 2023 at 06:50:18PM +0100, Hanna Czenczek wrote: > bdrv_pad_request() was the main user of qemu_iovec_init_extended(). > HEAD^ has removed that use, so we can remove qemu_iovec_init_extended() > now. > > The only remaining user is qemu_iovec_init_slice(), which can easily > inline the small part it really needs. > > Note that qemu_iovec_init_extended() offered a memcpy() optimization to > initialize the new I/O vector. qemu_iovec_concat_iov(), which is used > to replace its functionality, does not, but calls qemu_iovec_add() for > every single element. If we decide this optimization was important, we > will need to re-implement it in qemu_iovec_concat_iov(), which might > also benefit its pre-existing users. > > Signed-off-by: Hanna Czenczek > --- > include/qemu/iov.h | 5 --- > util/iov.c | 79 +++--- > 2 files changed, 11 insertions(+), 73 deletions(-) > Reviewed-by: Eric Blake -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [PATCH 4/4] iotests/iov-padding: New test
On Fri, Mar 17, 2023 at 06:50:19PM +0100, Hanna Czenczek wrote: > Test that even vectored IO requests with 1024 vector elements that are > not aligned to the device's request alignment will succeed. > > Signed-off-by: Hanna Czenczek > --- > + > +# Four combinations: > +# - Offset 4096, length 1023 * 512 + 512: Fully aligned to 4k > +# - Offset 4096, length 1023 * 512 + 4096: Head is aligned, tail is not Making sure I understand - we don't care if intermediate iovs are smaller than the alignment requirement, because the scatter-gather effects will pool it together and our overall request is still aligned. Correct? Reviewed-by: Eric Blake -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [PATCH] doc: do not recommend -blockdev
Michael Tokarev writes: > Currently, documentation recommends to use -blockdev instead of -drive. > This is quite a bit misleading, because -blockdev is "too" low-level, > requires good knowlege of how to construct block device stack, esp. > in context of various qcow2 layers, and requires too explicit configuration. > More, quite some constructs does not work with -blockdev, - for example > this is -snapshot. > > Instead of "recommended" word, use another construct here. Could we expand the images section: https://qemu.readthedocs.io/en/latest/system/images.html to give a better overview of when you should use -device/-blockdev vs -drive? > > Signed-off-by: Michael Tokarev > --- > qemu-options.hx | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/qemu-options.hx b/qemu-options.hx > index 59bdf67a2c..8fe31b465d 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -1143,7 +1143,7 @@ have gone through several iterations as the feature set > and complexity > of the block layer have grown. Many online guides to QEMU often > reference older and deprecated options, which can lead to confusion. > > -The recommended modern way to describe disks is to use a combination of > +The low-level detailed way to describe disks is to use a combination of > ``-device`` to specify the hardware device and ``-blockdev`` to > describe the backend. The device defines what the guest sees and the > backend describes how QEMU handles the data. How about: The most explicit way to describe disks is to use a combination of ``-device`` to specify the hardware device and ``-blockdev`` to describe the backend. The device defines what the guest sees and the backend describes how QEMU handles the data. The ``--drive`` option combines the device and backend into a single command line options which is useful in the majority of cases. Older options like ``-hda`` make a bake in a lot of assumptions from the days when QEMU was emulating a legacy PC, they are not recommended for modern configurations. -- Alex Bennée Virtualisation Tech Lead @ Linaro
[PATCH for-8.0] Revert "ui: set cursor position upon listener registration"
Commit 6effaa16ac98 ("ui: set cursor position upon listener registration") causes the mouse cursor to be placed into the lower left corner when QEMU starts. This could be reproduced with just by running `qemu-system-x86_64`. This reverts commit 6effaa16ac9846e7d6197ee54a0551fba61aecd7. Signed-off-by: Bernhard Beschow --- ui/console.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/ui/console.c b/ui/console.c index f3783021e5..35f8274aab 100644 --- a/ui/console.c +++ b/ui/console.c @@ -95,7 +95,6 @@ struct QemuConsole { QemuUIInfo ui_info; QEMUTimer *ui_timer; QEMUCursor *cursor; -int cursor_x, cursor_y, cursor_on; const GraphicHwOps *hw_ops; void *hw; @@ -1666,9 +1665,6 @@ void register_displaychangelistener(DisplayChangeListener *dcl) if (con && con->cursor && dcl->ops->dpy_cursor_define) { dcl->ops->dpy_cursor_define(dcl, con->cursor); } -if (con && dcl->ops->dpy_mouse_set) { -dcl->ops->dpy_mouse_set(dcl, con->cursor_x, con->cursor_y, con->cursor_on); -} text_console_update_cursor(NULL); } @@ -1913,9 +1909,6 @@ void dpy_mouse_set(QemuConsole *con, int x, int y, int on) DisplayState *s = con->ds; DisplayChangeListener *dcl; -con->cursor_x = x; -con->cursor_y = y; -con->cursor_on = on; if (!qemu_console_is_visible(con)) { return; } -- 2.40.0
Re: [PATCH v8] audio/pwaudio.c: Add Pipewire audio backend for QEMU
Hi Dorinda, This commit adds a new audiodev backend to allow QEMU to use Pipewire as both an audio sink and source. This backend is available on most systems Add Pipewire entry points for QEMU Pipewire audio backend Add wrappers for QEMU Pipewire audio backend in qpw_pcm_ops() qpw_write function returns the current state of the stream to pwaudio and Writes some data to the server for playback streams using pipewire spa_ringbuffer implementation. qpw_read function returns the current state of the stream to pwaudio and reads some data from the server for capture streams using pipewire spa_ringbuffer implementation. These functions qpw_write and qpw_read are called during playback and capture. Added some functions that convert pw audio formats to QEMU audio format and vice versa which would be needed in the pipewire audio sink and source functions qpw_init_in() & qpw_init_out(). These methods that implement playback and recording will create streams for playback and capture that will start processing and will result in the on_process callbacks to be called. Built a connection to the Pipewire sound system server in the qpw_audio_init() method. Signed-off-by: Dorinda Bassey --- v8: Improve error handling Improve code documentation Improve latency handling Refactor playback process Add qpw_buffer_get_free method Change latency options Fix typo audio/audio.c | 3 + audio/audio_template.h| 4 + audio/meson.build | 1 + audio/pwaudio.c | 820 ++ audio/trace-events| 7 + meson.build | 8 + meson_options.txt | 4 +- qapi/audio.json | 42 ++ qemu-options.hx | 17 + scripts/meson-buildoptions.sh | 8 +- 10 files changed, 911 insertions(+), 3 deletions(-) create mode 100644 audio/pwaudio.c diff --git a/audio/audio.c b/audio/audio.c index 70b096713c..90c7c49d11 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -2061,6 +2061,9 @@ void audio_create_pdos(Audiodev *dev) #ifdef CONFIG_AUDIO_PA CASE(PA, pa, Pa); #endif +#ifdef CONFIG_AUDIO_PIPEWIRE +CASE(PIPEWIRE, pipewire, Pipewire); +#endif #ifdef CONFIG_AUDIO_SDL CASE(SDL, sdl, Sdl); #endif diff --git a/audio/audio_template.h b/audio/audio_template.h index e42326c20d..dc0c74aa74 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -362,6 +362,10 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev) case AUDIODEV_DRIVER_PA: return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE); #endif +#ifdef CONFIG_AUDIO_PIPEWIRE +case AUDIODEV_DRIVER_PIPEWIRE: +return qapi_AudiodevPipewirePerDirectionOptions_base(dev->u.pipewire.TYPE); +#endif #ifdef CONFIG_AUDIO_SDL case AUDIODEV_DRIVER_SDL: return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE); diff --git a/audio/meson.build b/audio/meson.build index 074ba9..65a49c1a10 100644 --- a/audio/meson.build +++ b/audio/meson.build @@ -19,6 +19,7 @@ foreach m : [ ['sdl', sdl, files('sdlaudio.c')], ['jack', jack, files('jackaudio.c')], ['sndio', sndio, files('sndioaudio.c')], + ['pipewire', pipewire, files('pwaudio.c')], ['spice', spice, files('spiceaudio.c')] ] if m[1].found() diff --git a/audio/pwaudio.c b/audio/pwaudio.c new file mode 100644 index 00..8d11bbb92b --- /dev/null +++ b/audio/pwaudio.c @@ -0,0 +1,820 @@ +/* + * QEMU Pipewire audio driver + * + * Copyright (c) 2023 Red Hat Inc. + * + * Author: Dorinda Bassey + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/module.h" +#include "audio.h" +#include +#include "qemu/error-report.h" +#include +#include +#include + +#include +#include "trace.h" + +#define AUDIO_CAP "pipewire" +#define RINGBUFFER_SIZE(1u << 22) +#define RINGBUFFER_MASK(RINGBUFFER_SIZE - 1) + +#include "audio_int.h" + +enum { +MODE_SINK, +MODE_SOURCE +}; + +typedef struct pwaudio { +Audiodev *dev; +struct pw_thread_loop *thread_loop; +struct pw_context *context; + +struct pw_core *core; +struct spa_hook core_listener; +int seq; +} pwaudio; + +typedef struct PWVoice { +pwaudio *g; +bool enabled; +struct pw_stream *stream; +struct spa_hook stream_listener; +struct spa_audio_info_raw info; +uint32_t highwater_mark; +uint32_t frame_size; +struct spa_ringbuffer ring; +uint8_t buffer[RINGBUFFER_SIZE]; + +uint32_t mode; +struct pw_properties *props; props is unused. +} PWVoice; + +typedef struct PWVoiceOut { +HWVoiceOut hw; +PWVoice v; +} PWVoiceOut; + +typedef struct PWVoiceIn { +HWVoiceIn hw; +PWVoice v; +} PWVoiceIn; + +static void +stream_destroy(void *data) +{ +PWVoice *v = (PWVoice *) data; +spa_hook_remove(&v->stream_listener); +v->stream = NULL; +} + +/* output data processing function to read stuffs
Re: Using QEMU how to redirect serial /dev/ttyS2 output of guest machine to host machine.
Hi Alex , Cédric, we have tried this *option:-serial *pty* -serial *pty* -serial *pty *-serial *pty *-serial *pty to check the serial output on screen. Here we are providing 2 scenarios without and with the changes suggested by @Cédric Le Goater . In first we are able to get /dev/ttyS4 serial port not /dev/ttyS2 In second we are able to get /dev/ttyS2 not /dev/ttyS4 *Scenario1:* *previously with normal qemu build i have tried emulation as:* qemu-system-arm -m 512 -M ast2500-evb,fmc-model=mx66u51235f,spi-model=mx66u 51235f -nographic -drive file=./pru-1.2.4_dev-rc1.static.mtd,format=raw,if=mtd -serial pty -serial pty -serial pty -serial pty which gives us output as. QEMU 7.2.0 monitor - type 'help' for more information (qemu) char device redirected to /dev/pts/15 (label serial0) char device redirected to /dev/pts/16 (label serial1) char device redirected to /dev/pts/17 (label serial2) char device redirected to /dev/pts/18 (label serial3) so we can use *screen *to interact with the ttyS4 serial port like : screen /dev/pts/15 In which we have our boot process and shell prompt . *Scenario2:* *when I am using the newly build image with the changes *@Cédric Le Goater * provided* With the below command: ./qemu-system-arm -m 512 -M ast2500-evb,uart-default=uart2,fmc-model=mx66u 51235f,spi-model=mx66u51235f -nographic -drive file=./pru-1.2.4_dev-rc1.static.mtd,format=raw,if=mtd -serial pty -serial pty -serial pty -serial pty got the output: QEMU 7.2.90 monitor - type 'help' for more information (qemu) char device redirected to /dev/pts/4 (label serial0) char device redirected to /dev/pts/5 (label serial1) char device redirected to /dev/pts/6 (label serial2) char device redirected to /dev/pts/7 (label serial3) where we are able to get the output of /dev/ttyS2 serial in the *screen* /dev/pts/7 but we are not getting the output of serial /dev/ttyS4 we have tried increasing the number of *-serial pty* options also and checked the output of each with a screen but no success. Can you please guide us further. Regards, Abhishek >
KVM call for agenda for 2023-03-21
Hi NOTE, NOTE, NOTE Remember that we are back in that crazy part of the year when daylight saving applies. Call is done on US timezone. If you are anything else, just doublecheck that it is working for you properly. NOTE, NOTE, NOTE Topics in the backburner: - single qemu binary Philippe? - The future of icount. Alex? My understanding is that you are interested in qemu 8.1 to open. Anything else? Please, send any topic that you are interested in covering. At the end of Monday I will send an email with the agenda or the cancellation of the call, so hurry up. After discussions on the QEMU Summit, we are going to have always open a KVM call where you can add topics. Call details: By popular demand, a google calendar public entry with it https://calendar.google.com/calendar/event?action=TEMPLATE&tmeid=NWR0NWppODdqNXFyYzAwbzYza3RxN2dob3VfMjAyMjEwMThUMTMwMDAwWiBlZ2VkN2NraTA1bG11MXRuZ3ZrbDN0aGlkc0Bn&tmsrc=eged7cki05lmu1tngvkl3thids%40group.calendar.google.com&scp=ALL (Let me know if you have any problems with the calendar entry. I just gave up about getting right at the same time CEST, CET, EDT and DST). If you need phone number details, contact me privately Thanks, Juan.
Should I record QEMU developers fortnightly call?
Hi I got asked several times if we have a record of previous QEMU calls. I think that we don't discuss anything that prevent us for recording the calls. But they have never been recorded in the past. Could we discuss if should record them and make the recordings available, or not? Is there anyone that has any strong opinion in any of the two directions? Thanks, Juan.
[PATCH for 8.0] qemu/osdep: Switch position of "extern" and "G_NORETURN"
Fixes the Windows build under msys2 using GCC 12 which fails with the following error: [184/579] Compiling C++ object qga/vss-win32/qga-vss.dll.p/install.cpp.obj FAILED: qga/vss-win32/qga-vss.dll.p/install.cpp.obj "c++" "-m64" "-mcx16" "-Iqga/vss-win32/qga-vss.dll.p" "-Iqga/vss-win32" "-I../src/qga/vss-win32" "-I." "-Iqapi" "-Itrace" "-Iui" "-Iui/shader" "-IC:/msys64/mingw64/include/glib-2.0" "-IC:/msys64/mingw64/lib/glib-2.0/include" "-fdiagnostics-color=auto" "-Wall" "-Winvalid-pch" "-Wnon-virtual-dtor" "-Werror" "-std=gnu++11" "-g" "-iquote" "." "-iquote" "C:/msys64/home/shentey/Projects/qemu/src" "-iquote" "C:/msys64/home/shentey/Projects/qemu/src/include" "-iquote" "C:/msys64/home/shentey/Projects/qemu/src/tcg/i386" "-D__STDC_LIMIT_MACROS" "-D__STDC_CONSTANT_MACROS" "-D__STDC_FORMAT_MACROS" "-fno-pie" "-no-pie" "-D_GNU_SOURCE" "-D_FILE_OFFSET_BITS=64" "-D_LARGEFILE_SOURCE" "-fno-strict-aliasing" "-fno-common" "-fwrapv" "-Wundef" "-Wwrite-strings" "-Wtype-limits" "-Wformat-security" "-Wformat-y2k" "-Winit-self" "-Wignored-qualifiers" "-Wempty-body" "-Wendif-labels" "-Wexpansion-to-defined" "-Wimplicit-fallthrough=2" "-Wmissing-format-attribute" "-Wno-missing-include-dirs" "-Wno-shift-negative-value" "-Wno-psabi" "-fstack-protector-strong" "-Wno-unknown-pragmas" "-Wno-delete-non-virtual-dtor" "-Wno-non-virtual-dtor" -MD -MQ qga/vss-win32/qga-vss.dll.p/install.cpp.obj -MF "qga/vss-win32/qga-vss.dll.p/install.cpp.obj.d" -o qga/vss-win32/qga-vss.dll.p/install.cpp.obj "-c" ../src/qga/vss-win32/install.cpp In file included from C:/msys64/mingw64/lib/glib-2.0/include/glibconfig.h:9, from C:/msys64/mingw64/include/glib-2.0/glib/gtypes.h:34, from C:/msys64/mingw64/include/glib-2.0/glib/galloca.h:34, from C:/msys64/mingw64/include/glib-2.0/glib.h:32, from C:/msys64/home/shentey/Projects/qemu/src/include/glib-compat.h:32, from C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:144, from ../src/qga/vss-win32/install.cpp:13: C:/msys64/mingw64/include/glib-2.0/glib/gmacros.h:1075:21: error: standard attributes in middle of decl-specifiers 1075 | # define G_NORETURN [[noreturn]] | ^ C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:240:8: note: in expansion of macro 'G_NORETURN' 240 | extern G_NORETURN |^~ C:/msys64/mingw64/include/glib-2.0/glib/gmacros.h:1075:21: note: standard attributes must precede the decl-specifiers to apply to the declaration, or follow them to apply to the type 1075 | # define G_NORETURN [[noreturn]] | ^ C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:240:8: note: in expansion of macro 'G_NORETURN' 240 | extern G_NORETURN |^~ C:/msys64/mingw64/include/glib-2.0/glib/gmacros.h:1075:21: error: attribute ignored [-Werror=attributes] 1075 | # define G_NORETURN [[noreturn]] | ^ C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:240:8: note: in expansion of macro 'G_NORETURN' 240 | extern G_NORETURN |^~ C:/msys64/mingw64/include/glib-2.0/glib/gmacros.h:1075:21: note: an attribute that appertains to a type-specifier is ignored 1075 | # define G_NORETURN [[noreturn]] | ^ C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:240:8: note: in expansion of macro 'G_NORETURN' 240 | extern G_NORETURN |^~ cc1plus.exe: all warnings being treated as errors Apparently it also fixes the compilation with Clang 15 (see https://gitlab.com/qemu-project/qemu/-/issues/1541 ). Signed-off-by: Bernhard Beschow --- include/qemu/osdep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index f68b5d8708..9eff0be95b 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -237,7 +237,7 @@ extern "C" { * supports QEMU_ERROR, this will be reported at compile time; otherwise * this will be reported at link time due to the missing symbol. */ -extern G_NORETURN +G_NORETURN extern void QEMU_ERROR("code path is reachable") qemu_build_not_reached_always(void); #if defined(__OPTIMIZE__) && !defined(__NO_INLINE__) -- 2.40.0
[PATCH for-8.1 v3 10/26] target/riscv/cpu.c: avoid set_misa() in validate_set_extensions()
set_misa() will be tuned up to do more than it's already doing and it will be redundant to what riscv_cpu_validate_set_extensions() does. Note that we don't ever change env->misa_mlx in this function, so set_misa() can be replaced by just assigning env->misa_ext and env->misa_ext_mask to 'ext'. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index c7b6e7b84b..36c55abda0 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -949,7 +949,8 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) /* * Check consistency between chosen extensions while setting - * cpu->cfg accordingly, doing a set_misa() in the end. + * cpu->cfg accordingly, setting env->misa_ext and + * misa_ext_mask in the end. */ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) { @@ -1168,7 +1169,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) ext |= RVJ; } -set_misa(env, env->misa_mxl, ext); +env->misa_ext_mask = env->misa_ext = ext; } #ifndef CONFIG_USER_ONLY -- 2.39.2
[PATCH for-8.1 v3 03/26] target/riscv/cpu.c: remove set_priv_version()
The setter is doing nothing special. Just set env->priv_ver directly. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 30 +- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 2752efe1eb..18032dfd4e 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -240,11 +240,6 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) env->misa_ext_mask = env->misa_ext = ext; } -static void set_priv_version(CPURISCVState *env, int priv_ver) -{ -env->priv_ver = priv_ver; -} - #ifndef CONFIG_USER_ONLY static uint8_t satp_mode_from_str(const char *satp_mode_str) { @@ -343,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj) VM_1_10_SV32 : VM_1_10_SV57); #endif -set_priv_version(env, PRIV_VERSION_1_12_0); +env->priv_ver = PRIV_VERSION_1_12_0; register_cpu_props(obj); } @@ -355,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj) set_misa(env, MXL_RV64, 0); register_cpu_props(obj); /* Set latest version of privileged specification */ -set_priv_version(env, PRIV_VERSION_1_12_0); +env->priv_ver = PRIV_VERSION_1_12_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); #endif @@ -366,7 +361,7 @@ static void rv64_sifive_u_cpu_init(Object *obj) CPURISCVState *env = &RISCV_CPU(obj)->env; set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); register_cpu_props(obj); -set_priv_version(env, PRIV_VERSION_1_10_0); +env->priv_ver = PRIV_VERSION_1_10_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39); #endif @@ -379,7 +374,7 @@ static void rv64_sifive_e_cpu_init(Object *obj) set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU); register_cpu_props(obj); -set_priv_version(env, PRIV_VERSION_1_10_0); +env->priv_ver = PRIV_VERSION_1_10_0; cpu->cfg.mmu = false; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); @@ -392,7 +387,7 @@ static void rv64_thead_c906_cpu_init(Object *obj) RISCVCPU *cpu = RISCV_CPU(obj); set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); -set_priv_version(env, PRIV_VERSION_1_11_0); +env->priv_ver = PRIV_VERSION_1_11_0; cpu->cfg.ext_g = true; cpu->cfg.ext_c = true; @@ -431,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj) set_misa(env, MXL_RV128, 0); register_cpu_props(obj); /* Set latest version of privileged specification */ -set_priv_version(env, PRIV_VERSION_1_12_0); +env->priv_ver = PRIV_VERSION_1_12_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); #endif @@ -444,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj) set_misa(env, MXL_RV32, 0); register_cpu_props(obj); /* Set latest version of privileged specification */ -set_priv_version(env, PRIV_VERSION_1_12_0); +env->priv_ver = PRIV_VERSION_1_12_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); #endif @@ -454,8 +449,9 @@ static void rv32_sifive_u_cpu_init(Object *obj) { CPURISCVState *env = &RISCV_CPU(obj)->env; set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); + register_cpu_props(obj); -set_priv_version(env, PRIV_VERSION_1_10_0); +env->priv_ver = PRIV_VERSION_1_10_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); #endif @@ -468,7 +464,7 @@ static void rv32_sifive_e_cpu_init(Object *obj) set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU); register_cpu_props(obj); -set_priv_version(env, PRIV_VERSION_1_10_0); +env->priv_ver = PRIV_VERSION_1_10_0; cpu->cfg.mmu = false; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); @@ -482,7 +478,7 @@ static void rv32_ibex_cpu_init(Object *obj) set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU); register_cpu_props(obj); -set_priv_version(env, PRIV_VERSION_1_11_0); +env->priv_ver = PRIV_VERSION_1_11_0; cpu->cfg.mmu = false; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); @@ -497,7 +493,7 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj) set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU); register_cpu_props(obj); -set_priv_version(env, PRIV_VERSION_1_10_0); +env->priv_ver = PRIV_VERSION_1_10_0; cpu->cfg.mmu = false; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); @@ -1160,7 +1156,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } if (priv_version >= PRIV_VERSION_1_10_0) { -set_priv_version(env, priv_version); +env->priv_ver = priv_version; } /* Force disable extensions if priv spec version does not match */ -- 2.39.
[PATCH for-8.1 v3 08/26] target/riscv/cpu.c: validate extensions before riscv_timer_init()
There is no need to init timers if we're not even sure that our extensions are valid. Execute riscv_cpu_validate_set_extensions() before riscv_timer_init(). Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 7458845fec..fef55d7d79 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1237,12 +1237,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } -#ifndef CONFIG_USER_ONLY -if (cpu->cfg.ext_sstc) { -riscv_timer_init(cpu); -} -#endif /* CONFIG_USER_ONLY */ - riscv_cpu_validate_set_extensions(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); @@ -1250,6 +1244,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } #ifndef CONFIG_USER_ONLY +if (cpu->cfg.ext_sstc) { +riscv_timer_init(cpu); +} + if (cpu->cfg.pmu_num) { if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) { cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, -- 2.39.2
[PATCH for-8.1 v3 04/26] target/riscv: add PRIV_VERSION_LATEST
All these generic CPUs are using the latest priv available, at this moment PRIV_VERSION_1_12_0: - riscv_any_cpu_init() - rv32_base_cpu_init() - rv64_base_cpu_init() - rv128_base_cpu_init() Create a new PRIV_VERSION_LATEST enum and use it in those cases. I'll make it easier to update everything at once when a new priv version is available. Reviewed-by: Richard Henderson Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 8 target/riscv/cpu.h | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 18032dfd4e..1ee322001b 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -338,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj) VM_1_10_SV32 : VM_1_10_SV57); #endif -env->priv_ver = PRIV_VERSION_1_12_0; +env->priv_ver = PRIV_VERSION_LATEST; register_cpu_props(obj); } @@ -350,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj) set_misa(env, MXL_RV64, 0); register_cpu_props(obj); /* Set latest version of privileged specification */ -env->priv_ver = PRIV_VERSION_1_12_0; +env->priv_ver = PRIV_VERSION_LATEST; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); #endif @@ -426,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj) set_misa(env, MXL_RV128, 0); register_cpu_props(obj); /* Set latest version of privileged specification */ -env->priv_ver = PRIV_VERSION_1_12_0; +env->priv_ver = PRIV_VERSION_LATEST; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); #endif @@ -439,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj) set_misa(env, MXL_RV32, 0); register_cpu_props(obj); /* Set latest version of privileged specification */ -env->priv_ver = PRIV_VERSION_1_12_0; +env->priv_ver = PRIV_VERSION_LATEST; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); #endif diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 638e47c75a..76f81c6b68 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -88,6 +88,8 @@ enum { PRIV_VERSION_1_10_0 = 0, PRIV_VERSION_1_11_0, PRIV_VERSION_1_12_0, + +PRIV_VERSION_LATEST = PRIV_VERSION_1_12_0, }; #define VEXT_VERSION_1_00_0 0x0001 -- 2.39.2
[PATCH for-8.1 v3 13/26] target/riscv: put env->misa_ext <-> cpu->cfg code into helpers
The extremely tedious code that sets cpu->cfg based on misa_ext, and vice-versa, is scattered around riscv_cpu_validate_set_extensions() and set_misa(). Introduce helpers to do this work, cleaning up the logic of both functions a bit. While we're at it, add a note in cpu.h informing that any future change in MISA RV* bits should also be reflected in the helpers as well. We'll want to keep env->misa_ext changes in sync with cpu->cfg during realize() in the next patches, and both helpers will have a role to play in that. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 120 - target/riscv/cpu.h | 3 +- 2 files changed, 65 insertions(+), 58 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 6b5096d25e..28d4c5f768 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -234,10 +234,69 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async) } } -static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) +static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg) { -RISCVCPU *cpu; +uint32_t ext = 0; +if (cfg->ext_i) { +ext |= RVI; +} +if (cfg->ext_e) { +ext |= RVE; +} +if (cfg->ext_m) { +ext |= RVM; +} +if (cfg->ext_a) { +ext |= RVA; +} +if (cfg->ext_f) { +ext |= RVF; +} +if (cfg->ext_d) { +ext |= RVD; +} +if (cfg->ext_c) { +ext |= RVC; +} +if (cfg->ext_s) { +ext |= RVS; +} +if (cfg->ext_u) { +ext |= RVU; +} +if (cfg->ext_h) { +ext |= RVH; +} +if (cfg->ext_v) { +ext |= RVV; +} +if (cfg->ext_j) { +ext |= RVJ; +} + +return ext; +} + +static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg, + uint32_t misa_ext) +{ +cfg->ext_i = misa_ext & RVI; +cfg->ext_e = misa_ext & RVE; +cfg->ext_m = misa_ext & RVM; +cfg->ext_a = misa_ext & RVA; +cfg->ext_f = misa_ext & RVF; +cfg->ext_d = misa_ext & RVD; +cfg->ext_v = misa_ext & RVV; +cfg->ext_c = misa_ext & RVC; +cfg->ext_s = misa_ext & RVS; +cfg->ext_u = misa_ext & RVU; +cfg->ext_h = misa_ext & RVH; +cfg->ext_j = misa_ext & RVJ; +} + +static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) +{ env->misa_mxl_max = env->misa_mxl = mxl; env->misa_ext_mask = env->misa_ext = ext; @@ -251,25 +310,7 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) return; } -/* - * We can't use riscv_cpu_cfg() in this case because it is - * a read-only inline and we're going to change the values - * of cpu->cfg. - */ -cpu = env_archcpu(env); - -cpu->cfg.ext_i = ext & RVI; -cpu->cfg.ext_e = ext & RVE; -cpu->cfg.ext_m = ext & RVM; -cpu->cfg.ext_a = ext & RVA; -cpu->cfg.ext_f = ext & RVF; -cpu->cfg.ext_d = ext & RVD; -cpu->cfg.ext_v = ext & RVV; -cpu->cfg.ext_c = ext & RVC; -cpu->cfg.ext_s = ext & RVS; -cpu->cfg.ext_u = ext & RVU; -cpu->cfg.ext_h = ext & RVH; -cpu->cfg.ext_j = ext & RVJ; +riscv_set_cpucfg_with_misa(&env_archcpu(env)->cfg, ext); } #ifndef CONFIG_USER_ONLY @@ -1156,42 +1197,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) */ riscv_cpu_disable_priv_spec_isa_exts(cpu); -if (cpu->cfg.ext_i) { -ext |= RVI; -} -if (cpu->cfg.ext_e) { -ext |= RVE; -} -if (cpu->cfg.ext_m) { -ext |= RVM; -} -if (cpu->cfg.ext_a) { -ext |= RVA; -} -if (cpu->cfg.ext_f) { -ext |= RVF; -} -if (cpu->cfg.ext_d) { -ext |= RVD; -} -if (cpu->cfg.ext_c) { -ext |= RVC; -} -if (cpu->cfg.ext_s) { -ext |= RVS; -} -if (cpu->cfg.ext_u) { -ext |= RVU; -} -if (cpu->cfg.ext_h) { -ext |= RVH; -} -if (cpu->cfg.ext_v) { -ext |= RVV; -} -if (cpu->cfg.ext_j) { -ext |= RVJ; -} +ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg); env->misa_ext_mask = env->misa_ext = ext; } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index ebe0fff668..2263629332 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -66,7 +66,8 @@ #define RV(x) ((target_ulong)1 << (x - 'A')) /* - * Consider updating set_misa() when adding new + * Consider updating riscv_get_misa_ext_with_cpucfg() + * and riscv_set_cpucfg_with_misa() when adding new * MISA bits here. */ #define RVI RV('I') -- 2.39.2
[PATCH for-8.1 v3 24/26] target/riscv: update cpu->cfg misa bits in commit_cpu_cfg()
write_misa() is able to use the same validation workflow riscv_cpu_realize() uses. But it's still not capable of updating cpu->cfg misa props yet. We have no way of blocking future (and current) code from checking env->misa_ext (via riscv_has_ext()) or reading cpu->cfg directly, so our best alternative is to keep everything in sync. riscv_cpu_commit_cpu_cfg() now receives an extra 'misa_ext' parameter. If this val is different from the existing env->misa_ext, update env->misa and cpu->cfg with the new value. riscv_cpu_realize() will ignore this code since env->misa_ext isn't touched during validation, but write_misa() will use it to keep cpu->cfg in sync with the new env->misa_ext value. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 16 ++-- target/riscv/cpu.h | 2 +- target/riscv/csr.c | 3 +-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 67a46504bb..2d2a354af3 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1213,8 +1213,20 @@ void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext, } } -void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu) +void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu, uint32_t misa_ext) { +CPURISCVState *env = &cpu->env; + +/* + * write_misa() needs to update cpu->cfg with the new + * MISA bits. This is a no-op for the riscv_cpu_realize() + * path. + */ +if (env->misa_ext != misa_ext) { +env->misa_ext = misa_ext; +riscv_set_cpucfg_with_misa(&cpu->cfg, misa_ext); +} + if (cpu->cfg.ext_zk) { cpu->cfg.ext_zkn = true; cpu->cfg.ext_zkr = true; @@ -1383,7 +1395,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } -riscv_cpu_commit_cpu_cfg(cpu); +riscv_cpu_commit_cpu_cfg(cpu, env->misa_ext); #ifndef CONFIG_USER_ONLY if (cpu->cfg.ext_sstc) { diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index ca2ba6a647..befc3b8fff 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -597,7 +597,7 @@ void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext, Error **errp); void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext, Error **errp); -void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu); +void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu, uint32_t misa_ext); #define cpu_list riscv_cpu_list #define cpu_mmu_index riscv_cpu_mmu_index diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 8d5e8f9ad1..839862f1a8 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1396,7 +1396,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -riscv_cpu_commit_cpu_cfg(cpu); +riscv_cpu_commit_cpu_cfg(cpu, val); if (!(val & RVF)) { env->mstatus &= ~MSTATUS_FS; @@ -1404,7 +1404,6 @@ static RISCVException write_misa(CPURISCVState *env, int csrno, /* flush translation cache */ tb_flush(env_cpu(env)); -env->misa_ext = val; env->xl = riscv_cpu_mxl(env); return RISCV_EXCP_NONE; } -- 2.39.2
[PATCH for-8.1 v3 15/26] target/riscv/cpu.c: split RVG code from validate_set_extensions()
We can set all RVG related extensions during realize time, before validate_set_extensions() itself. Put it in a separated function so the validate function already uses the updated state. Note that we're adding an extra constraint: ext_zfinx is a blocker for F, which is a requirement to enable G. If zfinx is enabled we'll have to error out. Note that we're setting both cfg->ext_N and env->misa_ext bits, instead of just setting cfg->ext_N. The intention here is to start syncing all misa_ext operations with its cpu->cfg flags, in preparation to allow for the validate function to operate using a misa_ext. This doesn't make any difference for the current code state, but will be a requirement for write_misa() later on. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 66 +++--- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 48ad7372b9..110b52712c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -281,6 +281,42 @@ static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg) return ext; } +static void riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp) +{ +CPURISCVState *env = &cpu->env; +RISCVCPUConfig *cfg = &cpu->cfg; + +if (cpu->cfg.ext_zfinx) { +error_setg(errp, "Unable to enable G: Zfinx is enabled, " + "so F can not be enabled"); +return; +} + +if (!(cfg->ext_i && cfg->ext_m && cfg->ext_a && + cfg->ext_f && cfg->ext_d && + cfg->ext_icsr && cfg->ext_ifencei)) { + +warn_report("Setting G will also set IMAFD_Zicsr_Zifencei"); +cfg->ext_i = true; +env->misa_ext |= RVI; + +cfg->ext_m = true; +env->misa_ext |= RVM; + +cfg->ext_a = true; +env->misa_ext |= RVA; + +cfg->ext_f = true; +env->misa_ext |= RVF; + +cfg->ext_d = true; +env->misa_ext |= RVD; + +cfg->ext_icsr = true; +cfg->ext_ifencei = true; +} +} + static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg, uint32_t misa_ext) { @@ -1036,21 +1072,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) return; } -/* Do some ISA extension error checking */ -if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m && -cpu->cfg.ext_a && cpu->cfg.ext_f && -cpu->cfg.ext_d && -cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) { -warn_report("Setting G will also set IMAFD_Zicsr_Zifencei"); -cpu->cfg.ext_i = true; -cpu->cfg.ext_m = true; -cpu->cfg.ext_a = true; -cpu->cfg.ext_f = true; -cpu->cfg.ext_d = true; -cpu->cfg.ext_icsr = true; -cpu->cfg.ext_ifencei = true; -} - if (cpu->cfg.ext_i && cpu->cfg.ext_e) { error_setg(errp, "I and E extensions are incompatible"); @@ -1293,6 +1314,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) CPUState *cs = CPU(dev); RISCVCPU *cpu = RISCV_CPU(dev); RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); +CPURISCVState *env = &cpu->env; Error *local_err = NULL; cpu_exec_realizefn(cs, &local_err); @@ -1313,6 +1335,20 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } +if (cpu->cfg.ext_g) { +riscv_cpu_enable_g(cpu, &local_err); +if (local_err != NULL) { +error_propagate(errp, local_err); +return; +} + +/* + * Sync env->misa_ext_mask with the new + * env->misa_ext val. + */ +env->misa_ext_mask = env->misa_ext; +} + riscv_cpu_validate_set_extensions(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); -- 2.39.2
[PATCH for-8.1 v3 05/26] target/riscv/cpu.c: add priv_spec validate/disable_exts helpers
We're doing env->priv_spec validation and assignment at the start of riscv_cpu_realize(), which is fine, but then we're doing a force disable on extensions that aren't compatible with the priv version. This second step is being done too early. The disabled extensions might be re-enabled again in riscv_cpu_validate_set_extensions() by accident. A better place to put this code is at the end of riscv_cpu_validate_set_extensions() after all the validations are completed. Add a new helper, riscv_cpu_disable_priv_spec_isa_exts(), to disable the extesions after the validation is done. While we're at it, create a riscv_cpu_validate_priv_spec() helper to host all env->priv_spec related validation to unclog riscv_cpu_realize a bit. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 91 -- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1ee322001b..17b301967c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -833,6 +833,52 @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, env->vext_ver = vext_version; } +static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp) +{ +CPURISCVState *env = &cpu->env; +int priv_version = -1; + +if (cpu->cfg.priv_spec) { +if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) { +priv_version = PRIV_VERSION_1_12_0; +} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) { +priv_version = PRIV_VERSION_1_11_0; +} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) { +priv_version = PRIV_VERSION_1_10_0; +} else { +error_setg(errp, + "Unsupported privilege spec version '%s'", + cpu->cfg.priv_spec); +return; +} + +env->priv_ver = priv_version; +} +} + +static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) +{ +CPURISCVState *env = &cpu->env; +int i; + +/* Force disable extensions if priv spec version does not match */ +for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { +if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) && +(env->priv_ver < isa_edata_arr[i].min_version)) { +isa_ext_update_enabled(cpu, &isa_edata_arr[i], false); +#ifndef CONFIG_USER_ONLY +warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx +" because privilege spec version does not match", +isa_edata_arr[i].name, env->mhartid); +#else +warn_report("disabling %s extension because " +"privilege spec version does not match", +isa_edata_arr[i].name); +#endif +} +} +} + /* * Check consistency between chosen extensions while setting * cpu->cfg accordingly, doing a set_misa() in the end. @@ -1002,6 +1048,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) cpu->cfg.ext_zksh = true; } +/* + * Disable isa extensions based on priv spec after we + * validated and set everything we need. + */ +riscv_cpu_disable_priv_spec_isa_exts(cpu); + if (cpu->cfg.ext_i) { ext |= RVI; } @@ -1131,7 +1183,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) CPURISCVState *env = &cpu->env; RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); CPUClass *cc = CPU_CLASS(mcc); -int i, priv_version = -1; Error *local_err = NULL; cpu_exec_realizefn(cs, &local_err); @@ -1140,40 +1191,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } -if (cpu->cfg.priv_spec) { -if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) { -priv_version = PRIV_VERSION_1_12_0; -} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) { -priv_version = PRIV_VERSION_1_11_0; -} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) { -priv_version = PRIV_VERSION_1_10_0; -} else { -error_setg(errp, - "Unsupported privilege spec version '%s'", - cpu->cfg.priv_spec); -return; -} -} - -if (priv_version >= PRIV_VERSION_1_10_0) { -env->priv_ver = priv_version; -} - -/* Force disable extensions if priv spec version does not match */ -for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { -if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) && -(env->priv_ver < isa_edata_arr[i].min_version)) { -isa_ext_update_enabled(cpu, &isa_edata_arr[i], false); -#ifndef CONFIG_USER_ONLY -warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx -" because privilege spec version does not match", -isa_edata_arr[i].name, env->mhartid); -#else -warn_report("disablin
[PATCH for-8.1 v3 26/26] target/riscv: allow write_misa() to enable RVV
Allow write_misa() to enable RVV like we did with RVG. We'll need a riscv_cpu_enable_v() to enable all related misa bits and Z extensions. This new helper validates the existing 'env' conf by using the existing riscv_cpu_validate_v(). We'll also check if we'll be able to enable 'F' by checking for ext_zfinx. As with RVG, enabling RVV is considered to be a standalone operation in write_misa(). This means that we'll guarantee that we're not being inconsistent in riscv_cpu_enable_v() and that we're okay with skipping regular validation. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 35 +++ target/riscv/cpu.h | 1 + target/riscv/csr.c | 14 ++ 3 files changed, 50 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 73a5fa46ee..9c16b29f27 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -983,6 +983,41 @@ static void riscv_cpu_validate_v(CPURISCVState *env, env->vext_ver = vext_version; } +target_ulong riscv_cpu_enable_v(RISCVCPU *cpu, Error **errp) +{ +CPURISCVState *env = &cpu->env; +RISCVCPUConfig *cfg = &cpu->cfg; +Error *local_err = NULL; + +riscv_cpu_validate_v(env, cfg, &local_err); +if (local_err != NULL) { +error_propagate(errp, local_err); +return 0; +} + +if (cpu->cfg.ext_zfinx) { +error_setg(errp, "Unable to enable V: Zfinx is enabled, " + "so F can not be enabled"); +return 0; +} + +cfg->ext_f = true; +env->misa_ext |= RVF; + +cfg->ext_d = true; +env->misa_ext |= RVD; + +/* + * The V vector extension depends on the + * Zve32f, Zve64f and Zve64d extensions. + */ +cpu->cfg.ext_zve64d = true; +cpu->cfg.ext_zve64f = true; +cpu->cfg.ext_zve32f = true; + +return env->misa_ext; +} + static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp) { CPURISCVState *env = &cpu->env; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 3ca1d4903c..45e801d926 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -600,6 +600,7 @@ void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext, void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu, uint32_t misa_ext); target_ulong riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp); +target_ulong riscv_cpu_enable_v(RISCVCPU *cpu, Error **errp); #define cpu_list riscv_cpu_list #define cpu_mmu_index riscv_cpu_mmu_index diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 4335398c19..e9e1afc57e 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1395,6 +1395,20 @@ static RISCVException write_misa(CPURISCVState *env, int csrno, goto commit; } +if (val & RVV && !(env->misa_ext & RVV)) { +/* + * If the write wants to enable RVV, only RVV and + * its dependencies will be updated in the CSR. + */ +val = riscv_cpu_enable_v(cpu, &local_err); +if (local_err != NULL) { +return RISCV_EXCP_NONE; +} + +val |= RVV; +goto commit; +} + /* * This flow is similar to what riscv_cpu_realize() does, * with the difference that we will update env->misa_ext -- 2.39.2
[PATCH for-8.1 v3 25/26] target/riscv: allow write_misa() to enable RVG
Allow write_misa() to enable RVG by changing riscv_cpu_enable_g() slighty: instead of returning void, return the current env->misa_ext value. This is then retrieved by 'val', which will add the RVG flag itself, and then we'll skip validation and go right into commiting the changes. The reason why it's ok to skip validation in this case is because we're only allowing RVG (and its associated extensions/Z extensions) to be enabled in the hart, and riscv_cpu_enable_g() already does its own validation before enabling itself. Everything else is considered to be already validated beforehand, so we don't need to repeat ourselves. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 7 +-- target/riscv/cpu.h | 2 ++ target/riscv/csr.c | 15 +++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 2d2a354af3..73a5fa46ee 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -281,7 +281,8 @@ static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg) return ext; } -static void riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp) + +target_ulong riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp) { CPURISCVState *env = &cpu->env; RISCVCPUConfig *cfg = &cpu->cfg; @@ -289,7 +290,7 @@ static void riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp) if (cpu->cfg.ext_zfinx) { error_setg(errp, "Unable to enable G: Zfinx is enabled, " "so F can not be enabled"); -return; +return 0; } if (!(cfg->ext_i && cfg->ext_m && cfg->ext_a && @@ -315,6 +316,8 @@ static void riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp) cfg->ext_icsr = true; cfg->ext_ifencei = true; } + +return env->misa_ext; } static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg, diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index befc3b8fff..3ca1d4903c 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -599,6 +599,8 @@ void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext, Error **errp); void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu, uint32_t misa_ext); +target_ulong riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp); + #define cpu_list riscv_cpu_list #define cpu_mmu_index riscv_cpu_mmu_index diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 839862f1a8..4335398c19 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1381,6 +1381,20 @@ static RISCVException write_misa(CPURISCVState *env, int csrno, val &= RVE; } +if (val & RVG && !(env->misa_ext & RVG)) { +/* + * If the write wants to enable RVG, only RVG and + * its dependencies will be updated in the CSR. + */ +val = riscv_cpu_enable_g(cpu, &local_err); +if (local_err != NULL) { +return RISCV_EXCP_NONE; +} + +val |= RVG; +goto commit; +} + /* * This flow is similar to what riscv_cpu_realize() does, * with the difference that we will update env->misa_ext @@ -1396,6 +1410,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +commit: riscv_cpu_commit_cpu_cfg(cpu, val); if (!(val & RVF)) { -- 2.39.2
[PATCH for-8.1 v3 16/26] target/riscv/cpu.c: add riscv_cpu_validate_misa_ext()
Even after taking RVG off from riscv_cpu_validate_set_extensions(), the function is still doing too much. It is validating misa bits, then validating named extensions, and if the validation succeeds it's doing more changes in both cpu->cfg and MISA bits. It works for the support we have today, since we'll error out during realize() time. This is not enough to support write_misa() though - we don't want to error out if userspace writes something odd in the CSR. This patch starts splitting riscv_cpu_validate_set_extensions() into a three step process: validate misa_ext, validate cpu->cfg, then commit the configuration. This separation will allow us to use these functions in write_misa() without having to worry about saving CPU state during runtime because the function changed state but failed to validate. riscv_cpu_validate_misa_ext() will host all validations related to misa bits only. Validations using misa bits + name extensions will remain in validate_set_extensions(). Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 77 ++ 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 110b52712c..c7b05d7c4e 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1025,6 +1025,43 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) } } +static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp) +{ +if (cpu->cfg.ext_i && cpu->cfg.ext_e) { +error_setg(errp, + "I and E extensions are incompatible"); +return; +} + +if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { +error_setg(errp, + "Either I or E extension must be set"); +return; +} + +if (cpu->cfg.ext_s && !cpu->cfg.ext_u) { +error_setg(errp, + "Setting S extension without U extension is illegal"); +return; +} + +if (cpu->cfg.ext_h && !cpu->cfg.ext_i) { +error_setg(errp, + "H depends on an I base integer ISA with 32 x registers"); +return; +} + +if (cpu->cfg.ext_h && !cpu->cfg.ext_s) { +error_setg(errp, "H extension implicitly requires S-mode"); +return; +} + +if (cpu->cfg.ext_d && !cpu->cfg.ext_f) { +error_setg(errp, "D extension requires F extension"); +return; +} +} + static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) { RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); @@ -1072,35 +1109,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) return; } -if (cpu->cfg.ext_i && cpu->cfg.ext_e) { -error_setg(errp, - "I and E extensions are incompatible"); -return; -} - -if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { -error_setg(errp, - "Either I or E extension must be set"); -return; -} - -if (cpu->cfg.ext_s && !cpu->cfg.ext_u) { -error_setg(errp, - "Setting S extension without U extension is illegal"); -return; -} - -if (cpu->cfg.ext_h && !cpu->cfg.ext_i) { -error_setg(errp, - "H depends on an I base integer ISA with 32 x registers"); -return; -} - -if (cpu->cfg.ext_h && !cpu->cfg.ext_s) { -error_setg(errp, "H extension implicitly requires S-mode"); -return; -} - if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) { error_setg(errp, "F extension requires Zicsr"); return; @@ -1120,11 +1128,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) return; } -if (cpu->cfg.ext_d && !cpu->cfg.ext_f) { -error_setg(errp, "D extension requires F extension"); -return; -} - /* The V vector extension depends on the Zve64d extension */ if (cpu->cfg.ext_v) { cpu->cfg.ext_zve64d = true; @@ -1349,6 +1352,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) env->misa_ext_mask = env->misa_ext; } +riscv_cpu_validate_misa_ext(cpu, &local_err); +if (local_err != NULL) { +error_propagate(errp, local_err); +return; +} + riscv_cpu_validate_set_extensions(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); -- 2.39.2
[PATCH for-8.1 v3 17/26] target/riscv: move riscv_cpu_validate_v() to validate_misa_ext()
riscv_cpu_validate_v() consists of checking RVV related attributes, such as vlen and elen, and setting env->vext_spec. This can be done during riscv_cpu_validate_misa_ext() time, allowing us to fail earlier if RVV constrains are not met. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index c7b05d7c4e..1116686cd1 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1027,6 +1027,9 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp) { +CPURISCVState *env = &cpu->env; +Error *local_err = NULL; + if (cpu->cfg.ext_i && cpu->cfg.ext_e) { error_setg(errp, "I and E extensions are incompatible"); @@ -1060,6 +1063,14 @@ static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp) error_setg(errp, "D extension requires F extension"); return; } + +if (cpu->cfg.ext_v) { +riscv_cpu_validate_v(env, &cpu->cfg, &local_err); +if (local_err != NULL) { +error_propagate(errp, local_err); +return; +} +} } static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) @@ -1097,7 +1108,6 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) { CPURISCVState *env = &cpu->env; -Error *local_err = NULL; uint32_t ext = 0; if (cpu->cfg.epmp && !cpu->cfg.pmp) { @@ -1188,14 +1198,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) } } -if (cpu->cfg.ext_v) { -riscv_cpu_validate_v(env, &cpu->cfg, &local_err); -if (local_err != NULL) { -error_propagate(errp, local_err); -return; -} -} - if (cpu->cfg.ext_zk) { cpu->cfg.ext_zkn = true; cpu->cfg.ext_zkr = true; -- 2.39.2
[PATCH for-8.1 v3 18/26] target/riscv: error out on priv failure for RVH
riscv_cpu_disable_priv_spec_isa_exts(), at the end of riscv_cpu_validate_set_extensions(), will disable cpu->cfg.ext_h and cpu->cfg.ext_v if priv_ver check fails. This check can be done in riscv_cpu_validate_misa_ext(). The difference here is that we're not silently disable it: we'll error out. Silently disabling a MISA extension after all the validation is completed can can cause inconsistencies that we don't have to deal with. Verify ealier and fail faster. Note that we're ignoring RVV priv_ver validation since its minimal priv is also the minimal value we support. RVH will error out if enabled under priv_ver under 1_12_0. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1116686cd1..d8f2eca6ca 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1064,6 +1064,20 @@ static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp) return; } +/* + * Check for priv spec version. RVH is 1_12_0, RVV is 1_10_0. + * We don't support anything under 1_10_0 so skip checking + * priv for RVV. + * + * We're hardcoding it here to avoid looping into the + * 50+ entries of isa_edata_arr[] just to check the RVH + * entry. + */ +if (cpu->cfg.ext_h && env->priv_ver < PRIV_VERSION_1_12_0) { +error_setg(errp, "H extension requires priv spec 1.12.0"); +return; +} + if (cpu->cfg.ext_v) { riscv_cpu_validate_v(env, &cpu->cfg, &local_err); if (local_err != NULL) { -- 2.39.2
[PATCH for-8.1 v3 12/26] target/riscv/cpu.c: redesign register_cpu_props()
Now that the function is a no-op if 'env.misa_ext != 0', and no one that are setting misa_ext != 0 is calling it because set_misa() is setting the cpu cfg accordingly, remove the now deprecated code and rename the function to register_generic_cpu_props(). This function is now doing exactly what the name says: it is creating user-facing properties to allow changes in the CPU cfg via the QEMU command line, setting default values if no user input is provided. Note that there's the possibility of a CPU to set a certain misa value and, at the same, also want user-facing flags and defaults from this function. This is not the case since commit 26b2bc58599c ("target/riscv: Don't expose the CPU properties on names CPUs"), but given that this is also a possibility, clarify in the function that using this function will overwrite existing values in cpu->cfg. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 48 ++ 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 7841676473..6b5096d25e 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -221,7 +221,7 @@ static const char * const riscv_intr_names[] = { "reserved" }; -static void register_cpu_props(Object *obj); +static void register_generic_cpu_props(Object *obj); const char *riscv_cpu_get_trap_name(target_ulong cause, bool async) { @@ -386,7 +386,7 @@ static void rv64_base_cpu_init(Object *obj) CPURISCVState *env = &RISCV_CPU(obj)->env; /* We set this in the realise function */ set_misa(env, MXL_RV64, 0); -register_cpu_props(obj); +register_generic_cpu_props(obj); /* Set latest version of privileged specification */ env->priv_ver = PRIV_VERSION_LATEST; #ifndef CONFIG_USER_ONLY @@ -475,7 +475,7 @@ static void rv128_base_cpu_init(Object *obj) CPURISCVState *env = &RISCV_CPU(obj)->env; /* We set this in the realise function */ set_misa(env, MXL_RV128, 0); -register_cpu_props(obj); +register_generic_cpu_props(obj); /* Set latest version of privileged specification */ env->priv_ver = PRIV_VERSION_LATEST; #ifndef CONFIG_USER_ONLY @@ -488,7 +488,7 @@ static void rv32_base_cpu_init(Object *obj) CPURISCVState *env = &RISCV_CPU(obj)->env; /* We set this in the realise function */ set_misa(env, MXL_RV32, 0); -register_cpu_props(obj); +register_generic_cpu_props(obj); /* Set latest version of privileged specification */ env->priv_ver = PRIV_VERSION_LATEST; #ifndef CONFIG_USER_ONLY @@ -575,7 +575,7 @@ static void riscv_host_cpu_init(Object *obj) #elif defined(TARGET_RISCV64) set_misa(env, MXL_RV64, 0); #endif -register_cpu_props(obj); +register_generic_cpu_props(obj); } #endif @@ -1557,44 +1557,16 @@ static Property riscv_cpu_extensions[] = { }; /* - * Register CPU props based on env.misa_ext. If a non-zero - * value was set, register only the required cpu->cfg.ext_* - * properties and leave. env.misa_ext = 0 means that we want - * all the default properties to be registered. + * Register generic CPU props with user-facing flags declared + * in riscv_cpu_extensions[]. + * + * Note that this will overwrite existing values in cpu->cfg. */ -static void register_cpu_props(Object *obj) +static void register_generic_cpu_props(Object *obj) { -RISCVCPU *cpu = RISCV_CPU(obj); -uint32_t misa_ext = cpu->env.misa_ext; Property *prop; DeviceState *dev = DEVICE(obj); -/* - * If misa_ext is not zero, set cfg properties now to - * allow them to be read during riscv_cpu_realize() - * later on. - */ -if (cpu->env.misa_ext != 0) { -cpu->cfg.ext_i = misa_ext & RVI; -cpu->cfg.ext_e = misa_ext & RVE; -cpu->cfg.ext_m = misa_ext & RVM; -cpu->cfg.ext_a = misa_ext & RVA; -cpu->cfg.ext_f = misa_ext & RVF; -cpu->cfg.ext_d = misa_ext & RVD; -cpu->cfg.ext_v = misa_ext & RVV; -cpu->cfg.ext_c = misa_ext & RVC; -cpu->cfg.ext_s = misa_ext & RVS; -cpu->cfg.ext_u = misa_ext & RVU; -cpu->cfg.ext_h = misa_ext & RVH; -cpu->cfg.ext_j = misa_ext & RVJ; - -/* - * We don't want to set the default riscv_cpu_extensions - * in this case. - */ -return; -} - for (prop = riscv_cpu_extensions; prop && prop->name; prop++) { qdev_property_add_static(dev, prop); } -- 2.39.2
[PATCH for-8.1 v3 00/26] target/riscv: rework CPU extensions validation
Hi, This new version contains changes suggested by Weiwei Li. I've also reworked write_misa() to cover more cases. write_misa() is now able to properly enable RVG, RVV and RVE. A more in-depth description of what was attempted here can be found in [1]. Note that the current validation flow already prevents certain misa bits from being disabled (e.g. RVF) due to the presence of Z extensions that are already enabled in the hart, so I decided not to add extra logic to handle these cases. Patches are rebased on top of Alistair's riscv-to-apply.next. Changes from v2: - patches removed: - patch 15 ('do not allow RVG in write_misa()') - patch 19 ('add misa_ext V-> D & F dependency') - patch 15: - add zfinx dependency to enable RVG - patch 19 (former patch 17): - remove misa_ext* assignment from validate_set_extensions() - patch 23 (former 25): - enable RVE in write_misa() - new patch 25: - enable RVG in write_misa() - new patch 26: - enable RVV in write_misa() - v2 link: https://lists.gnu.org/archive/html/qemu-devel/2023-03/msg04424.html [1] https://lists.gnu.org/archive/html/qemu-devel/2023-03/msg04674.html Daniel Henrique Barboza (26): target/riscv/cpu.c: add riscv_cpu_validate_v() target/riscv/cpu.c: remove set_vext_version() target/riscv/cpu.c: remove set_priv_version() target/riscv: add PRIV_VERSION_LATEST target/riscv/cpu.c: add priv_spec validate/disable_exts helpers target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl() target/riscv: move pmp and epmp validations to validate_set_extensions() target/riscv/cpu.c: validate extensions before riscv_timer_init() target/riscv/cpu.c: remove cfg setup from riscv_cpu_init() target/riscv/cpu.c: avoid set_misa() in validate_set_extensions() target/riscv/cpu.c: set cpu config in set_misa() target/riscv/cpu.c: redesign register_cpu_props() target/riscv: put env->misa_ext <-> cpu->cfg code into helpers target/riscv: add RVG target/riscv/cpu.c: split RVG code from validate_set_extensions() target/riscv/cpu.c: add riscv_cpu_validate_misa_ext() target/riscv: move riscv_cpu_validate_v() to validate_misa_ext() target/riscv: error out on priv failure for RVH target/riscv: write env->misa_ext* in register_generic_cpu_props() target/riscv: make validate_misa_ext() use a misa_ext val target/riscv: split riscv_cpu_validate_set_extensions() target/riscv: use misa_ext val in riscv_cpu_validate_extensions() target/riscv: rework write_misa() target/riscv: update cpu->cfg misa bits in commit_cpu_cfg() target/riscv: allow write_misa() to enable RVG target/riscv: allow write_misa() to enable RVV target/riscv/cpu.c | 691 + target/riscv/cpu.h | 17 +- target/riscv/csr.c | 85 -- 3 files changed, 522 insertions(+), 271 deletions(-) -- 2.39.2
[PATCH for-8.1 v3 21/26] target/riscv: split riscv_cpu_validate_set_extensions()
We're now ready to split riscv_cpu_validate_set_extensions() in two. None of these steps are going to touch env->misa_ext*. riscv_cpu_validate_extensions() will take care of all validations based on cpu->cfg values. cpu->cfg changes that are required for the validation are being tolerated here. This is the case of extensions such as ext_zfh enabling ext_zfhmin. The RVV chain enablement (ext_zve64d, ext_zve64f and ext_zve32f) is also being tolerated because the risk of failure is being mitigated by the RVV -> RVD && RVF dependency in validate_misa_ext() done prior. In an ideal world we would have all these extensions declared as object properties, with getters and setters, and we would be able to, e.g., enable ext_zfhmin as soon as ext_zfh is enabled. This would avoid cpu->cfg changes during riscv_cpu_validate_extensions(). Easier said than done, not just because of the hundreds of lines involved in it, but also because we want these properties to be available just for generic CPUs (named CPUs don't want these properties exposed for users). For now we'll work with that we have. riscv_cpu_commit_cpu_cfg() is the last step of the validation where more cpu->cfg properties are set and disabling of extensions due to priv spec happens. We're already validated everything we wanted, so any cpu->cfg change made here is valid. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 7861f0421e..69fc0d17a5 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1118,10 +1118,10 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) } /* - * Check consistency between chosen extensions while setting - * cpu->cfg accordingly. + * Check consistency between chosen extensions. No changes + * in env->misa_ext are made. */ -static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) +static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp) { if (cpu->cfg.epmp && !cpu->cfg.pmp) { /* @@ -1210,7 +1210,10 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) return; } } +} +static void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu) +{ if (cpu->cfg.ext_zk) { cpu->cfg.ext_zkn = true; cpu->cfg.ext_zkr = true; @@ -1373,12 +1376,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } -riscv_cpu_validate_set_extensions(cpu, &local_err); +riscv_cpu_validate_extensions(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; } +riscv_cpu_commit_cpu_cfg(cpu); + #ifndef CONFIG_USER_ONLY if (cpu->cfg.ext_sstc) { riscv_timer_init(cpu); -- 2.39.2
[PATCH for-8.1 v3 14/26] target/riscv: add RVG
The 'G' bit in misa_ext is a virtual extension that enables a set of extensions (i, m, a, f, d, icsr and ifencei). We're already have code to handle it but no bit definition. Add it. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 4 target/riscv/cpu.h | 1 + 2 files changed, 5 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 28d4c5f768..48ad7372b9 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -274,6 +274,9 @@ static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg) if (cfg->ext_j) { ext |= RVJ; } +if (cfg->ext_g) { +ext |= RVG; +} return ext; } @@ -293,6 +296,7 @@ static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg, cfg->ext_u = misa_ext & RVU; cfg->ext_h = misa_ext & RVH; cfg->ext_j = misa_ext & RVJ; +cfg->ext_g = misa_ext & RVG; } static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 2263629332..dbb4df9df0 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -82,6 +82,7 @@ #define RVU RV('U') #define RVH RV('H') #define RVJ RV('J') +#define RVG RV('G') /* Privileged specification version */ -- 2.39.2
[PATCH for-8.1 v3 01/26] target/riscv/cpu.c: add riscv_cpu_validate_v()
The RVV verification will error out if fails and it's being done at the end of riscv_cpu_validate_set_extensions(). Let's put it in its own function and do it earlier. We'll move it out of riscv_cpu_validate_set_extensions() in the near future, but for now this is enough to clean the code a bit. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 86 ++ 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1e97473af2..18591aa53a 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -802,6 +802,46 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) } } +static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, + Error **errp) +{ +int vext_version = VEXT_VERSION_1_00_0; + +if (!is_power_of_2(cfg->vlen)) { +error_setg(errp, "Vector extension VLEN must be power of 2"); +return; +} +if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) { +error_setg(errp, + "Vector extension implementation only supports VLEN " + "in the range [128, %d]", RV_VLEN_MAX); +return; +} +if (!is_power_of_2(cfg->elen)) { +error_setg(errp, "Vector extension ELEN must be power of 2"); +return; +} +if (cfg->elen > 64 || cfg->elen < 8) { +error_setg(errp, + "Vector extension implementation only supports ELEN " + "in the range [8, 64]"); +return; +} +if (cfg->vext_spec) { +if (!g_strcmp0(cfg->vext_spec, "v1.0")) { +vext_version = VEXT_VERSION_1_00_0; +} else { +error_setg(errp, "Unsupported vector spec version '%s'", + cfg->vext_spec); +return; +} +} else { +qemu_log("vector version is not specified, " + "use the default value v1.0\n"); +} +set_vext_version(env, vext_version); +} + /* * Check consistency between chosen extensions while setting * cpu->cfg accordingly, doing a set_misa() in the end. @@ -809,6 +849,7 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) { CPURISCVState *env = &cpu->env; +Error *local_err = NULL; uint32_t ext = 0; /* Do some ISA extension error checking */ @@ -939,6 +980,14 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) } } +if (cpu->cfg.ext_v) { +riscv_cpu_validate_v(env, &cpu->cfg, &local_err); +if (local_err != NULL) { +error_propagate(errp, local_err); +return; +} +} + if (cpu->cfg.ext_zk) { cpu->cfg.ext_zkn = true; cpu->cfg.ext_zkr = true; @@ -993,44 +1042,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) ext |= RVH; } if (cpu->cfg.ext_v) { -int vext_version = VEXT_VERSION_1_00_0; ext |= RVV; -if (!is_power_of_2(cpu->cfg.vlen)) { -error_setg(errp, - "Vector extension VLEN must be power of 2"); -return; -} -if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) { -error_setg(errp, - "Vector extension implementation only supports VLEN " - "in the range [128, %d]", RV_VLEN_MAX); -return; -} -if (!is_power_of_2(cpu->cfg.elen)) { -error_setg(errp, - "Vector extension ELEN must be power of 2"); -return; -} -if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) { -error_setg(errp, - "Vector extension implementation only supports ELEN " - "in the range [8, 64]"); -return; -} -if (cpu->cfg.vext_spec) { -if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) { -vext_version = VEXT_VERSION_1_00_0; -} else { -error_setg(errp, - "Unsupported vector spec version '%s'", - cpu->cfg.vext_spec); -return; -} -} else { -qemu_log("vector version is not specified, " - "use the default value v1.0\n"); -} -set_vext_version(env, vext_version); } if (cpu->cfg.ext_j) { ext |= RVJ; -- 2.39.2
[PATCH for-8.1 v3 20/26] target/riscv: make validate_misa_ext() use a misa_ext val
We have all MISA specific validations in riscv_cpu_validate_misa_ext(), and we have a guarantee that env->misa_ext will always be in sync with cpu->cfg at this point during realize time, so let's convert it to use a 'misa_ext' parameter instead of reading cpu->cfg. This will prepare the function to be used in write_misa() where we won't have an updated cpu->cfg object to work with. riscv_cpu_validate_v() is changed to receive a const pointer to the cpu->cfg object via riscv_cpu_cfg(). Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 29 - 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 992edd1735..7861f0421e 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -939,7 +939,8 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) } } -static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, +static void riscv_cpu_validate_v(CPURISCVState *env, + const RISCVCPUConfig *cfg, Error **errp) { int vext_version = VEXT_VERSION_1_00_0; @@ -1025,41 +1026,43 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) } } -static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp) + +static void riscv_cpu_validate_misa_ext(CPURISCVState *env, +uint32_t misa_ext, +Error **errp) { -CPURISCVState *env = &cpu->env; Error *local_err = NULL; -if (cpu->cfg.ext_i && cpu->cfg.ext_e) { +if (misa_ext & RVI && misa_ext & RVE) { error_setg(errp, "I and E extensions are incompatible"); return; } -if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { +if (!(misa_ext & RVI) && !(misa_ext & RVE)) { error_setg(errp, "Either I or E extension must be set"); return; } -if (cpu->cfg.ext_s && !cpu->cfg.ext_u) { +if (misa_ext & RVS && !(misa_ext & RVU)) { error_setg(errp, "Setting S extension without U extension is illegal"); return; } -if (cpu->cfg.ext_h && !cpu->cfg.ext_i) { +if (misa_ext & RVH && !(misa_ext & RVI)) { error_setg(errp, "H depends on an I base integer ISA with 32 x registers"); return; } -if (cpu->cfg.ext_h && !cpu->cfg.ext_s) { +if (misa_ext & RVH && !(misa_ext & RVS)) { error_setg(errp, "H extension implicitly requires S-mode"); return; } -if (cpu->cfg.ext_d && !cpu->cfg.ext_f) { +if (misa_ext & RVD && !(misa_ext & RVF)) { error_setg(errp, "D extension requires F extension"); return; } @@ -1073,13 +1076,13 @@ static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp) * 50+ entries of isa_edata_arr[] just to check the RVH * entry. */ -if (cpu->cfg.ext_h && env->priv_ver < PRIV_VERSION_1_12_0) { +if (misa_ext & RVH && env->priv_ver < PRIV_VERSION_1_12_0) { error_setg(errp, "H extension requires priv spec 1.12.0"); return; } -if (cpu->cfg.ext_v) { -riscv_cpu_validate_v(env, &cpu->cfg, &local_err); +if (misa_ext & RVV) { +riscv_cpu_validate_v(env, riscv_cpu_cfg(env), &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; @@ -1364,7 +1367,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) env->misa_ext_mask = env->misa_ext; } -riscv_cpu_validate_misa_ext(cpu, &local_err); +riscv_cpu_validate_misa_ext(env, env->misa_ext, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; -- 2.39.2
[PATCH for-8.1 v3 22/26] target/riscv: use misa_ext val in riscv_cpu_validate_extensions()
Similar to what we did with riscv_cpu_validate_misa_ext(), let's read all MISA bits from a misa_ext val instead of reading from the cpu->cfg object. This will allow write_misa() to use riscv_cpu_validate_extensions(). Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 69fc0d17a5..e9172ec310 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1118,10 +1118,13 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) } /* - * Check consistency between chosen extensions. No changes - * in env->misa_ext are made. + * Check consistency between cpu->cfg extensions and a + * candidate misa_ext value. No changes in env->misa_ext + * are made. */ -static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp) +static void riscv_cpu_validate_extensions(RISCVCPU *cpu, + uint32_t misa_ext, + Error **errp) { if (cpu->cfg.epmp && !cpu->cfg.pmp) { /* @@ -1132,12 +1135,12 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp) return; } -if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) { +if (misa_ext & RVF && !cpu->cfg.ext_icsr) { error_setg(errp, "F extension requires Zicsr"); return; } -if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) { +if ((cpu->cfg.ext_zawrs) && !(misa_ext & RVA)) { error_setg(errp, "Zawrs extension requires A extension"); return; } @@ -1146,13 +1149,13 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp) cpu->cfg.ext_zfhmin = true; } -if (cpu->cfg.ext_zfhmin && !cpu->cfg.ext_f) { +if (cpu->cfg.ext_zfhmin && !(misa_ext & RVF)) { error_setg(errp, "Zfh/Zfhmin extensions require F extension"); return; } /* The V vector extension depends on the Zve64d extension */ -if (cpu->cfg.ext_v) { +if (misa_ext & RVV) { cpu->cfg.ext_zve64d = true; } @@ -1166,12 +1169,12 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp) cpu->cfg.ext_zve32f = true; } -if (cpu->cfg.ext_zve64d && !cpu->cfg.ext_d) { +if (cpu->cfg.ext_zve64d && !(misa_ext & RVD)) { error_setg(errp, "Zve64d/V extensions require D extension"); return; } -if (cpu->cfg.ext_zve32f && !cpu->cfg.ext_f) { +if (cpu->cfg.ext_zve32f && !(misa_ext & RVF)) { error_setg(errp, "Zve32f/Zve64f extensions require F extension"); return; } @@ -1204,7 +1207,7 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp) error_setg(errp, "Zfinx extension requires Zicsr"); return; } -if (cpu->cfg.ext_f) { +if (misa_ext & RVF) { error_setg(errp, "Zfinx cannot be supported together with F extension"); return; @@ -1376,7 +1379,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } -riscv_cpu_validate_extensions(cpu, &local_err); +riscv_cpu_validate_extensions(cpu, env->misa_ext, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; -- 2.39.2
[PATCH for-8.1 v3 07/26] target/riscv: move pmp and epmp validations to validate_set_extensions()
In the near future, write_misa() will use a variation of what we have now as riscv_cpu_validate_set_extensions(). The pmp and epmp validation will be required in write_misa() and it's already required here in riscv_cpu_realize(), so move it to riscv_cpu_validate_set_extensions(). Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1a298e5e55..7458845fec 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -916,6 +916,15 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) Error *local_err = NULL; uint32_t ext = 0; +if (cpu->cfg.epmp && !cpu->cfg.pmp) { +/* + * Enhanced PMP should only be available + * on harts with PMP support + */ +error_setg(errp, "Invalid configuration: EPMP requires PMP support"); +return; +} + /* Do some ISA extension error checking */ if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m && cpu->cfg.ext_a && cpu->cfg.ext_f && @@ -1228,16 +1237,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } -if (cpu->cfg.epmp && !cpu->cfg.pmp) { -/* - * Enhanced PMP should only be available - * on harts with PMP support - */ -error_setg(errp, "Invalid configuration: EPMP requires PMP support"); -return; -} - - #ifndef CONFIG_USER_ONLY if (cpu->cfg.ext_sstc) { riscv_timer_init(cpu); -- 2.39.2
[PATCH for-8.1 v3 19/26] target/riscv: write env->misa_ext* in register_generic_cpu_props()
In the process of creating the user-facing flags in register_generic_cpu_props() we're also setting default values for the cpu->cfg flags that represents MISA bits. Leaving it as is will cause a discrepancy between users of this function (at this moment the non-named CPUs) and named CPUs. Named CPUs are using set_misa() with a non-zero 'ext' value, writing cpu->cfg in the process. They'll reach riscv_cpu_realize() in a state where env->misa_ext will reflect cpu->cfg, allowing functions to choose whether to use env->misa_ext or cpu->cfg to validate MISA bits. If we guarantee that env->misa_ext will always reflect cpu->cfg at the start of riscv_cpu_realize(), functions will be able to no longer rely on cpu->cfg for MISA validation. This happens to be one blocker we have to properly support write_misa(). Sync env->misa_ext* in register_generic_cpu_props(). After that, there will be no more places where env->misa_ext needs to be sync back with cpu->cfg, so remove the now obsolete code at the end of riscv_cpu_validate_set_extensions(). Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index d8f2eca6ca..992edd1735 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1116,14 +1116,10 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) /* * Check consistency between chosen extensions while setting - * cpu->cfg accordingly, setting env->misa_ext and - * misa_ext_mask in the end. + * cpu->cfg accordingly. */ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) { -CPURISCVState *env = &cpu->env; -uint32_t ext = 0; - if (cpu->cfg.epmp && !cpu->cfg.pmp) { /* * Enhanced PMP should only be available @@ -1240,10 +1236,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) * validated and set everything we need. */ riscv_cpu_disable_priv_spec_isa_exts(cpu); - -ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg); - -env->misa_ext_mask = env->misa_ext = ext; } #ifndef CONFIG_USER_ONLY @@ -1354,6 +1346,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } +/* + * This is the last point where env->misa_ext* can + * be changed. + */ if (cpu->cfg.ext_g) { riscv_cpu_enable_g(cpu, &local_err); if (local_err != NULL) { @@ -1631,10 +1627,12 @@ static Property riscv_cpu_extensions[] = { * Register generic CPU props with user-facing flags declared * in riscv_cpu_extensions[]. * - * Note that this will overwrite existing values in cpu->cfg. + * Note that this will overwrite existing values in cpu->cfg + * and MISA. */ static void register_generic_cpu_props(Object *obj) { +RISCVCPU *cpu = RISCV_CPU(obj); Property *prop; DeviceState *dev = DEVICE(obj); @@ -1645,6 +1643,10 @@ static void register_generic_cpu_props(Object *obj) #ifndef CONFIG_USER_ONLY riscv_add_satp_mode_properties(obj); #endif + +/* Keep env->misa_ext and misa_ext_mask updated */ +cpu->env.misa_ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg); +cpu->env.misa_ext_mask = cpu->env.misa_ext; } static Property riscv_cpu_properties[] = { -- 2.39.2
[PATCH for-8.1 v3 11/26] target/riscv/cpu.c: set cpu config in set_misa()
set_misa() is setting all 'misa' related env states and nothing else. But other functions, namely riscv_cpu_validate_set_extensions(), uses the config object to do its job. This creates a need to set the single letter extensions in the cfg object to keep both in sync. At this moment this is being done by register_cpu_props(), forcing every CPU to do a call to this function. Let's beef up set_misa() and make the function do the sync for us. This will relieve named CPUs to having to call register_cpu_props(), which will then be redesigned to a more specialized role next. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 40 target/riscv/cpu.h | 4 ++-- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 36c55abda0..7841676473 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async) static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) { +RISCVCPU *cpu; + env->misa_mxl_max = env->misa_mxl = mxl; env->misa_ext_mask = env->misa_ext = ext; + +/* + * ext = 0 will only be a thing during cpu_init() functions + * as a way of setting an extension-agnostic CPU. We do + * not support clearing misa_ext* and the ext_N flags in + * RISCVCPUConfig in regular circunstances. + */ +if (ext == 0) { +return; +} + +/* + * We can't use riscv_cpu_cfg() in this case because it is + * a read-only inline and we're going to change the values + * of cpu->cfg. + */ +cpu = env_archcpu(env); + +cpu->cfg.ext_i = ext & RVI; +cpu->cfg.ext_e = ext & RVE; +cpu->cfg.ext_m = ext & RVM; +cpu->cfg.ext_a = ext & RVA; +cpu->cfg.ext_f = ext & RVF; +cpu->cfg.ext_d = ext & RVD; +cpu->cfg.ext_v = ext & RVV; +cpu->cfg.ext_c = ext & RVC; +cpu->cfg.ext_s = ext & RVS; +cpu->cfg.ext_u = ext & RVU; +cpu->cfg.ext_h = ext & RVH; +cpu->cfg.ext_j = ext & RVJ; } #ifndef CONFIG_USER_ONLY @@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj) #endif env->priv_ver = PRIV_VERSION_LATEST; -register_cpu_props(obj); /* inherited from parent obj via riscv_cpu_init() */ cpu->cfg.ext_ifencei = true; @@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj) RISCVCPU *cpu = RISCV_CPU(obj); CPURISCVState *env = &cpu->env; set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); -register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_10_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39); @@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj) RISCVCPU *cpu = RISCV_CPU(obj); set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU); -register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_10_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); @@ -472,8 +501,6 @@ static void rv32_sifive_u_cpu_init(Object *obj) RISCVCPU *cpu = RISCV_CPU(obj); CPURISCVState *env = &cpu->env; set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); - -register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_10_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); @@ -492,7 +519,6 @@ static void rv32_sifive_e_cpu_init(Object *obj) RISCVCPU *cpu = RISCV_CPU(obj); set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU); -register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_10_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); @@ -510,7 +536,6 @@ static void rv32_ibex_cpu_init(Object *obj) RISCVCPU *cpu = RISCV_CPU(obj); set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU); -register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_11_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); @@ -529,7 +554,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj) RISCVCPU *cpu = RISCV_CPU(obj); set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU); -register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_10_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 76f81c6b68..ebe0fff668 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -66,8 +66,8 @@ #define RV(x) ((target_ulong)1 << (x - 'A')) /* - * Consider updating register_cpu_props() when adding - * new MISA bits here. + * Consider updating set_misa() when adding new + * MISA bits here. */ #define RVI RV('I') #define RVE RV('E') /* E and I are mutually exclusive */ -- 2.39.2
[PATCH for-8.1 v3 06/26] target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl()
Let's remove more code that is open coded in riscv_cpu_realize() and put it into a helper. Let's also add an error message instead of just asserting out if env->misa_mxl_max != env->misa_mlx. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 51 ++ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 17b301967c..1a298e5e55 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -879,6 +879,33 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) } } +static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) +{ +RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); +CPUClass *cc = CPU_CLASS(mcc); +CPURISCVState *env = &cpu->env; + +/* Validate that MISA_MXL is set properly. */ +switch (env->misa_mxl_max) { +#ifdef TARGET_RISCV64 +case MXL_RV64: +case MXL_RV128: +cc->gdb_core_xml_file = "riscv-64bit-cpu.xml"; +break; +#endif +case MXL_RV32: +cc->gdb_core_xml_file = "riscv-32bit-cpu.xml"; +break; +default: +g_assert_not_reached(); +} + +if (env->misa_mxl_max != env->misa_mxl) { +error_setg(errp, "misa_mxl_max must be equal to misa_mxl"); +return; +} +} + /* * Check consistency between chosen extensions while setting * cpu->cfg accordingly, doing a set_misa() in the end. @@ -1180,9 +1207,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); RISCVCPU *cpu = RISCV_CPU(dev); -CPURISCVState *env = &cpu->env; RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); -CPUClass *cc = CPU_CLASS(mcc); Error *local_err = NULL; cpu_exec_realizefn(cs, &local_err); @@ -1197,6 +1222,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } +riscv_cpu_validate_misa_mxl(cpu, &local_err); +if (local_err != NULL) { +error_propagate(errp, local_err); +return; +} + if (cpu->cfg.epmp && !cpu->cfg.pmp) { /* * Enhanced PMP should only be available @@ -1213,22 +1244,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } #endif /* CONFIG_USER_ONLY */ -/* Validate that MISA_MXL is set properly. */ -switch (env->misa_mxl_max) { -#ifdef TARGET_RISCV64 -case MXL_RV64: -case MXL_RV128: -cc->gdb_core_xml_file = "riscv-64bit-cpu.xml"; -break; -#endif -case MXL_RV32: -cc->gdb_core_xml_file = "riscv-32bit-cpu.xml"; -break; -default: -g_assert_not_reached(); -} -assert(env->misa_mxl_max == env->misa_mxl); - riscv_cpu_validate_set_extensions(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); -- 2.39.2
[PATCH for-8.1 v3 09/26] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()
We have 4 config settings being done in riscv_cpu_init(): ext_ifencei, ext_icsr, mmu and pmp. This is also the constructor of the "riscv-cpu" device, which happens to be the parent device of every RISC-V cpu. The result is that these 4 configs are being set every time, and every other CPU should always account for them. CPUs such as sifive_e need to disable settings that aren't enabled simply because the parent class happens to be enabling it. Moving all configurations from the parent class to each CPU will centralize the config of each CPU into its own init(), which is clearer than having to account to whatever happens to be set in the parent device. These settings are also being set in register_cpu_props() when no 'misa_ext' is set, so for these CPUs we don't need changes. Named CPUs will receive all cfgs that the parent were setting into their init(). Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 60 -- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index fef55d7d79..c7b6e7b84b 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -325,7 +325,8 @@ static void set_satp_mode_default_map(RISCVCPU *cpu) static void riscv_any_cpu_init(Object *obj) { -CPURISCVState *env = &RISCV_CPU(obj)->env; +RISCVCPU *cpu = RISCV_CPU(obj); +CPURISCVState *env = &cpu->env; #if defined(TARGET_RISCV32) set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU); #elif defined(TARGET_RISCV64) @@ -340,6 +341,12 @@ static void riscv_any_cpu_init(Object *obj) env->priv_ver = PRIV_VERSION_LATEST; register_cpu_props(obj); + +/* inherited from parent obj via riscv_cpu_init() */ +cpu->cfg.ext_ifencei = true; +cpu->cfg.ext_icsr = true; +cpu->cfg.mmu = true; +cpu->cfg.pmp = true; } #if defined(TARGET_RISCV64) @@ -358,13 +365,20 @@ static void rv64_base_cpu_init(Object *obj) static void rv64_sifive_u_cpu_init(Object *obj) { -CPURISCVState *env = &RISCV_CPU(obj)->env; +RISCVCPU *cpu = RISCV_CPU(obj); +CPURISCVState *env = &cpu->env; set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_10_0; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39); #endif + +/* inherited from parent obj via riscv_cpu_init() */ +cpu->cfg.ext_ifencei = true; +cpu->cfg.ext_icsr = true; +cpu->cfg.mmu = true; +cpu->cfg.pmp = true; } static void rv64_sifive_e_cpu_init(Object *obj) @@ -375,10 +389,14 @@ static void rv64_sifive_e_cpu_init(Object *obj) set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU); register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_10_0; -cpu->cfg.mmu = false; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); #endif + +/* inherited from parent obj via riscv_cpu_init() */ +cpu->cfg.ext_ifencei = true; +cpu->cfg.ext_icsr = true; +cpu->cfg.pmp = true; } static void rv64_thead_c906_cpu_init(Object *obj) @@ -411,6 +429,10 @@ static void rv64_thead_c906_cpu_init(Object *obj) #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_SV39); #endif + +/* inherited from parent obj via riscv_cpu_init() */ +cpu->cfg.ext_ifencei = true; +cpu->cfg.pmp = true; } static void rv128_base_cpu_init(Object *obj) @@ -447,7 +469,8 @@ static void rv32_base_cpu_init(Object *obj) static void rv32_sifive_u_cpu_init(Object *obj) { -CPURISCVState *env = &RISCV_CPU(obj)->env; +RISCVCPU *cpu = RISCV_CPU(obj); +CPURISCVState *env = &cpu->env; set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); register_cpu_props(obj); @@ -455,6 +478,12 @@ static void rv32_sifive_u_cpu_init(Object *obj) #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); #endif + +/* inherited from parent obj via riscv_cpu_init() */ +cpu->cfg.ext_ifencei = true; +cpu->cfg.ext_icsr = true; +cpu->cfg.mmu = true; +cpu->cfg.pmp = true; } static void rv32_sifive_e_cpu_init(Object *obj) @@ -465,10 +494,14 @@ static void rv32_sifive_e_cpu_init(Object *obj) set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU); register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_10_0; -cpu->cfg.mmu = false; #ifndef CONFIG_USER_ONLY set_satp_mode_max_supported(cpu, VM_1_10_MBARE); #endif + +/* inherited from parent obj via riscv_cpu_init() */ +cpu->cfg.ext_ifencei = true; +cpu->cfg.ext_icsr = true; +cpu->cfg.pmp = true; } static void rv32_ibex_cpu_init(Object *obj) @@ -479,11 +512,15 @@ static void rv32_ibex_cpu_init(Object *obj) set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU); register_cpu_props(obj); env->priv_ver = PRIV_VERSION_1_11_0; -cpu->cfg.mmu = false; #ifndef CONFIG_USER_ONLY set_satp_mo
[PATCH for-8.1 v3 23/26] target/riscv: rework write_misa()
write_misa() must use as much common logic as possible. We want to open code just the bits that are exclusive to the CSR write operation and TCG internals. Rewrite write_misa() to work as follows: - mask the write using misa_ext_mask to avoid enabling unsupported extensions; - suppress RVC if the next insn isn't aligned; - handle RVE. This is done by filtering all bits but RVE from 'val'. Setting RVE will forcefully set only RVE - assuming it gets validated afterwards; - emulate the steps done by realize(): validate the candidate misa_ext val, then validate the configuration with the candidate misa_ext val, and finally commit the changes to cpu->cfg. If any of the validation steps fails, the write operation is a no-op. Let's keep write_misa() as experimental for now until this logic gains enough mileage. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 12 -- target/riscv/cpu.h | 6 + target/riscv/csr.c | 59 ++ 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index e9172ec310..67a46504bb 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1027,9 +1027,8 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) } -static void riscv_cpu_validate_misa_ext(CPURISCVState *env, -uint32_t misa_ext, -Error **errp) +void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext, + Error **errp) { Error *local_err = NULL; @@ -1122,9 +1121,8 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) * candidate misa_ext value. No changes in env->misa_ext * are made. */ -static void riscv_cpu_validate_extensions(RISCVCPU *cpu, - uint32_t misa_ext, - Error **errp) +void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext, + Error **errp) { if (cpu->cfg.epmp && !cpu->cfg.pmp) { /* @@ -1215,7 +1213,7 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, } } -static void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu) +void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu) { if (cpu->cfg.ext_zk) { cpu->cfg.ext_zkn = true; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index dbb4df9df0..ca2ba6a647 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -593,6 +593,12 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, char *riscv_isa_string(RISCVCPU *cpu); void riscv_cpu_list(void); +void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext, + Error **errp); +void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext, + Error **errp); +void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu); + #define cpu_list riscv_cpu_list #define cpu_mmu_index riscv_cpu_mmu_index diff --git a/target/riscv/csr.c b/target/riscv/csr.c index d522efc0b6..8d5e8f9ad1 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1343,39 +1343,17 @@ static RISCVException read_misa(CPURISCVState *env, int csrno, static RISCVException write_misa(CPURISCVState *env, int csrno, target_ulong val) { +RISCVCPU *cpu = env_archcpu(env); +Error *local_err = NULL; + if (!riscv_cpu_cfg(env)->misa_w) { /* drop write to misa */ return RISCV_EXCP_NONE; } -/* 'I' or 'E' must be present */ -if (!(val & (RVI | RVE))) { -/* It is not, drop write to misa */ -return RISCV_EXCP_NONE; -} - -/* 'E' excludes all other extensions */ -if (val & RVE) { -/* - * when we support 'E' we can do "val = RVE;" however - * for now we just drop writes if 'E' is present. - */ -return RISCV_EXCP_NONE; -} - -/* - * misa.MXL writes are not supported by QEMU. - * Drop writes to those bits. - */ - /* Mask extensions that are not supported by this hart */ val &= env->misa_ext_mask; -/* 'D' depends on 'F', so clear 'D' if 'F' is not present */ -if ((val & RVD) && !(val & RVF)) { -val &= ~RVD; -} - /* * Suppress 'C' if next instruction is not aligned * TODO: this should check next_pc @@ -1389,6 +1367,37 @@ static RISCVException write_misa(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +/* + * We'll handle special cases in separate. If one + * of these bits are enabled we'll handle them and + * end the CSR write. + */ +if (val & RVE && !(env->misa_ext & RVE)) { +/* + * RVE must be enabled by itself. Clear all other + * misa_env bits and let the validation do its + * job. + */ +val &= RVE; +} + +/* +
[PATCH for-8.1 v3 02/26] target/riscv/cpu.c: remove set_vext_version()
This setter is doing nothing else but setting env->vext_ver. Assign the value directly. Signed-off-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 18591aa53a..2752efe1eb 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -245,11 +245,6 @@ static void set_priv_version(CPURISCVState *env, int priv_ver) env->priv_ver = priv_ver; } -static void set_vext_version(CPURISCVState *env, int vext_ver) -{ -env->vext_ver = vext_ver; -} - #ifndef CONFIG_USER_ONLY static uint8_t satp_mode_from_str(const char *satp_mode_str) { @@ -839,7 +834,7 @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, qemu_log("vector version is not specified, " "use the default value v1.0\n"); } -set_vext_version(env, vext_version); +env->vext_ver = vext_version; } /* -- 2.39.2
Re: [PATCH for 8.0] qemu/osdep: Switch position of "extern" and "G_NORETURN"
+ Thomas, Daniel (gitlab issue) and Stefan (Windows) Am 18. März 2023 18:59:31 UTC schrieb Bernhard Beschow : >Fixes the Windows build under msys2 using GCC 12 which fails with the following >error: > > [184/579] Compiling C++ object qga/vss-win32/qga-vss.dll.p/install.cpp.obj > FAILED: qga/vss-win32/qga-vss.dll.p/install.cpp.obj > "c++" "-m64" "-mcx16" "-Iqga/vss-win32/qga-vss.dll.p" "-Iqga/vss-win32" > "-I../src/qga/vss-win32" "-I." "-Iqapi" "-Itrace" "-Iui" "-Iui/shader" > "-IC:/msys64/mingw64/include/glib-2.0" > "-IC:/msys64/mingw64/lib/glib-2.0/include" "-fdiagnostics-color=auto" "-Wall" > "-Winvalid-pch" "-Wnon-virtual-dtor" "-Werror" "-std=gnu++11" "-g" "-iquote" > "." "-iquote" "C:/msys64/home/shentey/Projects/qemu/src" "-iquote" > "C:/msys64/home/shentey/Projects/qemu/src/include" "-iquote" > "C:/msys64/home/shentey/Projects/qemu/src/tcg/i386" "-D__STDC_LIMIT_MACROS" > "-D__STDC_CONSTANT_MACROS" "-D__STDC_FORMAT_MACROS" "-fno-pie" "-no-pie" > "-D_GNU_SOURCE" "-D_FILE_OFFSET_BITS=64" "-D_LARGEFILE_SOURCE" > "-fno-strict-aliasing" "-fno-common" "-fwrapv" "-Wundef" "-Wwrite-strings" > "-Wtype-limits" "-Wformat-security" "-Wformat-y2k" "-Winit-self" > "-Wignored-qualifiers" "-Wempty-body" "-Wendif-labels" > "-Wexpansion-to-defined" "-Wimplicit-fallthrough=2" > "-Wmissing-format-attribute" "-Wno-missing-include-dirs" > "-Wno-shift-negative-value" "-Wno-psabi" "-fstack-protector-strong" > "-Wno-unknown-pragmas" "-Wno-delete-non-virtual-dtor" "-Wno-non-virtual-dtor" > -MD -MQ qga/vss-win32/qga-vss.dll.p/install.cpp.obj -MF > "qga/vss-win32/qga-vss.dll.p/install.cpp.obj.d" -o > qga/vss-win32/qga-vss.dll.p/install.cpp.obj "-c" > ../src/qga/vss-win32/install.cpp > In file included from C:/msys64/mingw64/lib/glib-2.0/include/glibconfig.h:9, > from C:/msys64/mingw64/include/glib-2.0/glib/gtypes.h:34, > from C:/msys64/mingw64/include/glib-2.0/glib/galloca.h:34, > from C:/msys64/mingw64/include/glib-2.0/glib.h:32, > from > C:/msys64/home/shentey/Projects/qemu/src/include/glib-compat.h:32, > from > C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:144, > from ../src/qga/vss-win32/install.cpp:13: > C:/msys64/mingw64/include/glib-2.0/glib/gmacros.h:1075:21: error: standard > attributes in middle of decl-specifiers > 1075 | # define G_NORETURN [[noreturn]] >| ^ > C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:240:8: note: > in expansion of macro 'G_NORETURN' > 240 | extern G_NORETURN >|^~ > C:/msys64/mingw64/include/glib-2.0/glib/gmacros.h:1075:21: note: standard > attributes must precede the decl-specifiers to apply to the declaration, or > follow them to apply to the type > 1075 | # define G_NORETURN [[noreturn]] >| ^ > C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:240:8: note: > in expansion of macro 'G_NORETURN' > 240 | extern G_NORETURN >|^~ > C:/msys64/mingw64/include/glib-2.0/glib/gmacros.h:1075:21: error: attribute > ignored [-Werror=attributes] > 1075 | # define G_NORETURN [[noreturn]] >| ^ > C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:240:8: note: > in expansion of macro 'G_NORETURN' > 240 | extern G_NORETURN >|^~ > C:/msys64/mingw64/include/glib-2.0/glib/gmacros.h:1075:21: note: an > attribute that appertains to a type-specifier is ignored > 1075 | # define G_NORETURN [[noreturn]] >| ^ > C:/msys64/home/shentey/Projects/qemu/src/include/qemu/osdep.h:240:8: note: > in expansion of macro 'G_NORETURN' > 240 | extern G_NORETURN >|^~ > cc1plus.exe: all warnings being treated as errors > >Apparently it also fixes the compilation with Clang 15 (see >https://gitlab.com/qemu-project/qemu/-/issues/1541 ). > >Signed-off-by: Bernhard Beschow >--- > include/qemu/osdep.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h >index f68b5d8708..9eff0be95b 100644 >--- a/include/qemu/osdep.h >+++ b/include/qemu/osdep.h >@@ -237,7 +237,7 @@ extern "C" { > * supports QEMU_ERROR, this will be reported at compile time; otherwise > * this will be reported at link time due to the missing symbol. > */ >-extern G_NORETURN >+G_NORETURN extern > void QEMU_ERROR("code path is reachable") > qemu_build_not_reached_always(void); > #if defined(__OPTIMIZE__) && !defined(__NO_INLINE__)
Re: [PATCH] doc: do not recommend -blockdev
18.03.2023 15:32, Alex Bennée пишет: .. Could we expand the images section: https://qemu.readthedocs.io/en/latest/system/images.html to give a better overview of when you should use -device/-blockdev vs -drive? Probably. It's not really about image formats but this info should be somewhere anyway. It's a separate step though. Signed-off-by: Michael Tokarev --- qemu-options.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-options.hx b/qemu-options.hx index 59bdf67a2c..8fe31b465d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1143,7 +1143,7 @@ have gone through several iterations as the feature set and complexity of the block layer have grown. Many online guides to QEMU often reference older and deprecated options, which can lead to confusion. -The recommended modern way to describe disks is to use a combination of +The low-level detailed way to describe disks is to use a combination of ``-device`` to specify the hardware device and ``-blockdev`` to describe the backend. The device defines what the guest sees and the backend describes how QEMU handles the data. How about: The most explicit way to describe disks is to use a combination of ``-device`` to specify the hardware device and ``-blockdev`` to describe the backend. The device defines what the guest sees and the backend describes how QEMU handles the data. The ``--drive`` option combines the device and backend into a single command line options which is useful in the majority of cases. Older options like ``-hda`` make a bake in a lot of assumptions from the days when QEMU was emulating a legacy PC, they are not recommended for modern configurations. This is much better indeed (with one exception, the double-dash in --drive isn't usual). Would you like to send it as an actual patch? Thanks! /mjt