Commit Graph
29 Commits
Author SHA1 Message Date
Jan Beulich 57acad12a0 hvmloader/PCI: skip huge BARs in certain calculations
BARs of size 2Gb and up can't possibly fit below 4Gb: Both the bottom of
the lower 2Gb range and the top of the higher 2Gb range have special
purpose. Don't even have them influence whether to (perhaps) relocate
low RAM.

Reported-by: Neowutran <xen@neowutran.ovh>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
2024-03-06 10:19:29 +01:00
Jan Beulich 1c4589280a hvmloader: tidy pci_mem_{start,end}
For one at least pci_mem_start has to be precisely 32 bits wide, so use
uint32_t for both. Otherwise expressions like "pci_mem_start <<= 1"
won't have the intended effect (in their context).

Further since its introduction pci_mem_end was never written to. Mark it
const to make this explicit.

Finally drop PCI_MEM_END: It is used just once and needlessly
disconnected from the other constant (RESERVED_MEMBASE) it needs to
match. Use RESERVED_MEMBASE as initializer of pci_mem_end instead.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
2021-12-17 08:56:34 +01:00
Igor Druzhinin 8efa46516c hvmloader: indicate ACPI tables with "ACPI data" type in e820
Guest kernel does need to know in some cases where the tables are located
to treat these regions properly. One example is kexec process where
the first kernel needs to pass ACPI region locations to the second
kernel which is now a requirement in Linux after 02a3e3cdb7f12 ("x86/boot:
Parse SRAT table and count immovable memory regions") in order for kexec
transition to actually work.

That commit introduced accesses to XSDT and SRAT while the second kernel
is still using kexec transition tables. The transition tables do not have
e820 "reserved" regions mapped where those tables are located currently
in a Xen guest. Instead "ACPI data" regions are mapped with the transition
tables that was introduced by the following commit 6bbeb276b7 ("x86/kexec:
Add the EFI system tables and ACPI tables to the ident map").

Reserve 1MB (out of 16MB currently available) right after ACPI info page for
ACPI tables exclusively but populate this region on demand and only indicate
populated memory as "ACPI data" since according to ACPI spec that memory is
reclaimable by the guest if necessary. That is close to how we treat
the same ACPI data in PVH guests. 1MB should be enough for now but could be
later extended if required.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2020-09-09 17:56:13 +02:00
Harsha Shamsundara Havanur a8e0c228c7 hvmloader: enable MMIO and I/O decode, after all resource allocation
It was observed that PCI MMIO and/or IO BARs were programmed with
memory and I/O decodes (bits 0 and 1 of PCI COMMAND register) enabled,
during PCI setup phase. This resulted in incorrect memory mapping as
soon as the lower half of the 64 bit bar is programmed.
This displaced any RAM mappings under 4G. After the
upper half is programmed PCI memory mapping is restored to its
intended high mem location, but the RAM displaced is not restored.
The OS then continues to boot and function until it tries to access
the displaced RAM at which point it suffers a page fault and crashes.

This patch address the issue by deferring enablement of memory and
I/O decode in command register until all the resources, like interrupts
I/O and/or MMIO BARs for all the PCI device functions are programmed,
in the descending order of memory requested.

Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2020-04-16 10:58:46 +02:00
Konrad Rzeszutek Wilk cd02f96d54 hvmloader: Use MB(x) and GB(x) macros
instead of hardcoding values. We also drop the uint64_t
cast as the macro uses ULL to produce the proper width
types.

Acked-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
2017-09-18 15:42:02 -04:00
Xiong Zhang ecc607b185 hvmloader: use base instead of pci_mem_start for find_next_rmrr()
find_next_rmrr(base) is used to find the lowest RMRR ending above base
but below 4G. Current method couldn't cover the following situation:
a. two rmrr exist, small gap between them
b. pci_mem_start and mem_resource.base is below the first rmrr.base
c. find_next_rmrr(pci_mem_start) will find the first rmrr
d. After aligning mem_resource.base to bar size,
   first_rmrr.end < new_base < second_rmrr.base and
   new_base + bar_sz > second_rmrr.base.
   So the new bar will overlap with the second rmrr and doesn't overlap
with the first rmrr.
But the next_rmrr point to the first rmrr, then check_overlap() couldn't
find the overlap. Finally assign a wrong address to bar.

This patch using aligned new base to find the next rmrr, could fix the
above case and find all the overlapped rmrr with new base.

Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2017-08-28 10:51:24 +02:00
Ian Campbell 443701ef0c Replace FSF street address with canonical URL
As recommended in http://www.gnu.org/licenses/gpl-howto.en.html.

This is the result of:
$ git grep -El Mass\|Temple\|Franklin | xargs ./fsf.pl

Where fsf.pl is:
    #!/usr/bin/perl -w -pi.bak -0777
    my $repl = 'If not, see <http://www.gnu.org/licenses/>.';
    my $br = qr/(?:\s*\n\s*(?:[\*\#]|\/\/|\.\\" )?\s*|\s+)/;

    my $inwt = qr/[Ii]f${br}not,${br}write${br}(?:to${br})?the${br}Free${br}Software${br}Foundation,(?:${br}Inc\.,)?/;

    my $mass = qr/675${br}Mass${br}Ave,?${br}Cambridge,?${br}MA${br}02139,?${br}USA,?\.?/;
    my $franklin = qr/51${br}Franklin${br}St(?:reet)?(?:,${br}| - )Fifth${br}Floor,?${br}Boston,?${br}MA,?${br}02110-1301,?${br}USA,?\.?/;
    my $temple = qr/59${br}Temple${br}Place(?:,${br}| - )Suite${br}330,?${br}Boston,?${br}MA,?${br}021110?-1307,?${br}USA,?\.?/;

    s|$inwt$br$mass|$repl|m;
    s|$inwt$br$franklin|$repl|m;
    s|$inwt$br$temple|$repl|m;

The only remaining mentions of these addresses are in COPYING files which I
haven't touched.

Some of the changed files are imports from elsewhere, however
filtering them out is tricky, I think it is tolerable to have these
files be modified here and then perhaps reverted on the next sync,
since it's only 1-2 lines and obvious what is going on.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
2015-07-29 11:14:07 +01:00
Tiejun Chen 2c4f5125fd tools/hvmloader: sync memory map[]
Currently we always use memory map[] to help hvmloader construct e820 table
but hvmloader may have relocated RAM to support mmio allocation or just
populated ram to ensure we can have enough room to load ovmf. Anyway we
need to sync these changes into memory map[].

CC: Keir Fraser <keir@xen.org>
CC: Jan Beulich <jbeulich@suse.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
CC: Ian Jackson <ian.jackson@eu.citrix.com>
CC: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: George Dunlap <george.dunlap@eu.citrix.com>
Signed-off-by: Tiejun Chen <tiejun.chen@intel.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2015-07-28 14:02:02 +01:00
George Dunlap b730fc3e15 hvmloader/pci: try to avoid placing BARs in RMRRs
Try to avoid placing PCI BARs over RMRRs:

- If mmio_hole_size is not specified, and the existing MMIO range has
  RMRRs in it, and there is space to expand the hole in lowmem without
  moving more memory, then make the MMIO hole as large as possible.

- When placing RMRRs, find the next RMRR higher than the current base
  in the lowmem mmio hole.  If it overlaps, skip ahead of it and find
  the next one.

This certainly won't work in all cases, but it should work in a
significant number of cases.  Additionally, users should be able to
work around problems by setting mmio_hole_size larger in the guest
config.

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Signed-off-by: Tiejun Chen <tiejun.chen@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Wei Liu <wei.liu2@citrix.com>
2015-07-23 13:45:25 +01:00
Jan Beulich 73aa7fc292 hvmloader: don't treat ROM BAR like other BARs
Its low 11 bits have different meaning.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2015-03-26 11:17:51 +01:00
Don Slutz 2d927fc41b x86: hvm: Allow configuration of the size of the mmio_hole.
If you add enough PCI devices then all mmio may not fit below 4G
which may not be the layout the user wanted. This allows you to
increase the below 4G address space that PCI devices can use and
therefore in more cases not have any mmio that is above 4G.

There are real PCI cards that do not support mmio over 4G, so if you
want to emulate them precisely, you may also need to increase the
space below 4G for them. There are drivers for these cards that also
do not work if they have their mmio space mapped above 4G.

This allows growing the MMIO hole to the size needed.

This may help with using pci passthru and HVM.

In the tools this is named mmio_hole_memkb.

Signed-off-by: Don Slutz <dslutz@verizon.com>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
[ ijc -- fixed build error in xl_cmdimpl.c with s/%PRIu64/%ld/.
         Reworded title ]
2014-10-23 11:47:49 +01:00
Jan Beulich d068866943 hvmloader: also cover PCI MMIO ranges above 4G with UC MTRR ranges
When adding support for BAR assignments to addresses above 4G, the MTRR
side of things was left out.

Additionally the MMIO ranges in the DSDT's \_SB.PCI0._CRS were having
memory types not matching the ones put into MTRRs: The legacy VGA range
is supposed to be WC, and the other ones should be UC.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
2014-05-21 18:13:36 +02:00
George Dunlap c74c1f906a libxl,hvmloader: Don't relocate memory for MMIO hole
At the moment, qemu-xen can't handle memory being relocated by
hvmloader.  This may happen if a device with a large enough memory
region is passed through to the guest.  At the moment, if this
happens, then at some point in the future qemu will crash and the
domain will hang.  (qemu-traditional is fine.)

It's too late in the release to do a proper fix, so we try to do
damage control.

hvmloader already has mechanisms to relocate memory to 64-bit space if
it can't make a big enough MMIO hole.  By default this is 2GiB; if we
just refuse to make the hole bigger if it will overlap with guest
memory, then the relocation will happen by default.

v5:
 - Update comment to not refer to "this series".
v4:
 - Wrap long line in libxl_dm.c
 - Fix comment
v3:
 - Fix polarity of comparison
 - Move diagnostic messages to another patch
 - Tested with xen platform pci device hacked to have different BAR sizes
   {256MiB, 1GiB} x {qemu-xen, qemu-traditional} x various memory
   configurations
 - Add comment explaining why we default to "allow"
 - Remove cast to bool
v2:
 - style fixes
 - fix and expand comment on the MMIO hole loop
 - use "%d" rather than "%s" -> (...)?"1":"0"
 - use bool instead of uint8_t
 - Move 64-bit bar relocate detection to another patch
 - Add more diagnostic messages

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Stefano Stabellini <stefano.stabellini@citrix.com>
CC: Hanweidong <hanweidong@huawei.com>
CC: Keir Fraser <keir@xen.org>
CC: Keir Fraser <keir@xen.org>
2013-06-24 12:20:29 +01:00
George Dunlap 6392092e7e hvmloader: Remove minimum size for BARs to relocate to 64-bit space
Allow devices with BARs less than 512MiB to be relocated to high
memory.

This will only be invoked if there is not enough low MMIO space to map
the device, and will be done preferentially to large devices first; so
in all likelihood only large devices will be remapped anyway.

This is needed to work-around the issue of qemu-xen not being able to
handle moving guest memory around to resize the MMIO hole.  The
default MMIO hole size is less than 256MiB.

v3:
 - Fixed minor style issue

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Hanweidong <hanweidong@huawei.com>
CC: Keir Fraser <keir@xen.org>
2013-06-24 12:20:29 +01:00
George Dunlap 56fb55c42e hvmloader: Load large devices into high MMIO space as needed
Keep track of how much mmio space is left total, as well as the amount
of "low" MMIO space (<4GiB), and only load devices into high memory if
there is not enough low memory for the rest of the devices to fit.

Because devices are processed by size in order from large to small,
this should preferentially relocate devices with large BARs to 64-bit
space.

v3:
 - Just use mmio_total rather than introducing a new variable.
 - Port to using mem_resource directly rather than low_mmio_left

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Stefano Stabellini <stefano.stabellini@citrix.com>
CC: Hanweidong <hanweidong@huawei.com>
CC: Keir Fraser <keir@xen.org>
2013-06-24 12:20:29 +01:00
George Dunlap 703e150231 hvmloader: Correct bug in low mmio region accounting
When deciding whether to map a device in low MMIO space (<4GiB),
hvmloader compares it with "mmio_left", which is set to the size of
the low MMIO range (pci_mem_end - pci_mem_start).  However, even if it
does map a device in high MMIO space, it still removes the size of its
BAR from mmio_left.

In reality we don't need to do a separate accounting of the low memory
available -- this can be calculated from mem_resource.  Just get rid
of the variable and the duplicate accounting entirely.  This will make
the code more robust.

Note also that the calculation of whether to move a device to 64-bit
is fragile at the moment, depending on some unstated assumptions.
State those assumptions in a comment for future reference.

v5:
 - Add comment documenting fragility of the move-to-highmem check
v3:
 - Use mem_resource values directly instead of doing duplicate
   accounting

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Stefano Stabellini <stefano.stabellini@citrix.com>
CC: Hanweidong <hanweidong@huawei.com>
CC: Keir Fraser <keir@xen.org>
2013-06-24 12:20:29 +01:00
George Dunlap 3458ab670f hvmloader: Fix check for needing a 64-bit bar
After attempting to resize the MMIO hole, the check to determine
whether there is a need to relocate BARs into 64-bit space checks the
specific thing that caused the loop to exit (MMIO hole == 2GiB) rather
than checking whether the required MMIO will fit in the hole.

But even then it does it wrong: the polarity of the check is
backwards.

Check for the actual condition we care about (the sizeof the MMIO
hole) rather than checking for the loop exit condition.

v3:
 - Move earlier in the series, before other functional changes

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Stefano Stabellini <stefano.stabellini@citrix.com>
CC: Hanweidong <hanweidong@huawei.com>
CC: Keir Fraser <keir@xen.org>
2013-06-24 12:20:29 +01:00
George Dunlap 42d075411b hvmloader: Set up highmem resouce appropriately if there is no RAM above 4G
hvmloader will read hvm_info->high_mem_pgend to calculate where to
start the highmem PCI region.  However, if the guest does not have any
memory in the high region, this is set to zero, which will cause
hvmloader to use the "0" for the base of the highmem region, rather
than 1 << 32.

Check to see whether hvm_info->high_mem_pgend is set; if so, do the
normal calculation; otherwise, use 1<<32.

v4:
 - Handle case where hfm_info->high_mem_pgend is non-zero but doesn't
   point into high memory, throwing a warning.

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Stefano Stabellini <stefano.stabellini@citrix.com>
CC: Hanweidong <hanweidong@huawei.com>
CC: Keir Fraser <keir@xen.org>
2013-06-24 12:20:29 +01:00
George Dunlap 91993aee68 hvmloader: Make the printfs more informative
* Warn that you're relocating some BARs to 64-bit

* Warn that you're relocating guest pages, and how many

* Include upper 32-bits of the base register when printing the bar
  placement info

v4:
 - Move message about relocating guest pages into loop, include number
   of pages and guest paddr
 - Fixed minor brace style issue

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Stefano Stabellini <stefano.stabellini@citrix.com>
CC: Hanweidong <hanweidong@huawei.com>
CC: Keir Fraser <keir@xen.org>
2013-06-24 12:20:29 +01:00
George Dunlap d23749aaf7 hvmloader: Remove all 64-bit print arguments
The printf() available to hvmloader does not handle 64-bit data types;
manually break them down as two 32-bit strings.

v4:
 - Make macros for the requisite format and bit shifting

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Keir Fraser <keir@xen.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Stefano Stabellini <stefano.stabellini@citrix.com>
CC: Hanweidong <hanweidong@huawei.com>
CC: Keir Fraser <keir@xen.org>
2013-06-24 12:20:29 +01:00
David Vrabel 82639998a5 Fix emacs local variable block to use correct C style variable.
The emacs variable to set the C style from a local variable block is
c-file-style, not c-set-style.

Signed-off-by: David Vrabel <david.vrabel@citrix.com
2013-02-21 16:12:46 +00:00
Keir Fraser 408a9e5634 hvmloader: Allocate 3 pages for Intel GPU OpRegion passthrough.
The 8kB region may not be page aligned, hence requiring 3 pages to
be mapped through.

Signed-off-by: Keir Fraser <keir@xen.org>
2013-01-10 17:26:24 +00:00
Xiantao Zhang 45f52f2646 hvmloader: Add 64 bits big bar support
Currently it is assumed PCI device BAR access < 4G memory. If there is
such a device whose BAR size is larger than 4G, it must access > 4G
memory address.  This patch enable the 64bits big BAR support on
hvmloader.

Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Xudong Hao <xudong.hao@intel.com>
Committed-by: Keir Fraser <keir@xen.org>
2012-10-01 20:01:55 +01:00
Jean Guyader cefeffc7e5 hvmloader: Intel GPU passthrough, reverse OpRegion
The Intel GPU uses a two pages NVS region called OpRegion.
In order to get full support for the driver in the guest
we need to map this region.

This patch reserves 2 pages on the top of the memory in the
reserved area and mark this region as NVS in the e820. Then
we write the address to the config space (offset 0xfc) so the
device model can map the OpRegion at this address in the guest.

Signed-off-by: Jean Guyader <jean.guyader@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
2011-11-24 15:43:59 +00:00
Keir Fraser 5a9a98a7a6 hvmloader: Fix memory relocation loop.
Signed-off-by: Keir Fraser <keir@xen.org>
2011-11-21 21:28:34 +00:00
Jean Guyader e51e2e0e58 hvmloader: Change memory relocation loop when overlap with PCI hole
Change the way we relocate the memory page if they overlap with pci
hole.  Use new map space (XENMAPSPACE_gmfn_range) to move the loop
into xen.

This code usually get triggered when a device is pass through to a
guest and the PCI hole has to be extended to have enough room to map
the device BARs.  The PCI hole will starts lower and it might overlap
with some RAM that has been alocated for the guest. That usually
happen if the guest has more than 4G of RAM.  We have to relocate
those pages in high mem otherwise they won't be accessible.

Signed-off-by: Jean Guyader <jean.guyader@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
2011-11-18 13:42:46 +00:00
Ian Campbell 95fad62ad6 hvmloader: add missing emacs local variables.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
2011-06-08 13:40:46 +01:00
Ian Campbell 80766862aa hvmloader: Add a simple "scratch allocator"
Returns memory which is passed to the subsequent BIOS but can be
reused once the contents is consumed. An example of this would be a
BIOS table which the BIOS consumes by copying rather than simply
referencing.

Users which need a temporary scratch buffer for internal use
scratch_start which follows these allocations.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
2011-06-01 16:46:28 +01:00
Ian Campbell b39d3fa428 hvmloader: setup PCI bus in a common function again.
Previous refactoring was premature.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
2011-06-01 16:41:42 +01:00