Some old DOS programs can also use f-segment space as Upper Memory
Blocks (UMB), so also report on what space is available in debug
messages.
Signed-off-by: Kevin O'Connor <kevin(a)koconnor.net>
---
src/pmm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/pmm.c b/src/pmm.c
index b003dd1..d1986c2 100644
--- a/src/pmm.c
+++ b/src/pmm.c
@@ -324,11 +324,12 @@ malloc_prepboot(void)
int size = (BUILD_BIOS_ADDR - base) / 512;
dummyrom->size = (size > 255) ? 255 : size;
memset((void*)RomEnd, 0, base-RomEnd);
- dprintf(1, "Space available for UMB: %08x-%08x\n", RomEnd, base);
// Clear unused f-seg ram.
struct allocinfo_s *info = findLast(&ZoneFSeg);
memset(info->dataend, 0, info->allocend - info->dataend);
+ dprintf(1, "Space available for UMB: %x-%x, %x-%x\n"
+ , RomEnd, base, (u32)info->dataend, (u32)info->allocend);
// Give back unused high ram.
info = findLast(&ZoneHigh);
--
1.7.11.7
Hi,
I noticed that under OVMF + SeaBIOS CSM + your related patches for both,
reset requested by the guest doesn't work as expected. The behavior is
an infinite loop, with the following debug fragment repeated by the
CSM-ized SeaBIOS:
In resume (status=0)
In 32bit resume
Attempting a hard reboot
i8042_wait_write
The corresponding call chain seems to be:
reset_vector() [src/romlayout.S]
entry_post()
entry_resume()
handle_resume() [src/resume.c]
prints "In resume"
handle_resume32()
prints "In 32bit resume"
tryReboot()
prints "Attempting a hard reboot"
i8042_reboot() [src/ps2port.c]
i8042_wait_write()
prints "i8042_wait_write"
outb(0xfe, PORT_PS2_STATUS)
(The entry_post -> entry_resume jump occurs because HaveRunPost has been
set to 1 by csm_maininit() --> interface_init() --> ivt_init().)
At this point kbd_write_command() in qemu-kvm's "hw/pckbd.c", case
KBD_CCMD_RESET, requests a system reset. Soon the reset handlers run,
among them cpu_reset() (which was registered by
pc_init1() [hw/pc.c]
pc_new_cpu()
). cpu_reset() [target-i386/helper.c] sets CS:IP to f000:fff0, which is
the exact address of... reset_vector() in SeaBIOS.
Of course OVMF should be re-run instead of SeaBIOS. When qemu-kvm
starts, "OVMF.fd" is installed as ROM, such that the last address it
occupies is "all-bits-one", independently of its size (below a limit of
course):
pc_init1() [hw/pc.c]
rom_add_file_fixed() []
open() / read() /close()
rom_insert()
some calls to inform KVM
I think when OVMF runs SeaBIOS as CSM, OVMF shadows the original ROM
(containing the OVMF binary itself) with the SeaBIOS code + static data
(I'm peeking at
<http://en.wikipedia.org/wiki/Shadow_RAM#Shadow_RAM>...). This should
render SeaBIOS visible / executable / writeable in the top 16-bit
segment, and leave OVMF in a permanently unusable state (in RAM at least).
My guess at the relevant edk2 function is ShadowAndStartLegacy16()
[IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c]. The
LegacyRegion->UnLock() call should be instrumental (implemented in
"OvmfPkg/Csm/CsmSupportLib/LegacyRegion.c" with PAM (Programmable
Attribute Map) registers?)
Hence I *presume* qemu-kvm should un-shadow the ROM at reset time (ie.
make OVMF visible again as ROM) not later than allowing the VCPU to
continue at f000:fff0 again. Normally that address should be occupied by
OVMF code from (I guess) "UefiCpuPkg/ResetVector/Vtf0".
Does this make any sense? Is qemu-kvm forgetting to reset the PAMs? Or
would that be the responsibility of tryReboot() in SeaBIOS?
... Aah! qemu_prep_reset() in SeaBIOS [src/shadow.c] goes like:
void
qemu_prep_reset(void)
{
if (!CONFIG_QEMU)
return;
// QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
// reset, so do that manually before invoking a hard reset.
make_bios_writable();
extern u8 code32flat_start[], code32flat_end[];
memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
, code32flat_end - code32flat_start);
if (HaveRunPost)
// Memory copy failed to work - try to halt the machine.
apm_shutdown();
}
and this function is actually called inside the infinite loop (I ignored
it before):
tryReboot()
prints "Attempting a hard reboot"
qemu_prep_reset() [src/shadow.c] <-------------- here
i8042_reboot() [src/ps2port.c]
i8042_wait_write()
prints "i8042_wait_write"
outb(0xfe, PORT_PS2_STATUS)
but of course it doesn't do anything with CONFIG_CSM (since that implies
!CONFIG_QEMU). What's more, qemu_prep_reset() and
make_bios_writable_intel() seem to exploit SeaBIOS characteristics
(code32flat_*, HaveRunPost etc.) that probably make no sense when the
data being restored is a different (= OVMF) image.
Can we dumb down ^W^W generalize this code? :) Or maybe should qemu
introduce a reset handler for PAMs?
(I realize I've been reading all the time about PAMs, in the "Writeable
files in fw_cfg" thread, in the discussion about unlocking the 0xE0000
segment for stack purposes... Didn't understand a single word before,
sorry. Downloaded my copy of the i440FX spec just today; I finally have
a remote idea how shadowing / write-protecting works.)
Thanks!
Laszlo
On Tue, Dec 18, 2012 at 10:41 AM, Vasilis Liaskovitis <
vasilis.liaskovitis(a)profitbricks.com> wrote:
> This is v4 of the ACPI memory hotplug functionality. Only x86_64 target is
> supported (both i440fx and q35). There are still several issues, but it's
> been a while since v3 and I wanted to get some more feedback on the current
> state of the patchseries.
>
>
We are working in memory hotplug functionality on pSeries machine. I'm
wondering whether and how we can better integrate things. Do you think the
DIMM abstraction is generic enough to be used in other machine types?
> Overview:
>
> Dimm device layout is modeled with a normal qemu device:
>
> "-device dimm,id=name,size=sz,node=pxm,populated=on|off,bus=membus.0"
>
>
How does this will handle the no-hotplugable memory for example the memory
passed in '-m' parameter?
> The starting physical address for all dimms is calculated from top of
> memory,
> during memory controller init, skipping the pci hole at [PCI_HOLE_START,
> 4G).
> e.g.
> "-device dimm,id=dimm0,size=512M,node=0,populated=off,bus=membus.0"
> will define a 512M memory dimm belonging to numa node 0, on bus membus.0.
>
> Because dimm layout needs to be configured on machine-boot, all dimm
> devices
> need to be specified on startup command line (either with populated=on or
> with
> populated=off). The dimm information is stored in dimm configuration
> structures.
>
> After machine startup, dimms are hot-added or removed with normal
> device_add
> and device_del operations e.g.:
> Hot-add syntax: "device_add dimm,id=mydimm0,bus=membus.0"
> Hot-remove syntax: "device_del dimm,id=mydimm0"
>
> Changes v3->v4
>
> - Dimms added with normal -device argument (extra -dimm arg dropped).
> - multiple memory buses can be registered. Memory buses of the real
> hw/chipset
> or a paravirtual memory bus can be added.
> - acpi implementation uses memory API instead of old ioports.
> - Support for q35/ich9 added (still buggy, see patch 12/31).
> - piix4/i440fx initialization code has been refactored to resemble q35.
> This
> will allow memory map initialization at chipset qdev init time for both
> machines, as well as more similar code.
> - Hot-remove functionality has been moved to separate patches. Hot-remove
> no
> longer frees memory but unmaps the dimm/qdev device from the guest's view.
> Freeing the memory should happen when the last user unrefs/unmaps the
> memory,
> see also (work in progress):
> https://lists.gnu.org/archive/html/qemu-devel/2012-11/msg00728.html
> https://lists.gnu.org/archive/html/qemu-devel/2012-11/msg02697.html
> - new qmp/hmp command for the state of each dimm (on/off)
>
> Changes v2->v3
>
> - qdev integration. Dimms are attached to a dimmbus. The dimmbus is a child
> of i440fx device in the pc machine. Hot-add and remove are done with
> normal
> device_add / device_del operations on the dimmbus. New commands
> "dimm_add" and
> "dimm_del" are obsolete.
> - Add _PS3 method to allow OSPM-induced hot operations.
> - pci-window calculation in Seabios takes dimms into account(for both
> 32-bit and
> 64-bit windows)
> - rename new qmp commands: query-memory-total and query-memory-hotplug
> - balloon driver can see the hotplugged memory
>
> Changes v1->v2
>
> - memory map is automatically calculated for hotplug dimms. Dimms are
> added from
> top-of-memory skipping the pci hole at [PCI_HOLE_START, 4G).
> - Renamed from "-memslot" to "-dimm". Commands changed to "dimm_add",
> "dimm_del"
> - Seabios ejection array reduced to a byte. Use extraction macros for dimm
> ssdt.
> - additional SRAT paravirt info does not break previous SRAT fw_cfg layout.
> - Documentation of new acpi_piix4 registers and paravirt data.
> - add ACPI _OST support for _OST enabled guests. This allows qemu to
> receive
> notification for success / failure of memory hot-add and hot-remove
> operations.
> Guest needs to support _OST (https://lkml.org/lkml/2012/6/25/321)
> - add monitor info command to report total guest memory (initial +
> hot-added)
>
> Issues:
>
> - hot-remove needs to only unmap the dimm device from guest's view.
> Freeing the
> memory should happen when the last user of the device (e.g. virtio-blk)
> unrefs
> the device. A testcase is needed for this.
>
> - Live Migration: Ramblocks are migrated before qdev VMStates are
> migrated. So
> the DimmDevice is handled diferrently than other devices. Should this be
> reworked ?( DimmDevice structure currently does not define a
> VMStateDescription)
> Live migration works as long as the dimm layout (command line args) are
> identical at the source and destination qemu command line, and destination
> takes
> into account hot-operations that have occured on source. (v3 patch 10/19
> created the DimmDevice that corresponds to an unknown incoming ramblock,
> e.g.
> for a dimm that was hot-added on source. but has been dropped for the
> moment).
>
> - A main blocker issue is windows guest functionality. The patchset does
> not
> work for windows currently. Testing on win2012 server RC or windows2008
> consumer prerelease, when adding a DIMM, there is a BSOD with
> ACPI_BIOS_ERROR
> message. After this, the VM keeps rebooting with ACPI_BIOS_ERROR. The
> windows
> pnpmem driver obviosuly has a problem with the seabios dimm implementation
> (or the seabios dimm implementation is not fully ACPI-compliant). If
> someone
> can review the seabios patches or has any ideas to debug this, let me know.
>
> - hot-operation notification lists need to be added to migration state.
>
> series is based on:
> - qemu master (commit a8a826a3) + patch:
> https://lists.gnu.org/archive/html/qemu-devel/2012-11/msg02699.html
> - seabios master (commit a810e4e7)
>
> Can also be found at:
>
> http://github.com/vliaskov/qemu-kvm/commits/memhp-v4
> http://github.com/vliaskov/seabios/commits/memhp-v4
>
> Vasilis Liaskovitis (21):
> qapi: make visit_type_size fallback to type_int
> Add SIZE type to qdev properties
> qemu-option: export parse_option_number
> Implement dimm device abstraction
> vl: handle "-device dimm"
> acpi_piix4 : Implement memory device hotplug registers
> acpi_ich9 : Implement memory device hotplug registers
> piix_pci and pc_piix: refactor
> piix_pci: Add i440fx dram controller initialization
> q35: Add i440fx dram controller initialization
> pc: Add dimm paravirt SRAT info
> Introduce paravirt interface QEMU_CFG_PCI_WINDOW
> Implement "info memory-total" and "query-memory-total"
> balloon: update with hotplugged memory
> Implement dimm-info
> dimm: add hot-remove capability
> acpi_piix4: add hot-remove capability
> acpi_ich9: add hot-remove capability
> Implement qmp and hmp commands for notification lists
> Add _OST dimm support
> Implement _PS3 for dimm
>
> docs/specs/acpi_hotplug.txt | 54 ++++++
> docs/specs/fwcfg.txt | 28 +++
> hmp-commands.hx | 6 +
> hmp.c | 41 ++++
> hmp.h | 3 +
> hw/Makefile.objs | 2 +-
> hw/acpi.h | 5 +
> hw/acpi_ich9.c | 115 +++++++++++-
> hw/acpi_ich9.h | 12 +-
> hw/acpi_piix4.c | 126 ++++++++++++-
> hw/dimm.c | 444
> +++++++++++++++++++++++++++++++++++++++++++
> hw/dimm.h | 102 ++++++++++
> hw/fw_cfg.h | 1 +
> hw/lpc_ich9.c | 2 +-
> hw/pc.c | 28 +++-
> hw/pc.h | 1 +
> hw/pc_piix.c | 74 ++++++--
> hw/pc_q35.c | 18 ++-
> hw/piix_pci.c | 249 ++++++++-----------------
> hw/q35.c | 27 +++
> hw/q35.h | 5 +
> hw/qdev-properties.c | 60 ++++++
> hw/qdev-properties.h | 3 +
> hw/virtio-balloon.c | 13 +-
> monitor.c | 21 ++
> qapi-schema.json | 63 ++++++
> qapi/qapi-visit-core.c | 11 +-
> qemu-option.c | 4 +-
> qemu-option.h | 4 +
> qmp-commands.hx | 57 ++++++
> sysemu.h | 1 +
> vl.c | 60 ++++++
> 32 files changed, 1432 insertions(+), 208 deletions(-)
> create mode 100644 docs/specs/acpi_hotplug.txt
> create mode 100644 docs/specs/fwcfg.txt
> create mode 100644 hw/dimm.c
> create mode 100644 hw/dimm.h
>
>
> Vasilis Liaskovitis (9):
> Add ACPI_EXTRACT_DEVICE* macros
> Add SSDT memory device support
> acpi-dsdt: Implement functions for memory hotplug
> acpi: generate hotplug memory devices
> q35: Add memory hotplug handler
> pci: Use paravirt interface for pcimem_start and pcimem64_start
> acpi: add _EJ0 operation and eject port for memory devices
> Add _OST dimm method
> Implement _PS3 method for memory device
>
> Makefile | 2 +-
> src/acpi-dsdt-mem-hotplug.dsl | 136 +++++++++++++++++++++++++++++++++++
> src/acpi-dsdt.dsl | 5 +-
> src/acpi.c | 158
> +++++++++++++++++++++++++++++++++++++++--
> src/paravirt.c | 6 ++
> src/paravirt.h | 2 +
> src/pciinit.c | 9 +++
> src/q35-acpi-dsdt.dsl | 6 +-
> src/ssdt-mem.dsl | 73 +++++++++++++++++++
> tools/acpi_extract.py | 28 +++++++
> 10 files changed, 415 insertions(+), 10 deletions(-)
> create mode 100644 src/acpi-dsdt-mem-hotplug.dsl
> create mode 100644 src/ssdt-mem.dsl
>
> --
> 1.7.9
>
>
>