qemu-kvm: x86: Refactor persistent CPU state
RFC PATCH 1/1 qemu-kvm: x86: Refactor persistent CPU state
This patch reworks the KVM-related layout and encoding of the CPU state to be saved to disk or migrated. The goal is to define a format, version 9, that is also acceptable for upstream and can later be merged into QEMU. Besides unconditionally writing KVM states, this format compresses interrupt_bitmap into a single number as there can be no more than one pending IRQ at a time.
---
target-i386/cpu.h | 2 +- target-i386/machine.c | 57 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 17 deletions(-)
target-i386/cpu.h +1 -1
@@ -838,7 +838,7 @@ static inline int cpu_get_time_fast(void)#define cpu_signal_handler cpu_x86_signal_handler#define cpu_list x86_cpu_list -#define CPU_SAVE_VERSION 8 +#define CPU_SAVE_VERSION 9/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-i386/machine.c +41 -16
90 lines not on this page · raw message
Quoted 11 lines · Jan Kiszka
This patch reworks the KVM-related layout and encoding of the CPU state to be saved to disk or migrated. The goal is to define a format, version 9, that is also acceptable for upstream and can later be merged into QEMU. Besides unconditionally writing KVM states, this format compresses
interrupt_bitmapinto a single number as there can be no more than one pending IRQ at a time.target-i386/machine.c +0
-2-if (kvm_enabled ()) { -for (i =0 ; i <sizeof (env->interrupt_bitmap)/8 ; i++) {
target-i386/machine.c void cpu_save(QEMUFile *f, void *opaque) · line 164
Quoted 10 lines
target-i386/machine.c +9
-1-qemu_put_be64s (f, &env->interrupt_bitmap[i]); +/* KVM-related states */ + +/* There can only be one pending IRQ set in the bitmap at a time, so try +to find it and save its number instead (-1 for none). */ + pending_irq =-1 ; +for (i =0 ; i <sizeof (env->interrupt_bitmap)/2 ; i++) { + bit =ffs (((uint16_t *)env->interrupt_bitmap)[i]); +if (bit) { + pending_irq = i *16 + bit;
bit - 1
Quoted 3 lines
+ break;
}Why are you using uint64_t? It would be more natural to use ffsll and the natural type of the bitmap vector.
target-i386/machine.c int cpu_load(QEMUFile *f, void *opaque, int version_id) · line 385
Quoted 7 lines
target-i386/machine.c +3
-0+ }else { +kvm_load_registers (env); +kvm_load_tsc (env);kvm_load_mpstate (env); } }
Don't you need to load the pending interrupt?
Signature · 1 line
error compiling committee.c: too many arguments to function
PATCH v2 1/1 qemu-kvm: x86: Refactor persistent CPU state
Quoted 24 lines · Avi Kivity
Quoted 16 lines · Jan Kiszka
This patch reworks the KVM-related layout and encoding of the CPU state to be saved to disk or migrated. The goal is to define a format, version 9, that is also acceptable for upstream and can later be merged into QEMU. Besides unconditionally writing KVM states, this format compresses
interrupt_bitmapinto a single number as there can be no more than one pending IRQ at a time.(quoted diff) +3
-3- if (kvm_enabled()) { - for (i = 0; i < sizeof(env->interrupt_bitmap)/8 ; i++) { - qemu_put_be64s(f, &env->interrupt_bitmap[i]); + /* KVM-related states */ + + /* There can only be one pending IRQ set in the bitmap at a time,so try
Review
Quoted 6 lines
(quoted diff) +6
-0+ to find it and save its number instead (-1 for none). */ + pending_irq = -1; + for (i = 0; i < sizeof(env->interrupt_bitmap)/2; i++) { + bit = ffs(((uint16_t *)env->interrupt_bitmap)[i]); + if (bit) { + pending_irq = i * 16 + bit;
Quoted 1 line
bit - 1
Fixed.
Quoted 7 lines
Quoted 4 lines
+ break; }Why are you using
uint64_t? It would be more natural to use ffsll and the natural type of the bitmap vector.
Better don't ask how I interpreted the ffs doc.
Quoted 11 lines
Review
Quoted 8 lines
(quoted diff) +3
-0+ } else { + kvm_load_registers(env); + kvm_load_tsc(env); kvm_load_mpstate(env); } }Don't you need to load the pending interrupt?
For >= v9 this is done in the previous hunk.
------------>
This patch reworks the KVM-related layout and encoding of the CPU state to be saved to disk or migrated. The goal is to define a format, version 9, that is also acceptable for upstream and can later be merged into QEMU. Besides unconditionally writing KVM states, this format compresses interrupt_bitmap into a single number as there can be no more than one pending IRQ at a time.
Changes in v2:
- fixed and simplified interrupt_bitmap parsing
---
target-i386/cpu.h | 2 +- target-i386/machine.c | 57 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 17 deletions(-)
target-i386/cpu.h +1 -1
@@ -838,7 +838,7 @@ static inline int cpu_get_time_fast(void)#define cpu_signal_handler cpu_x86_signal_handler#define cpu_list x86_cpu_list -#define CPU_SAVE_VERSION 8 +#define CPU_SAVE_VERSION 9/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-i386/machine.c +41 -16
90 lines not on this page · raw message
Quoted 6 lines · Jan Kiszka
Quoted 3 lines
Why are you using
uint64_t? It would be more natural to use ffsll and the natural type of the bitmap vector.Better don't ask how I interpreted the ffs doc.
It's a misdesigned API anyway.
target-i386/machine.c int cpu_load(QEMUFile *f, void *opaque, int version_id) · line 346
Quoted 7 lines
target-i386/machine.c +5
-0+if (version_id >=9 ) { +qemu_get_sbe32s (f, &pending_irq); +memset (&env->interrupt_bitmap,0 ,sizeof (env->interrupt_bitmap)); +if (pending_irq >=0 ) { + env->interrupt_bitmap[pending_irq /64 ] |=1 << (pending_irq %64 );
(uint64_t)1 so we don't lose the upper word.
Signature · 1 line
error compiling committee.c: too many arguments to function
PATCH v3 1/1 qemu-kvm: x86: Refactor persistent CPU state
This patch reworks the KVM-related layout and encoding of the CPU state to be saved to disk or migrated. The goal is to define a format, version 9, that is also acceptable for upstream and can later be merged into QEMU. Besides unconditionally writing KVM states, this format compresses interrupt_bitmap into a single number as there can be no more than one pending IRQ at a time.
Changes in v3:
- fixed bit-shift overflow
- replace upstream v9 format (should be merged upstream quickly)
Changes in v2:
- fixed and simplified interrupt_bitmap parsing
---
target-i386/machine.c | 51 ++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 44 insertions(+), 7 deletions(-)
target-i386/machine.c +44 -7
@@ -29,7 +29,8 @@ void cpu_save(QEMUFile *f, void *opaque)uint16_t fptag, fpus, fpuc, fpregs_format;uint32_t hflags;int32_t a20_mask; -int i; +int32_t pending_irq; +int i, bit;cpu_synchronize_state (env,0 );
@@ -141,11 +142,21 @@ void cpu_save(QEMUFile *f, void *opaque)qemu_put_be64s (f, &env->mtrr_var[i].mask); } -for (i =0 ; i <sizeof (env->interrupt_bitmap)/8 ; i++) { -qemu_put_be64s (f, &env->interrupt_bitmap[i]); +/* KVM-related states */ + +/* There can only be one pending IRQ set in the bitmap at a time, so try +to find it and save its number instead (-1 for none). */ + pending_irq =-1 ; +for (i =0 ; i <ARRAY_SIZE (env->interrupt_bitmap); i++) { + bit =ffsll (env->interrupt_bitmap[i]); +if (bit) { + pending_irq = i *64 + bit -1 ; +break ; + } } -qemu_put_be64s (f, &env->tsc); +qemu_put_sbe32s (f, &pending_irq);qemu_put_be32s (f, &env->mp_state); +qemu_put_be64s (f, &env->tsc); }#ifdef USE_X86LDOUBLE
@@ -179,6 +190,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)uint32_t hflags;uint16_t fpus, fpuc, fptag, fpregs_format;int32_t a20_mask; +int32_t pending_irq;if (version_id <3 || version_id >CPU_SAVE_VERSION )return -EINVAL ;
@@ -324,12 +336,16 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)qemu_get_be64s (f, &env->mtrr_var[i].mask); } } +if (version_id >=9 ) { -for (i =0 ; i <sizeof (env->interrupt_bitmap)/8 ; i++) { -qemu_get_be64s (f, &env->interrupt_bitmap[i]); +qemu_get_sbe32s (f, &pending_irq); +memset (&env->interrupt_bitmap,0 ,sizeof (env->interrupt_bitmap)); +if (pending_irq >=0 ) { + env->interrupt_bitmap[pending_irq /64 ] |= + (uint64_t )1 << (pending_irq %64 ); } -qemu_get_be64s (f, &env->tsc);qemu_get_be32s (f, &env->mp_state); +qemu_get_be64s (f, &env->tsc); }/* XXX: ensure compatiblity for halted bit ? */
@@ -337,5 +353,26 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) env->hflags = hflags;tlb_flush (env,1 );cpu_synchronize_state (env,1 ); +if (kvm_enabled ()) { +/* when in-kernel irqchip is used, env->halted causes deadlock +because no userspace IRQs will ever clear this flag */ + env->halted =0 ; +if (version_id <9 ) { +for (i =0 ; i <sizeof (env->interrupt_bitmap)/8 ; i++) { +qemu_get_be64s (f, &env->interrupt_bitmap[i]); + } +qemu_get_be64s (f, &env->tsc); +kvm_load_registers (env); +kvm_load_tsc (env); +if (version_id >=5 ) { +qemu_get_be32s (f, &env->mp_state); +kvm_load_mpstate (env); + } + }else { +kvm_load_registers (env); +kvm_load_tsc (env); +kvm_load_mpstate (env); + } + }return 0 ; }
Avi Kivity
AppliedQuoted 7 lines · Jan Kiszka
This patch reworks the KVM-related layout and encoding of the CPU state to be saved to disk or migrated. The goal is to define a format, version 9, that is also acceptable for upstream and can later be merged into QEMU. Besides unconditionally writing KVM states, this format compresses
interrupt_bitmapinto a single number as there can be no more than one pending IRQ at a time.
Applied, thanks.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 10 lines · Avi Kivity
Quoted 7 lines · Jan Kiszka
This patch reworks the KVM-related layout and encoding of the CPU state to be saved to disk or migrated. The goal is to define a format, version 9, that is also acceptable for upstream and can later be merged into QEMU. Besides unconditionally writing KVM states, this format compresses
interrupt_bitmapinto a single number as there can be no more than one pending IRQ at a time.Applied, thanks.
OK, will push its core upstream now.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux