Commit Graph
35600 Commits
Author SHA1 Message Date
Jan Beulich 4b78efa91c gnttab: correct maptrack table accesses
In order to observe a consistent (limit,pointer-table) pair, the reader
needs to either hold the maptrack lock (in line with documentation) or
both sides need to order their accesses suitably (the writer side
barrier was removed by commit dff515dfea ["gnttab: use per-VCPU
maptrack free lists"], and a read side barrier has never been there).

Make the writer publish a new table page before limit (for bounds
checks to work), and new list head last (for racing maptrack_entry()
invocations to work). At the same time add read barriers to lockless
readers.

Additionally get_maptrack_handle() must not assume ->maptrack_head to
not change behind its back: Another handle may be put (updating only
->maptrack_tail) and then got or stolen (updating ->maptrack_head).

This is part of XSA-218.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
2017-06-20 14:34:34 +02:00
George Dunlap b7f6cbb9d4 gnttab: Avoid potential double-put of maptrack entry
Each grant mapping for a particular domain is tracked by an in-Xen
"maptrack" entry.  This entry is is referenced by a "handle", which is
given to the guest when it calls gnttab_map_grant_ref().

There are two types of mapping a particular handle can refer to:
GNTMAP_host_map and GNTMAP_device_map.  A given
gnttab_unmap_grant_ref() call can remove either only one or both of
these entries.  When a particular handle has no entries left, it must
be freed.

gnttab_unmap_grant_ref() loops through its grant unmap request list
twice.  It first removes entries from any host pagetables and (if
appropraite) iommus; then it does a single domain TLB flush; then it
does the clean-up, including telling the granter that entries are no
longer being used (if appropriate).

At the moment, it's during the first pass that the maptrack flags are
cleared, but the second pass that the maptrack entry is freed.

Unfortunately this allows the following race, which results in a
double-free:

 A: (pass 1) clear host_map
 B: (pass 1) clear device_map
 A: (pass 2) See that maptrack entry has no mappings, free it
 B: (pass 2) See that maptrack entry has no mappings, free it #

Unfortunately, unlike the active entry pinning update, we can't simply
move the maptrack flag changes to the second half, because the
maptrack flags are used to determine if iommu entries need to be
added: a domain's iommu must never have fewer permissions than the
maptrack flags indicate, or a subsequent map_grant_ref() might fail to
add the necessary iommu entries.

Instead, free the maptrack entry in the first pass if there are no
further mappings.

This is part of XSA-218.

Reported-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
2017-06-20 14:33:13 +02:00
Jan Beulich 9a0bd460cf gnttab: fix unmap pin accounting race
Once all {writable} mappings of a grant entry have been unmapped, the
hypervisor informs the guest that the grant entry has been released by
clearing the _GTF_{reading,writing} usage flags in the guest's grant
table as appropriate.

Unfortunately, at the moment, the code that updates the accounting
happens in a different critical section than the one which updates the
usage flags; this means that under the right circumstances, there may be
a window in time after the hypervisor reported the grant as being free
during which the grant referee still had access to the page.

Move the grant accounting code into the same critical section as the
reporting code to make sure this kind of race can't happen.

This is part of XSA-218.

Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
2017-06-20 14:32:03 +02:00
Jan Beulich fae7d5be8b x86/mm: disallow page stealing from HVM domains
The operation's success can't be controlled by the guest, as the device
model may have an active mapping of the page. If we nevertheless
permitted this operation, we'd have to add further TLB flushing to
prevent scenarios like

"Domains A (HVM), B (PV), C (PV); B->target==A
 Steps:
 1. B maps page X from A as writable
 2. B unmaps page X without a TLB flush
 3. A sends page X to C via GNTTABOP_transfer
 4. C maps page X as pagetable (potentially causing a TLB flush in C,
 but not in B)

 At this point, X would be mapped as a pagetable in C while being
 writable through a stale TLB entry in B."

A similar scenario could be constructed for A using XENMEM_exchange and
some arbitrary PV domain C then having this page allocated.

This is XSA-217.

Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: George Dunlap <george.dunlap@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
2017-06-20 14:29:51 +02:00
Wei Liu 461b216534 ipxe: update to newer commit
To get 5f85cbb9ee1c00cec81a848a9e871ad5d1e7f53f to placate gcc 7.

The only patch we have applies cleanly.

Reported-by: Zhongze Liu <blackskygg@gmail.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
2017-06-19 14:05:58 +01:00
Zhongze Liu 2d78f78a14 tools: fix several "format-truncation" warnings with GCC 7
GCC 7.1.1 complains that several buffers passed to snprintf() in xenpmd
and tools/ocmal/xc are too small to hold the largest possible resulting string,
which is calculated by adding up the maximum length of all the substrings.

The warnings are treated as errors by -Werror, and goes like this (abbreviated):

xenpmd.c:94:36: error: ‘%s’ directive output may be truncated writing up to
255 bytes into a region of size 13 [-Werror=format-truncation=]
     #define BATTERY_INFO_FILE_PATH "/proc/acpi/battery/%s/info"
                                    ^
xenpmd.c:113:13: note: ‘snprintf’ output between 25 and 280 bytes into a
destination of size 32

xenpmd.c:95:37: error: ‘%s’ directive output may be truncated writing up to
255 bytes into a region of size 13 [-Werror=format-truncation=]
     #define BATTERY_STATE_FILE_PATH "/proc/acpi/battery/%s/state"
                                     ^
xenpmd.c:116:13: note: ‘snprintf’ output between 26 and 281 bytes into a
destination of size 32

xenctrl_stubs.c:65:15: error: ‘%s’ directive output may be truncated writing
up to 1023 bytes into a region of size 252 [-Werror=format-truncation=]
      "%d: %s: %s", error->code,
               ^~
xenctrl_stubs.c:64:4: note: ‘snprintf’ output 5 or more bytes (assuming 1028)
into a destination of size 256

Enlarge the size of these buffers as suggested by the complier
(and slightly rounded) to fix the warnings.

No functional changes.

Signed-off-by: Zhongze Liu <blackskygg@gmail.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
2017-06-19 12:34:31 +01:00
Jan Beulich 7251b0d2b2 x86emul: minor cleanup
Drop a redundant input constraint and correct a comment.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2017-06-16 16:18:54 +02:00
Dushyant Behl 3910756987 x86/SVM: correct comments in vmcb.h
The VMEXIT codes listed from EXCEPTION_PF to EXCEPTION_XF had comments
describe the exitcodes slightly shifted than the expected value.
The expected exitcode value for page-fault is 78 which should be 0x4E
and so on till exception XF.

Signed-off-by: Dushyant Behl <myselfdushyantbehl@gmail.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
2017-06-16 16:18:10 +02:00
Julien Grall 534ecddd8a xen/arm: mm: Use typesafe MFN in dump_pt_walk
Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:55:55 -07:00
Julien Grall 265b56de8d xen/arm: mm: Use typesafe MFN in set_fixmap
Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:55:42 -07:00
Julien Grall 8258c741e2 xen/arm: Use the newly introduced MFN <-> MADDR and GFN <-> MADDR helpers
Replace the following constructions:
    - _gfn(paddr_to_pfn(...))   => gaddr_to_gfn(...)
    - _mfn(paddr_to_pfn(...))   => maddr_to_mfn(...)
    - pfn_to_paddr(mfn_x(...))  => mfn_to_maddr(...)
    - pfn_to_paddr(gfn_x(...))  => gfn_to_gaddr(...)
    - _mfn(... >> PAGE_SHIFT)   => maddr_to_mfn(...)

Signed-off-by: Julien Grall <julien.grall@arm.com>
Acked-by: Tamas K Lengyel <tamas@tklengyel.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Cc: Razvan Cojocaru <rcojocaru@bitdefender.com>
Cc: Tamas K Lengyel <tamas@tklengyel.com>
2017-06-15 16:55:16 -07:00
Julien Grall b110455f42 xen/arm: Introduce wrappers for MFN <-> MADDR and GFN <-> GADDR
The new wrappers will add more safety when converting an address to a
frame number (either machine or guest). A follow-up patch will use them
to simplify the code.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:54:52 -07:00
Julien Grall 67c3ca7a77 xen/arm: traps: Replace p2m_lookup(..., ..., NULL) by gfn_to_mfn(..., ...)
gfn_to_mfn is a wrapper of p2m_lookup which does not return the
p2m_type.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:54:41 -07:00
Julien Grall 38426987b6 xen/arm: Replace DIV_ROUND_UP(..., PAGE_SIZE) by PFN_UP(...)
DIV_ROUND_UP(..., PAGE_SIZE) and PFN_UP(...) are equivalent.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:54:29 -07:00
Julien Grall 7723dd6b1a xen/arm: mm: Replace __va(pfn_to_paddr(...)) by mfn_to_virt
__va(pfn_to_paddr(...)) and mfn_to_virt are equivalent.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:54:13 -07:00
Julien Grall 324834e4f1 xen/arm: domain_build: Replace paddr_to_pfn(virt_to_maddr(.)) by virt_to_mfn(.)
paddr_to_pfn(virt_to_maddr(.)) and virt_to_mfn(.) are equivalent.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:53:52 -07:00
Julien Grall 948066d052 xen/arm: Define mfn_to_page/page_to_mfn in term of __mfn_to_page/__page_to_mfn
This is matching the x86 side where the __* version is used if you need
to override the helpers in source files.

At the same time, move the non-underscore version at the end of the
defintion and add a comment to explain them.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:53:41 -07:00
Julien Grall c702d8a05a xen/arm: mm: Use typesafe MFN in mfn_to_xen_entry
Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:53:11 -07:00
Julien Grall 7ddc55f2e3 xen/arm: mm: Clean-up mfn_to_xen_entry
The physical address is computed from the machine frame number, so
checking if the physical address is page aligned is pointless.

Furthermore, directly assigned the MFN to the corresponding field in the
entry rather than converting to a physical address and orring the value.
It will avoid to rely on the field position and make the code clearer.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:52:59 -07:00
Julien Grall b8d6b337d9 xen/arm: mm: Fix coding style of mfn_to_xen_entry
Fix the comment coding style and add a newline before the return.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:52:33 -07:00
Julien Grall ed67177ac2 xen/arm: mm: Move mfn_to_xen_entry from page.h to mm.c
The file mm.c is the only user of mfn_to_xen_entry. This will also help
to use the typesafe MFN.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:52:19 -07:00
Julien Grall 615656a910 xen/arm: mm: Introduce clear_table and use it
Add a new helper clear_table to clear a page table entry and invalidate
the cache.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:52:06 -07:00
Julien Grall 5da2fc8784 xen/arm: gic-v2: Fix indentation in gicv2_map_hwdom_extra_mappings
Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-15 16:51:44 -07:00
Andre Przywara 695bb5f504 ARM: vITS: create ITS subnodes for Dom0 DT
Dom0 expects all ITSes in the system to be propagated to be able to
use MSIs.
Create Dom0 DT nodes for each hardware ITS, keeping the register frame
address the same, as the doorbell address that the Dom0 drivers program
into the BARs has to match the hardware.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
2017-06-14 11:38:38 -07:00
Andre Przywara a1df3d257f ARM: vITS: create and initialize virtual ITSes for Dom0
For each hardware ITS create and initialize a virtual ITS for Dom0.
We use the same memory mapped address to keep the doorbell working.
This introduces a function to initialize a virtual ITS.
We maintain a list of virtual ITSes, at the moment for the only
purpose of later being able to free them again.
We configure the virtual ITSes to match the hardware ones, that is we
keep the number of device ID bits and event ID bits the same as the host
ITS.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
2017-06-14 11:38:38 -07:00
Andre Przywara 1bef9339a0 ARM: vITS: increase mmio_count for each ITS
Increase the count of MMIO regions needed by one for each ITS Dom0 has
to emulate. We emulate the ITSes 1:1 from the hardware, so the number
is the number of host ITSes.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara e975cca32b ARM: vITS: handle INVALL command
The INVALL command instructs an ITS to invalidate the configuration
data for all LPIs associated with a given redistributor (read: VCPU).
This is nasty to emulate exactly with our architecture, so we just
iterate over all mapped LPIs and filter for those from that particular
VCPU.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara e115e7c3e0 ARM: vITS: handle INV command
The INV command instructs the ITS to update the configuration data for
a given LPI by re-reading its entry from the property table.
We don't need to care so much about the priority value, but enabling
or disabling an LPI has some effect: We remove or push virtual LPIs
to their VCPUs, also check the virtual pending bit if an LPI gets enabled.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 5928960ee7 ARM: vITS: handle DISCARD command
The DISCARD command drops the connection between a DeviceID/EventID
and an LPI/collection pair.
We mark the respective structure entries as not allocated and make
sure that any queued IRQs are removed.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 5cf6a82627 ARM: vITS: handle MOVI command
The MOVI command moves the interrupt affinity from one redistributor
(read: VCPU) to another.
For now migration of "live" LPIs is not yet implemented, but we store
the changed affinity in our virtual ITTE and the pending_irq.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 5e8d02560a ARM: vITS: handle MAPTI/MAPI command
The MAPTI commands associates a DeviceID/EventID pair with a LPI/CPU
pair and actually instantiates LPI interrupts. MAPI is just a variant
of this comment, where the LPI ID is the same as the event ID.
We connect the already allocated host LPI to this virtual LPI, so that
any triggering LPI on the host can be quickly forwarded to a guest.
Beside entering the domain and the virtual LPI number in the respective
host LPI entry, we also initialize and add the already allocated
struct pending_irq to our radix tree, so that we can now easily find it
by its virtual LPI number.
We also read the property table to update the enabled bit and the
priority for our new LPI, as we might have missed this during an earlier
INVALL call (which only checks mapped LPIs). But we make sure that the
property table is actually valid, as all redistributors might still
be disabled at this point.
Since write_itte() now sees its first usage, we change the declaration
to static.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara bccfbe70a3 ARM: GICv3: handle unmapped LPIs
When LPIs get unmapped by a guest, they might still be in some LR of
some VCPU. Nevertheless we remove the corresponding pending_irq
(possibly freeing it), and detect this case (irq_to_pending() returns
NULL) when the LR gets cleaned up later.
However a *new* LPI may get mapped with the same number while the old
LPI is *still* in some LR. To avoid getting the wrong state, we mark
every newly mapped LPI as PRISTINE, which means: has never been in an
LR before. If we detect the LPI in an LR anyway, it must have been an
older one, which we can simply retire.
Before inserting such a PRISTINE LPI into an LR, we must make sure that
it's not already in another LR, as the architecture forbids two
interrupts with the same virtual IRQ number on one CPU.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 08055c8ea7 ARM: vITS: handle MAPD command
The MAPD command maps a device by associating a memory region for
storing ITEs with a certain device ID. Since it features a valid bit,
MAPD also covers the "unmap" functionality, which we also cover here.
We store the given guest physical address in the device table, and, if
this command comes from Dom0, tell the host ITS driver about this new
mapping, so it can issue the corresponding host MAPD command and create
the required tables. We take care of rolling back actions should one
step fail.
Upon unmapping a device we make sure we clean up all associated
resources and release the memory again.
We use our existing guest memory access function to find the right ITT
entry and store the mapping there (in guest memory).

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 70a7fe3a55 ARM: vITS: handle CLEAR command
This introduces the ITS command handler for the CLEAR command, which
clears the pending state of an LPI.
This removes a not-yet injected, but already queued IRQ from a VCPU.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 9d133712b4 ARM: vITS: handle MAPC command
The MAPC command associates a given collection ID with a given
redistributor, thus mapping collections to VCPUs.
We just store the vcpu_id in the collection table for that.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 0868890b06 ARM: vITS: handle INT command
The INT command sets a given LPI identified by a DeviceID/EventID pair
as pending and thus triggers it to be injected.
As read_itte() is now eventually used, we add the static keyword.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 1e73535149 ARM: vITS: provide access to struct pending_irq
For each device we allocate one struct pending_irq for each virtual
event (MSI).
Provide a helper function which returns the pointer to the appropriate
struct, to be able to find the right struct when given a virtual
deviceID/eventID pair.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:38 -07:00
Andre Przywara 4b09480a55 ARM: vITS: introduce translation table walks
The ITS stores the target (v)CPU and the (virtual) LPI number in tables.
Introduce functions to walk those tables and translate an device ID -
event ID pair into a pair of virtual LPI and vCPU.
We map those tables on demand - which is cheap on arm64 - and copy the
respective entries before using them, to avoid the guest tampering with
them meanwhile.

To allow compiling without warnings, we declare two functions as
non-static for the moment, which two later patches will fix.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara 4aa2e42406 ARM: vITS: add command handling stub and MMIO emulation
Emulate the memory mapped ITS registers and provide a stub to introduce
the ITS command handling framework (but without actually emulating any
commands at this time).
This fixes a misnomer in our virtual ITS structure, where the spec is
confusingly using ID_bits in GITS_TYPER to denote the number of event IDs
(in contrast to GICD_TYPER, where it means number of LPIs).

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara 9785ab2fd1 ARM: vGIC: advertise LPI support
To let a guest know about the availability of virtual LPIs, set the
respective bits in the virtual GIC registers and let a guest control
the LPI enable bit.
Only report the LPI capability if there is at least one ITS emulated
for that guest (which depends on the host having an ITS at the moment).
For Dom0 we report the same number of interrupts identifiers as the
host, whereas DomUs get a number fixed at 10 bits for the moments, which
covers all SPIs. Also we fix a slight inaccuracy here, since the
number of interrupt identifier specified in GICD_TYPER depends on the
stream interface and is independent from the number of actually wired
SPIs.
This also removes a "TBD" comment, as we now populate the processor
number in the GICR_TYPER register, which will be used by the ITS
emulation later on.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara 4b7846ba7c ARM: vGICv3: re-use vgic_reg64_check_access
vgic_reg64_check_access() checks for a valid access width of a 64-bit
MMIO register, which is useful beyond the current GICv3 emulation only.
Move this function to the vgic-emul.h to be easily reusable.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Vijaya Kumar K 1ba52a5724 ARM: introduce vgic_access_guest_memory()
This function allows to copy a chunk of data from and to guest physical
memory. It looks up the associated page from the guest's p2m tree
and maps this page temporarily for the time of the access.
This function was originally written by Vijaya as part of an earlier series:
https://patchwork.kernel.org/patch/8177251

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara fe7fa1332d ARM: vGICv3: handle virtual LPI pending and property tables
Allow a guest to provide the address and size for the memory regions
it has reserved for the GICv3 pending and property tables.
We sanitise the various fields of the respective redistributor
registers.
The MMIO read and write accesses are protected by locks, to avoid any
changing of the property or pending table address while a redistributor
is live and also to protect the non-atomic vgic_reg64_extract() function
on the MMIO read side.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara f98d6a0862 ARM: GICv3: forward pending LPIs to guests
Upon receiving an LPI on the host, we need to find the right VCPU and
virtual IRQ number to get this IRQ injected.
Iterate our two-level LPI table to find the domain ID and the virtual
LPI number quickly when the host takes an LPI. We then look up the
right VCPU in the struct pending_irq.
We use the existing injection function to let the GIC emulation deal
with this interrupt.
This introduces a do_LPI() as a hardware gic_ops.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara 41aca705ed ARM: GIC: ITS: remove no longer needed VCPU ID in host LPI entry
To get easy access to the VCPU a forwarded LPI interrupt should be
injected to, so far we stored the VCPU ID in the host LPI entry.
However this creates a redundancy, since we keep the target VCPU in
the struct pending_irq already, which we can easily look up given the
domain and the virtual LPI number.
Apart from removing the redundancy this avoids having to update this
information later and keeping it in sync in a race-free fashion.
Since this information has not been used that, this patch actually does
not change anything, it just removes the declaration and initialization.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara 33c68607f2 ARM: vGIC: add LPI VCPU ID to struct pending_irq
The target CPU for an LPI is encoded in the interrupt translation table
entry, so can't be easily derived from just an LPI number (short of
walking *all* tables and find the matching LPI).
To avoid this in case we need to know the VCPU (for the INVALL command,
for instance), put the VCPU ID in the struct pending_irq, so that it is
easily accessible.
We use the remaining 8 bits of padding space for that to avoid enlarging
the size of struct pending_irq. The number of VCPUs is limited to 127
at the moment anyway, which we also confirm with a BUILD_BUG_ON.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara 9c34e21429 ARM: vGIC: cache virtual LPI priority in struct pending_irq
We enhance struct pending_irq to cache the priority information
for LPIs. Reading the information from there is faster than accessing
the property table from guest memory. Also it use some padding area in
the struct, so does not require more memory.
This introduces the function to retrieve the LPI priority as a vgic_ops.
Also this moves the vgic_get_virq_priority() call in
vgic_vcpu_inject_irq() to happen after the NULL check of the pending_irq
pointer, so we can rely on the pointer in the new function.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
2017-06-14 11:38:37 -07:00
Andre Przywara 97b9b32509 ARM: GIC: export and extend vgic_init_pending_irq()
For LPIs we later want to dynamically allocate struct pending_irqs.
So beside needing to initialize the struct from there we also need
to clean it up and re-initialize it later on.
Export vgic_init_pending_irq() and extend it to be reusable.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Julien Grall <julien.grall@arm.com>
2017-06-14 11:38:37 -07:00
Andre Przywara 71c23f4d9f ARM: GICv3: introduce separate pending_irq structs for LPIs
For the same reason that allocating a struct irq_desc for each
possible LPI is not an option, having a struct pending_irq for each LPI
is also not feasible. We only care about mapped LPIs, so we can get away
with having struct pending_irq's only for them.
Maintain a radix tree per domain where we drop the pointer to the
respective pending_irq. The index used is the virtual LPI number.
The memory for the actual structures has been allocated already per
device at device mapping time.
Teach the existing VGIC functions to find the right pointer when being
given a virtual LPI number.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00
Andre Przywara 56e1b3ebc9 ARM: GIC: Add checks for NULL pointer pending_irq's
For LPIs the struct pending_irq's are dynamically allocated and the
pointers will be stored in a radix tree. Since an LPI can be "unmapped"
at any time, teach the VGIC how to deal with irq_to_pending() returning
a NULL pointer.
We just do nothing in this case or clean up the LR if the virtual LPI
number was still in an LR.

Those are all call sites for irq_to_pending(), as per:
"git grep irq_to_pending", and their evaluations:
(PROTECTED means: added NULL check and bailing out)

    xen/arch/arm/gic.c:
gic_route_irq_to_guest(): only called for SPIs, added ASSERT()
gic_remove_irq_from_guest(): only called for SPIs, added ASSERT()
gic_remove_from_lr_pending(): PROTECTED, called within VCPU VGIC lock
gic_raise_inflight_irq(): PROTECTED, called under VCPU VGIC lock
gic_raise_guest_irq(): PROTECTED, called under VCPU VGIC lock
gic_update_one_lr(): PROTECTED, called under VCPU VGIC lock

    xen/arch/arm/vgic.c:
vgic_migrate_irq(): not called for LPIs (virtual IRQs), added ASSERT()
arch_move_irqs(): not iterating over LPIs, LPI ASSERT already in place
vgic_disable_irqs(): not called for LPIs, added ASSERT()
vgic_enable_irqs(): not called for LPIs, added ASSERT()
vgic_vcpu_inject_irq(): PROTECTED, moved under VCPU VGIC lock

    xen/include/asm-arm/event.h:
local_events_need_delivery_nomask(): only called for a PPI, added ASSERT()

    xen/include/asm-arm/vgic.h:
(prototype)

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-14 11:38:37 -07:00