qemu gcc4 patch and disable not compiling targets

git-svn-id: https://svn.disconnected-by-peer.at/svn/linamh/trunk/linamh@713 6952d904-891a-0410-993b-d76249ca496b
This commit is contained in:
geos_one 2009-01-24 11:03:18 +00:00
parent 6c60228733
commit 9d45f1936c
34 changed files with 4483 additions and 0 deletions

217
app-emulation/kvm/ChangeLog Normal file
View File

@ -0,0 +1,217 @@
# ChangeLog for app-emulation/kvm
# Copyright 1999-2009 Gentoo Foundation; Distributed under the GPL v2
# $Header: /var/cvsroot/gentoo-x86/app-emulation/kvm/ChangeLog,v 1.25 2009/01/05 01:30:01 dang Exp $
*kvm-82 (05 Jan 2009)
05 Jan 2009; Daniel Gryniewicz <dang@gentoo.org> kvm-81.ebuild,
+kvm-82.ebuild:
Bump to 82
This release adds support for nested virtualization, a feature which
allows you to run kvm (and possibly other hypervisors) inside a guest.
This is an experimental feature and is only available on AMD hosts.
Also fixes bug #251903
*kvm-81 (16 Dec 2008)
16 Dec 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-79-r1.ebuild,
+kvm-81.ebuild:
Bump to kvm-81
- Fixed performance regression in qcow2 files
- Several display fixes
- Several virtio fixes/cleanups/speedups
- Clock fixes
*kvm-79-r1 (10 Dec 2008)
10 Dec 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-79-r1.ebuild:
Bump to kvm-79-r1
- Fix bug #250283: make kvm-ifup/kvm-ifdown not fail if there are
multiple bridges on the host
- Add patch from ubuntu to make non-alphabet keys work with evdev
25 Nov 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-79.ebuild:
New patch tarball: remove 06, update 02 (bug #248252)
*kvm-79 (19 Nov 2008)
19 Nov 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-79.ebuild:
Bump to kvm-79
This is the first release to fully support pci device assignment. You can
assign a pci device to qemu on the command line, or hot-plug it in via the
monitor. Note that at this time, Linux 2.6.28 is required on the host.
Note that, at this time, it requires VT-d hardware support from Intel.
11 Nov 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-78.ebuild:
Fix kernel build dir. bug #239189
*kvm-78 (06 Nov 2008)
06 Nov 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-74.ebuild,
kvm-77.ebuild, +kvm-78.ebuild:
Bump to kvm-78
21 Oct 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-77.ebuild:
Turn on modules by default; that's what most people want
*kvm-77 (21 Oct 2008)
21 Oct 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-73.ebuild,
+kvm-77.ebuild:
Bump kvm to 77
- 2 important changes from a user's point of view:
- The minimum version of the kernel for non-module installs is now
2.6.25.
- If you're building the modules, you need to have CONFIG_KVM enabled
in your kernel. This is because a type is not defined unless
CONFIG_KVM is set, and the compat code won't kick in unless you're
building completely outside the kernel tree (which we're not).
- Important upstream changes:
- Faster disk emulation
- Better handling of >4G of RAM
- Improved VNC
- Improved USB
- live migration fixes
- Speed improvements on 2.6.27+ hosts
15 Sep 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-71-r2.ebuild,
-kvm-72.ebuild, -kvm-72-r1.ebuild:
Nuke old versions
*kvm-75 (15 Sep 2008)
15 Sep 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-75.ebuild:
Bump to kvm-75
Ballooning is finally enabled in kvm-75. You will need a 2.6.27+ host for
ballooning to work properly.
*kvm-74 (09 Sep 2008)
09 Sep 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-73.ebuild,
+kvm-74.ebuild:
Bump to kvm-74
Changes from kvm-73:
- make real-mode startup state conform to spec
- fix scheduling error in experimental big real mode support
- fix reboot fault handler exception table entry (Eduardo Habkost)
- x86 emulator code cleanup (Roel Kluin)
- fix 'neg r/m' instruction emulation forced to byte size
- fix shadow ptes corruption on i386 hosts running smp guests
- fix kvmtrace ABI breakage (Adrian Bunk)
- enable virtio for ia64
- add generic shadow page table walker
- allocate internal guest memory as MAP_PRIVATE
- don't call get_user_pages(.force=1)
- paves the way for get_user_pages_fast()
- add mov r, imm instructions to the emulator (Mohammed Gamal)
- realmode emulator testsuite
- ia64 external module support (Xiantao Zhang)
- support tap IFF_VNET_HDR (Mark McLoughlin)
- merge qemu-svn
- improved usb support
- usb auto connect/disconnect
- protect against possible corruption during qemu fork() on older hosts
(Marcelo Tosatti)
09 Sep 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-70.ebuild,
-kvm-70-r1.ebuild:
Remove old versions referencing removed patches; bug #236890
23 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-73.ebuild:
Fix some whitespace
*kvm-73 (23 Aug 2008)
23 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml,
+kvm-73.ebuild:
Bump to kvm-73
- Add a "modules" USE flag to build the kvm kernel modules
*kvm-72-r1 (07 Aug 2008)
07 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml,
+kvm-72-r1.ebuild:
Add vde flag to expose new VDE support
04 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml,
+kvm-72.ebuild:
Bump to 72
*kvm-72 (04 Aug 2008)
04 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml,
+kvm-72.ebuild:
Bump to kvm-72
28 Jul 2008; Doug Goldstein <cardoe@gentoo.org> metadata.xml:
add GLEP 56 USE flag desc from use.local.desc
17 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
-files/kvm-45-qemu-configure.patch, -files/kvm-57-kernel-longmode.patch,
-files/kvm-57-qemu-kvm-cmdline.patch, -files/kvm-61-qemu-kvm.patch,
-files/kvm-68-libkvm-no-kernel.patch,
-files/kvm-69-qemu-ifup_ifdown.patch, -files/kvm-69-qemu-no-blobs.patch,
-files/kvm-70-block-rw-range-check.patch,
-files/kvm-70-qemu-kvm-doc.patch, -files/kvm-71-qemu-configure.patch,
-files/kvm-71-qemu-kvm-doc.patch, kvm-71-r2.ebuild:
Move patches into external tarball on mirrors. Git repo is hosted at
http://github.com/dang/kvm-patches/tree/master
*kvm-71-r2 (16 Jul 2008)
16 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
files/kvm-71-qemu-configure.patch, -kvm-71-r1.ebuild, +kvm-71-r2.ebuild:
Fix audio configuration again.
- Add OSS by default (bug #231926)
- make the sdl flag enable sdl audio (bug #231925)
- Make it possible to enable multiple outputs (kvm configure was broken
before)
*kvm-71-r1 (15 Jul 2008)
15 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
+files/kvm-71-qemu-configure.patch, -kvm-71.ebuild, +kvm-71-r1.ebuild:
Fix sound configuration broken in 71, and add pulseaudio
15 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> -files/kvm-48-kvm.patch,
+files/kvm-71-qemu-kvm-doc.patch, kvm-70.ebuild, kvm-70-r1.ebuild,
+kvm-71.ebuild:
Bump to 71
*kvm-71 (15 Jul 2008)
15 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-71.ebuild:
Bump to 71
*kvm-70-r1 (14 Jul 2008)
14 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
+files/kvm-70-block-rw-range-check.patch, +kvm-70-r1.ebuild:
Add block device bounds checking; bug #231753
10 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-70.ebuild:
Disable the bios flag for now, it doesn't build. Bug #231343
10 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml:
I guess virtualization isn't a herd yet
*kvm-70 (09 Jul 2008)
09 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
+files/kvm-45-qemu-configure.patch, +files/kvm-48-kvm.patch,
+files/kvm-57-kernel-longmode.patch, +files/kvm-57-qemu-kvm-cmdline.patch,
+files/kvm-61-qemu-kvm.patch, +files/kvm-68-libkvm-no-kernel.patch,
+files/kvm-69-qemu-ifup_ifdown.patch, +files/kvm-69-qemu-no-blobs.patch,
+files/kvm-70-qemu-kvm-doc.patch, +metadata.xml, +kvm-70.ebuild:
Add kvm to the tree

View File

@ -0,0 +1,32 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
DIST kvm-75.tar.gz 4108859 RMD160 e536cce39653111c1eb4d9eda8e908ae381362b8 SHA1 6b86df5554748998a31a1609cd8b4593af7cd3f0 SHA256 fff3add1e16b3ece8edfb29b10cbdcefed95d8a18ceac77b008a241a2427d0bf
DIST kvm-77.tar.gz 7320987 RMD160 3bb7cf48af0af2062769b95485c4a504a1274cd7 SHA1 bb3d0d09b369a4561e4cfe5de58bdf77b1d6a16e SHA256 9b6c1d61d27e5e67daea751b908927fc7290e0f15b3f4bbe391e154404d8abca
DIST kvm-78.tar.gz 4231476 RMD160 b4b06a717f6d9212feebd2b2744f3fc89a586a45 SHA1 18d0cb5958d9d3968710cd7a62349ae3d23ca830 SHA256 1ade8847ea3f72b662eedb01f7447325915ca243c3ea86b22ecbb5fafbed6217
DIST kvm-79.tar.gz 4263614 RMD160 006ed209cea5eb1936ce93fb773783b93cbd08fa SHA1 7e97f7f71b6891ecbe0daf3b0af30e124ecd1dd4 SHA256 8b3c43cf559308a30cef0152323c99d9398ab8ba1754a7b16cedb1601462383e
DIST kvm-81.tar.gz 4292487 RMD160 726abaf75da51d391c59e73669e9013035b178ce SHA1 3982fd20e3469d1279b5e70efcef9682758eb839 SHA256 19d71a028af2d019ed713a3a74d52a20ccbbe73ae6426ec256b7c71ddbecf9ad
DIST kvm-82.tar.gz 4301055 RMD160 c463160047f4de95b2d9ad45456a3166e754793e SHA1 9b4ea2c910683667d787ff623d001aa98d0d009e SHA256 fa9bc496db07d4eef738b0feaf3f72986a24b006f89be3b720ffecf4d14365ba
DIST kvm-patches-20080822.tar.gz 25178 RMD160 4640f1da457b3ab2da66f8ef6dc98f83464b741e SHA1 827f7a932968e4027902892191cf29cafc5f662a SHA256 811d8541f395c682d98384c7304486e0b47d8fcf6e3df2e02f5ccd7dee353dfb
DIST kvm-patches-20081020.tar.gz 21961 RMD160 8c51fa76fb0ec7b8bc4734c6b42e7dcd078bedcd SHA1 470678a4ffe7a25f2ab957ce5eaf5ab6fd730920 SHA256 424d13f264a65de2919bb37af3059391dcaf5fc82e304c6f4366f619c38cd478
DIST kvm-patches-20081106.tar.gz 21997 RMD160 f5585a2a3d8bb6e55827a85a689699e10c3338a6 SHA1 0b72d22b65bb01d3d1f4d190290bb0ee59a47f6b SHA256 3077741aff3aaf3b114fc9dd6bc15633ca043c6161ca58535bff0bd5bc21cc73
DIST kvm-patches-20081124.tar.gz 20255 RMD160 2af97b634060f5107b73534b7cc1d3de4f7e7b73 SHA1 93d64ba64c7cb0a5e1231b74514a809e4f2e8fd5 SHA256 67dbee0682df543e3cf9a67b8743b154af0e30fbb7caebdcbb7f329f6e870df1
DIST kvm-patches-20081210.tar.gz 22522 RMD160 4fe324a5913c1e951e4660cbcb0cd29102b923ba SHA1 803085a476d1228ace5a4ebe712b9f7a7a77281a SHA256 77f235dda72df526f824712e314d108777d8d6fd6f7bf7617662496feea786cd
DIST kvm-patches-20081216.tar.gz 23095 RMD160 f82d44f6eff2e49a59ff391e197f3b2fb8e951c6 SHA1 b49b82813162218ab8f08aa1905f63ee4f4d277b SHA256 e8197f8176756d9d8352f4d6eae7443b8977cefc92435c30538a7095d4704be8
DIST kvm-patches-20090104.tar.gz 23149 RMD160 1ce67d586a2a93cd7bf3e45161c24daeff9f1314 SHA1 b0013ddf9a2faeb35a519d263ffadaa795cff50d SHA256 384dfbf579aa3adef52e8050e29806cbf0bf6bc36c27dbd08f7584c5c8a2286f
EBUILD kvm-75.ebuild 6884 RMD160 aa189a1a1bd03e5088377742697a7ce8987de42c SHA1 e16a3d60e9e3be82e2d2c919eeb90c16e728d341 SHA256 f3561a33882a46235ea57a770a327449fd62dab95ddb38f4e892f28aac988ef6
EBUILD kvm-77.ebuild 6785 RMD160 4a95b99f9327c01d6b42ad2d97761208fd137e43 SHA1 a439d709ded61094c89a6a283a020c338da76436 SHA256 17f4905e61b79c41640ad411f96237ae20158af5331a6db0840e30075a6ceda1
EBUILD kvm-78.ebuild 6844 RMD160 de0d0f759f9d5d335bbdad908313099395bbb20b SHA1 858b87435a03f2940158b0ab6dae17dacb22d349 SHA256 e88f89f9b038d107a71d221f64047e3a41530421c2731ba5725a376df797bb4e
EBUILD kvm-79-r1.ebuild 6847 RMD160 6c956f6eee0253e0fb12b86235b7c87cdc1a582d SHA1 c19d6e9f23ca41aad34b6990ad5890d93eb10c12 SHA256 8aff31e884111e554303a4e8d9f1350da3ca33f7080e3aea1fd6d3fd1330af88
EBUILD kvm-79.ebuild 6844 RMD160 b81124ea07c87970460fc62168f7d6be46d50596 SHA1 4a2c098cdf52ddcbc720df5b3d18ccfedbd332c2 SHA256 4a9f9461f5acd8f53cd59b39a21420cde59a3f7257ae35d5e66c2f2d101c12eb
EBUILD kvm-81.ebuild 6994 RMD160 4ad0d79d6543c836f6d9c6b4f0d34daf400b1f1d SHA1 33d30a519f6ff405ea89351691b28a271adad931 SHA256 241a3422de81b30b083969c9ece3d34f55af89affeb4b3af3dd430ca04f999fd
EBUILD kvm-82.ebuild 6950 RMD160 f379ec52f9ca2957bef915c507195a2ce6fff45c SHA1 30c211ef5f192fbb0438d036d44a9fc28ceffcdf SHA256 02b34f93f24b5ce9245dce2e8ac8e77bb3b5b6af6f2c98cd80b5ac1a09dc59e3
MISC ChangeLog 7426 RMD160 bd16943d02c679d07ce1596c0e00f90ed0665d76 SHA1 a2fc49c842bb3c0626421d71629412a1a5df331a SHA256 9df749ff0a987b732270b97dda7cce6d37e6aaf1f537f4954cd4f5d1b168ed86
MISC metadata.xml 1282 RMD160 2c8cc65da23f96cfd73f757000192d4af7b29e9f SHA1 3b84cbafe2190715df0310fe8bde8dc6d483e6df SHA256 af8ea32fd7dedeb7401d4df31016c3e6a4a12d9720577bbb9673d4ae22b3dc54
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
iD8DBQFJYWKnomPajV0RnrERAt/OAJ993C6xXsdpu1bkH5GVZGq/YvdB/wCfU72R
WFs+nU4Ly9hPrO7q7uJ74Gc=
=r9qk
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,120 @@
# Send to upstream BOCHS
This ACPI BIOS patch provides:
- The PCI bus definition for PIC, HPET, RTC, SMC and OSYS and SMIF
- An PBLK which provides the size of the L2 and L3 caches
- If newer hardware like ICH6 IDE is found, init it
Signed-off-by: Alex Graf - http://alex.csgraf.de
Index: kvm-77/bios-mac/acpi-dsdt.dsl
===================================================================
--- kvm-77.orig/bios-mac/acpi-dsdt.dsl
+++ kvm-77/bios-mac/acpi-dsdt.dsl
@@ -78,6 +78,47 @@ DefinitionBlock (
/* PCI Bus definition */
Scope(\_SB) {
+ Device (HPET)
+ {
+ Name (_HID, EisaId ("PNP0103"))
+ Name (_CID, 0x010CD041)
+ Name (BUF0, ResourceTemplate ()
+ {
+ IRQNoFlags ()
+ {2}
+ IRQNoFlags ()
+ {8}
+ Memory32Fixed (ReadOnly,
+ 0xFED00000, // Address Base
+ 0x00000400, // Address Length
+ _Y16)
+ })
+ Method (_STA, 0, NotSerialized)
+ {
+ Return (0x0F)
+ }
+ Method (_CRS, 0, Serialized)
+ {
+ Return (BUF0)
+ }
+ }
+ Device (SMC)
+ {
+ Name (_HID, EisaId ("APP0001"))
+ Name (_CID, "smc-napa")
+ Name (_STA, 0x0B)
+ Name (_CRS, ResourceTemplate ()
+ {
+ IO (Decode16,
+ 0x0300, // Range Minimum
+ 0x0300, // Range Maximum
+ 0x01, // Alignment
+ 0x20, // Length
+ )
+ IRQNoFlags ()
+ {6}
+ })
+ }
Device(PCI0) {
Name (_HID, EisaId ("PNP0A03"))
Name (_ADR, 0x00)
Index: kvm-77/bios-mac/rombios32.c
===================================================================
--- kvm-77.orig/bios-mac/rombios32.c
+++ kvm-77/bios-mac/rombios32.c
@@ -628,6 +628,9 @@ void smp_probe(void)
#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
+#define PCI_DEVICE_ID_INTEL_874079 0x27a0 /* i945GM Express Chipset */
+#define PCI_DEVICE_ID_INTEL_945GL 0x27b9 /* ICH7 LPC */
+#define PCI_DEVICE_ID_INTEL_ICH6IDE 0x269e
#define PCI_VENDOR_ID_IBM 0x1014
#define PCI_VENDOR_ID_APPLE 0x106b
@@ -641,7 +644,9 @@ static uint32_t pci_bios_io_addr;
static uint32_t pci_bios_mem_addr;
static uint32_t pci_bios_bigmem_addr;
/* host irqs corresponding to PCI irqs A-D */
-static uint8_t pci_irqs[4] = { 10, 10, 11, 11 };
+static uint8_t pci_irqs[4] = { 11, 10, 11, 10 };
+//static uint8_t pci_irqs[4] = { 10, 10, 11, 11 };
+//static uint8_t pci_irqs[4] = { 0x10, 0x11, 0x12, 0x13 };
static PCIDevice i440_pcidev;
static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
@@ -772,7 +777,9 @@ static void pci_bios_init_bridges(PCIDev
if (vendor_id == PCI_VENDOR_ID_INTEL &&
(device_id == PCI_DEVICE_ID_INTEL_82371SB_0 ||
- device_id == PCI_DEVICE_ID_INTEL_82371AB_0)) {
+ device_id == PCI_DEVICE_ID_INTEL_82371AB_0 ||
+ device_id == PCI_DEVICE_ID_INTEL_874079 ||
+ device_id == PCI_DEVICE_ID_INTEL_945GL)) {
int i, irq;
uint8_t elcr[2];
@@ -854,8 +861,9 @@ static void pci_bios_init_device(PCIDevi
case 0x0101:
if (vendor_id == PCI_VENDOR_ID_INTEL &&
(device_id == PCI_DEVICE_ID_INTEL_82371SB_1 ||
- device_id == PCI_DEVICE_ID_INTEL_82371AB)) {
- /* PIIX3/PIIX4 IDE */
+ device_id == PCI_DEVICE_ID_INTEL_82371AB ||
+ device_id == PCI_DEVICE_ID_INTEL_ICH6IDE)) {
+ /* PIIX3/PIIX4/ICH6 IDE */
pci_config_writew(d, 0x40, 0x8000); // enable IDE0
pci_config_writew(d, 0x42, 0x8000); // enable IDE1
goto default_map;
@@ -1559,6 +1567,13 @@ void acpi_bios_init(void)
acpi_build_table_header((struct acpi_table_header *)madt,
"APIC", madt_size, 1);
}
+ /* PBLK (CPU information structure) */
+ {
+ uint32_t *pblk = (void*) (0x410);
+ *pblk = 0;
+ ((char*)pblk)[4] = 64; /* size of the Level 2 cache */
+ ((char*)pblk)[5] = 0; /* size of the Level 3 cache */
+ }
}
/* SMBIOS entry point -- must be written to a 16-bit aligned address

View File

@ -0,0 +1,13 @@
Index: kvm-77/kernel/x86/preempt.c
===================================================================
--- kvm-77.orig/kernel/x86/preempt.c
+++ kvm-77/kernel/x86/preempt.c
@@ -251,7 +251,7 @@ void preempt_notifier_sys_exit(void)
struct idt_desc idt_desc;
dprintk("\n");
- on_each_cpu(do_disable, NULL, 1, 1);
+ kvm_on_each_cpu(do_disable, NULL, 1);
asm ("sidt %0" : "=m"(idt_desc));
idt_desc.gates[1] = orig_int1_gate;
}

View File

@ -0,0 +1,8 @@
--- a/user/test/x86/vmexit.c
+++ b/user/test/x86/vmexit.c
@@ -1,4 +1,4 @@
-
+int printf(const char *,...);
#include "printf.h"
static inline unsigned long long rdtsc()

View File

@ -0,0 +1,130 @@
# Fixes boot with gfxboot of SUSE 10.0 till openSUSE 10.3 and other
# distributions which use this version of gfxboot.
# Has been discussed upstream, but upstream does not seem to care
# much and wants to go for full emulation of this, but it's a project
# for multible months to do that.
# Room for improvement: Should use an explicitly defined illegal
# instruction, not just one which happens to be illegal with current
# CPUs.
# Signed-off-by: Alex Graf - agraf@suse
===================================================================
Index: kernel/include/asm-x86/kvm_host.h
===================================================================
--- kernel/include/asm-x86/kvm_host.h.orig
+++ kernel/include/asm-x86/kvm_host.h
@@ -240,6 +240,7 @@ struct kvm_vcpu_arch {
u32 regs_avail;
u32 regs_dirty;
+ u16 backup_ss;
unsigned long cr0;
unsigned long cr2;
unsigned long cr3;
Index: kernel/x86/vmx.c
===================================================================
--- kernel/x86/vmx.c.orig
+++ kernel/x86/vmx.c
@@ -1301,8 +1301,10 @@ static void fix_pmode_dataseg(int seg, s
static void enter_pmode(struct kvm_vcpu *vcpu)
{
unsigned long flags;
+ unsigned long rip;
+ u8 opcodes[2];
struct vcpu_vmx *vmx = to_vmx(vcpu);
-
+
vmx->emulation_required = 1;
vcpu->arch.rmode.active = 0;
@@ -1328,12 +1330,39 @@ static void enter_pmode(struct kvm_vcpu
fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
fix_pmode_dataseg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
+ /* Save real mode SS */
+ vcpu->arch.backup_ss = vmcs_read16(GUEST_SS_SELECTOR);
+
vmcs_write16(GUEST_SS_SELECTOR, 0);
vmcs_write32(GUEST_SS_AR_BYTES, 0x93);
vmcs_write16(GUEST_CS_SELECTOR,
vmcs_read16(GUEST_CS_SELECTOR) & ~SELECTOR_RPL_MASK);
vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
+
+ /* VMX checks for SS.CPL = CS.CPL on VM entry, if we are in
+ * protected mode. This fails on the transistion from real mode
+ * to protected mode, as just after that, SS still contains the
+ * real mode segment, which does not know anything about CPLs.
+ *
+ * As far as I know only gfxboot exploits this feature, by using
+ * the old real mode SS value to find a new SS selector in protected
+ * mode. This happens using a mov %ss, %eax instruction, which we
+ * can patch to an invalid opcode and emulate later on, giving eax
+ * the real SS value, that existed before the protected mode
+ * switch. */
+ rip = kvm_rip_read(vcpu) + vmcs_readl(GUEST_CS_BASE) + 14;
+ emulator_read_std(rip, (void *)opcodes, 2, vcpu);
+
+ if ( opcodes[0] == 0x8c && opcodes[1] == 0xd0 ) {
+ vcpu_printf(vcpu, "%s: patching mov SS\n", __FUNCTION__);
+ opcodes[0] = 0x0f;
+ opcodes[1] = 0x0c;
+ if (emulator_write_emulated(rip, opcodes,
+ 2, vcpu) != X86EMUL_CONTINUE)
+ vcpu_printf(vcpu, "%s: unable to patch mov SS\n",
+ __FUNCTION__);
+ }
}
static gva_t rmode_tss_base(struct kvm *kvm)
Index: kernel/x86/x86.c
===================================================================
--- kernel/x86/x86.c.orig
+++ kernel/x86/x86.c
@@ -2444,13 +2444,14 @@ int emulate_instruction(struct kvm_vcpu
r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
- /* Reject the instructions other than VMCALL/VMMCALL when
+ /* Reject the instructions other than VMCALL/VMMCALL/HACKS when
* try to emulate invalid opcode */
c = &vcpu->arch.emulate_ctxt.decode;
if ((emulation_type & EMULTYPE_TRAP_UD) &&
- (!(c->twobyte && c->b == 0x01 &&
+ ((!(c->twobyte && c->b == 0x01 &&
(c->modrm_reg == 0 || c->modrm_reg == 3) &&
- c->modrm_mod == 3 && c->modrm_rm == 1)))
+ c->modrm_mod == 3 && c->modrm_rm == 1)) &&
+ c->b != 0x0c))
return EMULATE_FAIL;
++vcpu->stat.insn_emulation;
Index: kernel/x86/x86_emulate.c
===================================================================
--- kernel/x86/x86_emulate.c.orig
+++ kernel/x86/x86_emulate.c
@@ -196,7 +196,7 @@ static u16 opcode_table[256] = {
static u16 twobyte_table[256] = {
/* 0x00 - 0x0F */
0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0,
- ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
+ ImplicitOps, ImplicitOps, 0, 0, ImplicitOps, ImplicitOps | ModRM, 0, 0,
/* 0x10 - 0x1F */
0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
/* 0x20 - 0x2F */
@@ -1898,6 +1898,16 @@ twobyte_insn:
case 0x18: /* Grp16 (prefetch/nop) */
c->dst.type = OP_NONE;
break;
+ case 0x0c: /* Invalid (used to patch mov %ss, %eax) */
+ /* This opcode is declared invalid, according to the Intel
+ * specification. As it is only used on VMX, we do not have
+ * to take AMD instructions into account. For more
+ * information, why this is needed, please see
+ * vmx.c:enter_pmode.
+ */
+ c->dst.type = OP_NONE;
+ c->regs[VCPU_REGS_RAX] = ctxt->vcpu->arch.backup_ss;
+ break;
case 0x20: /* mov cr, reg */
if (c->modrm_mod != 3)
goto cannot_emulate;

View File

@ -0,0 +1,14 @@
Index: kvm-75/kernel/x86/ioapic.c
===================================================================
--- kvm-75.orig/kernel/x86/ioapic.c
+++ kvm-75/kernel/x86/ioapic.c
@@ -274,7 +274,8 @@ void kvm_ioapic_set_irq(struct kvm_ioapi
if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
entry = ioapic->redirtbl[irq];
- level ^= entry.fields.polarity;
+// polarity is always active high in qemu
+// level ^= entry.fields.polarity;
if (!level)
ioapic->irr &= ~mask;
else {

View File

@ -0,0 +1,35 @@
# Quick patch until proper version is upstream, but is safe.
# Signed-off-by: Alex Graf - agraf@suse
Index: kvm-75/kernel/x86/x86.c
===================================================================
--- kvm-75.orig/kernel/x86/x86.c
+++ kvm-75/kernel/x86/x86.c
@@ -1260,7 +1260,7 @@ static int kvm_vcpu_ioctl_set_cpuid(stru
struct kvm_cpuid *cpuid,
struct kvm_cpuid_entry *entries)
{
- int r, i;
+ int r, i, n = 0;
struct kvm_cpuid_entry *cpuid_entries;
r = -E2BIG;
@@ -1280,8 +1280,17 @@ static int kvm_vcpu_ioctl_set_cpuid(stru
vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
- vcpu->arch.cpuid_entries[i].index = 0;
- vcpu->arch.cpuid_entries[i].flags = 0;
+ switch(vcpu->arch.cpuid_entries[i].function) {
+ case 4:
+ vcpu->arch.cpuid_entries[i].index = n;
+ vcpu->arch.cpuid_entries[i].flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+ n++;
+ break;
+ default:
+ vcpu->arch.cpuid_entries[i].index = 0;
+ vcpu->arch.cpuid_entries[i].flags = 0;
+ break;
+ }
vcpu->arch.cpuid_entries[i].padding[0] = 0;
vcpu->arch.cpuid_entries[i].padding[1] = 0;
vcpu->arch.cpuid_entries[i].padding[2] = 0;

View File

@ -0,0 +1,27 @@
Index: kvm-75/kernel/x86/x86.c
===================================================================
--- kvm-75.orig/kernel/x86/x86.c
+++ kvm-75/kernel/x86/x86.c
@@ -874,7 +874,11 @@ static int set_msr_mtrr(struct kvm_vcpu
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
+printk(KERN_INFO "MSR write: 0x%lx = 0x%llx\n", msr, data);
switch (msr) {
+ case 0xe2:
+ printk(KERN_INFO "CState MSR write: 0x%llx\n", data);
+ break;
case MSR_EFER:
set_efer(vcpu, data);
break;
@@ -1025,6 +1029,10 @@ int kvm_get_msr_common(struct kvm_vcpu *
case MSR_EFER:
data = vcpu->arch.shadow_efer;
break;
+ case 0xe2:
+ printk(KERN_INFO "CState MSR read: 0x0\n");
+ data = 0;
+ break;
case MSR_KVM_WALL_CLOCK:
data = vcpu->kvm->arch.wall_clock;
break;

View File

@ -0,0 +1,21 @@
Index: kvm-75/qemu/qemu-kvm-x86.c
===================================================================
--- kvm-75.orig/qemu/qemu-kvm-x86.c
+++ kvm-75/qemu/qemu-kvm-x86.c
@@ -11,6 +11,7 @@
#include <string.h>
#include "hw/hw.h"
+#include "hw/boards.h"
#include "qemu-kvm.h"
#include <libkvm.h>
@@ -498,7 +499,7 @@ static void do_cpuid_ent(struct kvm_cpui
// isn't supported in compatibility mode on Intel. so advertise the
// actuall cpu, and say goodbye to migration between different vendors
// is you use compatibility mode.
- if (function == 0) {
+ if (function == 0 && current_machine != &mac_machine) {
uint32_t bcd[3];
host_cpuid(0, NULL, &bcd[0], &bcd[1], &bcd[2]);

View File

@ -0,0 +1,44 @@
Index: kvm-75/kernel/x86/svm.c
===================================================================
--- kvm-75.orig/kernel/x86/svm.c
+++ kvm-75/kernel/x86/svm.c
@@ -50,12 +50,8 @@ MODULE_LICENSE("GPL");
#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
/* enable NPT for AMD64 and X86 with PAE */
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
-static bool npt_enabled = true;
-#else
static bool npt_enabled = false;
-#endif
-static int npt = 1;
+static int npt = 0;
module_param(npt, int, S_IRUGO);
@@ -439,19 +435,19 @@ static __init int svm_hardware_setup(voi
svm_features = cpuid_edx(SVM_CPUID_FUNC);
- if (!svm_has(SVM_FEATURE_NPT))
- npt_enabled = false;
+ if (npt)
+ npt_enabled = true;
- if (npt_enabled && !npt) {
- printk(KERN_INFO "kvm: Nested Paging disabled\n");
+ if (!svm_has(SVM_FEATURE_NPT))
npt_enabled = false;
- }
if (npt_enabled) {
printk(KERN_INFO "kvm: Nested Paging enabled\n");
kvm_enable_tdp();
- } else
+ } else {
+ printk(KERN_INFO "kvm: Nested Paging disabled\n");
kvm_disable_tdp();
+ }
return 0;

View File

@ -0,0 +1,62 @@
From: "Marcel Zumstein" <marcel.zumstein@oxinia.ch>
Subject: [Qemu-devel] AltGr and dead keys with VNC
In VNC mode, my AltGr key (mapped to ISO_Level3_Shift) and the dead keys
aren't supported. This patch adds XK_ISO_Level3_Shift (keysym 0xfe03) to
the keymap. Furthermore, it adds support for the dead keys, which were
for some reason present in the keymaps, but not in vnc_keysym.h. This is
relevant for VNC viewers that pass dead keys on to the guest system
(e.g. tightvnc does) and don't compose the accented letters themselves.
Index: qemu/keymaps/modifiers
===================================================================
--- qemu/keymaps/modifiers.orig
+++ qemu/keymaps/modifiers
@@ -3,6 +3,7 @@ Shift_L 0x2a
Alt_R 0xb8
Mode_switch 0xb8
+ISO_Level3_Shift 0xb8
Alt_L 0x38
Control_R 0x9d
Index: qemu/vnc_keysym.h
===================================================================
--- qemu/vnc_keysym.h.orig
+++ qemu/vnc_keysym.h
@@ -204,6 +204,7 @@ static const name2keysym_t name2keysym[]
{"EuroSign", 0x20ac}, /* XK_EuroSign */
/* modifiers */
+{"ISO_Level3_Shift", 0xfe03}, /* XK_ISO_Level3_Shift */
{"Control_L", 0xffe3}, /* XK_Control_L */
{"Control_R", 0xffe4}, /* XK_Control_R */
{"Alt_L", 0xffe9}, /* XK_Alt_L */
@@ -286,6 +287,27 @@ static const name2keysym_t name2keysym[]
{"Pause", 0xff13}, /* XK_Pause */
{"Escape", 0xff1b}, /* XK_Escape */
+/* dead keys */
+{"dead_grave", 0xfe50}, /* XK_dead_grave */
+{"dead_acute", 0xfe51}, /* XK_dead_acute */
+{"dead_circumflex", 0xfe52}, /* XK_dead_circumflex */
+{"dead_tilde", 0xfe53}, /* XK_dead_tilde */
+{"dead_macron", 0xfe54}, /* XK_dead_macron */
+{"dead_breve", 0xfe55}, /* XK_dead_breve */
+{"dead_abovedot", 0xfe56}, /* XK_dead_abovedot */
+{"dead_diaeresis", 0xfe57}, /* XK_dead_diaeresis */
+{"dead_abovering", 0xfe58}, /* XK_dead_abovering */
+{"dead_doubleacute", 0xfe59}, /* XK_dead_doubleacute */
+{"dead_caron", 0xfe5a}, /* XK_dead_caron */
+{"dead_cedilla", 0xfe5b}, /* XK_dead_cedilla */
+{"dead_ogonek", 0xfe5c}, /* XK_dead_ogonek */
+{"dead_iota", 0xfe5d}, /* XK_dead_iota */
+{"dead_voiced_sound", 0xfe5e}, /* XK_dead_voiced_sound */
+{"dead_semivoiced_sound", 0xfe5f}, /* XK_dead_semivoiced_sound */
+{"dead_belowdot", 0xfe60}, /* XK_dead_belowdot */
+{"dead_hook", 0xfe61}, /* XK_dead_hook */
+{"dead_horn", 0xfe62}, /* XK_dead_horn */
+
/* localized keys */
{"BackApostrophe", 0xff21},
{"Muhenkan", 0xff22},

View File

@ -0,0 +1,545 @@
From 3be490091c2503d8b50f4a0ce1efe68004f65d3e Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 4 Nov 2008 18:48:21 +0100
Subject: [PATCH] Activate Virtualization On Demand v3
X86 CPUs need to have some magic happening to enable the virtualization
extensions on them. This magic can result in unpleasant results for
users, like blocking other VMMs from working (vmx) or using invalid TLB
entries (svm).
Currently KVM activates virtualization when the respective kernel module
is loaded. This blocks us from autoloading KVM modules without breaking
other VMMs.
To circumvent this problem at least a bit, this patch introduces on
demand activation of virtualization. This means, that instead
virtualization is enabled on creation of the first virtual machine
and disabled on removal of the last one.
So using this, KVM can be easily autoloaded, while keeping other
hypervisors usable.
v2 adds returns to non-x86 hardware_enables and adds IA64 change
v3 changes:
- use spin_lock instead of atomics
- put locking to new functions hardware_{en,dis}able_all that get called
on VM creation/destruction
- remove usage counter checks where not necessary
- return -EINVAL for IA64 slot < 0 case
Signed-off-by: Alexander Graf <agraf@suse.de>
---
arch/ia64/kvm/kvm-ia64.c | 8 +++--
arch/powerpc/kvm/powerpc.c | 3 +-
arch/s390/kvm/kvm-s390.c | 3 +-
kernel/x86/svm.c | 13 +++++--
kernel/x86/vmx.c | 7 +++-
kernel/x86/x86.c | 4 +-
kernel/include/asm-x86/kvm_host.h | 2 +-
kernel/include/linux/kvm_host.h | 2 +-
virt/kvm/kvm_main.c | 75 ++++++++++++++++++++++++++++++++++++-------
9 files changed, 90 insertions(+), 27 deletions(-)
Index: kvm-78/kernel/ia64/kvm-ia64.c
===================================================================
--- kvm-78.orig/kernel/ia64/kvm-ia64.c
+++ kvm-78/kernel/ia64/kvm-ia64.c
@@ -138,7 +138,7 @@ long ia64_pal_vp_create(u64 *vpd, u64 *h
static DEFINE_SPINLOCK(vp_lock);
-void kvm_arch_hardware_enable(void *garbage)
+int kvm_arch_hardware_enable(void *garbage)
{
long status;
long tmp_base;
@@ -152,7 +152,7 @@ void kvm_arch_hardware_enable(void *garb
slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
local_irq_restore(saved_psr);
if (slot < 0)
- return;
+ return -EINVAL;
spin_lock(&vp_lock);
status = ia64_pal_vp_init_env(kvm_vsa_base ?
@@ -160,7 +160,7 @@ void kvm_arch_hardware_enable(void *garb
__pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base);
if (status != 0) {
printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n");
- return ;
+ return -EINVAL;
}
if (!kvm_vsa_base) {
@@ -169,6 +169,8 @@ void kvm_arch_hardware_enable(void *garb
}
spin_unlock(&vp_lock);
ia64_ptr_entry(0x3, slot);
+
+ return 0;
}
void kvm_arch_hardware_disable(void *garbage)
Index: kvm-78/kernel/x86/svm.c
===================================================================
--- kvm-78.orig/kernel/x86/svm.c
+++ kvm-78/kernel/x86/svm.c
@@ -300,7 +300,7 @@ static void svm_hardware_disable(void *g
wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK);
}
-static void svm_hardware_enable(void *garbage)
+static int svm_hardware_enable(void *garbage)
{
struct svm_cpu_data *svm_data;
@@ -309,16 +309,20 @@ static void svm_hardware_enable(void *ga
struct kvm_desc_struct *gdt;
int me = raw_smp_processor_id();
+ rdmsrl(MSR_EFER, efer);
+ if (efer & MSR_EFER_SVME_MASK)
+ return -EBUSY;
+
if (!has_svm()) {
printk(KERN_ERR "svm_cpu_init: err EOPNOTSUPP on %d\n", me);
- return;
+ return -EINVAL;
}
svm_data = per_cpu(svm_data, me);
if (!svm_data) {
printk(KERN_ERR "svm_cpu_init: svm_data is NULL on %d\n",
me);
- return;
+ return -EINVAL;
}
svm_data->asid_generation = 1;
@@ -329,11 +333,12 @@ static void svm_hardware_enable(void *ga
gdt = (struct kvm_desc_struct *)gdt_descr.address;
svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
- rdmsrl(MSR_EFER, efer);
wrmsrl(MSR_EFER, efer | MSR_EFER_SVME_MASK);
wrmsrl(MSR_VM_HSAVE_PA,
page_to_pfn(svm_data->save_area) << PAGE_SHIFT);
+
+ return 0;
}
static void svm_cpu_uninit(int cpu)
Index: kvm-78/kernel/x86/vmx.c
===================================================================
--- kvm-78.orig/kernel/x86/vmx.c
+++ kvm-78/kernel/x86/vmx.c
@@ -1090,12 +1090,15 @@ static __init int vmx_disabled_by_bios(v
/* locked but not enabled */
}
-static void hardware_enable(void *garbage)
+static int hardware_enable(void *garbage)
{
int cpu = raw_smp_processor_id();
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
u64 old;
+ if (read_cr4() & X86_CR4_VMXE)
+ return -EBUSY;
+
INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu));
rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
if ((old & (FEATURE_CONTROL_LOCKED |
@@ -1110,6 +1113,8 @@ static void hardware_enable(void *garbag
asm volatile (ASM_VMX_VMXON_RAX
: : "a"(&phys_addr), "m"(phys_addr)
: "memory", "cc");
+
+ return 0;
}
static void vmclear_local_vcpus(void)
Index: kvm-78/kernel/x86/x86.c
===================================================================
--- kvm-78.orig/kernel/x86/x86.c
+++ kvm-78/kernel/x86/x86.c
@@ -4077,9 +4077,9 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu
return kvm_x86_ops->vcpu_reset(vcpu);
}
-void kvm_arch_hardware_enable(void *garbage)
+int kvm_arch_hardware_enable(void *garbage)
{
- kvm_x86_ops->hardware_enable(garbage);
+ return kvm_x86_ops->hardware_enable(garbage);
}
void kvm_arch_hardware_disable(void *garbage)
Index: kvm-78/kernel/include/asm-x86/kvm_host.h
===================================================================
--- kvm-78.orig/kernel/include/asm-x86/kvm_host.h
+++ kvm-78/kernel/include/asm-x86/kvm_host.h
@@ -453,7 +453,7 @@ struct descriptor_table {
struct kvm_x86_ops {
int (*cpu_has_kvm_support)(void); /* __init */
int (*disabled_by_bios)(void); /* __init */
- void (*hardware_enable)(void *dummy); /* __init */
+ int (*hardware_enable)(void *dummy); /* __init */
void (*hardware_disable)(void *dummy);
void (*check_processor_compatibility)(void *rtn);
int (*hardware_setup)(void); /* __init */
Index: kvm-78/kernel/include/linux/kvm_host.h
===================================================================
--- kvm-78.orig/kernel/include/linux/kvm_host.h
+++ kvm-78/kernel/include/linux/kvm_host.h
@@ -300,7 +300,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu);
int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu);
-void kvm_arch_hardware_enable(void *garbage);
+int kvm_arch_hardware_enable(void *garbage);
void kvm_arch_hardware_disable(void *garbage);
int kvm_arch_hardware_setup(void);
void kvm_arch_hardware_unsetup(void);
Index: kvm-78/kernel/x86/kvm_main.c
===================================================================
--- kvm-78.orig/kernel/x86/kvm_main.c
+++ kvm-78/kernel/x86/kvm_main.c
@@ -93,6 +93,8 @@ DEFINE_SPINLOCK(kvm_lock);
LIST_HEAD(vm_list);
static cpumask_t cpus_hardware_enabled;
+static int kvm_usage_count = 0;
+static DEFINE_SPINLOCK(kvm_usage_lock);
struct kmem_cache *kvm_vcpu_cache;
EXPORT_SYMBOL_GPL(kvm_vcpu_cache);
@@ -103,6 +105,8 @@ struct dentry *kvm_debugfs_dir;
static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
unsigned long arg);
+static int hardware_enable_all(void);
+static void hardware_disable_all(void);
bool kvm_rebooting;
@@ -592,19 +596,25 @@ static const struct mmu_notifier_ops kvm
static struct kvm *kvm_create_vm(void)
{
+ int r = 0;
struct kvm *kvm = kvm_arch_create_vm();
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
struct page *page;
#endif
if (IS_ERR(kvm))
- goto out;
+ return kvm;
+
+ r = hardware_enable_all();
+ if (r) {
+ goto out_err;
+ }
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!page) {
- kfree(kvm);
- return ERR_PTR(-ENOMEM);
+ r = -ENOMEM;
+ goto out_err;
}
kvm->coalesced_mmio_ring =
(struct kvm_coalesced_mmio_ring *)page_address(page);
@@ -612,15 +622,13 @@ static struct kvm *kvm_create_vm(void)
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
{
- int err;
kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops;
- err = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
- if (err) {
+ r = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
+ if (r) {
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
put_page(page);
#endif
- kfree(kvm);
- return ERR_PTR(err);
+ goto out_err;
}
}
#endif
@@ -639,8 +647,12 @@ mmget(&kvm->mm->mm_count);
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
kvm_coalesced_mmio_init(kvm);
#endif
-out:
return kvm;
+
+out_err:
+ hardware_disable_all();
+ kfree(kvm);
+ return ERR_PTR(r);
}
/*
@@ -689,6 +701,7 @@ static void kvm_destroy_vm(struct kvm *k
mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
#endif
kvm_arch_destroy_vm(kvm);
+ hardware_disable_all();
mmdrop(mm);
}
@@ -1796,14 +1809,40 @@ static struct miscdevice kvm_dev = {
&kvm_chardev_ops,
};
-static void hardware_enable(void *junk)
+static void hardware_enable(void *_r)
{
int cpu = raw_smp_processor_id();
+ int r;
+
+ /* If enabling a previous CPU failed already, let's not continue */
+ if (_r && *((int*)_r))
+ return;
if (cpu_isset(cpu, cpus_hardware_enabled))
return;
+ r = kvm_arch_hardware_enable(NULL);
+ if (_r)
+ *((int*)_r) = r;
+ if (r) {
+ printk(KERN_INFO "kvm: enabling virtualization on "
+ "CPU%d failed\n", cpu);
+ return;
+ }
+
cpu_set(cpu, cpus_hardware_enabled);
- kvm_arch_hardware_enable(NULL);
+}
+
+static int hardware_enable_all(void)
+{
+ int r = 0;
+
+ spin_lock(&kvm_usage_lock);
+ kvm_usage_count++;
+ if (kvm_usage_count == 1)
+ kvm_on_each_cpu(hardware_enable, &r, 1);
+ spin_unlock(&kvm_usage_lock);
+
+ return r;
}
static void hardware_disable(void *junk)
@@ -1816,6 +1855,18 @@ static void hardware_disable(void *junk)
kvm_arch_hardware_disable(NULL);
}
+static void hardware_disable_all(void)
+{
+ if (!kvm_usage_count)
+ return;
+
+ spin_lock(&kvm_usage_lock);
+ kvm_usage_count--;
+ if (!kvm_usage_count)
+ kvm_on_each_cpu(hardware_disable, NULL, 1);
+ spin_unlock(&kvm_usage_lock);
+}
+
static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
void *v)
{
@@ -2061,7 +2112,6 @@ int kvm_init(void *opaque, unsigned int
goto out_free_1;
}
- kvm_on_each_cpu(hardware_enable, NULL, 1);
r = register_cpu_notifier(&kvm_cpu_notifier);
if (r)
goto out_free_2;
@@ -2114,7 +2164,6 @@ out_free_3:
unregister_reboot_notifier(&kvm_reboot_notifier);
unregister_cpu_notifier(&kvm_cpu_notifier);
out_free_2:
- kvm_on_each_cpu(hardware_disable, NULL, 1);
out_free_1:
kvm_arch_hardware_unsetup();
out_free_0:
Index: kvm-78/kernel/ia64/kvm_main.c
===================================================================
--- kvm-78.orig/kernel/ia64/kvm_main.c
+++ kvm-78/kernel/ia64/kvm_main.c
@@ -93,6 +93,8 @@ DEFINE_SPINLOCK(kvm_lock);
LIST_HEAD(vm_list);
static cpumask_t cpus_hardware_enabled;
+static int kvm_usage_count = 0;
+static DEFINE_SPINLOCK(kvm_usage_lock);
struct kmem_cache *kvm_vcpu_cache;
EXPORT_SYMBOL_GPL(kvm_vcpu_cache);
@@ -103,6 +105,8 @@ struct dentry *kvm_debugfs_dir;
static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
unsigned long arg);
+static int hardware_enable_all(void);
+static void hardware_disable_all(void);
bool kvm_rebooting;
@@ -592,19 +596,25 @@ static const struct mmu_notifier_ops kvm
static struct kvm *kvm_create_vm(void)
{
+ int r = 0;
struct kvm *kvm = kvm_arch_create_vm();
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
struct page *page;
#endif
if (IS_ERR(kvm))
- goto out;
+ return kvm;
+
+ r = hardware_enable_all();
+ if (r) {
+ goto out_err;
+ }
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!page) {
- kfree(kvm);
- return ERR_PTR(-ENOMEM);
+ r = -ENOMEM;
+ goto out_err;
}
kvm->coalesced_mmio_ring =
(struct kvm_coalesced_mmio_ring *)page_address(page);
@@ -612,15 +622,13 @@ static struct kvm *kvm_create_vm(void)
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
{
- int err;
kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops;
- err = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
- if (err) {
+ r = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
+ if (r) {
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
put_page(page);
#endif
- kfree(kvm);
- return ERR_PTR(err);
+ goto out_err;
}
}
#endif
@@ -639,8 +647,12 @@ static struct kvm *kvm_create_vm(void)
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
kvm_coalesced_mmio_init(kvm);
#endif
-out:
return kvm;
+
+out_err:
+ hardware_disable_all();
+ kfree(kvm);
+ return ERR_PTR(r);
}
/*
@@ -689,6 +701,7 @@ static void kvm_destroy_vm(struct kvm *k
mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
#endif
kvm_arch_destroy_vm(kvm);
+ hardware_disable_all();
mmdrop(mm);
}
@@ -1796,14 +1809,40 @@ static struct miscdevice kvm_dev = {
&kvm_chardev_ops,
};
-static void hardware_enable(void *junk)
+static void hardware_enable(void *_r)
{
int cpu = raw_smp_processor_id();
+ int r;
+
+ /* If enabling a previous CPU failed already, let's not continue */
+ if (_r && *((int*)_r))
+ return;
if (cpu_isset(cpu, cpus_hardware_enabled))
return;
+ r = kvm_arch_hardware_enable(NULL);
+ if (_r)
+ *((int*)_r) = r;
+ if (r) {
+ printk(KERN_INFO "kvm: enabling virtualization on "
+ "CPU%d failed\n", cpu);
+ return;
+ }
+
cpu_set(cpu, cpus_hardware_enabled);
- kvm_arch_hardware_enable(NULL);
+}
+
+static int hardware_enable_all(void)
+{
+ int r = 0;
+
+ spin_lock(&kvm_usage_lock);
+ kvm_usage_count++;
+ if (kvm_usage_count == 1)
+ on_each_cpu(hardware_enable, &r, 1);
+ spin_unlock(&kvm_usage_lock);
+
+ return r;
}
static void hardware_disable(void *junk)
@@ -1816,6 +1855,18 @@ static void hardware_disable(void *junk)
kvm_arch_hardware_disable(NULL);
}
+static void hardware_disable_all(void)
+{
+ if (!kvm_usage_count)
+ return;
+
+ spin_lock(&kvm_usage_lock);
+ kvm_usage_count--;
+ if (!kvm_usage_count)
+ on_each_cpu(hardware_disable, NULL, 1);
+ spin_unlock(&kvm_usage_lock);
+}
+
static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
void *v)
{
@@ -2058,7 +2109,6 @@ int kvm_init(void *opaque, unsigned int
goto out_free_1;
}
- kvm_on_each_cpu(hardware_enable, NULL, 1);
r = register_cpu_notifier(&kvm_cpu_notifier);
if (r)
goto out_free_2;
@@ -2104,7 +2154,6 @@ out_free_3:
unregister_reboot_notifier(&kvm_reboot_notifier);
unregister_cpu_notifier(&kvm_cpu_notifier);
out_free_2:
- kvm_on_each_cpu(hardware_disable, NULL, 1);
out_free_1:
kvm_arch_hardware_unsetup();
out_free_0:

View File

@ -0,0 +1,243 @@
#qemu-only -> submit upstream qemu
Index: kvm-75/qemu/Makefile.target
===================================================================
--- kvm-75.orig/qemu/Makefile.target
+++ kvm-75/qemu/Makefile.target
@@ -610,7 +610,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o lpc.o
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o lpc.o applesmc.o
ifeq ($(USE_KVM_PIT), 1)
OBJS+= i8254-kvm.o
endif
Index: kvm-75/qemu/hw/applesmc.c
===================================================================
--- /dev/null
+++ kvm-75/qemu/hw/applesmc.c
@@ -0,0 +1,171 @@
+/*
+ * Apple SMC controller
+ *
+ * Copyright (c) 2007 Alexander Graf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * *****************************************************************
+ *
+ * In all Intel-based Apple hardware there is an SMC chip to control the
+ * backlight, fans and several other generic device parameters. It also
+ * contains the magic keys used to dongle Mac OS X to the device.
+ *
+ * This driver was mostly created by looking at the Linux AppleSMC driver
+ * implementation and does not support IRQ.
+ *
+ */
+
+#include "hw.h"
+#include "pci.h"
+#include "console.h"
+#include "qemu-timer.h"
+
+/* data port used by Apple SMC */
+#define APPLESMC_DATA_PORT 0x300
+/* command/status port used by Apple SMC */
+#define APPLESMC_CMD_PORT 0x304
+#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
+#define APPLESMC_MAX_DATA_LENGTH 32
+
+#define APPLESMC_READ_CMD 0x10
+#define APPLESMC_WRITE_CMD 0x11
+#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
+#define APPLESMC_GET_KEY_TYPE_CMD 0x13
+
+static char osk[64] = "This is a dummy key. Enter the real key using the -osk parameter";
+
+struct AppleSMCData {
+ uint8_t len;
+ char *key;
+ char *data;
+};
+
+static struct AppleSMCData data[] = {
+ { .key = "REV ", .len=6, .data="\0x01\0x13\0x0f\0x00\0x00\0x03" },
+ { .key = "OSK0", .len=32, .data=osk },
+ { .key = "OSK1", .len=32, .data=osk+32 },
+ { .key = "NATJ", .len=1, .data="\0" },
+ { .key = "MSSP", .len=1, .data="\0" },
+ { .key = "MSSD", .len=1, .data="\0x3" },
+ { .len=0 }
+};
+
+struct AppleSMCStatus {
+ uint8_t cmd;
+ uint8_t status;
+ uint8_t key[4];
+ uint8_t read_pos;
+ uint8_t data_len;
+ uint8_t data_pos;
+ uint8_t data[255];
+ uint8_t charactic[4];
+};
+
+static void applesmc_io_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+ struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque;
+ printf("APPLESMC: CMD Write B: %#x = %#x\n", addr, val);
+ switch(val) {
+ case APPLESMC_READ_CMD:
+ s->status = 0x0c;
+ break;
+ }
+ s->cmd = val;
+ s->read_pos = 0;
+ s->data_pos = 0;
+}
+
+static void applesmc_fill_data(struct AppleSMCStatus *s)
+{
+ struct AppleSMCData *d;
+ for(d=data; d->len; d++) {
+ uint32_t key_data = *((uint32_t*)d->key);
+ uint32_t key_current = *((uint32_t*)s->key);
+ if(key_data == key_current) {
+ printf("APPLESMC: Key matched (%s Len=%d Data=%s)\n", d->key, d->len, d->data);
+ memcpy(s->data, d->data, d->len);
+ return;
+ }
+ }
+}
+
+static void applesmc_io_data_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+ struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque;
+ printf("APPLESMC: DATA Write B: %#x = %#x\n", addr, val);
+ switch(s->cmd) {
+ case APPLESMC_READ_CMD:
+ if(s->read_pos < 4) {
+ s->key[s->read_pos] = val;
+ s->status = 0x04;
+ } else if(s->read_pos == 4) {
+ s->data_len = val;
+ s->status = 0x05;
+ s->data_pos = 0;
+ printf("APPLESMC: Key = %c%c%c%c Len = %d\n", s->key[0], s->key[1], s->key[2], s->key[3], val);
+ applesmc_fill_data(s);
+ }
+ s->read_pos++;
+ break;
+ }
+}
+
+static uint32_t applesmc_io_data_readb(void *opaque, uint32_t addr1)
+{
+ struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque;
+ uint8_t retval = 0;
+ switch(s->cmd) {
+ case APPLESMC_READ_CMD:
+ if(s->data_pos < s->data_len) {
+ retval = s->data[s->data_pos];
+ printf("APPLESMC: READ_DATA[%d] = %#hhx\n", s->data_pos, retval);
+ s->data_pos++;
+ if(s->data_pos == s->data_len) {
+ s->status = 0x00;
+ printf("APPLESMC: EOF\n");
+ } else
+ s->status = 0x05;
+ }
+ }
+ printf("APPLESMC: DATA Read b: %#x = %#x\n", addr1, retval);
+ return retval;
+}
+
+static uint32_t applesmc_io_cmd_readb(void *opaque, uint32_t addr1)
+{
+ printf("APPLESMC: CMD Read B: %#x\n", addr1);
+ return ((struct AppleSMCStatus*)opaque)->status;
+}
+
+void applesmc_setkey(char *key) {
+ if(strlen(key) == 64) {
+ memcpy(osk, key, 64);
+ }
+}
+
+void applesmc_init() {
+ struct ApleSMCStatus *s;
+ s = qemu_mallocz(sizeof(struct AppleSMCStatus));
+
+ if(osk[0] == 'T') {
+ printf("WARNING: Using AppleSMC with invalid key\n");
+ }
+ register_ioport_read(APPLESMC_DATA_PORT, 4, 1, applesmc_io_data_readb, s);
+ register_ioport_read(APPLESMC_CMD_PORT, 4, 1, applesmc_io_cmd_readb, s);
+ register_ioport_write(APPLESMC_DATA_PORT, 4, 1, applesmc_io_data_writeb, s);
+ register_ioport_write(APPLESMC_CMD_PORT, 4, 1, applesmc_io_cmd_writeb, s);
+}
+
Index: kvm-75/qemu/hw/pc.h
===================================================================
--- kvm-75.orig/qemu/hw/pc.h
+++ kvm-75/qemu/hw/pc.h
@@ -150,6 +150,10 @@ void pci_piix4_ide_init(PCIBus *bus, Blo
void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd);
+/* applesmc.c */
+void applesmc_init(void);
+void applesmc_setkey(char *key);
+
/* lpc.c */
void lpc_init(PCIBus *bus, int devfn, qemu_irq *pic);
Index: kvm-75/qemu/vl.c
===================================================================
--- kvm-75.orig/qemu/vl.c
+++ kvm-75/qemu/vl.c
@@ -8381,6 +8381,7 @@ static void help(int exitcode)
#endif
#ifdef TARGET_I386
"-no-fd-bootchk disable boot signature checking for floppy disks\n"
+ "-osk key set AppleSMC key\n"
#endif
"-m megs set virtual RAM size to megs MB [default=%d]\n"
"-smp n set the number of CPUs to 'n' [default=1]\n"
@@ -8547,6 +8548,7 @@ enum {
QEMU_OPTION_snapshot,
#ifdef TARGET_I386
QEMU_OPTION_no_fd_bootchk,
+ QEMU_OPTION_osk,
#endif
QEMU_OPTION_m,
QEMU_OPTION_nographic,
@@ -8648,6 +8650,7 @@ const QEMUOption qemu_options[] = {
{ "snapshot", 0, QEMU_OPTION_snapshot },
#ifdef TARGET_I386
{ "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
+ { "osk", HAS_ARG, QEMU_OPTION_osk },
#endif
{ "m", HAS_ARG, QEMU_OPTION_m },
{ "nographic", 0, QEMU_OPTION_nographic },
@@ -9360,6 +9363,9 @@ int main(int argc, char **argv)
case QEMU_OPTION_no_fd_bootchk:
fd_bootchk = 0;
break;
+ case QEMU_OPTION_osk:
+ applesmc_setkey(optarg);
+ break;
#endif
case QEMU_OPTION_net:
if (nb_net_clients >= MAX_NET_CLIENTS) {

View File

@ -0,0 +1,58 @@
# Quick patch until proper version is upstream, but is safe.
# Signed-off-by: Alex Graf - agraf@suse
Index: kvm-75/qemu/qemu-kvm-x86.c
===================================================================
--- kvm-75.orig/qemu/qemu-kvm-x86.c
+++ kvm-75/qemu/qemu-kvm-x86.c
@@ -465,10 +465,11 @@ static void host_cpuid(uint32_t function
}
-static void do_cpuid_ent(struct kvm_cpuid_entry *e, uint32_t function,
+static void do_cpuid_ent(struct kvm_cpuid_entry *e, uint32_t function, uint32_t index,
CPUState *env)
{
env->regs[R_EAX] = function;
+ env->regs[R_ECX] = index;
qemu_kvm_cpuid_on_env(env);
e->function = function;
e->eax = env->regs[R_EAX];
@@ -554,7 +555,7 @@ int kvm_arch_qemu_init_env(CPUState *cen
#endif
int cpuid_nent = 0;
CPUState copy;
- uint32_t i, limit;
+ uint32_t i, j, limit;
copy = *cenv;
@@ -579,15 +580,26 @@ int kvm_arch_qemu_init_env(CPUState *cen
qemu_kvm_cpuid_on_env(&copy);
limit = copy.regs[R_EAX];
- for (i = 0; i <= limit; ++i)
- do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, &copy);
+ for (i = 0; i <= limit; ++i) {
+ switch(i) {
+ case 4:
+ for(j = 0; ; j++) {
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, j, &copy);
+ if(!copy.regs[R_EAX]) break;
+ }
+ break;
+ default:
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, &copy);
+ break;
+ }
+ }
copy.regs[R_EAX] = 0x80000000;
qemu_kvm_cpuid_on_env(&copy);
limit = copy.regs[R_EAX];
for (i = 0x80000000; i <= limit; ++i)
- do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, &copy);
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, &copy);
kvm_setup_cpuid(kvm_context, cenv->cpu_index, cpuid_nent, cpuid_ent);
return 0;

View File

@ -0,0 +1,13 @@
Index: kvm-77/qemu/vl.c
===================================================================
--- kvm-77.orig/qemu/vl.c
+++ kvm-77/qemu/vl.c
@@ -162,7 +162,7 @@
#ifdef TARGET_PPC
#define DEFAULT_RAM_SIZE 144
#else
-#define DEFAULT_RAM_SIZE 128
+#define DEFAULT_RAM_SIZE 384
#endif
/* Max number of USB devices that can be specified on the commandline. */

View File

@ -0,0 +1,341 @@
#qemu-only -> submit upstream qemu
Index: kvm-75/qemu/Makefile.target
===================================================================
--- kvm-75.orig/qemu/Makefile.target
+++ kvm-75/qemu/Makefile.target
@@ -610,7 +610,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o
ifeq ($(USE_KVM_PIT), 1)
OBJS+= i8254-kvm.o
endif
Index: kvm-75/qemu/hw/hpet.c
===================================================================
--- /dev/null
+++ kvm-75/qemu/hw/hpet.c
@@ -0,0 +1,322 @@
+/*
+ * High Precisition Event Timer emulation
+ *
+ * Copyright (c) 2007 Alexander Graf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * *****************************************************************
+ *
+ * This driver attempts to emulate an HPET device in software. It is by no
+ * means complete and is prone to break on certain conditions.
+ *
+ */
+#include "hw.h"
+#include "console.h"
+#include "qemu-timer.h"
+
+#define HPET_DEBUG
+
+#define HPET_BASE 0xfed00000
+
+#define HPET_NUM_TIMERS 3
+#define HPET_TIMER_TYPE_LEVEL 1
+#define HPET_TIMER_TYPE_EDGE 0
+#define HPET_TIMER_DELIVERY_APIC 0
+#define HPET_TIMER_DELIVERY_FSB 1
+#define HPET_TIMER_CAP_FSB_INT_DEL (1 << 15)
+#define HPET_TIMER_CAP_PER_INT (1 << 4)
+
+struct HPETState;
+typedef struct HPETTimer {
+ QEMUTimer *timer;
+ struct HPETState *state;
+ uint8_t type;
+ uint8_t active;
+ uint8_t delivery;
+ uint8_t apic_port;
+ uint8_t periodic;
+ uint8_t enabled;
+ uint32_t comparator; // if(hpet_counter == comparator) IRQ();
+ qemu_irq irq;
+} HPETTimer;
+
+typedef struct HPETState {
+ uint64_t hpet_counter;
+ int64_t next_periodic_time;
+ uint8_t active;
+ qemu_irq *irqs;
+ HPETTimer timer[HPET_NUM_TIMERS];
+} HPETState;
+
+static void update_irq(struct HPETTimer *timer)
+{
+ qemu_set_irq(timer->irq, timer->active && timer->state->active);
+}
+
+static void update_irq_all(struct HPETState *s)
+{
+ int i;
+ for(i=0; i<HPET_NUM_TIMERS; i++)
+ update_irq(&s->timer[i]);
+}
+
+static void hpet_timer(void *opaque)
+{
+ HPETTimer *s = (HPETTimer*)opaque;
+ printf("hpet i!\n");
+ if(s->periodic) {
+ printf("periodic hpet!\n");
+ qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + ((s->comparator) * (ticks_per_sec * 99) / 100));
+ }
+ s->active = 1;
+ update_irq(s);
+}
+
+static void hpet_check(HPETTimer *s)
+{
+ if(s->enabled) {
+ if(s->periodic)
+ qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + s->comparator * (ticks_per_sec * 99) / 100);
+ else
+ qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + ((s->comparator - s->state->hpet_counter) * (ticks_per_sec * 99) / 100));
+ }
+}
+
+static uint32_t hpet_ram_readb(void *opaque, target_phys_addr_t addr)
+{
+#ifdef HPET_DEBUG
+ printf("qemu: hpet_read b at %#lx\n", addr);
+#endif
+ return 10;
+}
+
+static uint32_t hpet_ram_readw(void *opaque, target_phys_addr_t addr)
+{
+#ifdef HPET_DEBUG
+ printf("qemu: hpet_read w at %#lx\n", addr);
+#endif
+ return 10;
+}
+
+static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
+{
+ HPETState *s = (HPETState *)opaque;
+#ifdef HPET_DEBUG
+ printf("qemu: hpet_read l at %#lx\n", addr);
+#endif
+ switch(addr - HPET_BASE) {
+ case 0x00:
+ return 0x8086a201;
+ case 0x04:
+ return 0x0429b17f;
+ case 0x10:
+ case 0x14:
+ return 0;
+ case 0xf0:
+ return s->hpet_counter;
+ case 0xf4:
+ return 0;
+ case 0x20:
+ {
+ uint32_t retval = 0;
+ int i;
+ for(i=0; i<HPET_NUM_TIMERS; i++) {
+ if(s->timer[i].type == HPET_TIMER_TYPE_LEVEL)
+ retval |= s->timer[i].active << i;
+ }
+ return retval;
+ }
+ case 0x100 ... 0x3ff:
+ {
+ uint8_t timer_id = (addr - HPET_BASE - 0x100) / 0x20;
+ HPETTimer *timer = &s->timer[timer_id];
+
+ switch((addr - HPET_BASE - 0x100) % 0x20) {
+ case 0x0:
+ return ((timer->delivery == HPET_TIMER_DELIVERY_FSB) << 14)
+ | (timer->apic_port << 9)
+ | HPET_TIMER_CAP_PER_INT
+ | (timer->periodic << 3)
+ | (timer->enabled << 2)
+ | (timer->type << 1);
+ case 0x4: // Interrupt capabilities
+ return 0x00ff;
+ case 0x8: // comparator register
+ return timer->comparator;
+ case 0xc:
+ return 0x0;
+ }
+ }
+ break;
+ }
+
+#ifdef HPET_DEBUG
+ printf("qemu: invalid hpet_read l at %#x\n", addr);
+#endif
+ return 10;
+}
+
+static void hpet_ram_writeb(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+#ifdef HPET_DEBUG
+ printf("qemu: invalid hpet_write b at %#x = %#x\n", addr, value);
+#endif
+}
+
+static void hpet_ram_writew(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+#ifdef HPET_DEBUG
+ printf("qemu: invalid hpet_write w at %#x = %#x\n", addr, value);
+#endif
+}
+
+static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+ HPETState *s = (HPETState *)opaque;
+#ifdef HPET_DEBUG
+ printf("qemu: hpet_write l at %#x = %#x\n", addr, value);
+#endif
+ switch(addr - HPET_BASE) {
+ case 0x00:
+ return;
+ case 0x10:
+ case 0x14: // set interrupt enabled flag
+ if(value < 2) {
+ s->active = value;
+ update_irq_all(s);
+ } else {
+#ifdef HPET_DEBUG
+ printf("qemu: invalid hpet_write l at %#x = %#x\n", addr, value);
+#endif
+ }
+ break;
+ case 0x20:
+ {
+ int i;
+ for(i=0; i<HPET_NUM_TIMERS; i++) {
+ if(s->timer[i].type == HPET_TIMER_TYPE_LEVEL) {
+ if(value & (1 << i)) {
+ s->timer[i].active = 0;
+ update_irq(&s->timer[i]);
+ }
+ }
+ }
+ }
+ break;
+ case 0xf0:
+ s->hpet_counter = (s->hpet_counter & (0xffffffffULL << 32)) | value;
+#ifdef HPET_DEBUG
+ printf("qemu: HPET counter 0xf0 set to %#x -> %#llx\n", value, s->hpet_counter);
+#endif
+ break;
+ case 0xf4:
+ s->hpet_counter = (s->hpet_counter & 0xffffffffULL) | (((uint64_t)value) << 32);
+#ifdef HPET_DEBUG
+ printf("qemu: HPET counter 0xf4 set to %#x -> %#llx\n", value, s->hpet_counter);
+#endif
+ break;
+ case 0x100 ... 0x3ff:
+ {
+ uint8_t timer_id = (addr - HPET_BASE - 0x100) / 0x20;
+ HPETTimer *timer = &s->timer[timer_id];
+
+ switch((addr - HPET_BASE - 0x100) % 0x20) {
+ case 0x0:
+ if(value & 1) break; // reserved
+ timer->delivery = (value >> 14) & 1;
+ timer->apic_port = (value >> 9) & 16;
+ timer->irq = s->irqs[timer->apic_port];
+ timer->periodic = (value >> 3) & 1;
+ timer->enabled = (value >> 2) & 1;
+ timer->type = (value >> 1) & 1;
+#ifdef HPET_DEBUG
+ printf("qemu: hpet_write l at %#x = %#x\n", addr, value);
+#endif
+ hpet_check(timer);
+ break;
+#ifdef HPET_DEBUG
+ case 0x4: // Interrupt capabilities
+ printf("qemu: invalid hpet_write l at %#x = %#x\n", addr, value);
+ break;
+#endif
+ case 0x8: // comparator register
+ timer->comparator = value;
+ hpet_check(timer);
+ break;
+ case 0xc:
+#ifdef HPET_DEBUG
+ printf("qemu: invalid hpet_write l at %#x = %#x\n", addr, value);
+#endif
+ break;
+ }
+ }
+ default:
+ printf("qemu: invalid hpet_write l at %#x = %#x\n", addr, value);
+ }
+
+}
+
+static CPUReadMemoryFunc *hpet_ram_read[] = {
+ hpet_ram_readb,
+ hpet_ram_readw,
+ hpet_ram_readl,
+};
+
+static CPUWriteMemoryFunc *hpet_ram_write[] = {
+ hpet_ram_writeb,
+ hpet_ram_writew,
+ hpet_ram_writel,
+};
+
+
+void hpet_init(qemu_irq *irq) {
+ int iomemtype, i;
+ HPETState *s;
+
+ /* XXX this is a dirty hack for HPET support w/o LPC
+ Actually this is a config descriptor for the RCBA */
+ s = qemu_mallocz(sizeof(HPETState));
+ s->irqs = irq;
+
+ for(i=0; i<HPET_NUM_TIMERS; i++) {
+ HPETTimer *timer = &s->timer[i];
+ timer->comparator = 0xffffffff;
+ timer->state = s;
+ timer->timer = qemu_new_timer(vm_clock, hpet_timer, s->timer+i);
+ switch(i) {
+ case 0:
+ timer->apic_port = 2;
+ break;
+ case 1:
+ timer->apic_port = 8;
+ break;
+ default:
+ timer->apic_port = 0;
+ break;
+ }
+ s->timer[i].irq = irq[timer->apic_port];
+ }
+
+ /* HPET Area */
+
+ iomemtype = cpu_register_io_memory(0, hpet_ram_read,
+ hpet_ram_write, s);
+
+ cpu_register_physical_memory(HPET_BASE, 0x400, iomemtype);
+}

View File

@ -0,0 +1,96 @@
#qemu-only -> submit upstream qemu
Index: kvm-75/qemu/hw/ide.c
===================================================================
--- kvm-75.orig/qemu/hw/ide.c
+++ kvm-75/qemu/hw/ide.c
@@ -462,6 +462,7 @@ static inline int media_is_cd(IDEState *
#define IDE_TYPE_PIIX3 0
#define IDE_TYPE_CMD646 1
#define IDE_TYPE_PIIX4 2
+#define IDE_TYPE_ICH6 3
/* CMD646 specific */
#define MRDMODE 0x71
@@ -3164,6 +3165,57 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
qemu_register_reset(piix3_reset, d);
piix3_reset(d);
+
+ pci_register_io_region((PCIDevice *)d, 4, 0x10,
+ PCI_ADDRESS_SPACE_IO, bmdma_map);
+
+ ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
+ ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
+ ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
+ ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+
+ for (i = 0; i < 4; i++)
+ if (hd_table[i])
+ hd_table[i]->devfn = d->dev.devfn;
+
+ register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
+}
+
+
+/* hd_table must contain 4 block drivers */
+/* NOTE: for the ICH-6, the IRQs and IOports are hardcoded */
+void pci_ich6_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
+ qemu_irq *pic)
+{
+ PCIIDEState *d;
+ uint8_t *pci_conf;
+ int i;
+
+ /* register a function 1 of ICH-6 */
+ d = (PCIIDEState *)pci_register_device(bus, "ICH-6 IDE",
+ sizeof(PCIIDEState),
+ devfn,
+ NULL, NULL);
+ d->type = IDE_TYPE_ICH6;
+
+ pci_conf = d->dev.config;
+ pci_conf[0x00] = 0x86; // Intel
+ pci_conf[0x01] = 0x80;
+ pci_conf[0x02] = 0x9e;
+ pci_conf[0x03] = 0x26;
+
+ pci_conf[0x09] = 0x80; // legacy ATA mode
+ pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
+ pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
+ pci_conf[0x0e] = 0x00; // header_type
+
+ pci_conf[0x40] = 0;
+ pci_conf[0x41] = 0xf0; // primary port enabled
+ pci_conf[0x42] = 0;
+ pci_conf[0x43] = 0x00; // secondary port disabled
+
+ qemu_register_reset(piix3_reset, d);
+ piix3_reset(d);
pci_register_io_region((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map);
Index: kvm-75/qemu/hw/irq.c
===================================================================
--- kvm-75.orig/qemu/hw/irq.c
+++ kvm-75/qemu/hw/irq.c
@@ -35,6 +35,7 @@ void qemu_set_irq(qemu_irq irq, int leve
if (!irq)
return;
+//printf("IRQ set %#hhx = %#hhd using %p\n", irq->n, level, irq->handler);
irq->handler(irq->opaque, irq->n, level);
}
Index: kvm-75/qemu/hw/pc.h
===================================================================
--- kvm-75.orig/qemu/hw/pc.h
+++ kvm-75/qemu/hw/pc.h
@@ -145,6 +145,8 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
qemu_irq *pic);
void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
qemu_irq *pic);
+void pci_ich6_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
+ qemu_irq *pic);
/* ne2000.c */

View File

@ -0,0 +1,196 @@
#qemu-only -> submit upstream qemu
Index: kvm-75/qemu/Makefile.target
===================================================================
--- kvm-75.orig/qemu/Makefile.target
+++ kvm-75/qemu/Makefile.target
@@ -610,7 +610,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o lpc.o
ifeq ($(USE_KVM_PIT), 1)
OBJS+= i8254-kvm.o
endif
Index: kvm-75/qemu/hw/lpc.c
===================================================================
--- /dev/null
+++ kvm-75/qemu/hw/lpc.c
@@ -0,0 +1,163 @@
+/*
+ * Low Pin Count emulation
+ *
+ * Copyright (c) 2007 Alexander Graf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * *****************************************************************
+ *
+ * This driver emulates an ICH-7 LPC partially. The LPC is basically the
+ * same as the ISA-bridge in the existing PIIX implementation, but
+ * more recent and includes support for HPET and Power Management.
+ *
+ */
+#include "hw.h"
+#include "pci.h"
+#include "console.h"
+
+#define RCBA_BASE 0xFED1C000
+
+void hpet_init(qemu_irq irq);
+
+static uint32_t rcba_ram_readl(void *opaque, target_phys_addr_t addr)
+{
+ printf("qemu: rcba_read l at %#lx\n", addr);
+ if(addr == RCBA_BASE + 0x3404) { /* This is the HPET config pointer */
+ printf("qemu: rcba_read HPET_CONFIG_POINTER\n");
+ return 0xf0; // enabled at 0xfed00000
+ } else if(addr == RCBA_BASE + 0x3410) { /* This is the HPET config pointer */
+ printf("qemu: rcba_read GCS\n");
+ return 0;
+ } else {
+ return 0x0;
+ }
+}
+
+static void rcba_ram_writel(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+ printf("qemu: rcba_write l %#lx = %#x\n", addr, value);
+}
+
+static CPUReadMemoryFunc *rcba_ram_read[] = {
+ NULL,
+ NULL,
+ rcba_ram_readl,
+};
+
+static CPUWriteMemoryFunc *rcba_ram_write[] = {
+ NULL,
+ NULL,
+ rcba_ram_writel,
+};
+
+void lpc_init(PCIBus *bus, int devfn, qemu_irq *pic) {
+ int iomemtype;
+ uint8_t *pci_conf;
+ PCIDevice *d;
+
+ /* register a function 1 of PIIX3 */
+ d = (PCIDevice *)pci_register_device(bus, "LPC",
+ sizeof(PCIDevice),
+ 31 << 3,
+ NULL, NULL);
+ pci_conf = d->config;
+ pci_conf[0x00] = 0x86;
+ pci_conf[0x01] = 0x80;
+ pci_conf[0x02] = 0xb9;
+ pci_conf[0x03] = 0x27;
+ pci_conf[0x08] = 0x02; // Revision 2
+
+ pci_conf[0x0a] = 0x01; // PCI-to-ISA Bridge
+ pci_conf[0x0b] = 0x06; // Bridge
+
+ pci_conf[0x0e] = 0xf0;
+
+ // Subsystem
+ pci_conf[0x2c] = 0x86;
+ pci_conf[0x2d] = 0x80;
+ pci_conf[0x2e] = 0x70;
+ pci_conf[0x2f] = 0x72;
+
+ pci_conf[0x3d] = 0x03;
+
+ // PMBASE
+ pci_conf[0x40] = 0x01;
+ pci_conf[0x41] = 0x0b;
+
+ pci_conf[0xf0] = RCBA_BASE | 1; // enabled
+ pci_conf[0xf1] = RCBA_BASE << 8;
+ pci_conf[0xf2] = RCBA_BASE << 16;
+ pci_conf[0xf3] = RCBA_BASE << 24;
+
+
+ /* RCBA Area */
+
+ iomemtype = cpu_register_io_memory(0, rcba_ram_read,
+ rcba_ram_write, d);
+
+ cpu_register_physical_memory(RCBA_BASE, 0x4000, iomemtype);
+#if 0
+ cpu_register_physical_memory(0x00CDA000, 0x4000, iomemtype);
+#endif
+
+
+
+ pci_conf[0x04] = 0x07; // master, memory and I/O
+ pci_conf[0x05] = 0x00;
+ pci_conf[0x06] = 0x00;
+ pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
+ pci_conf[0x4c] = 0x4d;
+ pci_conf[0x4e] = 0x03;
+ pci_conf[0x4f] = 0x00;
+ pci_conf[0x60] = 0x0a; // PCI A -> IRQ 10
+ pci_conf[0x61] = 0x0a; // PCI B -> IRQ 10
+ pci_conf[0x62] = 0x0b; // PCI C -> IRQ 11
+ pci_conf[0x63] = 0x0b; // PCI D -> IRQ 11
+ pci_conf[0x69] = 0x02;
+ pci_conf[0x70] = 0x80;
+ pci_conf[0x76] = 0x0c;
+ pci_conf[0x77] = 0x0c;
+ pci_conf[0x78] = 0x02;
+ pci_conf[0x79] = 0x00;
+ pci_conf[0x80] = 0x00;
+ pci_conf[0x82] = 0x00;
+ pci_conf[0xa0] = 0x08;
+ pci_conf[0xa2] = 0x00;
+ pci_conf[0xa3] = 0x00;
+ pci_conf[0xa4] = 0x00;
+ pci_conf[0xa5] = 0x00;
+ pci_conf[0xa6] = 0x00;
+ pci_conf[0xa7] = 0x00;
+ pci_conf[0xa8] = 0x0f;
+ pci_conf[0xaa] = 0x00;
+ pci_conf[0xab] = 0x00;
+ pci_conf[0xac] = 0x00;
+ pci_conf[0xae] = 0x00;
+
+// XXX hpet goes via apic
+ hpet_init(pic);
+
+#if 0
+ register_ioport_read(0x1000, 128, 1, pmbase_readb, d);
+ register_ioport_write(0x1000, 128, 1, pmbase_writeb, d);
+ register_ioport_read(0x1000, 64, 2, pmbase_readw, d);
+ register_ioport_write(0x1000, 64, 2, pmbase_writew, d);
+ register_ioport_read(0x1000, 32, 4, pmbase_readl, d);
+ register_ioport_write(0x1000, 32, 5, pmbase_writel, d);
+#endif
+}
+
Index: kvm-75/qemu/hw/pc.h
===================================================================
--- kvm-75.orig/qemu/hw/pc.h
+++ kvm-75/qemu/hw/pc.h
@@ -150,6 +150,9 @@ void pci_piix4_ide_init(PCIBus *bus, Blo
void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd);
+/* lpc.c */
+void lpc_init(PCIBus *bus, int devfn, qemu_irq *pic);
+
/* virtio-net.c */
PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn);

View File

@ -0,0 +1,309 @@
#qemu-only -> submit upstream qemu, but improve first:
# undo rather hacky pci_enabled -> model > MODEL_ISA changes
# and replace checks wether to enable newer emulated Mac hardware
# depending in the bits in a bitfield which is passed pc_init1()
# like this: pc_init1(.... , ISA, ...)
# pc_init1(.... , PCI | IOAPIC | PIIX, .....
# pc_init1(.... , PCI | ICH6, LPC, SMC , ...)
Index: kvm-78/qemu/hw/pc.c
===================================================================
--- kvm-78.orig/qemu/hw/pc.c
+++ kvm-78/qemu/hw/pc.c
@@ -58,6 +58,12 @@ static PITState *pit;
static IOAPICState *ioapic;
static PCIDevice *i440fx_state;
+enum pc_model {
+ MODEL_ISA = 0,
+ MODEL_PCI = 1,
+ MODEL_MAC = 2
+};
+
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
{
}
@@ -805,7 +811,7 @@ static void pc_init1(ram_addr_t ram_size
const char *boot_device, DisplayState *ds,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename,
- int pci_enabled, const char *cpu_model)
+ int model, const char *cpu_model)
{
char buf[1024];
int ret, linux_boot, i;
@@ -833,15 +839,19 @@ static void pc_init1(ram_addr_t ram_size
/* init CPUs */
if (cpu_model == NULL) {
+ if(model == MODEL_MAC) {
+ cpu_model = "coreduo";
+ } else {
#ifdef TARGET_X86_64
- cpu_model = "qemu64";
+ cpu_model = "qemu64";
#else
- cpu_model = "qemu32";
+ cpu_model = "qemu32";
#endif
+ }
}
for(i = 0; i < smp_cpus; i++) {
- env = pc_new_cpu(i, cpu_model, pci_enabled);
+ env = pc_new_cpu(i, cpu_model, model > MODEL_ISA);
}
vmport_init();
@@ -880,8 +890,16 @@ static void pc_init1(ram_addr_t ram_size
vga_ram_addr = qemu_ram_alloc(vga_ram_size);
/* BIOS load */
- if (bios_name == NULL)
- bios_name = BIOS_FILENAME;
+ if (bios_name == NULL) {
+ switch(model) {
+ case MODEL_MAC:
+ bios_name = "bios-mac.bin";
+ break;
+ default:
+ bios_name = BIOS_FILENAME;
+ break;
+ }
+ }
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
bios_size = get_image_size(buf);
if (bios_size <= 0 ||
@@ -956,7 +974,7 @@ static void pc_init1(ram_addr_t ram_size
i8259 = i8259_init(cpu_irq[0]);
ferr_irq = i8259[13];
- if (pci_enabled) {
+ if (model > MODEL_ISA) {
pci_bus = i440fx_init(&i440fx_state, i8259);
piix3_devfn = piix3_init(pci_bus, -1);
} else {
@@ -969,7 +987,7 @@ static void pc_init1(ram_addr_t ram_size
register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
if (cirrus_vga_enabled) {
- if (pci_enabled) {
+ if (model > MODEL_ISA) {
pci_cirrus_vga_init(pci_bus,
ds, phys_ram_base + vga_ram_addr,
vga_ram_addr, vga_ram_size);
@@ -978,13 +996,13 @@ static void pc_init1(ram_addr_t ram_size
vga_ram_addr, vga_ram_size);
}
} else if (vmsvga_enabled) {
- if (pci_enabled)
+ if (model > MODEL_ISA)
pci_vmsvga_init(pci_bus, ds, phys_ram_base + vga_ram_addr,
vga_ram_addr, vga_ram_size);
else
fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__);
} else {
- if (pci_enabled) {
+ if (model > MODEL_ISA) {
pci_vga_init(pci_bus, ds, phys_ram_base + vga_ram_addr,
vga_ram_addr, vga_ram_size, 0, 0);
} else {
@@ -1000,8 +1018,13 @@ static void pc_init1(ram_addr_t ram_size
register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
- if (pci_enabled) {
- ioapic = ioapic_init();
+ switch (model) {
+ case MODEL_MAC:
+ applesmc_init();
+ lpc_init(pci_bus, piix3_devfn, i8259);
+ case MODEL_PCI:
+ ioapic = ioapic_init();
+ break;
}
#ifdef USE_KVM_PIT
if (kvm_enabled() && qemu_kvm_pit_in_kernel())
@@ -1010,7 +1033,7 @@ static void pc_init1(ram_addr_t ram_size
#endif
pit = pit_init(0x40, i8259[0]);
pcspk_init(pit);
- if (pci_enabled) {
+ if (model > MODEL_ISA) {
pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
}
@@ -1031,15 +1054,22 @@ static void pc_init1(ram_addr_t ram_size
for(i = 0; i < nb_nics; i++) {
nd = &nd_table[i];
if (!nd->model) {
- if (pci_enabled) {
- nd->model = "rtl8139";
- } else {
- nd->model = "ne2k_isa";
+ switch(model) {
+ case MODEL_ISA:
+ nd->model = "ne2k_isa";
+ break;
+ case MODEL_MAC:
+ nd->model = "rtl8139";
+ nd->link = Link_10mbps;
+ break;
+ default:
+ nd->model = "ne2k_pci";
+ break;
}
}
if (strcmp(nd->model, "ne2k_isa") == 0) {
pc_init_ne2k_isa(nd, i8259);
- } else if (pci_enabled) {
+ } else if (model > MODEL_ISA) {
if (strcmp(nd->model, "?") == 0)
fprintf(stderr, "qemu: Supported ISA NICs: ne2k_isa\n");
if (!pci_nic_init(pci_bus, nd, -1))
@@ -1068,19 +1098,25 @@ static void pc_init1(ram_addr_t ram_size
hd[i] = NULL;
}
- if (pci_enabled) {
- pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, i8259);
- } else {
- for(i = 0; i < MAX_IDE_BUS; i++) {
- isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
- hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
- }
+ switch(model) {
+ case MODEL_MAC:
+ pci_ich6_ide_init(pci_bus, hd, piix3_devfn + 1, i8259);
+ break;
+ case MODEL_PCI:
+ pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, i8259);
+ break;
+ default:
+ for(i = 0; i < 2; i++) {
+ isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
+ hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
+ }
+ break;
}
i8042_init(i8259[1], i8259[12], 0x60);
DMA_init(0);
#ifdef HAS_AUDIO
- audio_init(pci_enabled ? pci_bus : NULL, i8259);
+ audio_init((model > MODEL_ISA) ? pci_bus : NULL, i8259);
#endif
for(i = 0; i < MAX_FD; i++) {
@@ -1094,11 +1130,11 @@ static void pc_init1(ram_addr_t ram_size
cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd);
- if (pci_enabled && usb_enabled) {
+ if ((model > MODEL_ISA) && usb_enabled) {
usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
}
- if (pci_enabled && acpi_enabled) {
+ if ((model > MODEL_ISA) && acpi_enabled) {
uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
i2c_bus *smbus;
@@ -1113,7 +1149,7 @@ static void pc_init1(ram_addr_t ram_size
i440fx_init_memory_mappings(i440fx_state);
}
- if (pci_enabled) {
+ if (model > MODEL_ISA) {
int max_bus;
int bus, unit;
void *scsi;
@@ -1132,7 +1168,7 @@ static void pc_init1(ram_addr_t ram_size
}
/* Add virtio block devices */
- if (pci_enabled) {
+ if (model > MODEL_ISA) {
int index;
int unit_id = 0;
@@ -1155,10 +1191,22 @@ static void pc_init1(ram_addr_t ram_size
extboot_init(info->bdrv, 1);
}
- if (pci_enabled)
+ if (model > MODEL_ISA)
virtio_balloon_init(pci_bus);
}
+static void pc_init_mac(ram_addr_t ram_size, int vga_ram_size,
+ const char *boot_device, DisplayState *ds,
+ const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ const char *cpu_model)
+{
+ pc_init1(ram_size, vga_ram_size, boot_device, ds,
+ kernel_filename, kernel_cmdline,
+ initrd_filename, MODEL_MAC, cpu_model);
+}
+
static void pc_init_pci(ram_addr_t ram_size, int vga_ram_size,
const char *boot_device, DisplayState *ds,
const char *kernel_filename,
@@ -1168,7 +1216,7 @@ static void pc_init_pci(ram_addr_t ram_s
{
pc_init1(ram_size, vga_ram_size, boot_device, ds,
kernel_filename, kernel_cmdline,
- initrd_filename, 1, cpu_model);
+ initrd_filename, MODEL_PCI, cpu_model);
}
static void pc_init_isa(ram_addr_t ram_size, int vga_ram_size,
@@ -1180,7 +1228,7 @@ static void pc_init_isa(ram_addr_t ram_s
{
pc_init1(ram_size, vga_ram_size, boot_device, ds,
kernel_filename, kernel_cmdline,
- initrd_filename, 0, cpu_model);
+ initrd_filename, MODEL_ISA, cpu_model);
}
QEMUMachine pc_machine = {
@@ -1190,6 +1238,14 @@ QEMUMachine pc_machine = {
.ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE,
.max_cpus = 255,
};
+
+QEMUMachine mac_machine = {
+ .name = "mac",
+ .desc = "Intel-Mac",
+ .init = pc_init_mac,
+ .ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE,
+ .max_cpus = 255,
+};
QEMUMachine isapc_machine = {
.name = "isapc",
Index: kvm-78/qemu/hw/boards.h
===================================================================
--- kvm-78.orig/qemu/hw/boards.h
+++ kvm-78/qemu/hw/boards.h
@@ -33,6 +33,7 @@ extern QEMUMachine bareetraxfs_machine;
/* pc.c */
extern QEMUMachine pc_machine;
extern QEMUMachine isapc_machine;
+extern QEMUMachine mac_machine;
/* ppc.c */
extern QEMUMachine prep_machine;
Index: kvm-78/qemu/target-i386/machine.c
===================================================================
--- kvm-78.orig/qemu/target-i386/machine.c
+++ kvm-78/qemu/target-i386/machine.c
@@ -10,6 +10,7 @@ void register_machines(void)
{
qemu_register_machine(&pc_machine);
qemu_register_machine(&isapc_machine);
+ qemu_register_machine(&mac_machine);
}
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)

View File

@ -0,0 +1,492 @@
Index: kvm-75/qemu/elf_ops.h
===================================================================
--- kvm-75.orig/qemu/elf_ops.h
+++ kvm-75/qemu/elf_ops.h
@@ -156,6 +156,10 @@ static int glue(load_elf, SZ)(int fd, in
}
if (ELF_MACHINE != ehdr.e_machine)
+#if (ELF_MACHINE == EM_X86_64) && !CONFIG_USER_ONLY
+ /* x86_64 systems can run i386 code as well */
+ if(ehdr.e_machine != EM_386)
+#endif
goto fail;
if (pentry)
Index: kvm-75/qemu/hw/pc.c
===================================================================
--- kvm-75.orig/qemu/hw/pc.c
+++ kvm-75/qemu/hw/pc.c
@@ -512,6 +512,416 @@ static long get_file_size(FILE *f)
return size;
}
+/* Generate an initial boot sector which sets state and jump to
+ a specified vector */
+static void generate_bootsect_multiboot(uint32_t mh_entry_addr, uint32_t bootinfo)
+{
+ uint8_t bootsect[512], *p, *pgdt, *pmmaploop;
+ uint32_t ip;
+ int i;
+ int hda;
+ int mmaploop;
+
+ hda = drive_get_index(IF_IDE, 0, 0);
+ if (hda == -1) {
+ fprintf(stderr, "A disk image must be given for 'hda' when booting "
+ "a Multiboot kernel\n");
+ exit(1);
+ }
+
+ memset(bootsect, 0, sizeof(bootsect));
+
+ /* Copy the MSDOS partition table if possible */
+ bdrv_read(drives_table[hda].bdrv, 0, bootsect, 1);
+
+ /* Make sure we have a partition signature */
+ bootsect[510] = 0x55;
+ bootsect[511] = 0xaa;
+
+ /* Actual code */
+ p = bootsect;
+ *p++ = 0xfa; /* CLI */
+ *p++ = 0xfc; /* CLD */
+
+ // 660f011528000000 lgdt [0x28]
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0x0f; /* LGDT [0x128] */
+ *p++ = 0x01;
+ *p++ = 0x15;
+ pgdt=p; /* we calculate the gdt position later */
+ p+=4;
+
+ /* Initialize multiboot mmap structs using the 0x15(e820) */
+ *p++ = 0x31; /* XOR BX,BX */
+ *p++ = 0xdb;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0xbf; /* MOV EDI,0x9004 */
+ *p++ = 0x04;
+ *p++ = 0x90;
+ *p++ = 0x00;
+ *p++ = 0x00;
+
+ pmmaploop = p;
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0xb8; /* MOV EAX,0x20 */
+ *p++ = 0x20;
+ *p++ = 0x00;
+ *p++ = 0x00;
+ *p++ = 0x00;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0x89; /* MOV -4(EDI),EAX */
+ *p++ = 0x47;
+ *p++ = 0xfc;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0xb8; /* MOV EAX,0x0000e820 */
+ *p++ = 0x20;
+ *p++ = 0xe8;
+ *p++ = 0x00;
+ *p++ = 0x00;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0xba; /* MOV EDX,0x534d4150 */
+ *p++ = 0x50;
+ *p++ = 0x41;
+ *p++ = 0x4d;
+ *p++ = 0x53;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0xb9; /* MOV ECX,0x20 */
+ *p++ = 0x20;
+ *p++ = 0x00;
+ *p++ = 0x00;
+ *p++ = 0x00;
+
+ *p++ = 0xcd; /* INT 0x15 */
+ *p++ = 0x15;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0xb8; /* MOV EAX, 0x24 */
+ *p++ = 0x24;
+ *p++ = 0x00;
+ *p++ = 0x00;
+ *p++ = 0x00;
+
+ *p++ = 0xf7; /* MUL AX, BX */
+ *p++ = 0xe3;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0x21; /* AND EBX, EBX */
+ *p++ = 0xdb;
+
+ /* don't store if bx = 0 */
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0x0f; /* JZ next instruction */
+ *p++ = 0x84;
+ *p++ = 0x07;
+ *p++ = 0x00;
+ *p++ = 0x00;
+ *p++ = 0x00;
+
+ /* store the amount of blocks in the bootinfo struct */
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0xa3; /* MOV [bootinfo+0x2c], EAX */
+ *p++ = (bootinfo+0x2c);
+ *p++ = (bootinfo+0x2c) >> 8;
+ *p++ = (bootinfo+0x2c) >> 16;
+ *p++ = (bootinfo+0x2c) >> 24;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0x05; /* ADD EAX, 0x9004 */
+ *p++ = 0x04;
+ *p++ = 0x90;
+ *p++ = 0x00;
+ *p++ = 0x00;
+
+ *p++ = 0x89; /* MOV DI, AX */
+ *p++ = 0xc7;
+
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0x21; /* AND EBX, EBX */
+ *p++ = 0xdb;
+
+ /* process next entry */
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0x67; /* 32-bit addr size */
+ *p++ = 0x0f; /* JNZ mmaploop */
+ *p++ = 0x85;
+ mmaploop = (int)((long)pmmaploop) - ((long)p) - 4;
+ *p++ = mmaploop;
+ *p++ = mmaploop >> 8;
+ *p++ = mmaploop >> 16;
+ *p++ = mmaploop >> 24;
+
+ /* get us to protected mode now */
+
+ *p++ = 0x66;
+ *p++ = 0xb8; /* MOV EAX,0x01 */
+ *p++ = 0x01;
+ *p++ = 0x00;
+ *p++ = 0x00;
+ *p++ = 0x00;
+
+ *p++ = 0x0f; /* MOV CR0,EAX */
+ *p++ = 0x22;
+ *p++ = 0xc0;
+
+ /* the JMP sets CS for us and gets us to 32-bit */
+ ip = 0x00007c00 + (p - bootsect) + 8; // set i to the IP after the JMP
+ *p++ = 0x66; /* 32-bit operand size */
+ *p++ = 0xea; /* JMP */
+ *p++ = ip; /* IP */
+ *p++ = ip >> 8;
+ *p++ = ip >> 16;
+ *p++ = ip >> 24;
+ *p++ = 0x08;
+ *p++ = 0x00;
+
+ /* initialize all other segments */
+ *p++ = 0xb8; /* MOV EAX,0x10 */
+ *p++ = 0x10;
+ *p++ = 0x00;
+ *p++ = 0x00;
+ *p++ = 0x00;
+ for (i = 0; i < 6; i++) {
+ if (i == 1) /* Skip CS */
+ continue;
+
+ *p++ = 0x8e; /* MOV <seg>,EAX */
+ *p++ = 0xc0 + (i << 3);
+ }
+
+ /* EBX contains a pointer to the bootinfo struct */
+ *p++ = 0xbb; /* MOV EBX,imm32 */
+ *p++ = bootinfo;
+ *p++ = bootinfo >> 8;
+ *p++ = bootinfo >> 16;
+ *p++ = bootinfo >> 24;
+
+ /* EAX has to contain the following magic */
+ *p++ = 0xb8; /* MOV EAX,0x2badb002 */
+ *p++ = 0x02;
+ *p++ = 0xb0;
+ *p++ = 0xad;
+ *p++ = 0x2b;
+
+ /* Jump off to the kernel */
+ *p++ = 0xea; /* JMP */
+ *p++ = mh_entry_addr; /* IP */
+ *p++ = mh_entry_addr >> 8;
+ *p++ = mh_entry_addr >> 16;
+ *p++ = mh_entry_addr >> 24;
+ *p++ = 0x08;
+ *p++ = 0x00;
+
+ { /* GDT loading */
+ uint32_t gdt_base = 0x00007c00 + (p - bootsect); // 0x00007c00 is the first IP;
+ uint32_t gdtr = gdt_base + 0x28;
+ uint8_t gdt[] = { // GDT base: 0x00000100
+ // 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k)
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00,
+ // 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k)
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00,
+ // 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b)
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00,
+ // 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b)
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00,
+ // 0x28: gdtdesc
+ 0x27, 0x00, gdt_base, gdt_base >> 8, gdt_base >> 16, gdt_base >> 24
+ };
+
+ memcpy(p, gdt, sizeof(gdt));
+ p+=sizeof(gdt);
+ *pgdt++ = gdtr;
+ *pgdt++ = gdtr >> 8;
+ *pgdt++ = gdtr >> 16;
+ *pgdt++ = gdtr >> 24;
+ }
+
+ fprintf(stderr, "qemu: multiboot loader code is %d bytes long.\n", (int)(p-bootsect));
+
+ bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect));
+}
+
+static int load_multiboot(FILE *f,
+ const char *kernel_filename,
+ const char *initrd_filename,
+ const char *kernel_cmdline,
+ uint8_t *header)
+{
+ int i, is_multiboot = 0;
+ uint32_t flags = 0;
+ uint32_t mh_entry_addr;
+ uint32_t mh_load_addr;
+ uint32_t mb_kernel_size;
+ uint32_t mb_bootinfo = 0x90000;
+ uint32_t tmp_size;
+
+ // Ok, let's see if it is a multiboot image
+ for(i = 0; i < 8144; i += 4) { // the header is 12x32bit long, so
+ // the latest entry may be 8192 - 48
+ if(ldl_p(header+i) == 0x1BADB002) {
+ uint32_t checksum = ldl_p(header+i+8);
+ flags = ldl_p(header+i+4);
+ checksum += flags;
+ checksum += (uint32_t)0x1BADB002;
+ if(!checksum) {
+ is_multiboot = 1;
+ break;
+ }
+ }
+ }
+
+ if(!is_multiboot) return 0; // no multiboot
+ fprintf(stderr, "qemu: I believe we found a multiboot image!\n");
+
+ if(flags & 0x00000004) { // MULTIBOOT_HEADER_HAS_VBE
+ fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");
+ }
+ if(!(flags & 0x00010000)) { // MULTIBOOT_HEADER_HAS_ADDR
+ uint64_t elf_entry;
+ int kernel_size;
+ fclose(f);
+ kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
+ if(kernel_size < 0) {
+ fprintf(stderr, "Error while loading elf kernel\n");
+ exit(1);
+ }
+ mh_load_addr = mh_entry_addr = elf_entry;
+ mb_kernel_size = kernel_size;
+
+ fprintf(stderr, "qemu: loading multiboot-elf kernel (%#x bytes) with entry %#zx\n",
+ mb_kernel_size, (size_t)mh_entry_addr);
+ } else {
+ /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */
+ uint32_t mh_header_addr = ldl_p(header+i+12);
+ mh_load_addr = ldl_p(header+i+16);
+ uint32_t mh_load_end_addr = ldl_p(header+i+20);
+ uint32_t mh_bss_end_addr = ldl_p(header+i+24);
+ uint8_t *mb_kernel_addr = phys_ram_base + (mh_load_addr);
+ uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
+
+ mh_entry_addr = ldl_p(header+i+28);
+ mb_kernel_size = get_file_size(f) - mb_kernel_text_offset;
+
+ /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE.
+ uint32_t mh_mode_type = ldl_p(header+i+32);
+ uint32_t mh_width = ldl_p(header+i+36);
+ uint32_t mh_height = ldl_p(header+i+40);
+ uint32_t mh_depth = ldl_p(header+i+44); */
+
+ fprintf(stderr, "multiboot: mh_header_addr = %#x\n", mh_header_addr);
+ fprintf(stderr, "multiboot: mh_load_addr = %#x\n", mh_load_addr);
+ fprintf(stderr, "multiboot: mh_load_end_addr = %#x\n", mh_load_end_addr);
+ fprintf(stderr, "multiboot: mh_bss_end_addr = %#x\n", mh_bss_end_addr);
+
+ fseek(f, mb_kernel_text_offset, SEEK_SET);
+
+ fprintf(stderr, "qemu: loading multiboot kernel (%#x bytes) at %#zx\n",
+ mb_kernel_size, mb_kernel_addr - phys_ram_base);
+
+ if ((tmp_size=fread(mb_kernel_addr, 1, mb_kernel_size, f)) != mb_kernel_size) {
+ fprintf(stderr, "qemu: read error on multiboot kernel '%s' (%#x != %#x)\n", kernel_filename, tmp_size, mb_kernel_size);
+ exit(1);
+ }
+ fclose(f);
+ }
+
+
+ // load modules
+
+ stl_p(phys_ram_base + mb_bootinfo + 20, 0x0); // mods_count
+ if(initrd_filename) {
+ uint32_t mb_mod_info = mb_bootinfo + 0x100;
+ uint32_t mb_mod_cmdline = mb_bootinfo+ 0x300;
+ uint32_t mb_mod_start = mh_load_addr;
+ uint32_t mb_mod_length = mb_kernel_size;
+ char *next_initrd;
+ char *next_space;
+ int mb_mod_count = 0;
+
+ do {
+ next_initrd = strchr(initrd_filename, ',');
+ if(next_initrd)
+ *next_initrd = '\0';
+ /* if a space comes after the module filename, treat everything after that as parameters */
+ strcpy(phys_ram_base + mb_mod_cmdline, initrd_filename);
+ stl_p(phys_ram_base + mb_mod_info + 8, mb_mod_cmdline); // string
+ mb_mod_cmdline += strlen(initrd_filename) + 1;
+ if(next_space = strchr(initrd_filename, ' '))
+ *next_space = '\0';
+printf("multiboot loading module: %s\n", initrd_filename);
+ f = fopen(initrd_filename, "rb");
+ if(f) {
+ mb_mod_start = (mb_mod_start + mb_mod_length + (TARGET_PAGE_SIZE - 1))
+ & (TARGET_PAGE_MASK);
+ mb_mod_length = get_file_size(f);
+
+ if ((tmp_size=fread((phys_ram_base + mb_mod_start), 1, mb_mod_length, f))
+ != mb_mod_length) {
+ fprintf(stderr, "qemu: read error on multiboot module '%s' (%#x != %#x)\n",
+ initrd_filename, tmp_size, mb_mod_length);
+ exit(1);
+ }
+
+ mb_mod_count++;
+ stl_p(phys_ram_base + mb_mod_info + 0, mb_mod_start);
+ stl_p(phys_ram_base + mb_mod_info + 4, mb_mod_start + mb_mod_length);
+printf("mod_start: %#x\nmod_end: %#x\n", mb_mod_start, mb_mod_start + mb_mod_length);
+ stl_p(phys_ram_base + mb_mod_info + 12, 0x0); // reserved
+ }
+ initrd_filename = next_initrd+1;
+ mb_mod_info += 16;
+ } while(next_initrd);
+ stl_p(phys_ram_base + mb_bootinfo + 20, mb_mod_count); // mods_count
+ stl_p(phys_ram_base + mb_bootinfo + 24, mb_bootinfo + 0x100); // mods_addr
+ }
+
+ /* Commandline support */
+ stl_p(phys_ram_base + mb_bootinfo + 16, mb_bootinfo + 0x200);
+ strcpy((char*)(phys_ram_base + mb_bootinfo + 0x200), kernel_cmdline);
+
+ // the kernel is where we want it to be now
+
+#define MULTIBOOT_FLAGS_MEMORY (1 << 0)
+#define MULTIBOOT_FLAGS_BOOT_DEVICE (1 << 1)
+#define MULTIBOOT_FLAGS_CMDLINE (1 << 2)
+#define MULTIBOOT_FLAGS_MODULES (1 << 3)
+#define MULTIBOOT_FLAGS_MMAP (1 << 6)
+ stl_p(phys_ram_base + mb_bootinfo, MULTIBOOT_FLAGS_MEMORY
+ | MULTIBOOT_FLAGS_BOOT_DEVICE
+ | MULTIBOOT_FLAGS_CMDLINE
+ | MULTIBOOT_FLAGS_MODULES
+ | MULTIBOOT_FLAGS_MMAP);
+ stl_p(phys_ram_base + mb_bootinfo + 4, 640 * 1024); // mem_lower
+ stl_p(phys_ram_base + mb_bootinfo + 8, ram_size); // mem_upper
+ stl_p(phys_ram_base + mb_bootinfo + 12, 0x8001ffff); // XXX: use the -boot switch?
+ stl_p(phys_ram_base + mb_bootinfo + 48, 0x9000); // mmap_addr
+
+ fprintf(stderr, "multiboot: mh_entry_addr = %#x\n", mh_entry_addr);
+
+ generate_bootsect_multiboot(mh_entry_addr, mb_bootinfo);
+
+ return 1; // yes, we are multiboot
+}
+
static void load_linux(const char *kernel_filename,
const char *initrd_filename,
const char *kernel_cmdline)
@@ -522,7 +932,7 @@ static void load_linux(const char *kerne
uint16_t real_seg;
int setup_size, kernel_size, initrd_size, cmdline_size;
uint32_t initrd_max;
- uint8_t header[1024];
+ uint8_t header[8192];
target_phys_addr_t real_addr, prot_addr, cmdline_addr, initrd_addr;
FILE *f, *fi;
@@ -532,7 +942,7 @@ static void load_linux(const char *kerne
/* load the kernel header */
f = fopen(kernel_filename, "rb");
if (!f || !(kernel_size = get_file_size(f)) ||
- fread(header, 1, 1024, f) != 1024) {
+ fread(header, 1, 8192, f) != 8192) {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
kernel_filename);
exit(1);
@@ -542,10 +952,15 @@ static void load_linux(const char *kerne
#if 0
fprintf(stderr, "header magic: %#x\n", ldl_p(header+0x202));
#endif
- if (ldl_p(header+0x202) == 0x53726448)
- protocol = lduw_p(header+0x206);
- else
- protocol = 0;
+ if (ldl_p(header+0x202) == 0x53726448) {
+ protocol = lduw_p(header+0x206);
+ } else {
+ // This looks like a multiboot kernel. If it is, let's stop
+ // treating it like Linux.
+ if(load_multiboot(f,kernel_filename,initrd_filename, kernel_cmdline, header))
+ return;
+ protocol = 0;
+ }
if (protocol < 0x200 || !(header[0x211] & 0x01)) {
/* Low kernel */
@@ -638,7 +1053,7 @@ static void load_linux(const char *kerne
}
/* store the finalized header and load the rest of the kernel */
- cpu_physical_memory_write(real_addr, header, 1024);
+ cpu_physical_memory_write(real_addr, header, 8192);
setup_size = header[0x1f1];
if (setup_size == 0)
@@ -647,7 +1062,7 @@ static void load_linux(const char *kerne
setup_size = (setup_size+1)*512;
kernel_size -= setup_size; /* Size of protected-mode code */
- if (!fread_targphys_ok(real_addr+1024, setup_size-1024, f) ||
+ if (!fread_targphys_ok(real_addr+8192, setup_size-8192, f) ||
!fread_targphys_ok(prot_addr, kernel_size, f)) {
fprintf(stderr, "qemu: read error on kernel '%s'\n",
kernel_filename);

View File

@ -0,0 +1,14 @@
Index: kvm-78/qemu/vl.c
===================================================================
--- kvm-78.orig/qemu/vl.c
+++ kvm-78/qemu/vl.c
@@ -10057,7 +10057,8 @@ int main(int argc, char **argv)
if (kvm_enabled()) {
if (kvm_qemu_init() < 0) {
extern int kvm_allowed;
- fprintf(stderr, "Could not initialize KVM, will disable KVM support\n");
+ fprintf(stderr, "Could not initialize KVM. Do you have kvm-amd or kvm-intel modprobe'd?\nIf you want to use CPU emulation, start with -no-kvm.\n");
+ exit(1);
#ifdef NO_CPU_EMULATION
fprintf(stderr, "Compiled with --disable-cpu-emulation, exiting.\n");
exit(1);

View File

@ -0,0 +1,109 @@
# Fix the Link detection in MacOS
# Author Alex Graf - agraf@suse
Index: kvm-75/qemu/hw/rtl8139.c
===================================================================
--- kvm-75.orig/qemu/hw/rtl8139.c
+++ kvm-75/qemu/hw/rtl8139.c
@@ -422,6 +422,9 @@ static void RTL8139TallyCounters_load(QE
/* Saves values of tally counters to VM state file */
static void RTL8139TallyCounters_save(QEMUFile* f, RTL8139TallyCounters *tally_counters);
+static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr);
+static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr);
+
typedef struct RTL8139State {
uint8_t phys[8]; /* mac address */
uint8_t mult[8]; /* multicast mask array */
@@ -462,6 +465,7 @@ typedef struct RTL8139State {
uint16_t CpCmd;
uint8_t TxThresh;
+ enum NICLink link;
PCIDevice *pci_dev;
VLANClientState *vc;
@@ -1227,7 +1231,7 @@ static void rtl8139_reset(RTL8139State *
s->Config0 = 0x0; /* No boot ROM */
s->Config1 = 0xC; /* IO mapped and MEM mapped registers available */
s->Config3 = 0x1; /* fast back-to-back compatible */
- s->Config5 = 0x0;
+ s->Config5 = Cfg5_LDPS;
s->CSCR = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD;
@@ -1251,6 +1255,13 @@ static void rtl8139_reset(RTL8139State *
s->TimerInt = 0;
s->TCTR_base = 0;
+ s->eeprom.contents[10] = s->Config0 | s->Config1 << 8;
+ s->eeprom.contents[6] = (rtl8139_io_readb(s, MediaStatus) & 0xc0) | ((rtl8139_io_readw(s, BasicModeCtrl) >> 8) & 0x23)
+ | (s->Config3 << 8);
+ s->eeprom.contents[12] = s->Config4 << 8;
+
+ s->eeprom.contents[15] = s->Config5 << 8;
+
/* reset tally counters */
RTL8139TallyCounters_clear(&s->tally_counters);
}
@@ -2846,7 +2857,7 @@ static uint32_t rtl8139_io_readb(void *o
break;
case MediaStatus:
- ret = 0xd0;
+ ret = 0xd0 | ((s->link == Link_10mbps) << 3);
DEBUG_PRINT(("RTL8139: MediaStatus read 0x%x\n", ret));
break;
@@ -3440,6 +3451,15 @@ PCIDevice *pci_rtl8139_init(PCIBus *bus,
s->pci_dev = (PCIDevice *)d;
memcpy(s->macaddr, nd->macaddr, 6);
+ switch(nd->link) {
+ case Link_10mbps:
+ case Link_100mbps:
+ s->link = nd->link;
+ break;
+ default:
+ s->link = Link_100mbps;
+ break;
+ }
rtl8139_reset(s);
s->vc = qemu_new_vlan_client(nd->vlan, rtl8139_receive,
rtl8139_can_receive, s);
Index: kvm-75/qemu/net.h
===================================================================
--- kvm-75.orig/qemu/net.h
+++ kvm-75/qemu/net.h
@@ -55,12 +55,20 @@ void net_client_uninit(NICInfo *nd);
#define MAX_NICS 8
+enum NICLink {
+ Link_default,
+ Link_10mbps,
+ Link_100mbps,
+ Link_1000mbps,
+};
+
struct NICInfo {
uint8_t macaddr[6];
const char *model;
VLANState *vlan;
int devfn;
int used;
+ enum NICLink link;
};
extern int nb_nics;
Index: kvm-75/qemu/vl.c
===================================================================
--- kvm-75.orig/qemu/vl.c
+++ kvm-75/qemu/vl.c
@@ -5555,6 +5555,7 @@ int net_client_init(const char *device,
}
nd->vlan = vlan;
nd->used = 1;
+ nd->link = Link_default;
nb_nics++;
vlan->nb_guest_devs++;
ret = idx;

View File

@ -0,0 +1,13 @@
# Revert default caching mode back to write-back for now
# Signed-off-by: Bruce Rogers <brogers@novell.com>
--- kvm-78.orig/qemu/vl.c
+++ kvm-78/qemu/vl.c
@@ -5892,7 +5892,7 @@ int drive_init(struct drive_opt *arg, in
unit_id = -1;
translation = BIOS_ATA_TRANSLATION_AUTO;
index = -1;
- cache = 1;
+ cache = 2;
if (machine->use_scsi) {
type = IF_SCSI;

View File

@ -0,0 +1,215 @@
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/app-emulation/kvm/kvm-82.ebuild,v 1.1 2009/01/05 01:30:01 dang Exp $
inherit eutils flag-o-matic toolchain-funcs linux-mod
EAPI="1"
# Patchset git repo is at http://github.com/dang/kvm-patches/tree/master
PATCHSET="kvm-patches-20090104"
SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz
http://apollo.fprintf.net/downloads/${PATCHSET}.tar.gz"
DESCRIPTION="Kernel-based Virtual Machine userland tools"
HOMEPAGE="http://kvm.qumranet.com/kvmwiki"
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="-* ~amd64 ~x86"
# Add bios back when it builds again
IUSE="alsa esd gnutls havekernel +modules ncurses pulseaudio +sdl test vde"
RESTRICT="test"
RDEPEND="sys-libs/zlib
alsa? ( >=media-libs/alsa-lib-1.0.13 )
esd? ( media-sound/esound )
pulseaudio? ( media-sound/pulseaudio )
gnutls? ( net-libs/gnutls )
ncurses? ( sys-libs/ncurses )
sdl? ( >=media-libs/libsdl-1.2.11 )
vde? ( net-misc/vde )"
# bios? (
# sys-devel/dev86
# dev-lang/perl
# sys-power/iasl
# )
DEPEND="${RDEPEND}
gnutls? ( dev-util/pkgconfig )
app-text/texi2html"
QA_TEXTRELS="usr/bin/kvm"
pkg_setup() {
linux-info_pkg_setup
if use havekernel && use modules ; then
ewarn "You have the 'havekernel' and 'modules' use flags enabled."
ewarn "'havekernel' trumps 'modules'; the kvm modules will not"
ewarn "be built. You must ensure you have a compatible kernel"
ewarn "with the kvm modules on your own"
elif use havekernel ; then
ewarn "You have the 'havekernel' use flag set. This means you"
ewarn "must ensure you have a compatible kernel on your own."
elif use modules ; then
if ! linux_chkconfig_present KVM; then
eerror "KVM now needs CONFIG_KVM built into your kernel, even"
eerror "if you're using the external modules from this package."
eerror "Please enable KVM support in your kernel, found at:"
eerror
eerror " Virtualization"
eerror " Kernel-based Virtual Machine (KVM) support"
eerror
die "KVM support not detected!"
fi
BUILD_TARGETS="all"
MODULE_NAMES="kvm(kvm:${S}/kernel:${S}/kernel/x86)"
MODULE_NAMES="${MODULE_NAMES} kvm-intel(kvm:${S}/kernel:${S}/kernel/x86)"
MODULE_NAMES="${MODULE_NAMES} kvm-amd(kvm:${S}/kernel:${S}/kernel/x86)"
linux-mod_pkg_setup
elif kernel_is lt 2 6 25; then
eerror "This version of KVM requres a host kernel of 2.6.25 or higher."
eerror "Either upgrade your kernel, or enable the 'modules' USE flag."
die "kvm version not compatible"
elif ! linux_chkconfig_present KVM; then
eerror "Please enable KVM support in your kernel, found at:"
eerror
eerror " Virtualization"
eerror " Kernel-based Virtual Machine (KVM) support"
eerror
eerror "or enable the 'modules' USE flag."
die "KVM support not detected!"
fi
if use sdl && ! built_with_use media-libs/libsdl X ; then
die "You need to rebuild media-libs/libsdl with the X use flag"
fi
enewgroup kvm
}
src_unpack() {
unpack ${A}
cd "${S}"
# prevent docs to get automatically installed
sed -i '/$(DESTDIR)$(docdir)/d' qemu/Makefile
# Alter target makefiles to accept CFLAGS set via flag-o
sed -i 's/^\(C\|OP_C\|HELPER_C\)FLAGS=/\1FLAGS+=/' \
qemu/Makefile qemu/Makefile.target
[[ -x /sbin/paxctl ]] && \
sed -i 's/^VL_LDFLAGS=$/VL_LDFLAGS=-Wl,-z,execheap/' \
qemu/Makefile.target
# avoid strip
sed -i 's/$(INSTALL) -m 755 -s/$(INSTALL) -m 755/' qemu/Makefile
# apply patchset
EPATCH_SOURCE="${WORKDIR}/${PATCHSET}"
EPATCH_SUFFIX="patch"
epatch
}
src_compile() {
local mycc conf_opts audio_opts
audio_opts="oss"
use gnutls || conf_opts="$conf_opts --disable-vnc-tls"
use ncurses || conf_opts="$conf_opts --disable-curses"
use sdl || conf_opts="$conf_opts --disable-gfx-check --disable-sdl"
use vde || conf_opts="$conf_opts --disable-vde"
use alsa && audio_opts="alsa $audio_opts"
use esd && audio_opts="esd $audio_opts"
use pulseaudio && audio_opts="pa $audio_opts"
use sdl && audio_opts="sdl $audio_opts"
use modules && conf_opts="$conf_opts --kerneldir=$KV_DIR"
conf_opts="$conf_opts --prefix=/usr"
#conf_opts="$conf_opts --audio-drv-list=\"$audio_opts\""
./configure ${conf_opts} --audio-drv-list="$audio_opts" || die "econf failed"
emake libkvm || die "emake libkvm failed"
if use test; then
emake user || die "emake user failed"
fi
mycc=$(cat qemu/config-host.mak | egrep "^CC=" | cut -d "=" -f 2)
filter-flags -fpie -fstack-protector
# If using gentoo's compiler set the SPEC to non-hardened
if [ ! -z ${GCC_SPECS} -a -f ${GCC_SPECS} ]; then
local myccver=$(${mycc} -dumpversion)
local gccver=$($(tc-getBUILD_CC) -dumpversion)
#Is this a SPEC for the right compiler version?
myspec="${GCC_SPECS/${gccver}/${myccver}}"
if [ "${myspec}" == "${GCC_SPECS}" ]; then
shopt -s extglob
GCC_SPECS="${GCC_SPECS/%hardened*specs/vanilla.specs}"
shopt -u extglob
else
unset GCC_SPECS
fi
fi
# if use bios; then
# emake bios || die "emake bios failed"
# emake vgabios || die "emake vgabios failed"
# fi
emake qemu || die "emake qemu failed"
if use modules && ! use havekernel ; then
linux-mod_src_compile
fi
}
src_install() {
# kcmd so we don't install kernel modules which weren't build
emake DESTDIR="${D}" kcmd='#' install || die "make install failed"
exeinto /usr/bin/
doexe "${S}/kvm_stat"
mv "${D}"/usr/share/man/man1/qemu.1 "${D}"/usr/share/man/man1/kvm.1
mv "${D}"/usr/share/man/man1/qemu-img.1 "${D}"/usr/share/man/man1/kvm-img.1
mv "${D}"/usr/share/man/man8/qemu-nbd.8 "${D}"/usr/share/man/man8/kvm-nbd.8
mv "${D}"/usr/bin/qemu-img "${D}"/usr/bin/kvm-img
mv "${D}"/usr/bin/qemu-nbd "${D}"/usr/bin/kvm-nbd
insinto /etc/udev/rules.d/
doins scripts/65-kvm.rules
insinto /etc/kvm/
insopts -m0755
newins scripts/qemu-ifup kvm-ifup
newins scripts/qemu-ifdown kvm-ifdown
dodoc qemu/pc-bios/README
newdoc qemu/qemu-doc.html kvm-doc.html
newdoc qemu/qemu-tech.html kvm-tech.html
if use modules && ! use havekernel ; then
linux-mod_src_install
fi
}
pkg_postinst() {
elog "If you don't have kvm compiled into the kernel, make sure you have"
elog "the kernel module loaded before running kvm. The easiest way to"
elog "ensure that the kernel module is loaded is to load it on boot."
elog "For AMD CPUs the module is called 'kvm-amd'"
elog "For Intel CPUs the module is called 'kvm-intel'"
elog "Please review /etc/conf.d/modules for how to load these"
elog
elog "Make sure your user is in the 'kvm' group"
elog "Just run 'gpasswd -a <USER> kvm', then have <USER> re-login."
elog
elog "You will need the Universal TUN/TAP driver compiled into your"
elog "kernel or loaded as a module to use the virtual network device"
elog "if using -net tap. You will also need support for 802.1d"
elog "Ethernet Bridging and a configured bridge if using the provided"
elog "kvm-ifup script from /etc/kvm."
echo
}

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<herd>none</herd>
<maintainer>
<email>dang@gentoo.org</email>
<name>Daniel Gryniewicz</name>
</maintainer>
<maintainer>
<email>cardoe@gentoo.org</email>
<name>Doug Goldstein</name>
</maintainer>
<longdescription lang="en">
KVM (for Kernel-based Virtual Machine) is a full virtualization solution
for Linux on x86 hardware containing virtualization extensions (Intel VT
or AMD-V)
</longdescription>
<use>
<flag name='alsa'>Enable alsa output for sound emulation</flag>
<flag name='esd'>Enable esound output for sound emulation</flag>
<flag name='gnutls'>Enable TLS support for the VNC console server</flag>
<flag name='havekernel'>Don't require a kernel build tree (useful if
using a binary distrbuted kernel aka binary packages)</flag>
<flag name='modules'>Build the kernel modules from the kvm package</flag>
<flag name='ncurses'>Enable the ncurses-based console</flag>
<flag name='pulseaudio'>Enable pulseaudio output for sound emulation</flag>
<flag name='sdl'>Enable the SDL-based console</flag>
<flag name='test'>Build tests</flag>
<flag name='vde'>Enable VDE-based networking</flag>
</use>
</pkgmetadata>

View File

@ -0,0 +1,263 @@
# ChangeLog for app-emulation/qemu-softmmu
# Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2
# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu-softmmu/ChangeLog,v 1.55 2008/07/28 19:11:06 cardoe Exp $
28 Jul 2008; Doug Goldstein <cardoe@gentoo.org> metadata.xml:
add GLEP 56 USE flag desc from use.local.desc
14 May 2008; Markus Meier <maekke@gentoo.org>
qemu-softmmu-0.9.1-r3.ebuild:
amd64 stable, bug #221943
14 May 2008; Luca Barbato <lu_zero@gentoo.org>
qemu-softmmu-0.9.1-r3.ebuild:
Marked ppc
14 May 2008; Christian Faulhammer <opfer@gentoo.org>
qemu-softmmu-0.9.1-r3.ebuild:
stable x86, security bug 212351
*qemu-softmmu-0.9.1-r3 (14 May 2008)
14 May 2008; Luca Barbato <lu_zero@gentoo.org>
+files/qemu-softmmu-0.9.1-CVE-2008-2004.patch,
+qemu-softmmu-0.9.1-r3.ebuild:
Address CVE-2008-2004, fix bug #221943, thanks to Celso Fernandes
(icezimm) <celso.fernandes@gmail.com>
*qemu-softmmu-0.9.1-r2 (12 May 2008)
12 May 2008; Peter Volkov <pva@gentoo.org>
+files/qemu-softmmu-0.9.1-CVE-2008-0928.patch,
+qemu-softmmu-0.9.1-r2.ebuild:
Updated patch for security bug #212351 to avoid qcow2 image regression.
Filtering CFLAGS to allow building with gcc-3.4.
20 Apr 2008; Luca Barbato <lu_zero@gentoo.org>
qemu-softmmu-0.9.1-r1.ebuild:
Move the gcc check in src_unpack
09 Mar 2008; Luca Barbato <lu_zero@gentoo.org>
qemu-softmmu-0.9.1-r1.ebuild:
Marked ppc
*qemu-softmmu-0.9.1-r1 (05 Mar 2008)
05 Mar 2008; Luca Barbato <lu_zero@gentoo.org>
+files/qemu-softmmu-0.9.1-block-device-address-range.patch,
+qemu-softmmu-0.9.1-r1.ebuild:
Fix CVE-2008-0928, patch from the red hat bugzilla
01 Feb 2008; Luca Barbato <lu_zero@gentoo.org>
-files/qemu-0.8.0-gcc4-hacks.patch, -files/qemu-0.8.0-gcc4-opts.patch,
-files/qemu-0.8.2-linux-headers.patch, -files/qemu-0.8.2-sparc-fp.patch,
-qemu-softmmu-0.8.0.ebuild, -qemu-softmmu-0.8.0.20060329.ebuild,
-qemu-softmmu-0.8.1.ebuild, -qemu-softmmu-0.8.1-r1.ebuild,
-qemu-softmmu-0.8.2.ebuild, -qemu-softmmu-0.8.2-r1.ebuild:
Remove qemu-0.8 series
*qemu-softmmu-0.9.1 (25 Jan 2008)
25 Jan 2008; Luca Barbato <lu_zero@gentoo.org> +qemu-softmmu-0.9.1.ebuild:
New version, improved ebuild by Carlo Marcelo Arenas Belon
<carenas@sajinet.com.pe>, bugs #204675
13 Nov 2007; Luca Barbato <lu_zero@gentoo.org>
qemu-softmmu-0.9.0-r1.ebuild:
Mark the revision stable
*qemu-softmmu-0.9.0-r1 (12 Nov 2007)
12 Nov 2007; Luca Barbato <lu_zero@gentoo.org>
+files/qemu-softmmu-0.9.0-block-qcow2.patch,
+qemu-softmmu-0.9.0-r1.ebuild:
address qcow2 corruption, thanks to Chris Williams <gentoo@psychogeeks.com>
for the patch, see bug #187075
09 Sep 2007; Luca Barbato <lu_zero@gentoo.org>
+files/qemu-softmmu-0.9.0-ide-cd.patch, qemu-softmmu-0.9.0.ebuild:
Address a glitch in the ide/cdrom emulation, thanks to Carlo Marcelo Arenas
Belon <carenas@sajinet.com.pe> for pointing the patch and reporting the
issue
02 Jul 2007; Piotr Jaroszyński <peper@gentoo.org>
qemu-softmmu-0.8.0.ebuild, qemu-softmmu-0.8.0.20060329.ebuild,
qemu-softmmu-0.8.1.ebuild, qemu-softmmu-0.8.1-r1.ebuild,
qemu-softmmu-0.8.2.ebuild, qemu-softmmu-0.8.2-r1.ebuild,
qemu-softmmu-0.9.0.ebuild:
(QA) RESTRICT clean up.
20 May 2007; Christian Faulhammer <opfer@gentoo.org>
qemu-softmmu-0.9.0.ebuild:
stable amd64, security bug 176674
16 May 2007; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.9.0.ebuild:
Marked ppc
08 May 2007; Markus Ullmann <jokey@gentoo.org> qemu-softmmu-0.9.0.ebuild:
Stable on x86 wrt security bug #176674
21 Feb 2007; Piotr Jaroszyński <peper@gentoo.org> ChangeLog:
Transition to Manifest2.
10 Feb 2007; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.9.0.ebuild:
Fix bug #164491
10 Feb 2007; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.9.0.ebuild:
Minor update
*qemu-softmmu-0.9.0 (07 Feb 2007)
07 Feb 2007; Luca Barbato <lu_zero@gentoo.org> +qemu-softmmu-0.9.0.ebuild:
New version
06 Feb 2007; Simon Stelling <blubb@gentoo.org>
qemu-softmmu-0.8.2-r1.ebuild:
stable on amd64; bug 159522
02 Jan 2007; Christian Faulhammer <opfer@gentoo.org>
qemu-softmmu-0.8.2-r1.ebuild:
stable x86, bug #159522
31 Dec 2006; Mike Frysinger <vapier@gentoo.org>
+files/qemu-0.8.2-linux-headers.patch, qemu-softmmu-0.8.2-r1.ebuild:
Fix building with sanitized headers.
31 Dec 2006; Luca Barbato <lu_zero@gentoo.org>
qemu-softmmu-0.8.2-r1.ebuild:
Marked ppc
22 Nov 2006; Kevin F. Quinn <kevquinn@gentoo.org>
qemu-softmmu-0.8.2-r1.ebuild:
Add QA variables indicating which files contain textrels, require
execstack, and contain WX PT_LOAD segments. The TEXTRELs are a feature of how
qemu works. The execstack/wx_load markings are for a foreign binary.
18 Aug 2006; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.8.2.ebuild:
remove stray dep
17 Aug 2006; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.8.2.ebuild,
qemu-softmmu-0.8.2-r1.ebuild:
Remove stray bits from the older ebuild
*qemu-softmmu-0.8.2-r1 (17 Aug 2006)
17 Aug 2006; Luca Barbato <lu_zero@gentoo.org>
qemu-softmmu-0.8.2-r1.ebuild, files/digest-qemu-softmmu-0.8.2-r1:
Added alsa support as requested in bug #116599 by Ivan Yosifov <ivan@yosifov.net>
and adlib support as requested by Jan Simons <gentoo@onkos.de> on the same bug;
use tc-getCC, patch from Damien THEBAULT <damien.thebault@laposte.net> in
bug #132602, set correct kqemu deps, should solve bug #141721
01 Aug 2006; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.8.2.ebuild:
False hope, gcc-3 is still required.
*qemu-softmmu-0.8.2 (01 Aug 2006)
01 Aug 2006; Luca Barbato <lu_zero@gentoo.org>
+files/qemu-0.8.2-sparc-fp.patch, +qemu-softmmu-0.8.2.ebuild:
New version, should work better with gcc-4
*qemu-softmmu-0.8.1-r1 (12 Jul 2006)
12 Jul 2006; Luca Barbato <lu_zero@gentoo.org>
+files/qemu-0.8.0-gcc4-hacks.patch, +files/qemu-0.8.0-gcc4-opts.patch,
+qemu-softmmu-0.8.1-r1.ebuild:
Updated revision, with alsa and partial gcc4 support on x86 (phreak and
genstef found the patches)
09 Jun 2006; Michael Sterrett <mr_bones_@gentoo.org>
-files/qemu-softmmu-0.7.0-errno.patch, -files/kqemu-0.7.1-sysfs.patch,
-files/kqemu-sysfs.patch, -qemu-softmmu-0.7.0-r1.ebuild,
-qemu-softmmu-0.7.1.ebuild, -qemu-softmmu-0.7.1-r1.ebuild,
-qemu-softmmu-0.7.2.ebuild:
clean out old files
*qemu-softmmu-0.8.1 (06 May 2006)
06 May 2006; Luca Barbato <lu_zero@gentoo.org> +qemu-softmmu-0.8.1.ebuild:
New version
28 Apr 2006; Luca Barbato <lu_zero@gentoo.org>
qemu-softmmu-0.8.0.20060329.ebuild:
Stray epatch removed
27 Apr 2006; Marien Zwart <marienz@gentoo.org>
files/digest-qemu-softmmu-0.7.0-r1, files/digest-qemu-softmmu-0.7.1,
files/digest-qemu-softmmu-0.7.1-r1, files/digest-qemu-softmmu-0.7.2,
files/digest-qemu-softmmu-0.8.0, files/digest-qemu-softmmu-0.8.0.20060329,
Manifest:
Fixing SHA256 digest for real, pass three...
27 Apr 2006; Marien Zwart <marienz@gentoo.org>
files/digest-qemu-softmmu-0.7.0-r1, files/digest-qemu-softmmu-0.7.1,
files/digest-qemu-softmmu-0.7.1-r1, files/digest-qemu-softmmu-0.7.2,
files/digest-qemu-softmmu-0.8.0, files/digest-qemu-softmmu-0.8.0.20060329,
Manifest:
Fixing SHA256 digest, pass two.
19 Apr 2006; Daniel Gryniewicz <dang@gentoo.org> ChangeLog:
Marked stable on amd64 per bug# 123972
16 Apr 2006; Michael Hanselmann <hansmi@gentoo.org>
qemu-softmmu-0.8.0.ebuild:
Stable on ppc.
01 Apr 2006; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.8.0.ebuild:
Restricted test feature
29 Mar 2006; Chris White <chriswhite@gentoo.org>
qemu-softmmu-0.8.0.ebuild:
x86 stable for qemu-softmmu-0.8.0 bug #123972.
08 Jan 2006; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.8.0.ebuild:
Disable gcc checks, thanks to Robert Führicht <the_master_of_disaster@gmx.at>
*qemu-softmmu-0.8.0 (23 Dec 2005)
23 Dec 2005; Luca Barbato <lu_zero@gentoo.org> +qemu-softmmu-0.8.0.ebuild:
New version
01 Dec 2005; <dang@gentoo.org> qemu-softmmu-0.7.0-r1.ebuild,
qemu-softmmu-0.7.1.ebuild, qemu-softmmu-0.7.1-r1.ebuild,
qemu-softmmu-0.7.2.ebuild:
Mark 0.7.2 stable, with workign kqemu. Remove amd64 from older, nonworking
versions
*qemu-softmmu-0.7.2 (11 Sep 2005)
11 Sep 2005; Luca Barbato <lu_zero@gentoo.org> +qemu-softmmu-0.7.2.ebuild:
New release
19 Aug 2005; Aron Griffis <agriffis@gentoo.org>
qemu-softmmu-0.7.1-r1.ebuild:
Minor ebuild fixups, particularly move MODULE_NAMES setting into pkg_setup.
The kqemu-sysfs patch is not compatible with 2.6.13-rc1+ because the new
interfaces are GPL-only, so refrain from applying the patch on those
versions; http://lkml.org/lkml/2005/7/4/5
*qemu-softmmu-0.7.1-r1 (06 Aug 2005)
06 Aug 2005; Luca Barbato <lu_zero@gentoo.org>
+qemu-softmmu-0.7.1-r1.ebuild:
Fix bug #101524
26 Jul 2005; Luca Barbato <lu_zero@gentoo.org>
+files/kqemu-0.7.1-sysfs.patch, qemu-softmmu-0.7.1.ebuild:
updated the sysfs patch, thanks to Philippe Weibel <philippe.weibel@free.fr>
26 Jul 2005; Luca Barbato <lu_zero@gentoo.org> qemu-softmmu-0.7.1.ebuild:
Fixes and workarounds for the latest kernels.
*qemu-softmmu-0.7.1 (25 Jul 2005)
25 Jul 2005; Luca Barbato <lu_zero@gentoo.org> +qemu-softmmu-0.7.1.ebuild:
New version
*qemu-softmmu-0.7.0-r1 (18 Jun 2005)
18 Jun 2005; Luca Barbato <lu_zero@gentoo.org>
+files/qemu-softmmu-0.7.0-errno.patch, +files/kqemu-sysfs.patch,
+metadata.xml, +qemu-softmmu-0.7.0-r1.ebuild:
qemu split ebuild, system emulators

View File

@ -0,0 +1,8 @@
AUX hotfix.patch 2316 RMD160 c969ffd31a69f3e4394dd97e186943e2081a408c SHA1 3f3c98935deefa1ede830f3fc6caf0295462a37d SHA256 620b04fcbc4ca288e965183f7156c237ed978bd92edb3eec7133fb49e55d7c3f
AUX qemu-0.9.1-gcc4.patch 12472 RMD160 18c9cd2fe148d8aa53cf97118ad5f204f52b5362 SHA1 8cff8dec4b06edafeac8659df657f480fb04feea SHA256 65cd8a53c8c1242e0fcccc02748bc8730f62f1b2b1fec4646ff26d524f852332
AUX qemu-softmmu-0.9.1-CVE-2008-0928.patch 9346 RMD160 79e4dbf7643d7057da4a74350833c907342fba1e SHA1 2ec9c89e6a995db97aa03cdab490fc0e5cef650c SHA256 ca040bdb401e6cdfe4f009e6874d25853103965370b19756724127b0fd4df559
AUX qemu-softmmu-0.9.1-CVE-2008-2004.patch 2002 RMD160 88f121766426b1b564d829bf6287aa0b99733ca7 SHA1 208701bd008b119f80553ff4dc441de87ddc98aa SHA256 15918d0e46a23d9b7283088489ce08be41a6ec9ced5df0f55ce1f8bcaa50fac3
DIST qemu-0.9.1.tar.gz 2804104 RMD160 ee7bdb55a4540df2082d4bde9ebfd2f4e6f201a5 SHA1 630ea20b5989f0df00128de7f7be661c573ed041 SHA256 4756d0b4a4dc7dd88354bc6b37d381e4462dd328d0feef94803e90c0455835a5
EBUILD qemu-softmmu-0.9.1-r3.ebuild 3271 RMD160 c6f1821d2b661fb3f3146c44c16af05d21fba87a SHA1 dcfbcf62e7f1da096549b8568b1dc32929386bc6 SHA256 e18eccfb3514acb1e09a9a8bba97ac755d5aeaa6974e0646e46fb0f8679d35e4
MISC ChangeLog 9553 RMD160 8f8bd1c79ea13d18d2dff387cab19611114b9386 SHA1 c4648c024c2507421e212e7d4d66b723bbbbd80a SHA256 f0a6e4970b1f13ec5f2cb7f449beb0b388698e6bcfac305e1bb1ed51c52df223
MISC metadata.xml 317 RMD160 ec5f64543d9db447cef26e8c71489ec7c732385c SHA1 f159811a9bba96ae163582b6d2aea10fc238f32b SHA256 46819898b75a387dea3828f35205aa0caab4a9b6fe7b44fea8f7b694e9fcbafd

View File

@ -0,0 +1,38 @@
# --- T2-COPYRIGHT-NOTE-BEGIN ---
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
#
# T2 SDE: package/.../qemu/hotfix.patch
# Copyright (C) 2008 The T2 SDE Project
#
# More information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
# --- T2-COPYRIGHT-NOTE-END ---
Currently not compiling architectures to due our gcc4 patchery relating to:
dyngen: Unable to replace ret with jmp in op_cmp_str_T0_T1
- Rene Rebe <rene@exactcode.de>
--- qemu-0.9.1/configure.vanilla 2008-01-22 13:56:47.000000000 +0100
+++ qemu-0.9.1/configure 2008-01-22 13:56:56.000000000 +0100
@@ -522,11 +522,11 @@
if test -z "$target_list" ; then
# these targets are portable
if [ "$softmmu" = "yes" ] ; then
- target_list="i386-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc-softmmu ppcemb-softmmu ppc64-softmmu m68k-softmmu sh4-softmmu sh4eb-softmmu cris-softmmu"
+ target_list="i386-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu cris-softmmu"
fi
# the following are Linux specific
if [ "$linux_user" = "yes" ] ; then
- target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user sparc64-linux-user sparc32plus-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user sh4-linux-user sh4eb-linux-user ppc-linux-user ppc64-linux-user ppc64abi32-linux-user x86_64-linux-user cris-linux-user $target_list"
+ target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user sparc64-linux-user sparc32plus-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user sh4-linux-user sh4eb-linux-user ppc-linux-user ppc64-linux-user ppc64abi32-linux-user x86_64-linux-user cris-linux-user $target_list"
fi
# the following are Darwin specific
if [ "$darwin_user" = "yes" ] ; then

View File

@ -0,0 +1,348 @@
diff -Naur qemu-0.9.1.orig/configure qemu-0.9.1/configure
--- qemu-0.9.1.orig/configure 2008-01-06 20:38:42.000000000 +0100
+++ qemu-0.9.1/configure 2008-02-06 10:19:59.000000000 +0100
@@ -790,6 +790,12 @@
if test "$cpu" = "i386" ; then
echo "ARCH=i386" >> $config_mak
echo "#define HOST_I386 1" >> $config_h
+
+ # add check for gcc4 breakage
+ echo "#if (__GNUC__ > 3)" >> $config_h
+ echo "#define GCC_BREAKS_T_REGISTER" >> $config_h
+ echo "#endif" >> $config_h
+
elif test "$cpu" = "x86_64" ; then
echo "ARCH=x86_64" >> $config_mak
echo "#define HOST_X86_64 1" >> $config_h
diff -Naur qemu-0.9.1.orig/dyngen.c qemu-0.9.1/dyngen.c
--- qemu-0.9.1.orig/dyngen.c 2008-01-06 20:38:42.000000000 +0100
+++ qemu-0.9.1/dyngen.c 2008-02-06 10:31:41.000000000 +0100
@@ -1488,6 +1488,16 @@
if (get32((uint32_t *)p) != 0x4e800020)
error("blr expected at the end of %s", name);
copy_size = p - p_start;
+
+/* blr check for inline returns */
+
+ if(strstart(name, "op_", NULL) && !strstart(name, "op_exit", NULL)) {
+ for(p=p_start; p < p_end - 4; p+=4) {
+ if ((get32((uint32_t *)p) & 0xfc00fff0) == 0x4c000020) {
+ error("Inline blr detected in %s. Please append FORCE_RET to the function.", name);
+ }
+ }
+ }
}
#elif defined(HOST_S390)
{
@@ -1931,6 +1941,17 @@
type = ELF32_R_TYPE(rel->r_info);
addend = rel->r_addend;
reloc_offset = rel->r_offset - start_offset;
+ if (strstart(sym_name, "__op_jmp", &p)) {
+ int n;
+ n = strtol(p, NULL, 10);
+ /* __op_jmp relocations are done at
+ runtime to do translated block
+ chaining: the offset of the instruction
+ needs to be stored */
+ fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
+ n, reloc_offset);
+ continue;
+ }
switch(type) {
case R_X86_64_32:
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
diff -Naur qemu-0.9.1.orig/exec-all.h qemu-0.9.1/exec-all.h
--- qemu-0.9.1.orig/exec-all.h 2008-01-06 20:38:42.000000000 +0100
+++ qemu-0.9.1/exec-all.h 2008-02-06 10:31:41.000000000 +0100
@@ -142,6 +142,9 @@
#if defined(__i386__) && !defined(_WIN32)
#define USE_DIRECT_JUMP
#endif
+#if defined(__x86_64__)
+#define USE_DIRECT_JUMP
+#endif
typedef struct TranslationBlock {
target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */
@@ -228,7 +231,7 @@
asm volatile ("sync" : : : "memory");
asm volatile ("isync" : : : "memory");
}
-#elif defined(__i386__)
+#elif defined(__i386__) || defined(__x86_64__)
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
{
/* patch the branch destination */
@@ -320,6 +323,18 @@
"1:\n");\
} while (0)
+#elif defined(__x86_64__) && defined(USE_DIRECT_JUMP)
+
+#define GOTO_TB(opname, tbparam, n)\
+do {\
+ asm volatile (ASM_DATA_SECTION\
+ ASM_OP_LABEL_NAME(n, opname) ":\n"\
+ ".quad 1f\n"\
+ ASM_PREVIOUS_SECTION \
+ "jmp " ASM_NAME(__op_jmp) #n "\n"\
+ "1:\n");\
+} while (0)
+
#else
/* jump to next block operations (more portable code, does not need
diff -Naur qemu-0.9.1.orig/softmmu_header.h qemu-0.9.1/softmmu_header.h
--- qemu-0.9.1.orig/softmmu_header.h 2008-01-06 20:38:42.000000000 +0100
+++ qemu-0.9.1/softmmu_header.h 2008-02-06 10:19:59.000000000 +0100
@@ -189,9 +189,15 @@
#else
#error unsupported size
#endif
+#ifdef GCC_BREAKS_T_REGISTER
+ "pushl %%ecx\n"
+#endif
"pushl %6\n"
"call %7\n"
"popl %%eax\n"
+#ifdef GCC_BREAKS_T_REGISTER
+ "popl %%ecx\n"
+#endif
"jmp 2f\n"
"1:\n"
"addl 8(%%edx), %%eax\n"
@@ -209,14 +215,22 @@
: "r" (ptr),
/* NOTE: 'q' would be needed as constraint, but we could not use it
with T1 ! */
+#if (DATA_SIZE == 1 || DATA_SIZE == 2) && defined(GCC_BREAKS_T_REGISTER)
+ "q" (v),
+#else
"r" (v),
+#endif
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
"i" (CPU_MMU_INDEX),
"m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
+#ifdef GCC_BREAKS_T_REGISTER
+ : "%eax", "%edx", "memory", "cc");
+#else
: "%eax", "%ecx", "%edx", "memory", "cc");
+#endif
}
#else
diff -Naur qemu-0.9.1.orig/target-alpha/cpu.h qemu-0.9.1/target-alpha/cpu.h
--- qemu-0.9.1.orig/target-alpha/cpu.h 2008-01-06 20:38:44.000000000 +0100
+++ qemu-0.9.1/target-alpha/cpu.h 2008-02-06 10:19:59.000000000 +0100
@@ -275,6 +275,8 @@
* used to emulate 64 bits target on 32 bits hosts
*/
target_ulong t0, t1, t2;
+#elif defined(GCC_BREAKS_T_REGISTER)
+ target_ulong t2;
#endif
/* */
double ft0, ft1, ft2;
diff -Naur qemu-0.9.1.orig/target-alpha/exec.h qemu-0.9.1/target-alpha/exec.h
--- qemu-0.9.1.orig/target-alpha/exec.h 2008-01-06 20:38:44.000000000 +0100
+++ qemu-0.9.1/target-alpha/exec.h 2008-02-06 10:19:59.000000000 +0100
@@ -36,6 +36,12 @@
#define T1 (env->t1)
#define T2 (env->t2)
+#elif defined(GCC_BREAKS_T_REGISTER)
+
+register uint64_t T0 asm(AREG1);
+register uint64_t T1 asm(AREG2);
+#define T2 (env->t2)
+
#else
register uint64_t T0 asm(AREG1);
diff -Naur qemu-0.9.1.orig/target-alpha/op_template.h qemu-0.9.1/target-alpha/op_template.h
--- qemu-0.9.1.orig/target-alpha/op_template.h 2008-01-06 20:38:44.000000000 +0100
+++ qemu-0.9.1/target-alpha/op_template.h 2008-02-06 10:31:23.000000000 +0100
@@ -29,7 +29,26 @@
#if !defined(HOST_SPARC) && !defined(HOST_SPARC64)
void OPPROTO glue(op_reset_FT, REG) (void)
{
+#ifdef HOST_PPC
+ /* We have a problem with HOST_PPC here:
+ We want this code:
+ glue(FT, REG) = 0;
+ unfortunately GCC4 notices that this stores (double)0.0 into
+ env->ft0 and emits that constant into the .rodata, and instructions
+ to load that zero from there. But that construct can't be parsed by dyngen.
+ We could add -ffast-math for compiling op.c, that would just make it generate
+ two stores of zeros into both words of ft0. But -ffast-math may have other
+ side-effects regarding the emulation. We could use __builtin_memset,
+ which perhaps would be the sanest. That relies on -O2 and our other options
+ to inline that memset, which currently it does, but who knows for how long.
+ So, we simply do that by hand, and a barely typesafe way :-/ */
+ union baeh { double d; unsigned int i[2];};
+ union baeh *p = (union baeh*)&(glue(FT, REG));
+ p->i[0] = 0;
+ p->i[1] = 0;
+#else
glue(FT, REG) = 0;
+#endif
RETURN();
}
#else
diff -Naur qemu-0.9.1.orig/target-arm/cpu.h qemu-0.9.1/target-arm/cpu.h
--- qemu-0.9.1.orig/target-arm/cpu.h 2008-01-06 20:38:44.000000000 +0100
+++ qemu-0.9.1/target-arm/cpu.h 2008-02-06 10:19:59.000000000 +0100
@@ -66,6 +66,9 @@
*/
typedef struct CPUARMState {
+#if defined(GCC_BREAKS_T_REGISTER)
+ uint32_t t2;
+#endif
/* Regs for current mode. */
uint32_t regs[16];
/* Frequently accessed CPSR bits are stored separately for efficiently.
diff -Naur qemu-0.9.1.orig/target-arm/exec.h qemu-0.9.1/target-arm/exec.h
--- qemu-0.9.1.orig/target-arm/exec.h 2008-01-06 20:38:44.000000000 +0100
+++ qemu-0.9.1/target-arm/exec.h 2008-02-06 10:19:59.000000000 +0100
@@ -23,7 +23,12 @@
register struct CPUARMState *env asm(AREG0);
register uint32_t T0 asm(AREG1);
register uint32_t T1 asm(AREG2);
+#if defined(GCC_BREAKS_T_REGISTER)
+#define T2 (env->t2)
+#else
register uint32_t T2 asm(AREG3);
+#endif
+
/* TODO: Put these in FP regs on targets that have such things. */
/* It is ok for FT0s and FT0d to overlap. Likewise FT1s and FT1d. */
diff -Naur qemu-0.9.1.orig/target-i386/cpu.h qemu-0.9.1/target-i386/cpu.h
--- qemu-0.9.1.orig/target-i386/cpu.h 2008-01-06 20:38:45.000000000 +0100
+++ qemu-0.9.1/target-i386/cpu.h 2008-02-06 10:19:59.000000000 +0100
@@ -470,6 +470,8 @@
#if TARGET_LONG_BITS > HOST_LONG_BITS
/* temporaries if we cannot store them in host registers */
target_ulong t0, t1, t2;
+#elif defined(GCC_BREAKS_T_REGISTER)
+ target_ulong t1;
#endif
/* standard registers */
diff -Naur qemu-0.9.1.orig/target-i386/exec.h qemu-0.9.1/target-i386/exec.h
--- qemu-0.9.1.orig/target-i386/exec.h 2008-01-06 20:38:45.000000000 +0100
+++ qemu-0.9.1/target-i386/exec.h 2008-02-06 10:19:59.000000000 +0100
@@ -39,6 +39,12 @@
#define T1 (env->t1)
#define T2 (env->t2)
+#elif defined(GCC_BREAKS_T_REGISTER)
+
+register target_ulong T0 asm(AREG1);
+#define T1 (env->t1)
+register target_ulong T2 asm(AREG3);
+
#else
/* XXX: use unsigned long instead of target_ulong - better code will
diff -Naur qemu-0.9.1.orig/target-i386/op.c qemu-0.9.1/target-i386/op.c
--- qemu-0.9.1.orig/target-i386/op.c 2008-01-06 20:38:45.000000000 +0100
+++ qemu-0.9.1/target-i386/op.c 2008-02-06 10:31:17.000000000 +0100
@@ -290,6 +290,7 @@
EDX = (uint32_t)(res >> 32);
CC_DST = res;
CC_SRC = (res != (int32_t)res);
+ FORCE_RET();
}
void OPPROTO op_imulw_T0_T1(void)
@@ -299,6 +300,7 @@
T0 = res;
CC_DST = res;
CC_SRC = (res != (int16_t)res);
+ FORCE_RET();
}
void OPPROTO op_imull_T0_T1(void)
@@ -308,6 +310,7 @@
T0 = res;
CC_DST = res;
CC_SRC = (res != (int32_t)res);
+ FORCE_RET();
}
#ifdef TARGET_X86_64
diff -Naur qemu-0.9.1.orig/target-i386/ops_template.h qemu-0.9.1/target-i386/ops_template.h
--- qemu-0.9.1.orig/target-i386/ops_template.h 2008-01-06 20:38:45.000000000 +0100
+++ qemu-0.9.1/target-i386/ops_template.h 2008-02-06 10:31:17.000000000 +0100
@@ -467,6 +467,7 @@
int count;
count = T1 & SHIFT_MASK;
CC_SRC = T0 >> count;
+ FORCE_RET();
}
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
diff -Naur qemu-0.9.1.orig/target-mips/cpu.h qemu-0.9.1/target-mips/cpu.h
--- qemu-0.9.1.orig/target-mips/cpu.h 2008-01-06 20:38:45.000000000 +0100
+++ qemu-0.9.1/target-mips/cpu.h 2008-02-06 10:19:59.000000000 +0100
@@ -149,6 +149,8 @@
target_ulong t0;
target_ulong t1;
target_ulong t2;
+#elif defined(GCC_BREAKS_T_REGISTER)
+ target_ulong t2;
#endif
target_ulong HI[MIPS_DSP_ACC][MIPS_TC_MAX];
target_ulong LO[MIPS_DSP_ACC][MIPS_TC_MAX];
diff -Naur qemu-0.9.1.orig/target-mips/exec.h qemu-0.9.1/target-mips/exec.h
--- qemu-0.9.1.orig/target-mips/exec.h 2008-01-06 20:38:45.000000000 +0100
+++ qemu-0.9.1/target-mips/exec.h 2008-02-06 10:19:59.000000000 +0100
@@ -14,6 +14,10 @@
#define T0 (env->t0)
#define T1 (env->t1)
#define T2 (env->t2)
+#elif defined(GCC_BREAKS_T_REGISTER)
+register target_ulong T0 asm(AREG1);
+register target_ulong T1 asm(AREG2);
+#define T2 (env->t2)
#else
register target_ulong T0 asm(AREG1);
register target_ulong T1 asm(AREG2);
diff -Naur qemu-0.9.1.orig/target-ppc/exec.h qemu-0.9.1/target-ppc/exec.h
--- qemu-0.9.1.orig/target-ppc/exec.h 2008-01-06 20:38:45.000000000 +0100
+++ qemu-0.9.1/target-ppc/exec.h 2008-02-06 10:29:35.000000000 +0100
@@ -38,6 +38,10 @@
#define T1 (env->t1)
#define T2 (env->t2)
#define TDX "%016" PRIx64
+#elif defined(GCC_BREAKS_T_REGISTER)
+register unsigned long T0 asm(AREG1);
+register unsigned long T1 asm(AREG2);
+#define T2 (env->t2)
#else
register unsigned long T0 asm(AREG1);
register unsigned long T1 asm(AREG2);
diff -Naur qemu-0.9.1.orig/target-sparc/exec.h qemu-0.9.1/target-sparc/exec.h
--- qemu-0.9.1.orig/target-sparc/exec.h 2008-01-06 20:38:45.000000000 +0100
+++ qemu-0.9.1/target-sparc/exec.h 2008-02-06 10:19:59.000000000 +0100
@@ -32,9 +32,13 @@
#else
#define REGWPTR env->regwptr
+#if !defined(GCC_BREAKS_T_REGISTER)
register uint32_t T2 asm(AREG3);
-#endif
#define reg_T2
+#else
+#define T2 (env->t2)
+#endif
+#endif
#endif
#define FT0 (env->ft0)

View File

@ -0,0 +1,239 @@
https://bugzilla.redhat.com/show_bug.cgi?id=433560
Revised block device address range patch
The original patch adds checks to the main bdrv_XXX apis to validate that
the I/O operation does not exceed the bounds of the disk - ie beyond the
total_sectors count. This works correctly for bdrv_XXX calls from the IDE
driver. With disk formats like QCow though, bdrv_XXX is re-entrant,
because the QCow driver uses the block APIs for dealing with its underlying
file. The problem is that QCow files are grow-on-demand, so writes will
*explicitly* be beyond the end of the file. The original patch blocks any
I/O operation which would cause the QCow file to grow, resulting it more
or less catasatrophic data loss.
Basically the bounds checking needs to distinguish between checking for
the logical disk extents, vs the physical disk extents. For raw files
these are the same so initial tests showed no problems, but for QCow
format disks they are different & thus we see a problem
What follows is a revised patch which introduces a flag BDRV_O_AUTOGROW
which can be passed to bdrv_open to indicate that the files can be allowed
to automatically extend their extents. This flag should only be used by
internal block drivers such as block-qcow2.c, block-vmdk.c In my testing
this has fixed the qcow corruption, and still maintains the goal of Ian's
original patch which was to prevent the guest VM writing beyond the logical
disk extents.
diff -rup kvm-60.orig/qemu/block.c kvm-60.new/qemu/block.c
--- kvm-60.orig/qemu/block.c 2008-02-26 18:44:28.000000000 -0500
+++ kvm-60.new/qemu/block.c 2008-02-26 18:44:52.000000000 -0500
@@ -124,6 +124,60 @@ void path_combine(char *dest, int dest_s
}
}
+static int bdrv_rd_badreq_sectors(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors)
+{
+ return
+ nb_sectors < 0 ||
+ sector_num < 0 ||
+ nb_sectors > bs->total_sectors ||
+ sector_num > bs->total_sectors - nb_sectors;
+}
+
+static int bdrv_rd_badreq_bytes(BlockDriverState *bs,
+ int64_t offset, int count)
+{
+ int64_t size = bs->total_sectors << SECTOR_BITS;
+ return
+ count < 0 ||
+ size < 0 ||
+ count > size ||
+ offset > size - count;
+}
+
+static int bdrv_wr_badreq_sectors(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors)
+{
+ if (sector_num < 0 ||
+ nb_sectors < 0)
+ return 1;
+
+ if (sector_num > bs->total_sectors - nb_sectors) {
+ if (bs->autogrow)
+ bs->total_sectors = sector_num + nb_sectors;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+static int bdrv_wr_badreq_bytes(BlockDriverState *bs,
+ int64_t offset, int count)
+{
+ int64_t size = bs->total_sectors << SECTOR_BITS;
+ if (count < 0 ||
+ offset < 0)
+ return 1;
+
+ if (offset > size - count) {
+ if (bs->autogrow)
+ bs->total_sectors = (offset + count + SECTOR_SIZE - 1) >> SECTOR_BITS;
+ else
+ return 1;
+ }
+ return 0;
+}
+
static void bdrv_register(BlockDriver *bdrv)
{
@@ -332,6 +386,10 @@ int bdrv_open2(BlockDriverState *bs, con
bs->read_only = 0;
bs->is_temporary = 0;
bs->encrypted = 0;
+ bs->autogrow = 0;
+
+ if (flags & BDRV_O_AUTOGROW)
+ bs->autogrow = 1;
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
@@ -376,6 +434,7 @@ int bdrv_open2(BlockDriverState *bs, con
}
bs->drv = drv;
bs->opaque = qemu_mallocz(drv->instance_size);
+ bs->total_sectors = 0; /* driver will set if it does not do getlength */
if (bs->opaque == NULL && drv->instance_size > 0)
return -1;
/* Note: for compatibility, we open disk image files as RDWR, and
@@ -441,6 +500,7 @@ void bdrv_close(BlockDriverState *bs)
bs->drv = NULL;
/* call the change callback */
+ bs->total_sectors = 0;
bs->media_changed = 1;
if (bs->change_cb)
bs->change_cb(bs->change_opaque);
@@ -506,6 +566,8 @@ int bdrv_read(BlockDriverState *bs, int6
if (!drv)
return -ENOMEDIUM;
+ if (bdrv_rd_badreq_sectors(bs, sector_num, nb_sectors))
+ return -EDOM;
if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
memcpy(buf, bs->boot_sector_data, 512);
sector_num++;
@@ -546,6 +608,8 @@ int bdrv_write(BlockDriverState *bs, int
return -ENOMEDIUM;
if (bs->read_only)
return -EACCES;
+ if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors))
+ return -EDOM;
if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
memcpy(bs->boot_sector_data, buf, 512);
}
@@ -671,6 +735,8 @@ int bdrv_pread(BlockDriverState *bs, int
return -ENOMEDIUM;
if (!drv->bdrv_pread)
return bdrv_pread_em(bs, offset, buf1, count1);
+ if (bdrv_rd_badreq_bytes(bs, offset, count1))
+ return -EDOM;
return drv->bdrv_pread(bs, offset, buf1, count1);
}
@@ -686,6 +752,8 @@ int bdrv_pwrite(BlockDriverState *bs, in
return -ENOMEDIUM;
if (!drv->bdrv_pwrite)
return bdrv_pwrite_em(bs, offset, buf1, count1);
+ if (bdrv_wr_badreq_bytes(bs, offset, count1))
+ return -EDOM;
return drv->bdrv_pwrite(bs, offset, buf1, count1);
}
@@ -1091,6 +1159,8 @@ int bdrv_write_compressed(BlockDriverSta
return -ENOMEDIUM;
if (!drv->bdrv_write_compressed)
return -ENOTSUP;
+ if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors))
+ return -EDOM;
return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
}
@@ -1237,6 +1307,8 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDri
if (!drv)
return NULL;
+ if (bdrv_rd_badreq_sectors(bs, sector_num, nb_sectors))
+ return NULL;
/* XXX: we assume that nb_sectors == 0 is suppored by the async read */
if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
@@ -1268,6 +1340,8 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDr
return NULL;
if (bs->read_only)
return NULL;
+ if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors))
+ return NULL;
if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
memcpy(bs->boot_sector_data, buf, 512);
}
diff -rup kvm-60.orig/qemu/block.h kvm-60.new/qemu/block.h
--- kvm-60.orig/qemu/block.h 2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block.h 2008-02-26 18:44:52.000000000 -0500
@@ -45,6 +45,7 @@ typedef struct QEMUSnapshotInfo {
it (default for
bdrv_file_open()) */
#define BDRV_O_DIRECT 0x0020
+#define BDRV_O_AUTOGROW 0x0040 /* Allow backing file to extend when writing past end of file */
#ifndef QEMU_IMG
void bdrv_info(void);
diff -rup kvm-60.orig/qemu/block_int.h kvm-60.new/qemu/block_int.h
--- kvm-60.orig/qemu/block_int.h 2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block_int.h 2008-02-26 18:44:52.000000000 -0500
@@ -97,6 +97,7 @@ struct BlockDriverState {
int locked; /* if true, the media cannot temporarily be ejected */
int encrypted; /* if true, the media is encrypted */
int sg; /* if true, the device is a /dev/sg* */
+ int autogrow; /* if true, the backing store can auto-extend to allocate new extents */
/* event callback when inserting/removing */
void (*change_cb)(void *opaque);
void *change_opaque;
diff -rup kvm-60.orig/qemu/block-qcow2.c kvm-60.new/qemu/block-qcow2.c
--- kvm-60.orig/qemu/block-qcow2.c 2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block-qcow2.c 2008-02-26 18:44:52.000000000 -0500
@@ -191,7 +191,7 @@ static int qcow_open(BlockDriverState *b
int len, i, shift, ret;
QCowHeader header;
- ret = bdrv_file_open(&s->hd, filename, flags);
+ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);
if (ret < 0)
return ret;
if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
diff -rup kvm-60.orig/qemu/block-qcow.c kvm-60.new/qemu/block-qcow.c
--- kvm-60.orig/qemu/block-qcow.c 2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block-qcow.c 2008-02-26 18:44:52.000000000 -0500
@@ -95,7 +95,7 @@ static int qcow_open(BlockDriverState *b
int len, i, shift, ret;
QCowHeader header;
- ret = bdrv_file_open(&s->hd, filename, flags);
+ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);
if (ret < 0)
return ret;
if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
diff -rup kvm-60.orig/qemu/block-vmdk.c kvm-60.new/qemu/block-vmdk.c
--- kvm-60.orig/qemu/block-vmdk.c 2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block-vmdk.c 2008-02-26 18:44:52.000000000 -0500
@@ -375,7 +375,7 @@ static int vmdk_open(BlockDriverState *b
flags = BDRV_O_RDONLY;
fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename);
- ret = bdrv_file_open(&s->hd, filename, flags);
+ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);
if (ret < 0)
return ret;
if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))

View File

@ -0,0 +1,55 @@
--- vl.c 2008-01-06 14:38:42.000000000 -0500
+++ vl.c 2008-05-13 09:56:45.000000000 -0400
@@ -4877,13 +4877,14 @@
int bus_id, unit_id;
int cyls, heads, secs, translation;
BlockDriverState *bdrv;
+ BlockDriver *drv = NULL;
int max_devs;
int index;
int cache;
int bdrv_flags;
char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
"secs", "trans", "media", "snapshot", "file",
- "cache", NULL };
+ "cache", "format", NULL };
if (check_params(buf, sizeof(buf), params, str) < 0) {
fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n",
@@ -5051,6 +5052,14 @@
}
}
+ if (get_param_value(buf, sizeof(buf), "format", str)) {
+ drv = bdrv_find_format(buf);
+ if (!drv) {
+ fprintf(stderr, "qemu: '%s' invalid format\n", buf);
+ return -1;
+ }
+ }
+
get_param_value(file, sizeof(file), "file", str);
/* compute bus and unit according index */
@@ -5150,7 +5159,7 @@
bdrv_flags |= BDRV_O_SNAPSHOT;
if (!cache)
bdrv_flags |= BDRV_O_DIRECT;
- if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file)) {
+ if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
fprintf(stderr, "qemu: could not open disk image %s\n",
file);
return -1;
--- qemu-doc.texi 2008-01-06 14:38:42.000000000 -0500
+++ qemu-doc.texi 2008-05-13 09:57:57.000000000 -0400
@@ -252,6 +252,10 @@
@var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}).
@item cache=@var{cache}
@var{cache} is "on" or "off" and allows to disable host cache to access data.
+@item format=@var{format}
+Specify which disk @var{format} will be used rather than detecting
+the format. Can be used to specifiy format=raw to avoid interpreting
+an untrusted format header.
@end table
Instead of @option{-cdrom} you can use:

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<herd>no-herd</herd>
<maintainer>
<email>lu_zero@gentoo.org</email>
</maintainer>
<use>
<flag name='kqemu'>Enables the kernel acceleration module on a x86
cpu</flag>
</use>
</pkgmetadata>

View File

@ -0,0 +1,121 @@
# Copyright 1999-2008 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu-softmmu/qemu-softmmu-0.9.1-r3.ebuild,v 1.4 2008/05/14 20:25:37 maekke Exp $
inherit eutils flag-o-matic toolchain-funcs
DESCRIPTION="Multi-platform & multi-targets cpu emulator and dynamic translator"
HOMEPAGE="http://fabrice.bellard.free.fr/qemu/"
SRC_URI="${HOMEPAGE}${P/-softmmu/}.tar.gz"
LICENSE="GPL-2 LGPL-2.1"
SLOT="0"
KEYWORDS="-alpha amd64 ppc -sparc x86"
IUSE="sdl kqemu gnutls alsa"
RESTRICT="binchecks test"
DEPEND="virtual/libc
sys-libs/zlib
sdl? ( media-libs/libsdl )
!<=app-emulation/qemu-0.7.0
kqemu? ( >=app-emulation/kqemu-1.3.0_pre10 )
gnutls? (
dev-util/pkgconfig
net-libs/gnutls
)
app-text/texi2html"
RDEPEND="sys-libs/zlib
sdl? ( media-libs/libsdl )
gnutls? ( net-libs/gnutls )
alsa? ( media-libs/alsa-lib )"
S=${WORKDIR}/${P/-softmmu/}
src_unpack() {
unpack ${A}
cd "${S}"
epatch "${FILESDIR}/qemu-0.9.1-gcc4.patch"
epatch "${FILESDIR}/hotfix.patch"
epatch "${FILESDIR}/${P}-CVE-2008-0928.patch" #212351
epatch "${FILESDIR}/${P}-CVE-2008-2004.patch" #221943
# Alter target makefiles to accept CFLAGS set via flag-o.
sed -i 's/^\(C\|OP_C\|HELPER_C\)FLAGS=/\1FLAGS+=/' \
Makefile Makefile.target tests/Makefile
# Ensure mprotect restrictions are relaxed for emulator binaries
[[ -x /sbin/paxctl ]] && \
sed -i 's/^VL_LDFLAGS=$/VL_LDFLAGS=-Wl,-z,execheap/' \
Makefile.target
# Prevent install of kernel module by qemu's makefile
sed -i 's/\(.\/install.sh\)/#\1/' Makefile
# avoid strip
sed -i 's:$(INSTALL) -m 755 -s:$(INSTALL) -m 755:' Makefile Makefile.target
}
src_compile() {
if use x86 ; then
# Force -march=pentium-mmx or lower. Fixes bug #212351.
local march
march=$(echo "${CFLAGS}" | sed 's:^.*-march=\([[:alnum:]-]\+\)\([[:blank:]].*\)\?$:\1:p;d')
case ${march} in
i386|i486|i586|pentium) ;;
*) # Either march is not enough low or not exists at all
case ${CHOST} in
i486-*-*) march=i486 ;;
i586-*-*) march=i586 ;;
*) march=pentium-mmx ;;
esac ;;
esac
#Let the application set its cflags
unset CFLAGS
append-flags -march=${march}
else
#Let the application set its cflags
unset CFLAGS
fi
# Switch off hardened tech
filter-flags -fpie -fstack-protector
myconf="--disable-gcc-check"
if use alsa; then
myconf="$myconf --enable-alsa"
fi
if ! use gnutls; then
myconf="$myconf --disable-vnc-tls"
fi
if ! use kqemu; then
myconf="$myconf --disable-kqemu"
fi
if ! use sdl ; then
myconf="$myconf --disable-sdl --disable-gfx-check"
fi
# econf does not work
./configure \
--prefix=/usr \
--enable-adlib \
--cc=$(tc-getCC) \
--host-cc=$(tc-getCC) \
--disable-linux-user \
--enable-system \
${myconf} \
|| die "could not configure"
emake OS_CFLAGS="${CFLAGS}" || die "make failed"
}
src_install() {
emake install \
prefix="${D}/usr" \
bindir="${D}/usr/bin" \
datadir="${D}/usr/share/qemu" \
docdir="${D}/usr/share/doc/${P}" \
mandir="${D}/usr/share/man" || die
chmod -x "${D}/usr/share/man/*/*"
}
pkg_postinst() {
einfo "You will need the Universal TUN/TAP driver compiled into"
einfo "kernel or as a module to use the virtual network device."
}