* [PATCH] qemu-kvm: Switch to upstream TPR optimization
@ 2012-03-09 21:35 Jan Kiszka
2012-03-09 22:17 ` [PATCH] qemu-kvm: Eliminate _kvm_arch_init_vcpu Jan Kiszka
2012-03-09 23:50 ` [PATCH] qemu-kvm: Switch to upstream TPR optimization Marcelo Tosatti
0 siblings, 2 replies; 5+ messages in thread
From: Jan Kiszka @ 2012-03-09 21:35 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm
From: Jan Kiszka <jan.kiszka@siemens.com>
The upstream version is feature-equivalent and covers more corner cases.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
As the upstream merge was not successful, this also unbreaks XP etc.
over current qemu-kvm.
.gitignore | 1 -
Makefile | 1 -
Makefile.target | 3 -
hw/pc.c | 6 -
kvm-tpr-opt.c | 380 --------------------------------------------
pc-bios/optionrom/Makefile | 2 -
pc-bios/optionrom/vapic.S | 341 ---------------------------------------
pc-bios/vapic.bin | Bin 8960 -> 0 bytes
qemu-kvm-x86.c | 33 ----
qemu-kvm.h | 5 -
target-i386/kvm.c | 15 --
11 files changed, 0 insertions(+), 787 deletions(-)
delete mode 100644 kvm-tpr-opt.c
delete mode 100644 pc-bios/optionrom/vapic.S
delete mode 100755 pc-bios/vapic.bin
diff --git a/.gitignore b/.gitignore
index af5fb3c..81b1510 100644
--- a/.gitignore
+++ b/.gitignore
@@ -77,7 +77,6 @@ pc-bios/vgabios-pq/status
pc-bios/optionrom/linuxboot.bin
pc-bios/optionrom/multiboot.bin
pc-bios/optionrom/multiboot.raw
-pc-bios/optionrom/vapic.bin
pc-bios/optionrom/kvmvapic.bin
.stgit-*
cscope.*
diff --git a/Makefile b/Makefile
index 35c30f9..2765dcb 100644
--- a/Makefile
+++ b/Makefile
@@ -260,7 +260,6 @@ multiboot.bin linuxboot.bin kvmvapic.bin \
s390-zipl.rom \
spapr-rtas.bin slof.bin \
palcode-clipper
-BLOBS += vapic.bin
else
BLOBS=
endif
diff --git a/Makefile.target b/Makefile.target
index 6b490f0..ae04331 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -86,9 +86,6 @@ libobj-y += cpuid.o
endif
libobj-$(TARGET_SPARC64) += vis_helper.o
libobj-$(CONFIG_NEED_MMU) += mmu.o
-
-libobj-$(CONFIG_KVM) += kvm-tpr-opt.o
-
libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
ifeq ($(TARGET_BASE_ARCH), sparc)
libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
diff --git a/hw/pc.c b/hw/pc.c
index 6dcf6df..74c19b9 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -60,8 +60,6 @@
#define DPRINTF(fmt, ...)
#endif
-#define VAPIC_FILENAME "vapic.bin"
-
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
#define ACPI_DATA_SIZE 0x10000
#define BIOS_CFG_IOPORT 0x510
@@ -1022,10 +1020,6 @@ void pc_memory_init(MemoryRegion *system_memory,
option_rom_mr,
1);
- option_rom[nb_option_roms].name = g_strdup(VAPIC_FILENAME);
- option_rom[nb_option_roms].bootindex = -1;
- nb_option_roms++;
-
fw_cfg = bochs_bios_init();
rom_set_fw(fw_cfg);
diff --git a/kvm-tpr-opt.c b/kvm-tpr-opt.c
deleted file mode 100644
index 83de497..0000000
--- a/kvm-tpr-opt.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * tpr optimization for qemu/kvm
- *
- * Copyright (C) 2007-2008 Qumranet Technologies
- *
- * Licensed under the terms of the GNU GPL version 2 or higher.
- */
-
-#include "config.h"
-#include "config-host.h"
-
-#include <string.h>
-
-#include "hw/hw.h"
-#include "hw/isa.h"
-#include "sysemu.h"
-#include "kvm.h"
-#include "cpu.h"
-
-#include <stdio.h>
-
-static uint64_t map_addr(CPUState *env, target_ulong virt, unsigned *perms)
-{
- uint64_t mask = ((1ull << 48) - 1) & ~4095ull;
- uint64_t p, pp = 7;
-
- p = env->cr[3];
- if (env->cr[4] & 0x20) {
- p &= ~31ull;
- p = ldq_phys(p + 8 * (virt >> 30));
- if (!(p & 1))
- return -1ull;
- p &= mask;
- p = ldq_phys(p + 8 * ((virt >> 21) & 511));
- if (!(p & 1))
- return -1ull;
- pp &= p;
- if (p & 128) {
- p += ((virt >> 12) & 511) << 12;
- } else {
- p &= mask;
- p = ldq_phys(p + 8 * ((virt >> 12) & 511));
- if (!(p & 1))
- return -1ull;
- pp &= p;
- }
- } else {
- p &= mask;
- p = ldl_phys(p + 4 * ((virt >> 22) & 1023));
- if (!(p & 1))
- return -1ull;
- pp &= p;
- if (p & 128) {
- p += ((virt >> 12) & 1023) << 12;
- } else {
- p &= mask;
- p = ldl_phys(p + 4 * ((virt >> 12) & 1023));
- pp &= p;
- if (!(p & 1))
- return -1ull;
- }
- }
- if (perms)
- *perms = pp >> 1;
- p &= mask;
- return p + (virt & 4095);
-}
-
-static uint8_t read_byte_virt(CPUState *env, target_ulong virt)
-{
- return ldub_phys(map_addr(env, virt, NULL));
-}
-
-static void write_byte_virt(CPUState *env, target_ulong virt, uint8_t b)
-{
- cpu_physical_memory_write_rom(map_addr(env, virt, NULL), &b, 1);
-}
-
-struct vapic_bios {
- char signature[8];
- uint32_t virt_base;
- uint32_t fixup_start;
- uint32_t fixup_end;
- uint32_t vapic;
- uint32_t vapic_size;
- uint32_t vcpu_shift;
- uint32_t real_tpr;
- struct vapic_patches {
- uint32_t set_tpr;
- uint32_t set_tpr_eax;
- uint32_t get_tpr[8];
- uint32_t get_tpr_stack;
- } __attribute__((packed)) up, mp;
-} __attribute__((packed));
-
-static struct vapic_bios vapic_bios;
-
-static uint32_t real_tpr;
-static uint32_t bios_addr;
-static uint32_t vapic_phys;
-static uint32_t bios_enabled;
-static uint32_t vbios_desc_phys;
-static uint32_t vapic_bios_addr;
-
-static void update_vbios_real_tpr(void)
-{
- cpu_physical_memory_rw(vbios_desc_phys, (void *)&vapic_bios, sizeof vapic_bios, 0);
- vapic_bios.real_tpr = real_tpr;
- vapic_bios.vcpu_shift = 7;
- cpu_physical_memory_write_rom(vbios_desc_phys, (void *)&vapic_bios, sizeof vapic_bios);
-}
-
-static unsigned modrm_reg(uint8_t modrm)
-{
- return (modrm >> 3) & 7;
-}
-
-static int is_abs_modrm(uint8_t modrm)
-{
- return (modrm & 0xc7) == 0x05;
-}
-
-static int instruction_is_ok(CPUState *env, uint64_t rip, int is_write)
-{
- uint8_t b1, b2;
- unsigned addr_offset;
- uint32_t addr;
- uint64_t p;
-
- if ((rip & 0xf0000000) != 0x80000000 && (rip & 0xf0000000) != 0xe0000000)
- return 0;
- if (env->regs[R_ESP] == 0)
- return 0;
- b1 = read_byte_virt(env, rip);
- b2 = read_byte_virt(env, rip + 1);
- switch (b1) {
- case 0xc7: /* mov imm32, r/m32 (c7/0) */
- if (modrm_reg(b2) != 0)
- return 0;
- /* fall through */
- case 0x89: /* mov r32 to r/m32 */
- case 0x8b: /* mov r/m32 to r32 */
- if (!is_abs_modrm(b2))
- return 0;
- addr_offset = 2;
- break;
- case 0xa1: /* mov abs to eax */
- case 0xa3: /* mov eax to abs */
- addr_offset = 1;
- break;
- case 0xff: /* push r/m32 */
- if (modrm_reg(b2) != 6 || !is_abs_modrm(b2))
- return 0;
- addr_offset = 2;
- break;
- default:
- return 0;
- }
- p = rip + addr_offset;
- addr = read_byte_virt(env, p++);
- addr |= read_byte_virt(env, p++) << 8;
- addr |= read_byte_virt(env, p++) << 16;
- addr |= read_byte_virt(env, p++) << 24;
- if ((addr & 0xfff) != 0x80)
- return 0;
- real_tpr = addr;
- update_vbios_real_tpr();
- return 1;
-}
-
-static int bios_is_mapped(CPUState *env, uint64_t rip)
-{
- uint32_t probe;
- uint64_t phys;
- unsigned perms;
- uint32_t i;
- uint32_t offset, fixup, start = vapic_bios_addr ? : 0xe0000;
- uint32_t patch;
-
- if (bios_enabled)
- return 1;
-
- probe = (rip & 0xf0000000) + start;
- phys = map_addr(env, probe, &perms);
- if (phys != start)
- return 0;
- bios_addr = probe;
- for (i = 0; i < 64; ++i) {
- cpu_physical_memory_read(phys, (void *)&vapic_bios, sizeof(vapic_bios));
- if (memcmp(vapic_bios.signature, "kvm aPiC", 8) == 0)
- break;
- phys += 1024;
- bios_addr += 1024;
- }
- if (i == 64)
- return 0;
- if (bios_addr == vapic_bios.virt_base)
- return 1;
- vbios_desc_phys = phys;
- for (i = vapic_bios.fixup_start; i < vapic_bios.fixup_end; i += 4) {
- offset = ldl_phys(phys + i - vapic_bios.virt_base);
- fixup = phys + offset;
- patch = ldl_phys(fixup) + bios_addr - vapic_bios.virt_base;
- cpu_physical_memory_write_rom(fixup, (uint8_t *)&patch, 4);
- }
- vapic_phys = vapic_bios.vapic - vapic_bios.virt_base + phys;
- return 1;
-}
-
-static int get_pcr_cpu(CPUState *env)
-{
- uint8_t b;
-
- cpu_synchronize_state(env);
-
- if (cpu_memory_rw_debug(env, env->segs[R_FS].base + 0x51, &b, 1, 0) < 0)
- return -1;
-
- return (int)b;
-}
-
-static int tpr_enable_vapic(CPUState *env)
-{
- static uint8_t one = 1;
- int pcr_cpu = get_pcr_cpu(env);
-
- if (pcr_cpu < 0)
- return 0;
-
- kvm_enable_vapic(env, vapic_phys + (pcr_cpu << 7));
- cpu_physical_memory_write_rom(vapic_phys + (pcr_cpu << 7) + 4, &one, 1);
- bios_enabled = 1;
- return 1;
-}
-
-void kvm_tpr_enable_vapic(CPUState *env)
-{
- if (!bios_enabled)
- return;
- tpr_enable_vapic(env);
-}
-
-static void patch_call(CPUState *env, uint64_t rip, uint32_t target)
-{
- uint32_t offset;
-
- offset = target - vapic_bios.virt_base + bios_addr - rip - 5;
- write_byte_virt(env, rip, 0xe8); /* call near */
- write_byte_virt(env, rip + 1, offset);
- write_byte_virt(env, rip + 2, offset >> 8);
- write_byte_virt(env, rip + 3, offset >> 16);
- write_byte_virt(env, rip + 4, offset >> 24);
-}
-
-static void patch_instruction(CPUState *env, uint64_t rip)
-{
- uint8_t b1, b2;
- struct vapic_patches *vp;
-
- vp = smp_cpus == 1 ? &vapic_bios.up : &vapic_bios.mp;
- b1 = read_byte_virt(env, rip);
- b2 = read_byte_virt(env, rip + 1);
- switch (b1) {
- case 0x89: /* mov r32 to r/m32 */
- write_byte_virt(env, rip, 0x50 + modrm_reg(b2)); /* push reg */
- patch_call(env, rip + 1, vp->set_tpr);
- break;
- case 0x8b: /* mov r/m32 to r32 */
- write_byte_virt(env, rip, 0x90);
- patch_call(env, rip + 1, vp->get_tpr[modrm_reg(b2)]);
- break;
- case 0xa1: /* mov abs to eax */
- patch_call(env, rip, vp->get_tpr[0]);
- break;
- case 0xa3: /* mov eax to abs */
- patch_call(env, rip, vp->set_tpr_eax);
- break;
- case 0xc7: /* mov imm32, r/m32 (c7/0) */
- write_byte_virt(env, rip, 0x68); /* push imm32 */
- write_byte_virt(env, rip + 1, read_byte_virt(env, rip+6));
- write_byte_virt(env, rip + 2, read_byte_virt(env, rip+7));
- write_byte_virt(env, rip + 3, read_byte_virt(env, rip+8));
- write_byte_virt(env, rip + 4, read_byte_virt(env, rip+9));
- patch_call(env, rip + 5, vp->set_tpr);
- break;
- case 0xff: /* push r/m32 */
- printf("patching push\n");
- write_byte_virt(env, rip, 0x50); /* push eax */
- patch_call(env, rip + 1, vp->get_tpr_stack);
- break;
- default:
- printf("funny insn %02x %02x\n", b1, b2);
- }
-}
-
-void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write)
-{
- cpu_synchronize_state(env);
- if (!instruction_is_ok(env, rip, is_write))
- return;
- if (!bios_is_mapped(env, rip))
- return;
- if (!tpr_enable_vapic(env))
- return;
- patch_instruction(env, rip);
-}
-
-static void tpr_save(QEMUFile *f, void *s)
-{
- int i;
-
- for (i = 0; i < (sizeof vapic_bios) / 4; ++i)
- qemu_put_be32s(f, &((uint32_t *)&vapic_bios)[i]);
- qemu_put_be32s(f, &bios_enabled);
- qemu_put_be32s(f, &real_tpr);
- qemu_put_be32s(f, &bios_addr);
- qemu_put_be32s(f, &vapic_phys);
- qemu_put_be32s(f, &vbios_desc_phys);
-}
-
-static int tpr_load(QEMUFile *f, void *s, int version_id)
-{
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- for (i = 0; i < (sizeof vapic_bios) / 4; ++i)
- qemu_get_be32s(f, &((uint32_t *)&vapic_bios)[i]);
- qemu_get_be32s(f, &bios_enabled);
- qemu_get_be32s(f, &real_tpr);
- qemu_get_be32s(f, &bios_addr);
- qemu_get_be32s(f, &vapic_phys);
- qemu_get_be32s(f, &vbios_desc_phys);
-
- return 0;
-}
-
-static void vtpr_ioport_write16(void *opaque, uint32_t addr, uint32_t val)
-{
- CPUState *env = cpu_single_env;
-
- cpu_synchronize_state(env);
-
- vapic_bios_addr = ((env->segs[R_CS].base + env->eip) & ~(512 - 1)) + val;
- bios_enabled = 0;
-}
-
-static void vtpr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- CPUState *env = cpu_single_env;
- uint32_t rip;
-
- cpu_synchronize_state(env);
-
- rip = env->eip - 2;
- write_byte_virt(env, rip, 0x66);
- write_byte_virt(env, rip + 1, 0x90);
- if (bios_enabled)
- return;
- if (!bios_is_mapped(env, rip))
- printf("bios not mapped?\n");
- for (addr = 0xfffff000u; addr >= 0x80000000u; addr -= 4096)
- if (map_addr(env, addr, NULL) == 0xfee00000u) {
- real_tpr = addr + 0x80;
- break;
- }
- bios_enabled = 1;
- update_vbios_real_tpr();
- tpr_enable_vapic(env);
-}
-
-static void kvm_tpr_opt_setup(void)
-{
- register_savevm(NULL, "kvm-tpr-opt", 0, 1, tpr_save, tpr_load, NULL);
- register_ioport_write(0x7e, 1, 1, vtpr_ioport_write, NULL);
- register_ioport_write(0x7e, 2, 2, vtpr_ioport_write16, NULL);
-}
-
-type_init(kvm_tpr_opt_setup);
diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
index ceb04d1..f6b4027 100644
--- a/pc-bios/optionrom/Makefile
+++ b/pc-bios/optionrom/Makefile
@@ -16,8 +16,6 @@ QEMU_CFLAGS = $(CFLAGS)
build-all: multiboot.bin linuxboot.bin kvmvapic.bin
-build-all: vapic.bin
-
# suppress auto-removal of intermediate files
.SECONDARY:
diff --git a/pc-bios/optionrom/vapic.S b/pc-bios/optionrom/vapic.S
deleted file mode 100644
index e1d8f18..0000000
--- a/pc-bios/optionrom/vapic.S
+++ /dev/null
@@ -1,341 +0,0 @@
-#
-# Local APIC acceleration for Windows XP and related guests
-#
-# Copyright 2011 Red Hat, Inc. and/or its affiliates
-#
-# Author: Avi Kivity <avi@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2, or (at your
-# option) any later version. See the COPYING file in the top-level directory.
-#
-
- .text 0
- .code16
-.global _start
-_start:
- .short 0xaa55
- .byte (_end - _start) / 512
- # clear vapic area: firmware load using rep insb may cause
- # stale tpr/isr/irr data to corrupt the vapic area.
- push %es
- push %cs
- pop %es
- xor %ax, %ax
- mov $vapic_size/2, %cx
- lea vapic, %di
- cld
- rep stosw
- pop %es
- mov $vapic_base, %ax
- out %ax, $0x7e
- lret
-
- .code32
-vapic_size = 2*4096
-
-.macro fixup delta=-4
-777:
- .text 1
- .long 777b + \delta - vapic_base
- .text 0
-.endm
-
-.macro reenable_vtpr
- out %al, $0x7e
-.endm
-
-.text 1
- fixup_start = .
-.text 0
-
-.align 16
-
-vapic_base:
- .ascii "kvm aPiC"
-
- /* relocation data */
- .long vapic_base ; fixup
- .long fixup_start ; fixup
- .long fixup_end ; fixup
-
- .long vapic ; fixup
- .long vapic_size
-vcpu_shift:
- .long 0
-real_tpr:
- .long 0
- .long up_set_tpr ; fixup
- .long up_set_tpr_eax ; fixup
- .long up_get_tpr_eax ; fixup
- .long up_get_tpr_ecx ; fixup
- .long up_get_tpr_edx ; fixup
- .long up_get_tpr_ebx ; fixup
- .long 0 /* esp. won't work. */
- .long up_get_tpr_ebp ; fixup
- .long up_get_tpr_esi ; fixup
- .long up_get_tpr_edi ; fixup
- .long up_get_tpr_stack ; fixup
- .long mp_set_tpr ; fixup
- .long mp_set_tpr_eax ; fixup
- .long mp_get_tpr_eax ; fixup
- .long mp_get_tpr_ecx ; fixup
- .long mp_get_tpr_edx ; fixup
- .long mp_get_tpr_ebx ; fixup
- .long 0 /* esp. won't work. */
- .long mp_get_tpr_ebp ; fixup
- .long mp_get_tpr_esi ; fixup
- .long mp_get_tpr_edi ; fixup
- .long mp_get_tpr_stack ; fixup
-
-.macro kvm_hypercall
- .byte 0x0f, 0x01, 0xc1
-.endm
-
-kvm_hypercall_vapic_poll_irq = 1
-
-pcr_cpu = 0x51
-
-.align 64
-
-mp_get_tpr_eax:
- pushf
- cli
- reenable_vtpr
- push %ecx
-
- fs/movzbl pcr_cpu, %eax
-
- mov vcpu_shift, %ecx ; fixup
- shl %cl, %eax
- testb $1, vapic+4(%eax) ; fixup delta=-5
- jz mp_get_tpr_bad
- movzbl vapic(%eax), %eax ; fixup
-
-mp_get_tpr_out:
- pop %ecx
- popf
- ret
-
-mp_get_tpr_bad:
- mov real_tpr, %eax ; fixup
- mov (%eax), %eax
- jmp mp_get_tpr_out
-
-mp_get_tpr_ebx:
- mov %eax, %ebx
- call mp_get_tpr_eax
- xchg %eax, %ebx
- ret
-
-mp_get_tpr_ecx:
- mov %eax, %ecx
- call mp_get_tpr_eax
- xchg %eax, %ecx
- ret
-
-mp_get_tpr_edx:
- mov %eax, %edx
- call mp_get_tpr_eax
- xchg %eax, %edx
- ret
-
-mp_get_tpr_esi:
- mov %eax, %esi
- call mp_get_tpr_eax
- xchg %eax, %esi
- ret
-
-mp_get_tpr_edi:
- mov %eax, %edi
- call mp_get_tpr_edi
- xchg %eax, %edi
- ret
-
-mp_get_tpr_ebp:
- mov %eax, %ebp
- call mp_get_tpr_eax
- xchg %eax, %ebp
- ret
-
-mp_get_tpr_stack:
- call mp_get_tpr_eax
- xchg %eax, 4(%esp)
- ret
-
-mp_set_tpr_eax:
- push %eax
- call mp_set_tpr
- ret
-
-mp_set_tpr:
- pushf
- push %eax
- push %ecx
- push %edx
- push %ebx
- cli
- reenable_vtpr
-
-mp_set_tpr_failed:
- fs/movzbl pcr_cpu, %edx
-
- mov vcpu_shift, %ecx ; fixup
- shl %cl, %edx
-
- testb $1, vapic+4(%edx) ; fixup delta=-5
- jz mp_set_tpr_bad
-
- mov vapic(%edx), %eax ; fixup
-
- mov %eax, %ebx
- mov 24(%esp), %bl
-
- /* %ebx = new vapic (%bl = tpr, %bh = isr, %b3 = irr) */
-
- lock cmpxchg %ebx, vapic(%edx) ; fixup
- jnz mp_set_tpr_failed
-
- /* compute ppr */
- cmp %bh, %bl
- jae mp_tpr_is_bigger
-mp_isr_is_bigger:
- mov %bh, %bl
-mp_tpr_is_bigger:
- /* %bl = ppr */
- mov %bl, %ch /* ch = ppr */
- rol $8, %ebx
- /* now: %bl = irr, %bh = ppr */
- cmp %bh, %bl
- ja mp_set_tpr_poll_irq
-
-mp_set_tpr_out:
- pop %ebx
- pop %edx
- pop %ecx
- pop %eax
- popf
- ret $4
-
-mp_set_tpr_poll_irq:
- mov $kvm_hypercall_vapic_poll_irq, %eax
- kvm_hypercall
- jmp mp_set_tpr_out
-
-mp_set_tpr_bad:
- mov 24(%esp), %ecx
- mov real_tpr, %eax ; fixup
- mov %ecx, (%eax)
- jmp mp_set_tpr_out
-
-up_get_tpr_eax:
- reenable_vtpr
- movzbl vapic, %eax ; fixup
- ret
-
-up_get_tpr_ebx:
- reenable_vtpr
- movzbl vapic, %ebx ; fixup
- ret
-
-up_get_tpr_ecx:
- reenable_vtpr
- movzbl vapic, %ecx ; fixup
- ret
-
-up_get_tpr_edx:
- reenable_vtpr
- movzbl vapic, %edx ; fixup
- ret
-
-up_get_tpr_esi:
- reenable_vtpr
- movzbl vapic, %esi ; fixup
- ret
-
-up_get_tpr_edi:
- reenable_vtpr
- movzbl vapic, %edi ; fixup
- ret
-
-up_get_tpr_ebp:
- reenable_vtpr
- movzbl vapic, %ebp ; fixup
- ret
-
-up_get_tpr_stack:
- reenable_vtpr
- movzbl vapic, %eax ; fixup
- xchg %eax, 4(%esp)
- ret
-
-up_set_tpr_eax:
- push %eax
- call up_set_tpr
- ret
-
-up_set_tpr:
- pushf
- push %eax
- push %ecx
- push %ebx
- reenable_vtpr
-
-up_set_tpr_failed:
- mov vapic, %eax ; fixup
-
- mov %eax, %ebx
- mov 20(%esp), %bl
-
- /* %ebx = new vapic (%bl = tpr, %bh = isr, %b3 = irr) */
-
- lock cmpxchg %ebx, vapic ; fixup
- jnz up_set_tpr_failed
-
- /* compute ppr */
- cmp %bh, %bl
- jae up_tpr_is_bigger
-up_isr_is_bigger:
- mov %bh, %bl
-up_tpr_is_bigger:
- /* %bl = ppr */
- mov %bl, %ch /* ch = ppr */
- rol $8, %ebx
- /* now: %bl = irr, %bh = ppr */
- cmp %bh, %bl
- ja up_set_tpr_poll_irq
-
-up_set_tpr_out:
- pop %ebx
- pop %ecx
- pop %eax
- popf
- ret $4
-
-up_set_tpr_poll_irq:
- mov $kvm_hypercall_vapic_poll_irq, %eax
- kvm_hypercall
- jmp up_set_tpr_out
-
-.text 1
- fixup_end = .
-.text 0
-
-/*
- * vapic format:
- * per-vcpu records of size 2^vcpu shift.
- * byte 0: tpr (r/w)
- * byte 1: highest in-service interrupt (isr) (r/o); bits 3:0 are zero
- * byte 2: zero (r/o)
- * byte 3: highest pending interrupt (irr) (r/o)
- */
-.text 2
-
-.align 128
-
-vapic:
-. = . + vapic_size
-
-.byte 0 # reserve space for signature
-.align 512, 0
-
-_end:
diff --git a/pc-bios/vapic.bin b/pc-bios/vapic.bin
deleted file mode 100755
index 35f0cf2a38451f59bbf425c392e69d11ce5c2add..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8960
zcmeH_Pe_wt9LJyO!Xe6Q;J{1jVNeHyqNE`NQ62<6Y+B&bLxGnlA;?vyF@(t1UCO^u
z+rdkL5aeZyI@o+PgP@Qud63Fry)a0HuyV-yJTqR>OHe1__k+*g?|8T8_kBOS7p4zp
zYSfq5YpWryn5#GY8!v~hoU0+9C{yYKsB&n8-}A$x)CQzr2A;!XFtf~c0p7xA2*PoA
z!M!agCvR{yQ%|k}KOBa8|1im|TrAvYr4NKTFj3va=ev)aaW9oU1C>@fZpueedg_?D
zukzn)?Yt@$i=*1kI<tiP+MaXLgb{7Obe<3<w7uy3Bur|1!Ffm+*UlK1yR8AQ4mmVc
zIvEOgcCnk){y$c)ZVv9OK9v|Wn{7SZ8>m~iW*(St(WPMFM%hqdXeFzC!NM(H&&5c0
zYR;=N=1j|z&3{dF1nNp%ZD0OVF2;kIKWdW>xvAPsem6C{>9m`Ux~X)^p8j3A*p&G}
zsbei2OADg;-5o1>_EcQ+(X|T9D^d#qI0DAKv3wGOa0XhT4LTqM=b;;V;S%)0HMkA~
za2sY}5td*XT99)V+93jWU<8uz2%f?-n1?s;9@bzR{`y97zKj?U17bi7hygJm2E>3E
v5CdXB42S_SAO^&M7!U(uKn#chF(3xSfEW-1Vn7Utf&Fga`+k3b|Ly+^8CLND
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 2dad5af..159779c 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -45,25 +45,6 @@ int kvm_create_pit(KVMState *s)
return 0;
}
-int kvm_handle_tpr_access(CPUState *env)
-{
- struct kvm_run *run = env->kvm_run;
- kvm_tpr_access_report(env,
- run->tpr_access.rip,
- run->tpr_access.is_write);
- return 1;
-}
-
-
-int kvm_enable_vapic(CPUState *env, uint64_t vapic)
-{
- struct kvm_vapic_addr va = {
- .vapic_addr = vapic,
- };
-
- return kvm_vcpu_ioctl(env, KVM_SET_VAPIC_ADDR, &va);
-}
-
int kvm_get_pit(KVMState *s, struct kvm_pit_state *pit_state)
{
if (!kvm_irqchip_in_kernel()) {
@@ -96,24 +77,10 @@ int kvm_set_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
return kvm_vm_ioctl(s, KVM_SET_PIT2, ps2);
}
-static int kvm_enable_tpr_access_reporting(CPUState *env)
-{
- int r;
- struct kvm_tpr_access_ctl tac = { .enabled = 1 };
-
- r = kvm_ioctl(env->kvm_state, KVM_CHECK_EXTENSION, KVM_CAP_VAPIC);
- if (r <= 0) {
- return -ENOSYS;
- }
- return kvm_vcpu_ioctl(env, KVM_TPR_ACCESS_REPORTING, &tac);
-}
-
static int _kvm_arch_init_vcpu(CPUState *env)
{
kvm_arch_reset_vcpu(env);
- kvm_enable_tpr_access_reporting(env);
-
return kvm_update_ioport_access(env);
}
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 3c4f023..db44019 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -180,8 +180,6 @@ struct kvm_pit_state {
void kvm_hpet_enable_kpit(void);
void kvm_hpet_disable_kpit(void);
-void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write);
-
int kvm_add_ioport_region(unsigned long start, unsigned long size,
bool is_hot_plug);
int kvm_remove_ioport_region(unsigned long start, unsigned long size,
@@ -196,7 +194,4 @@ int kvm_create_pit(KVMState *s);
extern int kvm_pit_reinject;
extern unsigned int kvm_shadow_memory;
-int kvm_handle_tpr_access(CPUState *env);
-void kvm_tpr_enable_vapic(CPUState *env);
-
#endif
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index e1bf254..461734d 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -583,18 +583,8 @@ int kvm_arch_init_vcpu(CPUState *env)
return 0;
}
-static void kvm_clear_vapic(CPUState *env)
-{
- struct kvm_vapic_addr va = {
- .vapic_addr = 0,
- };
-
- kvm_vcpu_ioctl(env, KVM_SET_VAPIC_ADDR, &va);
-}
-
void kvm_arch_reset_vcpu(CPUState *env)
{
- kvm_clear_vapic(env);
env->exception_injected = -1;
env->interrupt_injected = -1;
env->xcr0 = 1;
@@ -1583,9 +1573,6 @@ int kvm_arch_put_registers(CPUState *env, int level)
if (ret < 0) {
return ret;
}
- if (level == KVM_PUT_FULL_STATE) {
- kvm_tpr_enable_vapic(env);
- }
/* must be last */
ret = kvm_guest_debug_workarounds(env);
if (ret < 0) {
@@ -1774,7 +1761,6 @@ static int kvm_handle_halt(CPUState *env)
return 0;
}
-#ifdef KVM_UPSTREAM
static int kvm_handle_tpr_access(CPUState *env)
{
struct kvm_run *run = env->kvm_run;
@@ -1784,7 +1770,6 @@ static int kvm_handle_tpr_access(CPUState *env)
: TPR_ACCESS_READ);
return 1;
}
-#endif
int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
{
--
1.7.3.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH] qemu-kvm: Eliminate _kvm_arch_init_vcpu
2012-03-09 21:35 [PATCH] qemu-kvm: Switch to upstream TPR optimization Jan Kiszka
@ 2012-03-09 22:17 ` Jan Kiszka
2012-04-23 8:42 ` Jan Kiszka
2012-03-09 23:50 ` [PATCH] qemu-kvm: Switch to upstream TPR optimization Marcelo Tosatti
1 sibling, 1 reply; 5+ messages in thread
From: Jan Kiszka @ 2012-03-09 22:17 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm
From: Jan Kiszka <jan.kiszka@siemens.com>
There is no need for an explicit kvm_arch_reset_vcpu on arch cpu init
anymore, kvm_init_vcpu does it already. Call the remaining
kvm_update_ioport_access directly from kvm_arch_init_vcpu.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
This depends on the TPR switch-over patch.
qemu-kvm-x86.c | 7 -------
target-i386/kvm.c | 4 +---
2 files changed, 1 insertions(+), 10 deletions(-)
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 159779c..7de51dc 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -77,13 +77,6 @@ int kvm_set_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
return kvm_vm_ioctl(s, KVM_SET_PIT2, ps2);
}
-static int _kvm_arch_init_vcpu(CPUState *env)
-{
- kvm_arch_reset_vcpu(env);
-
- return kvm_update_ioport_access(env);
-}
-
#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
int kvm_arch_set_ioport_access(unsigned long start, unsigned long size,
bool enable)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 461734d..91110c1 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -345,8 +345,6 @@ static void cpu_update_state(void *opaque, int running, RunState state)
}
}
-static int _kvm_arch_init_vcpu(CPUState *env);
-
int kvm_arch_init_vcpu(CPUState *env)
{
struct {
@@ -360,7 +358,7 @@ int kvm_arch_init_vcpu(CPUState *env)
uint32_t signature[3];
int r;
- r = _kvm_arch_init_vcpu(env);
+ r = kvm_update_ioport_access(env);
if (r < 0) {
return r;
}
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] qemu-kvm: Switch to upstream TPR optimization
2012-03-09 21:35 [PATCH] qemu-kvm: Switch to upstream TPR optimization Jan Kiszka
2012-03-09 22:17 ` [PATCH] qemu-kvm: Eliminate _kvm_arch_init_vcpu Jan Kiszka
@ 2012-03-09 23:50 ` Marcelo Tosatti
1 sibling, 0 replies; 5+ messages in thread
From: Marcelo Tosatti @ 2012-03-09 23:50 UTC (permalink / raw)
To: Jan Kiszka; +Cc: Avi Kivity, kvm
On Fri, Mar 09, 2012 at 10:35:27PM +0100, Jan Kiszka wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
>
> The upstream version is feature-equivalent and covers more corner cases.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>
> As the upstream merge was not successful, this also unbreaks XP etc.
> over current qemu-kvm.
Applied, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] qemu-kvm: Eliminate _kvm_arch_init_vcpu
2012-03-09 22:17 ` [PATCH] qemu-kvm: Eliminate _kvm_arch_init_vcpu Jan Kiszka
@ 2012-04-23 8:42 ` Jan Kiszka
2012-04-27 15:00 ` Marcelo Tosatti
0 siblings, 1 reply; 5+ messages in thread
From: Jan Kiszka @ 2012-04-23 8:42 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: Avi Kivity, kvm
On 2012-03-09 23:17, Jan Kiszka wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
>
> There is no need for an explicit kvm_arch_reset_vcpu on arch cpu init
> anymore, kvm_init_vcpu does it already. Call the remaining
> kvm_update_ioport_access directly from kvm_arch_init_vcpu.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>
> This depends on the TPR switch-over patch.
>
> qemu-kvm-x86.c | 7 -------
> target-i386/kvm.c | 4 +---
> 2 files changed, 1 insertions(+), 10 deletions(-)
>
> diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
> index 159779c..7de51dc 100644
> --- a/qemu-kvm-x86.c
> +++ b/qemu-kvm-x86.c
> @@ -77,13 +77,6 @@ int kvm_set_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
> return kvm_vm_ioctl(s, KVM_SET_PIT2, ps2);
> }
>
> -static int _kvm_arch_init_vcpu(CPUState *env)
> -{
> - kvm_arch_reset_vcpu(env);
> -
> - return kvm_update_ioport_access(env);
> -}
> -
> #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
> int kvm_arch_set_ioport_access(unsigned long start, unsigned long size,
> bool enable)
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 461734d..91110c1 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -345,8 +345,6 @@ static void cpu_update_state(void *opaque, int running, RunState state)
> }
> }
>
> -static int _kvm_arch_init_vcpu(CPUState *env);
> -
> int kvm_arch_init_vcpu(CPUState *env)
> {
> struct {
> @@ -360,7 +358,7 @@ int kvm_arch_init_vcpu(CPUState *env)
> uint32_t signature[3];
> int r;
>
> - r = _kvm_arch_init_vcpu(env);
> + r = kvm_update_ioport_access(env);
> if (r < 0) {
> return r;
> }
Marcelo, what is the state of understanding why this change can cause
troubles in autotest? As I wrote offlist, I can neither reproduce nor
understand how it can cause any regression (I suspect it rather triggers
a so far hidden issue).
Jan
--
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] qemu-kvm: Eliminate _kvm_arch_init_vcpu
2012-04-23 8:42 ` Jan Kiszka
@ 2012-04-27 15:00 ` Marcelo Tosatti
0 siblings, 0 replies; 5+ messages in thread
From: Marcelo Tosatti @ 2012-04-27 15:00 UTC (permalink / raw)
To: Jan Kiszka; +Cc: Avi Kivity, kvm
On Mon, Apr 23, 2012 at 10:42:25AM +0200, Jan Kiszka wrote:
> On 2012-03-09 23:17, Jan Kiszka wrote:
> > From: Jan Kiszka <jan.kiszka@siemens.com>
> >
> > There is no need for an explicit kvm_arch_reset_vcpu on arch cpu init
> > anymore, kvm_init_vcpu does it already. Call the remaining
> > kvm_update_ioport_access directly from kvm_arch_init_vcpu.
> >
> > Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> > ---
> >
> > This depends on the TPR switch-over patch.
> >
> > qemu-kvm-x86.c | 7 -------
> > target-i386/kvm.c | 4 +---
> > 2 files changed, 1 insertions(+), 10 deletions(-)
> >
> > diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
> > index 159779c..7de51dc 100644
> > --- a/qemu-kvm-x86.c
> > +++ b/qemu-kvm-x86.c
> > @@ -77,13 +77,6 @@ int kvm_set_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
> > return kvm_vm_ioctl(s, KVM_SET_PIT2, ps2);
> > }
> >
> > -static int _kvm_arch_init_vcpu(CPUState *env)
> > -{
> > - kvm_arch_reset_vcpu(env);
> > -
> > - return kvm_update_ioport_access(env);
> > -}
> > -
> > #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
> > int kvm_arch_set_ioport_access(unsigned long start, unsigned long size,
> > bool enable)
> > diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> > index 461734d..91110c1 100644
> > --- a/target-i386/kvm.c
> > +++ b/target-i386/kvm.c
> > @@ -345,8 +345,6 @@ static void cpu_update_state(void *opaque, int running, RunState state)
> > }
> > }
> >
> > -static int _kvm_arch_init_vcpu(CPUState *env);
> > -
> > int kvm_arch_init_vcpu(CPUState *env)
> > {
> > struct {
> > @@ -360,7 +358,7 @@ int kvm_arch_init_vcpu(CPUState *env)
> > uint32_t signature[3];
> > int r;
> >
> > - r = _kvm_arch_init_vcpu(env);
> > + r = kvm_update_ioport_access(env);
> > if (r < 0) {
> > return r;
> > }
>
> Marcelo, what is the state of understanding why this change can cause
> troubles in autotest? As I wrote offlist, I can neither reproduce nor
> understand how it can cause any regression (I suspect it rather triggers
> a so far hidden issue).
>
> Jan
Still no understanding of previous failures, but results are
consistently OK now. Maybe the gods are happy with us now :)
Applied, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-04-27 15:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-09 21:35 [PATCH] qemu-kvm: Switch to upstream TPR optimization Jan Kiszka
2012-03-09 22:17 ` [PATCH] qemu-kvm: Eliminate _kvm_arch_init_vcpu Jan Kiszka
2012-04-23 8:42 ` Jan Kiszka
2012-04-27 15:00 ` Marcelo Tosatti
2012-03-09 23:50 ` [PATCH] qemu-kvm: Switch to upstream TPR optimization Marcelo Tosatti
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox