* [Qemu-devel] [PATCH] kvmvapic: Fix TB invalidation after instruction patching
@ 2012-11-04 6:51 Jan Kiszka
2012-11-04 7:51 ` Hervé Poussineau
0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2012-11-04 6:51 UTC (permalink / raw)
To: Blue Swirl, qemu-devel; +Cc: Hervé Poussineau, David Gibson
From: Jan Kiszka <jan.kiszka@siemens.com>
Since 0b57e287, cpu_memory_rw_debug already triggers a TB invalidation.
As it doesn't (and cannot) set is_cpu_write_access=1 but "consumes" the
currently executed TB, the tb_invalidate_phys_page_range call from
patch_instruction didn't work anymore.
Fix this by open-coding the required bits to restore the CPU state from
the current TB position before patching and resume execution on the
patched instruction afterward.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
I see no better way ATM.
hw/kvmvapic.c | 20 ++++++++++++++++----
1 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c
index dc111ee..e7ab3cc 100644
--- a/hw/kvmvapic.c
+++ b/hw/kvmvapic.c
@@ -384,10 +384,13 @@ static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong ip)
{
- hwaddr paddr;
VAPICHandlers *handlers;
uint8_t opcode[2];
uint32_t imm32;
+ TranslationBlock *current_tb;
+ target_ulong current_pc;
+ target_ulong current_cs_base;
+ int current_flags;
if (smp_cpus == 1) {
handlers = &s->rom_state.up;
@@ -395,6 +398,13 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i
handlers = &s->rom_state.mp;
}
+ if (!kvm_enabled()) {
+ current_tb = tb_find_pc(env->mem_io_pc);
+ cpu_restore_state(current_tb, env, env->mem_io_pc);
+ cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
+ ¤t_flags);
+ }
+
pause_all_vcpus();
cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
@@ -430,9 +440,11 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i
resume_all_vcpus();
- paddr = cpu_get_phys_page_debug(env, ip);
- paddr += ip & ~TARGET_PAGE_MASK;
- tb_invalidate_phys_page_range(paddr, paddr + 1, 1);
+ if (!kvm_enabled()) {
+ env->current_tb = NULL;
+ tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
+ cpu_resume_from_signal(env, NULL);
+ }
}
void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip,
--
1.7.3.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] kvmvapic: Fix TB invalidation after instruction patching
2012-11-04 6:51 [Qemu-devel] [PATCH] kvmvapic: Fix TB invalidation after instruction patching Jan Kiszka
@ 2012-11-04 7:51 ` Hervé Poussineau
2012-11-04 8:16 ` [Qemu-devel] [PATCH v2] " Jan Kiszka
0 siblings, 1 reply; 4+ messages in thread
From: Hervé Poussineau @ 2012-11-04 7:51 UTC (permalink / raw)
To: Jan Kiszka; +Cc: Blue Swirl, qemu-devel, David Gibson
Jan Kiszka a écrit :
> From: Jan Kiszka <jan.kiszka@siemens.com>
>
> Since 0b57e287, cpu_memory_rw_debug already triggers a TB invalidation.
> As it doesn't (and cannot) set is_cpu_write_access=1 but "consumes" the
> currently executed TB, the tb_invalidate_phys_page_range call from
> patch_instruction didn't work anymore.
>
> Fix this by open-coding the required bits to restore the CPU state from
> the current TB position before patching and resume execution on the
> patched instruction afterward.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>
Tested-by: Hervé Poussineau <hpoussin@reactos.org>
However, I had to initialize current_pc, current_cs_base and
current_flags to 0 to prevent uninitialized warning.
(GCC 4.7.1, KVM disabled by configure)
Regards,
Hervé
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH v2] kvmvapic: Fix TB invalidation after instruction patching
2012-11-04 7:51 ` Hervé Poussineau
@ 2012-11-04 8:16 ` Jan Kiszka
2012-11-10 19:27 ` Blue Swirl
0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2012-11-04 8:16 UTC (permalink / raw)
To: Blue Swirl, qemu-devel; +Cc: Hervé Poussineau, David Gibson
From: Jan Kiszka <jan.kiszka@siemens.com>
Since 0b57e287, cpu_memory_rw_debug already triggers a TB invalidation.
As it doesn't (and cannot) set is_cpu_write_access=1 but "consumes" the
currently executed TB, the tb_invalidate_phys_page_range call from
patch_instruction didn't work anymore.
Fix this by open-coding the required bits to restore the CPU state from
the current TB position before patching and resume execution on the
patched instruction afterward.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
Changes in v2:
- make the compiler happier by initializing local variables to 0
hw/kvmvapic.c | 20 ++++++++++++++++----
1 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c
index dc111ee..09c6433 100644
--- a/hw/kvmvapic.c
+++ b/hw/kvmvapic.c
@@ -384,10 +384,13 @@ static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong ip)
{
- hwaddr paddr;
VAPICHandlers *handlers;
uint8_t opcode[2];
uint32_t imm32;
+ TranslationBlock *current_tb;
+ target_ulong current_pc = 0;
+ target_ulong current_cs_base = 0;
+ int current_flags = 0;
if (smp_cpus == 1) {
handlers = &s->rom_state.up;
@@ -395,6 +398,13 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i
handlers = &s->rom_state.mp;
}
+ if (!kvm_enabled()) {
+ current_tb = tb_find_pc(env->mem_io_pc);
+ cpu_restore_state(current_tb, env, env->mem_io_pc);
+ cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
+ ¤t_flags);
+ }
+
pause_all_vcpus();
cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
@@ -430,9 +440,11 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i
resume_all_vcpus();
- paddr = cpu_get_phys_page_debug(env, ip);
- paddr += ip & ~TARGET_PAGE_MASK;
- tb_invalidate_phys_page_range(paddr, paddr + 1, 1);
+ if (!kvm_enabled()) {
+ env->current_tb = NULL;
+ tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
+ cpu_resume_from_signal(env, NULL);
+ }
}
void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip,
--
1.7.3.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2] kvmvapic: Fix TB invalidation after instruction patching
2012-11-04 8:16 ` [Qemu-devel] [PATCH v2] " Jan Kiszka
@ 2012-11-10 19:27 ` Blue Swirl
0 siblings, 0 replies; 4+ messages in thread
From: Blue Swirl @ 2012-11-10 19:27 UTC (permalink / raw)
To: Jan Kiszka; +Cc: Hervé Poussineau, qemu-devel, David Gibson
Thanks, applied. Fixes also Win2k boot.
On Sun, Nov 4, 2012 at 8:16 AM, Jan Kiszka <jan.kiszka@web.de> wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
>
> Since 0b57e287, cpu_memory_rw_debug already triggers a TB invalidation.
> As it doesn't (and cannot) set is_cpu_write_access=1 but "consumes" the
> currently executed TB, the tb_invalidate_phys_page_range call from
> patch_instruction didn't work anymore.
>
> Fix this by open-coding the required bits to restore the CPU state from
> the current TB position before patching and resume execution on the
> patched instruction afterward.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>
> Changes in v2:
> - make the compiler happier by initializing local variables to 0
>
> hw/kvmvapic.c | 20 ++++++++++++++++----
> 1 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c
> index dc111ee..09c6433 100644
> --- a/hw/kvmvapic.c
> +++ b/hw/kvmvapic.c
> @@ -384,10 +384,13 @@ static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
>
> static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong ip)
> {
> - hwaddr paddr;
> VAPICHandlers *handlers;
> uint8_t opcode[2];
> uint32_t imm32;
> + TranslationBlock *current_tb;
> + target_ulong current_pc = 0;
> + target_ulong current_cs_base = 0;
> + int current_flags = 0;
>
> if (smp_cpus == 1) {
> handlers = &s->rom_state.up;
> @@ -395,6 +398,13 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i
> handlers = &s->rom_state.mp;
> }
>
> + if (!kvm_enabled()) {
> + current_tb = tb_find_pc(env->mem_io_pc);
> + cpu_restore_state(current_tb, env, env->mem_io_pc);
> + cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
> + ¤t_flags);
> + }
> +
> pause_all_vcpus();
>
> cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
> @@ -430,9 +440,11 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i
>
> resume_all_vcpus();
>
> - paddr = cpu_get_phys_page_debug(env, ip);
> - paddr += ip & ~TARGET_PAGE_MASK;
> - tb_invalidate_phys_page_range(paddr, paddr + 1, 1);
> + if (!kvm_enabled()) {
> + env->current_tb = NULL;
> + tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
> + cpu_resume_from_signal(env, NULL);
> + }
> }
>
> void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip,
> --
> 1.7.3.4
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-11-10 19:27 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-04 6:51 [Qemu-devel] [PATCH] kvmvapic: Fix TB invalidation after instruction patching Jan Kiszka
2012-11-04 7:51 ` Hervé Poussineau
2012-11-04 8:16 ` [Qemu-devel] [PATCH v2] " Jan Kiszka
2012-11-10 19:27 ` Blue Swirl
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).