target/riscv/machine.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
Currently, the Machine Security Configuration Register (mseccfg) was
missing from the live migration state. This omission causes the register
to be reset to zero on the destination host after migration.
Fixed by adding vmstate_mseccfg subsection
This vulnerability was discovered and reported by SpecHunter, an
AI-driven architecture specification analysis tool.
Link: https://github.com/yizishun/rv-isa-sec/blob/a22e4459cd026ae970791dfbd9cfe5d110fbd46b/output/riscv-isa-manual/pr-1879/qemu.txt#L121
Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>
---
target/riscv/machine.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 09c032a87914..6776e7bf5a11 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -423,6 +423,25 @@ static const VMStateDescription vmstate_sstc = {
}
};
+static bool mseccfg_needed(void *opaque)
+{
+ RISCVCPU *cpu = opaque;
+
+ return cpu->cfg.ext_smepmp || cpu->cfg.ext_zkr
+ || cpu->cfg.ext_smmpm || cpu->cfg.ext_zicfilp;
+}
+
+static const VMStateDescription vmstate_mseccfg = {
+ .name = "cpu/mseccfg",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = mseccfg_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINTTL(env.mseccfg, RISCVCPU),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
const VMStateDescription vmstate_riscv_cpu = {
.name = "cpu",
.version_id = 11,
@@ -499,6 +518,7 @@ const VMStateDescription vmstate_riscv_cpu = {
&vmstate_ssp,
&vmstate_ctr,
&vmstate_sstc,
+ &vmstate_mseccfg,
NULL
}
};
--
2.51.2
On 11.05.2026 15:48, Zishun Yi wrote:
> Currently, the Machine Security Configuration Register (mseccfg) was
> missing from the live migration state. This omission causes the register
> to be reset to zero on the destination host after migration.
>
> Fixed by adding vmstate_mseccfg subsection
>
> This vulnerability was discovered and reported by SpecHunter, an
> AI-driven architecture specification analysis tool.
>
> Link: https://github.com/yizishun/rv-isa-sec/blob/a22e4459cd026ae970791dfbd9cfe5d110fbd46b/output/riscv-isa-manual/pr-1879/qemu.txt#L121
> Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>
This change has been nominated for inclusion into previous stable
releases by Alistar. However I've a concern here: can we add new
fields to older machine descriptions this way, and stay migratable?
I understand riscv machine is not versioned. How does migration work
in the first place?
Thanks,
/mjt
> ---
> target/riscv/machine.c | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 09c032a87914..6776e7bf5a11 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -423,6 +423,25 @@ static const VMStateDescription vmstate_sstc = {
> }
> };
>
> +static bool mseccfg_needed(void *opaque)
> +{
> + RISCVCPU *cpu = opaque;
> +
> + return cpu->cfg.ext_smepmp || cpu->cfg.ext_zkr
> + || cpu->cfg.ext_smmpm || cpu->cfg.ext_zicfilp;
> +}
> +
> +static const VMStateDescription vmstate_mseccfg = {
> + .name = "cpu/mseccfg",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .needed = mseccfg_needed,
> + .fields = (const VMStateField[]) {
> + VMSTATE_UINTTL(env.mseccfg, RISCVCPU),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> const VMStateDescription vmstate_riscv_cpu = {
> .name = "cpu",
> .version_id = 11,
> @@ -499,6 +518,7 @@ const VMStateDescription vmstate_riscv_cpu = {
> &vmstate_ssp,
> &vmstate_ctr,Add mseccfg to VMStateDescription
> &vmstate_sstc,
> + &vmstate_mseccfg,
> NULL
> }
> };
On Tue, 2026-05-26 at 10:26 +0300, Michael Tokarev wrote: > On 11.05.2026 15:48, Zishun Yi wrote: > > Currently, the Machine Security Configuration Register (mseccfg) > > was > > missing from the live migration state. This omission causes the > > register > > to be reset to zero on the destination host after migration. > > > > Fixed by adding vmstate_mseccfg subsection > > > > This vulnerability was discovered and reported by SpecHunter, an > > AI-driven architecture specification analysis tool. > > > > Link: > > https://github.com/yizishun/rv-isa-sec/blob/a22e4459cd026ae970791dfbd9cfe5d110fbd46b/output/riscv-isa-manual/pr-1879/qemu.txt#L121 > > Signed-off-by: Zishun Yi <vulab@iscas.ac.cn> > > This change has been nominated for inclusion into previous stable > releases by Alistar. However I've a concern here: can we add new > fields to older machine descriptions this way, and stay migratable? I was under the impression that we could, but as I write this I start to think that no we can't. We don't have to backport this then > > I understand riscv machine is not versioned. How does migration work > in the first place? As in the virt machine isn't versioned? or `vmstate_riscv_cpu` isn't versioned? Alistair > > Thanks, > > /mjt > >
On 27.05.2026 02:57, Alistair Francis wrote: > On Tue, 2026-05-26 at 10:26 +0300, Michael Tokarev wrote: >> This change has been nominated for inclusion into previous stable >> releases by Alistar. However I've a concern here: can we add new >> fields to older machine descriptions this way, and stay migratable? > > I was under the impression that we could, but as I write this I start > to think that no we can't. > > We don't have to backport this then hmm. >> I understand riscv machine is not versioned. How does migration work >> in the first place? > > As in the virt machine isn't versioned? or `vmstate_riscv_cpu` isn't > versioned? For i386, we've pc-q35-10.0, pc-8.2, etc - versioned after qemu. Each version has strictly defined set of properties, and there's conversion between different versions when doing cross-version migration. So it's possible to migrate a VM when the set of properties changes. I don't see similar construct for riscv. And since we do change things in there, modifying set of properties in various areas in the migration stream, - I dunno how migration works in riscv qemu land. So I'm asking.. :) From what I understand, migration should fail when the target qemu has different set of properties compared to the current one, - no? But if it works, we should apply this patch to older/stable releases, there should be no issues in there. But again, I don't understand the mechanism here. I'm adding Peter and Fabiano to Cc (maintainers of the migration code), -- can you clarify please? Thanks, /mjt
Michael Tokarev <mjt@tls.msk.ru> writes: > On 27.05.2026 02:57, Alistair Francis wrote: >> On Tue, 2026-05-26 at 10:26 +0300, Michael Tokarev wrote: > >>> This change has been nominated for inclusion into previous stable >>> releases by Alistar. However I've a concern here: can we add new >>> fields to older machine descriptions this way, and stay migratable? >> >> I was under the impression that we could, but as I write this I start >> to think that no we can't. >> >> We don't have to backport this then > > hmm. > >>> I understand riscv machine is not versioned. How does migration work >>> in the first place? >> >> As in the virt machine isn't versioned? or `vmstate_riscv_cpu` isn't >> versioned? > > For i386, we've pc-q35-10.0, pc-8.2, etc - versioned after qemu. > Each version has strictly defined set of properties, and there's > conversion between different versions when doing cross-version > migration. So it's possible to migrate a VM when the set of > properties changes. > > I don't see similar construct for riscv. And since we do change > things in there, modifying set of properties in various areas in > the migration stream, - I dunno how migration works in riscv qemu > land. So I'm asking.. :) > There are no migration compatibility guarantees for an unversioned machine type. Only migration and snapshots from same-version QEMUs are expected to work in this case. Other scenarios may or may not work. > From what I understand, migration should fail when the target qemu > has different set of properties compared to the current one, - no? > The addition from this patch is in a subsection, so .needed will determine whether it will be put on the stream. If we backport the change, then the stable QEMU build will (likely) start sending this subsection, which the old, non-stable QEMU will not recognize and migration will fail. Migration from stable-stable would likely work. So any stable versions that (would) contain this patch are likely to block migration from that version into an unpatched QEMU. Note that since the machine is unversioned, migration from QEMU x to QEMU x+1 is already prone to being broken. > But if it works, we should apply this patch to older/stable releases, > there should be no issues in there. > > But again, I don't understand the mechanism here. > > I'm adding Peter and Fabiano to Cc (maintainers of the migration code), > -- can you clarify please? > @Peter, I hope I got it right, feel free to correct me. > Thanks, > > /mjt
[Trimmed the Cc list a bit] On 27.05.2026 15:20, Fabiano Rosas wrote: > There are no migration compatibility guarantees for an unversioned > machine type. Only migration and snapshots from same-version QEMUs are > expected to work in this case. Other scenarios may or may not work. .. > > The addition from this patch is in a subsection, so .needed will > determine whether it will be put on the stream. If we backport the > change, then the stable QEMU build will (likely) start sending this > subsection, which the old, non-stable QEMU will not recognize and > migration will fail. Migration from stable-stable would likely work. > > So any stable versions that (would) contain this patch are likely to > block migration from that version into an unpatched QEMU. > > Note that since the machine is unversioned, migration from QEMU x to > QEMU x+1 is already prone to being broken. Yeah, this was my understanding too. And given all the above, I think we should apply the fixes to the stable series, and treat this as changing version (the version is actually changed, but only the minor version). Yes, the VMs wont be migratable between 10.0.9 and 10.0.10, exactly like it was not-migratable between 10.0.x and 10.1.x. Because basically, with no versioned machines, there's basically no migration capability between different qemus *at all*. When we do have versioned machines, we can't add fields to previous versions anymore, exactly because of the migration guarantees. But as long as we don't, there's no guarantees at all. And the only place where migration can be done is between different hosts with the same qemu versions. The above description leaves one question still. What happens when migrating from unpatched qemu to a patched qemu? Will the migration fail due to missing field, or succeed, making the missing field to have a default value? If it will succeed, then we definitely should add the field to fix the original issue. BTW, can't we just skip, at the receive end, fields we don't know about? But all this is.. well... sort of moot for this very change already. I haven't realized that this discussion is about a change which I *already* applied (I wanted to revert it until this question settles, but I forgot to do that!). And meanwhile, I released the next set of stable qemu releases, with the changes in question (two of them) applied. It wasn't my intention (or else I'd not start this discussion in the first place, obviously). So we do have this migration breakage already, "thanks" to my sloppiness. And I don't want to break things for users for no reason. The original issue were described as a security issue even, so there's a reason to fix it. I think. But in the future I'll try to be more careful about such things. Again, understanding the machinery and consequences helps here too. Thank, /mjt
On Wed, May 27, 2026 at 09:20:10AM -0300, Fabiano Rosas wrote: > Michael Tokarev <mjt@tls.msk.ru> writes: > > > On 27.05.2026 02:57, Alistair Francis wrote: > >> On Tue, 2026-05-26 at 10:26 +0300, Michael Tokarev wrote: > > > >>> This change has been nominated for inclusion into previous stable > >>> releases by Alistar. However I've a concern here: can we add new > >>> fields to older machine descriptions this way, and stay migratable? > >> > >> I was under the impression that we could, but as I write this I start > >> to think that no we can't. > >> > >> We don't have to backport this then > > > > hmm. > > > >>> I understand riscv machine is not versioned. How does migration work > >>> in the first place? > >> > >> As in the virt machine isn't versioned? or `vmstate_riscv_cpu` isn't > >> versioned? > > > > For i386, we've pc-q35-10.0, pc-8.2, etc - versioned after qemu. > > Each version has strictly defined set of properties, and there's > > conversion between different versions when doing cross-version > > migration. So it's possible to migrate a VM when the set of > > properties changes. > > > > I don't see similar construct for riscv. And since we do change > > things in there, modifying set of properties in various areas in > > the migration stream, - I dunno how migration works in riscv qemu > > land. So I'm asking.. :) > > > > There are no migration compatibility guarantees for an unversioned > machine type. Only migration and snapshots from same-version QEMUs are > expected to work in this case. Other scenarios may or may not work. > > > From what I understand, migration should fail when the target qemu > > has different set of properties compared to the current one, - no? > > > > The addition from this patch is in a subsection, so .needed will > determine whether it will be put on the stream. If we backport the > change, then the stable QEMU build will (likely) start sending this > subsection, which the old, non-stable QEMU will not recognize and > migration will fail. Migration from stable-stable would likely work. > > So any stable versions that (would) contain this patch are likely to > block migration from that version into an unpatched QEMU. > > Note that since the machine is unversioned, migration from QEMU x to > QEMU x+1 is already prone to being broken. > > > But if it works, we should apply this patch to older/stable releases, > > there should be no issues in there. > > > > But again, I don't understand the mechanism here. > > > > I'm adding Peter and Fabiano to Cc (maintainers of the migration code), > > -- can you clarify please? > > > > @Peter, I hope I got it right, feel free to correct me. Agreed with above. If riscv cares about migration compatibilities and the ability to upgrade clusters without interrupting VMs, maybe it's a good idea to start thinking about versioning the machines. Tkanks, -- Peter Xu
On 26.05.2026 10:26, Michael Tokarev wrote:
> On 11.05.2026 15:48, Zishun Yi wrote:
>> Currently, the Machine Security Configuration Register (mseccfg) was
>> missing from the live migration state. This omission causes the register
>> to be reset to zero on the destination host after migration.
>>
>> Fixed by adding vmstate_mseccfg subsection
>>
>> This vulnerability was discovered and reported by SpecHunter, an
>> AI-driven architecture specification analysis tool.
>>
>> Link: https://github.com/yizishun/rv-isa-sec/blob/
>> a22e4459cd026ae970791dfbd9cfe5d110fbd46b/output/riscv-isa-manual/
>> pr-1879/qemu.txt#L121
>> Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>
>
> This change has been nominated for inclusion into previous stable
> releases by Alistar. However I've a concern here: can we add new
> fields to older machine descriptions this way, and stay migratable?
>
> I understand riscv machine is not versioned. How does migration work
> in the first place?
...
>> const VMStateDescription vmstate_riscv_cpu = {
>> .name = "cpu",
>> .version_id = 11,
>> @@ -499,6 +518,7 @@ const VMStateDescription vmstate_riscv_cpu = {
>> &vmstate_ssp,
>> &vmstate_ctr,Add mseccfg to VMStateDescription
>> &vmstate_sstc,
>> + &vmstate_mseccfg,
>> NULL
>> }
BTW, if we're picking up this commit for 10.0.x series (should we?),
I guess the previous change in this are should be picked up too,
v10.1.0-859-gb0daaa172a "target/riscv: Save stimer and vstimer in CPU
vmstate", which added vmstate_sstc here.
Thanks,
/mjt
On Mon, May 11, 2026 at 10:50 PM Zishun Yi <vulab@iscas.ac.cn> wrote:
>
> Currently, the Machine Security Configuration Register (mseccfg) was
> missing from the live migration state. This omission causes the register
> to be reset to zero on the destination host after migration.
>
> Fixed by adding vmstate_mseccfg subsection
>
> This vulnerability was discovered and reported by SpecHunter, an
> AI-driven architecture specification analysis tool.
>
> Link: https://github.com/yizishun/rv-isa-sec/blob/a22e4459cd026ae970791dfbd9cfe5d110fbd46b/output/riscv-isa-manual/pr-1879/qemu.txt#L121
> Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>
Thanks!
Applied to riscv-to-apply.next
Alistair
> ---
> target/riscv/machine.c | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 09c032a87914..6776e7bf5a11 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -423,6 +423,25 @@ static const VMStateDescription vmstate_sstc = {
> }
> };
>
> +static bool mseccfg_needed(void *opaque)
> +{
> + RISCVCPU *cpu = opaque;
> +
> + return cpu->cfg.ext_smepmp || cpu->cfg.ext_zkr
> + || cpu->cfg.ext_smmpm || cpu->cfg.ext_zicfilp;
> +}
> +
> +static const VMStateDescription vmstate_mseccfg = {
> + .name = "cpu/mseccfg",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .needed = mseccfg_needed,
> + .fields = (const VMStateField[]) {
> + VMSTATE_UINTTL(env.mseccfg, RISCVCPU),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> const VMStateDescription vmstate_riscv_cpu = {
> .name = "cpu",
> .version_id = 11,
> @@ -499,6 +518,7 @@ const VMStateDescription vmstate_riscv_cpu = {
> &vmstate_ssp,
> &vmstate_ctr,
> &vmstate_sstc,
> + &vmstate_mseccfg,
> NULL
> }
> };
> --
> 2.51.2
>
>
On Mon, May 11, 2026 at 10:50 PM Zishun Yi <vulab@iscas.ac.cn> wrote:
>
> Currently, the Machine Security Configuration Register (mseccfg) was
> missing from the live migration state. This omission causes the register
> to be reset to zero on the destination host after migration.
>
> Fixed by adding vmstate_mseccfg subsection
>
> This vulnerability was discovered and reported by SpecHunter, an
> AI-driven architecture specification analysis tool.
>
> Link: https://github.com/yizishun/rv-isa-sec/blob/a22e4459cd026ae970791dfbd9cfe5d110fbd46b/output/riscv-isa-manual/pr-1879/qemu.txt#L121
> Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/machine.c | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 09c032a87914..6776e7bf5a11 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -423,6 +423,25 @@ static const VMStateDescription vmstate_sstc = {
> }
> };
>
> +static bool mseccfg_needed(void *opaque)
> +{
> + RISCVCPU *cpu = opaque;
> +
> + return cpu->cfg.ext_smepmp || cpu->cfg.ext_zkr
> + || cpu->cfg.ext_smmpm || cpu->cfg.ext_zicfilp;
> +}
> +
> +static const VMStateDescription vmstate_mseccfg = {
> + .name = "cpu/mseccfg",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .needed = mseccfg_needed,
> + .fields = (const VMStateField[]) {
> + VMSTATE_UINTTL(env.mseccfg, RISCVCPU),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> const VMStateDescription vmstate_riscv_cpu = {
> .name = "cpu",
> .version_id = 11,
> @@ -499,6 +518,7 @@ const VMStateDescription vmstate_riscv_cpu = {
> &vmstate_ssp,
> &vmstate_ctr,
> &vmstate_sstc,
> + &vmstate_mseccfg,
> NULL
> }
> };
> --
> 2.51.2
>
>
On Mon, May 11, 2026 at 08:48:28PM +0800, Zishun Yi wrote:
> Currently, the Machine Security Configuration Register (mseccfg) was
> missing from the live migration state. This omission causes the register
> to be reset to zero on the destination host after migration.
>
> Fixed by adding vmstate_mseccfg subsection
>
> This vulnerability was discovered and reported by SpecHunter, an
> AI-driven architecture specification analysis tool.
For the record, this was first disclosed to the QEMU security list,
however, since this only impacts TCG it falls under the non-virtualization
use case and thus doesn't qualify for security handling / CVE assignment
https://www.qemu.org/docs/master/system/security.html#non-virtualization-use-case
>
> Link: https://github.com/yizishun/rv-isa-sec/blob/a22e4459cd026ae970791dfbd9cfe5d110fbd46b/output/riscv-isa-manual/pr-1879/qemu.txt#L121
> Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>
> ---
> target/riscv/machine.c | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 09c032a87914..6776e7bf5a11 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -423,6 +423,25 @@ static const VMStateDescription vmstate_sstc = {
> }
> };
>
> +static bool mseccfg_needed(void *opaque)
> +{
> + RISCVCPU *cpu = opaque;
> +
> + return cpu->cfg.ext_smepmp || cpu->cfg.ext_zkr
> + || cpu->cfg.ext_smmpm || cpu->cfg.ext_zicfilp;
> +}
> +
> +static const VMStateDescription vmstate_mseccfg = {
> + .name = "cpu/mseccfg",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .needed = mseccfg_needed,
> + .fields = (const VMStateField[]) {
> + VMSTATE_UINTTL(env.mseccfg, RISCVCPU),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> const VMStateDescription vmstate_riscv_cpu = {
> .name = "cpu",
> .version_id = 11,
> @@ -499,6 +518,7 @@ const VMStateDescription vmstate_riscv_cpu = {
> &vmstate_ssp,
> &vmstate_ctr,
> &vmstate_sstc,
> + &vmstate_mseccfg,
> NULL
> }
> };
> --
> 2.51.2
>
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
© 2016 - 2026 Red Hat, Inc.