GitHub/moto-9609/android_kernel_motorola_exynos9610.git
7 years agoKVM: arm/arm64: Don't call map_resources when restoring ITS tables
Christoffer Dall [Mon, 8 May 2017 12:43:45 +0000 (14:43 +0200)]
KVM: arm/arm64: Don't call map_resources when restoring ITS tables

The only reason we called kvm_vgic_map_resources() when restoring the
ITS tables was because we wanted to have the KVM iodevs registered in
the KVM IO bus framework at the time when the ITS was restored such that
a restored and active device can inject MSIs prior to otherwise calling
kvm_vgic_map_resources() from the first run of a VCPU.

Since we now register the KVM iodevs for the redestributors and ITS as
soon as possible (when setting the base addresses), we no longer need
this call and kvm_vgic_map_resources() is again called only when first
running a VCPU.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: Register ITS iodev when setting base address
Christoffer Dall [Mon, 8 May 2017 11:14:57 +0000 (13:14 +0200)]
KVM: arm/arm64: Register ITS iodev when setting base address

We have to register the ITS iodevice before running the VM, because in
migration scenarios, we may be restoring a live device that wishes to
inject MSIs before the VCPUs have started.

All we need to register the ITS io device is the base address of the
ITS, so we can simply register that when the base address of the ITS is
set.

  [ Code to fix concurrency issues when setting the ITS base address and
    to fix the undef base address check written by Marc Zyngier ]

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: Get rid of its->initialized field
Marc Zyngier [Mon, 8 May 2017 17:15:40 +0000 (18:15 +0100)]
KVM: arm/arm64: Get rid of its->initialized field

The its->initialized doesn't bring much to the table, and creates
unnecessary ordering between setting the address and initializing it
(which amounts to exactly nothing).

Let's kill it altogether, making KVM_DEV_ARM_VGIC_CTRL_INIT the no-op
it deserves to be.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: Register iodevs when setting redist base and creating VCPUs
Christoffer Dall [Mon, 8 May 2017 10:30:24 +0000 (12:30 +0200)]
KVM: arm/arm64: Register iodevs when setting redist base and creating VCPUs

Instead of waiting with registering KVM iodevs until the first VCPU is
run, we can actually create the iodevs when the redist base address is
set.  The only downside is that we must now also check if we need to do
this for VCPUs which are created after creating the VGIC, because there
is no enforced ordering between creating the VGIC (and setting its base
addresses) and creating the VCPUs.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: Slightly rework kvm_vgic_addr
Christoffer Dall [Mon, 8 May 2017 10:28:19 +0000 (12:28 +0200)]
KVM: arm/arm64: Slightly rework kvm_vgic_addr

As we are about to handle setting the address for the redistributor base
region separately from some of the other base addresses, let's rework
this function to leave a little more room for being flexible in what
each type of base address does.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: Make vgic_v3_check_base more broadly usable
Christoffer Dall [Mon, 8 May 2017 10:23:51 +0000 (12:23 +0200)]
KVM: arm/arm64: Make vgic_v3_check_base more broadly usable

As we are about to fiddle with the IO device registration mechanism,
let's be a little more careful when setting base addresses as early as
possible.  When setting a base address, we can check that there's
address space enough for its scope and when the last of the two
base addresses (dist and redist) get set, we can also check if the
regions overlap at that time.

This allows us to provide error messages to the user at time when trying
to set the base address, as opposed to later when trying to run the VM.

To do this,  we make vgic_v3_check_base available in the core vgic-v3
code as well as in the other parts of the GICv3 code, namely the MMIO
config code.

We also return true for undefined base addresses so that the function
can be used before all base addresses are set; all callers already check
for uninitialized addresses before calling this function.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: Refactor vgic_register_redist_iodevs
Christoffer Dall [Mon, 8 May 2017 10:18:26 +0000 (12:18 +0200)]
KVM: arm/arm64: Refactor vgic_register_redist_iodevs

Split out the function to register all the redistributor iodevs into a
function that handles a single redistributor at a time in preparation
for being able to call this per VCPU as these get created.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: Add kvm_vcpu_get_idx to get vcpu index in kvm->vcpus
Christoffer Dall [Mon, 8 May 2017 18:38:40 +0000 (20:38 +0200)]
KVM: Add kvm_vcpu_get_idx to get vcpu index in kvm->vcpus

There are occasional needs to use the index of vcpu in the kvm->vcpus
array to map something related to a VCPU.  For example, unlike the
vcpu->vcpu_id, the vcpu index is guaranteed to not be sparse across all
vcpus which is useful when allocating a memory area for each vcpu.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: vgic: Rename kvm_vgic_vcpu_init to kvm_vgic_vcpu_enable
Christoffer Dall [Mon, 8 May 2017 10:09:13 +0000 (12:09 +0200)]
KVM: arm/arm64: vgic: Rename kvm_vgic_vcpu_init to kvm_vgic_vcpu_enable

This function really doesn't init anything, it enables the CPU
interface, so name it as such, which gives us the name to use for actual
init work later on.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: Clarification and relaxation to ITS save/restore ABI
Christoffer Dall [Mon, 8 May 2017 07:31:53 +0000 (09:31 +0200)]
KVM: arm/arm64: Clarification and relaxation to ITS save/restore ABI

Clarify what is meant by the save/restore ABI only supporting virtual
physical interrupts.

Relax the requirement of the order that the collection entries are
written in and be clear that there is no particular ordering enforced.

Some cosmetic changes in the capitalization of ID names to align with
the GICv3 manual and remove the empty line in the bottom of the patch.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm64: vgic-v3: KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES
Eric Auger [Mon, 9 Jan 2017 15:28:27 +0000 (16:28 +0100)]
KVM: arm64: vgic-v3: KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES

This patch adds a new attribute to GICV3 KVM device
KVM_DEV_ARM_VGIC_GRP_CTRL group. This allows userspace to
flush all GICR pending tables into guest RAM.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: Fix pending table sync
Eric Auger [Wed, 12 Apr 2017 12:13:27 +0000 (14:13 +0200)]
KVM: arm64: vgic-its: Fix pending table sync

In its_sync_lpi_pending_table() we currently ignore the
target_vcpu of the LPIs. We sync the pending bit found in
the vcpu pending table even if the LPI is not targeting it.

Also in vgic_its_cmd_handle_invall() we are supposed to
read the config table data for the LPIs associated to the
collection ID. At the moment we refresh all LPI config
information.

This patch passes a vpcu to vgic_copy_lpi_list() so that
this latter returns a snapshot of the LPIs targeting this
CPU and only those.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: ITT save and restore
Eric Auger [Wed, 3 May 2017 15:38:01 +0000 (17:38 +0200)]
KVM: arm64: vgic-its: ITT save and restore

Implement routines to save and restore device ITT and their
interrupt table entries (ITE).

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-its: Device table save/restore
Eric Auger [Mon, 9 Jan 2017 15:27:07 +0000 (16:27 +0100)]
KVM: arm64: vgic-its: Device table save/restore

This patch saves the device table entries into guest RAM.
Both flat table and 2 stage tables are supported. DeviceId
indexing is used.

For each device listed in the device table, we also save
the translation table using the vgic_its_save/restore_itt
routines. Those functions will be implemented in a subsequent
patch.

On restore, devices are re-allocated and their itt are
re-built.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-its: vgic_its_check_id returns the entry's GPA
Eric Auger [Tue, 31 Jan 2017 13:36:14 +0000 (14:36 +0100)]
KVM: arm64: vgic-its: vgic_its_check_id returns the entry's GPA

As vgic_its_check_id() computes the device/collection entry's
GPA, let's return it so that new callers can retrieve it easily.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Acked-by: Christoffer Dall <cdall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: Collection table save/restore
Eric Auger [Mon, 9 Jan 2017 15:19:41 +0000 (16:19 +0100)]
KVM: arm64: vgic-its: Collection table save/restore

The save path copies the collection entries into guest RAM
at the GPA specified in the BASER register. This obviously
requires the BASER to be set. The last written element is a
dummy collection table entry.

We do not index by collection ID as the collection entry
can fit into 8 bytes while containing the collection ID.

On restore path we re-allocate the collection objects.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: Add infrastructure for table lookup
Eric Auger [Wed, 8 Feb 2017 04:20:04 +0000 (05:20 +0100)]
KVM: arm64: vgic-its: Add infrastructure for table lookup

Add a generic scan_its_table() helper whose role consists in
scanning a contiguous table located in guest RAM and applying
a callback on each entry. Entries can be handled as linked lists
since the callback may return an id offset to the next entry and
also indicate whether the entry is the last one.

Helper functions also are added to compute the device/event ID
offset to the next DTE/ITE.

compute_next_devid_offset, compute_next_eventid_offset and
scan_table will become static in subsequent patches

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: vgic_its_alloc_ite/device
Eric Auger [Sun, 25 Dec 2016 17:57:54 +0000 (18:57 +0100)]
KVM: arm64: vgic-its: vgic_its_alloc_ite/device

Add two new helpers to allocate an its ite and an its device.
This will avoid duplication on restore path.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: KVM_DEV_ARM_ITS_SAVE/RESTORE_TABLES
Eric Auger [Sat, 24 Dec 2016 17:48:04 +0000 (18:48 +0100)]
KVM: arm64: vgic-its: KVM_DEV_ARM_ITS_SAVE/RESTORE_TABLES

Introduce new attributes in KVM_DEV_ARM_VGIC_GRP_CTRL group:
- KVM_DEV_ARM_ITS_SAVE_TABLES: saves the ITS tables into guest RAM
- KVM_DEV_ARM_ITS_RESTORE_TABLES: restores them into VGIC internal
  structures.

We hold the vcpus lock during the save and restore to make
sure no vcpu is running.

At this stage the functionality is not yet implemented. Only
the skeleton is put in place.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
[Given we will move the iodev register until setting the base addr]
Reviewed-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-its: Read config and pending bit in add_lpi()
Eric Auger [Thu, 4 May 2017 09:36:32 +0000 (11:36 +0200)]
KVM: arm64: vgic-its: Read config and pending bit in add_lpi()

When creating the lpi we now ask the redistributor what is the state
of the LPI (priority, enabled, pending).

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-v3: vgic_v3_lpi_sync_pending_status
Eric Auger [Thu, 4 May 2017 09:19:52 +0000 (11:19 +0200)]
KVM: arm64: vgic-v3: vgic_v3_lpi_sync_pending_status

this new helper synchronizes the irq pending_latch
with the LPI pending bit status found in rdist pending table.
As the status is consumed, we reset the bit in pending table.

As we need the PENDBASER_ADDRESS() in vgic-v3, let's move its
definition in the irqchip header. We restore the full length
of the field, ie [51:16]. Same for PROPBASER_ADDRESS with full
field length of [51:12].

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-its: Check the device id matches TYPER DEVBITS range
Eric Auger [Thu, 2 Feb 2017 13:37:33 +0000 (14:37 +0100)]
KVM: arm64: vgic-its: Check the device id matches TYPER DEVBITS range

On MAPD we currently check the device id can be stored in the device table.
Let's first check it can be encoded within the range defined by TYPER
DEVBITS.

Also check the collection ID belongs to the 16 bit range as GITS_TYPER
CIL field equals to 0.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: Interpret MAPD ITT_addr field
Eric Auger [Thu, 2 Feb 2017 12:45:45 +0000 (13:45 +0100)]
KVM: arm64: vgic-its: Interpret MAPD ITT_addr field

Up to now the MAPD ITT_addr had been ignored. We will need it
for save/restore. Let's record it in the its_device struct.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: Interpret MAPD Size field and check related errors
Eric Auger [Thu, 22 Dec 2016 17:14:14 +0000 (18:14 +0100)]
KVM: arm64: vgic-its: Interpret MAPD Size field and check related errors

Up to now the MAPD's ITT size field has been ignored. It encodes
the number of eventid bit minus 1. It should be used to check
the eventid when a MAPTI command is issued on a device. Let's
store the number of eventid bits in the its_device and do the
check on MAPTI. Also make sure the ITT size field does
not exceed the GITS_TYPER IDBITS field.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm64: vgic-its: Implement vgic_mmio_uaccess_write_its_iidr
Eric Auger [Thu, 23 Mar 2017 14:14:00 +0000 (15:14 +0100)]
KVM: arm64: vgic-its: Implement vgic_mmio_uaccess_write_its_iidr

The GITS_IIDR revision field is used to encode the migration ABI
revision. So we need to restore it to check the table layout is
readable by the destination.

By writing the IIDR, userspace thus forces the ABI revision to be
used and this must be less than or equal to the max revision KVM
supports.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-its: Introduce migration ABI infrastructure
Eric Auger [Thu, 13 Apr 2017 07:06:20 +0000 (09:06 +0200)]
KVM: arm64: vgic-its: Introduce migration ABI infrastructure

We plan to support different migration ABIs, ie. characterizing
the ITS table layout format in guest RAM. For example, a new ABI
will be needed if vLPIs get supported for nested use case.

So let's introduce an array of supported ABIs (at the moment a single
ABI is supported though). The following characteristics are foreseen
to vary with the ABI: size of table entries, save/restore operation,
the way abi settings are applied.

By default the MAX_ABI_REV is applied on its creation. In subsequent
patches we will introduce a way for the userspace to change the ABI
in use.

The entry sizes now are set according to the ABI version and not
hardcoded anymore.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-its: Implement vgic_mmio_uaccess_write_its_creadr
Eric Auger [Wed, 4 Jan 2017 10:58:41 +0000 (11:58 +0100)]
KVM: arm64: vgic-its: Implement vgic_mmio_uaccess_write_its_creadr

GITS_CREADR needs to be restored so let's implement the associated
uaccess_write_its callback. The write only is allowed if the its
is disabled.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-its: Implement vgic_its_has_attr_regs and attr_regs_access
Eric Auger [Tue, 20 Dec 2016 08:33:13 +0000 (09:33 +0100)]
KVM: arm64: vgic-its: Implement vgic_its_has_attr_regs and attr_regs_access

This patch implements vgic_its_has_attr_regs and vgic_its_attr_regs_access
upon the MMIO framework. VGIC ITS KVM device KVM_DEV_ARM_VGIC_GRP_ITS_REGS
group becomes functional.

At least GITS_CREADR and GITS_IIDR require to differentiate a guest write
action from a user access. As such let's introduce a new uaccess_its_write
vgic_register_region callback.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm/arm64: vgic: expose (un)lock_all_vcpus
Eric Auger [Thu, 23 Mar 2017 10:51:52 +0000 (11:51 +0100)]
KVM: arm/arm64: vgic: expose (un)lock_all_vcpus

We need to use those helpers in vgic-its.c so let's
expose them in the private vgic header.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm64: vgic-its: KVM_DEV_ARM_VGIC_GRP_ITS_REGS group
Eric Auger [Tue, 20 Dec 2016 06:36:35 +0000 (01:36 -0500)]
KVM: arm64: vgic-its: KVM_DEV_ARM_VGIC_GRP_ITS_REGS group

The ITS KVM device exposes a new KVM_DEV_ARM_VGIC_GRP_ITS_REGS
group which allows the userspace to save/restore ITS registers.

At this stage the get/set/has operations are not yet implemented.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoarm/arm64: vgic: turn vgic_find_mmio_region into public
Eric Auger [Tue, 20 Dec 2016 08:20:00 +0000 (09:20 +0100)]
arm/arm64: vgic: turn vgic_find_mmio_region into public

We plan to use vgic_find_mmio_region in vgic-its.c so let's
turn it into a public function.

Also let's take the opportunity to rename the region parameter
into regions to emphasize this latter is an array of regions.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic-its: rename itte into ite
Eric Auger [Wed, 8 Feb 2017 05:09:29 +0000 (06:09 +0100)]
KVM: arm/arm64: vgic-its: rename itte into ite

The actual abbreviation for the interrupt translation table entry
is ITE. Let's rename all itte instances by ite.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: Add GICV3 pending table save API documentation
Eric Auger [Fri, 14 Apr 2017 08:18:12 +0000 (10:18 +0200)]
KVM: arm/arm64: Add GICV3 pending table save API documentation

Add description for how to save GICV3 LPI pending bit into
guest RAM pending tables.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Acked-by: Christoffer Dall <cdall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm/arm64: Add ITS save/restore API documentation
Eric Auger [Mon, 9 Jan 2017 13:59:24 +0000 (14:59 +0100)]
KVM: arm/arm64: Add ITS save/restore API documentation

Add description for how to access ITS registers and how to save/restore
ITS tables into/from memory.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7 years agoKVM: arm/arm64: Move shared files to virt/kvm/arm
Christoffer Dall [Thu, 4 May 2017 11:54:17 +0000 (13:54 +0200)]
KVM: arm/arm64: Move shared files to virt/kvm/arm

For some time now we have been having a lot of shared functionality
between the arm and arm64 KVM support in arch/arm, which not only
required a horrible inter-arch reference from the Makefile in
arch/arm64/kvm, but also created confusion for newcomers to the code
base, as was recently seen on the mailing list.

Further, it causes confusion for things like cscope, which needs special
attention to index specific shared files for arm64 from the arm tree.

Move the shared files into virt/kvm/arm and move the trace points along
with it.  When moving the tracepoints we have to modify the way the vgic
creates definitions of the trace points, so we take the chance to
include the VGIC tracepoints in its very own special vgic trace.h file.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: KVM: Fix decoding of Rt/Rt2 when trapping AArch32 CP accesses
Marc Zyngier [Thu, 27 Apr 2017 18:06:48 +0000 (19:06 +0100)]
arm64: KVM: Fix decoding of Rt/Rt2 when trapping AArch32 CP accesses

Our 32bit CP14/15 handling inherited some of the ARMv7 code for handling
the trapped system registers, completely missing the fact that the
fields for Rt and Rt2 are now 5 bit wide, and not 4...

Let's fix it, and provide an accessor for the most common Rt case.

Cc: stable@vger.kernel.org
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: KVM: Fix idmap stub entry when running Thumb-2 code
Marc Zyngier [Thu, 20 Apr 2017 15:02:21 +0000 (16:02 +0100)]
ARM: KVM: Fix idmap stub entry when running Thumb-2 code

When entering the hyp stub implemented in the idmap, we try to
be mindful of the fact that we could be running a Thumb-2 kernel
by adding 1 to the address we compute. Unfortunately, the assembler
also knows about this trick, and has already generated an address
that has bit 0 set in the litteral pool.

Our superfluous correction ends up confusing the CPU entierely,
as we now branch to the stub in ARM mode instead of Thumb, and on
a possibly unaligned address for good measure. From that point,
nothing really good happens.

The obvious fix in to remove this stupid target PC correction.

Fixes: 6bebcecb6c5b ("ARM: KVM: Allow the main HYP code to use the init hyp stub implementation")
Reported-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: hyp-stub: Fix Thumb-2 compilation
Marc Zyngier [Thu, 20 Apr 2017 10:16:20 +0000 (11:16 +0100)]
ARM: hyp-stub: Fix Thumb-2 compilation

The assembler defaults to emiting the short form of ADR, leading
to an out-of-range immediate. Using the wide version solves this
issue.

Fixes: bc845e4fbbbb ("ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code")
Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic-v3: Fix off-by-one LR access
Marc Zyngier [Mon, 10 Apr 2017 09:19:44 +0000 (10:19 +0100)]
KVM: arm/arm64: vgic-v3: Fix off-by-one LR access

When iterating over the used LRs, be careful not to try to access
an unused LR, or even an unimplemented one if you're unlucky...

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic-v3: De-optimize VMCR save/restore when emulating a GICv2
Marc Zyngier [Wed, 19 Apr 2017 11:15:26 +0000 (12:15 +0100)]
KVM: arm/arm64: vgic-v3: De-optimize VMCR save/restore when emulating a GICv2

When emulating a GICv2-on-GICv3, special care must be taken to only
save/restore VMCR_EL2 when ICC_SRE_EL1.SRE is cleared. Otherwise,
all Group-0 interrupts end-up being delivered as FIQ, which is
probably not what the guest expects, as demonstrated here with
an unhappy EFI:

FIQ Exception at 0x000000013BD21CC4

This means that we cannot perform the load/put trick when dealing
with VMCR_EL2 (because the host has SRE set), and we have to deal
with it in the world-switch.

Fortunately, this is not the most common case (modern guests should
be able to deal with GICv3 directly), and the performance is not worse
than what it was before the VMCR optimization.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: fix races in kvm_psci_vcpu_on
Andrew Jones [Tue, 18 Apr 2017 15:59:58 +0000 (17:59 +0200)]
KVM: arm/arm64: fix races in kvm_psci_vcpu_on

Fix potential races in kvm_psci_vcpu_on() by taking the kvm->lock
mutex.  In general, it's a bad idea to allow more than one PSCI_CPU_ON
to process the same target VCPU at the same time.  One such problem
that may arise is that one PSCI_CPU_ON could be resetting the target
vcpu, which fills the entire sys_regs array with a temporary value
including the MPIDR register, while another looks up the VCPU based
on the MPIDR value, resulting in no target VCPU found.  Resolves both
races found with the kvm-unit-tests/arm/psci unit test.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reported-by: Levente Kurusa <lkurusa@redhat.com>
Suggested-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Andrew Jones <drjones@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoMerge remote-tracking branch 'rutland/kvm/common-sysreg' into next-fix
Christoffer Dall [Sun, 9 Apr 2017 14:50:34 +0000 (07:50 -0700)]
Merge remote-tracking branch 'rutland/kvm/common-sysreg' into next-fix

7 years agoKVM: arm/arm64: Advertise support for KVM_CAP_ARM_USER_IRQ
Christoffer Dall [Wed, 1 Feb 2017 11:54:11 +0000 (12:54 +0100)]
KVM: arm/arm64: Advertise support for KVM_CAP_ARM_USER_IRQ

Now that we support both timers and PMU reporting interrupts
to userspace, we can advertise this support.

Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7 years agoKVM: arm/arm64: Report PMU overflow interrupts to userspace irqchip
Christoffer Dall [Wed, 1 Feb 2017 11:51:52 +0000 (12:51 +0100)]
KVM: arm/arm64: Report PMU overflow interrupts to userspace irqchip

When not using an in-kernel VGIC, but instead emulating an interrupt
controller in userspace, we should report the PMU overflow status to
that userspace interrupt controller using the KVM_CAP_ARM_USER_IRQ
feature.

Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7 years agoKVM: arm/arm64: Support arch timers with a userspace gic
Alexander Graf [Tue, 27 Sep 2016 19:08:06 +0000 (21:08 +0200)]
KVM: arm/arm64: Support arch timers with a userspace gic

If you're running with a userspace gic or other interrupt controller
(that is no vgic in the kernel), then you have so far not been able to
use the architected timers, because the output of the architected
timers, which are driven inside the kernel, was a kernel-only construct
between the arch timer code and the vgic.

This patch implements the new KVM_CAP_ARM_USER_IRQ feature, where we use a
side channel on the kvm_run structure, run->s.regs.device_irq_level, to
always notify userspace of the timer output levels when using a userspace
irqchip.

This works by ensuring that before we enter the guest, if the timer
output level has changed compared to what we last told userspace, we
don't enter the guest, but instead return to userspace to notify it of
the new level.  If we are exiting, because of an MMIO for example, and
the level changed at the same time, the value is also updated and
userspace can sample the line as it needs.  This is nicely achieved
simply always updating the timer_irq_level field after the main run
loop.

Note that the kvm_timer_update_irq trace event is changed to show the
host IRQ number for the timer instead of the guest IRQ number, because
the kernel no longer know which IRQ userspace wires up the timer signal
to.

Also note that this patch implements all required functionality but does
not yet advertise the capability.

Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7 years agoKVM: arm/arm64: Add ARM user space interrupt signaling ABI
Alexander Graf [Tue, 27 Sep 2016 19:08:05 +0000 (21:08 +0200)]
KVM: arm/arm64: Add ARM user space interrupt signaling ABI

We have 2 modes for dealing with interrupts in the ARM world. We can
either handle them all using hardware acceleration through the vgic or
we can emulate a gic in user space and only drive CPU IRQ pins from
there.

Unfortunately, when driving IRQs from user space, we never tell user
space about events from devices emulated inside the kernel, which may
result in interrupt line state changes, so we lose out on for example
timer and PMU events if we run with user space gic emulation.

Define an ABI to publish such device output levels to userspace.

Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoKVM: arm/arm64: Cleanup the arch timer code's irqchip checking
Christoffer Dall [Tue, 27 Sep 2016 19:08:04 +0000 (21:08 +0200)]
KVM: arm/arm64: Cleanup the arch timer code's irqchip checking

Currently we check if we have an in-kernel irqchip and if the vgic was
properly implemented several places in the arch timer code.  But, we
already predicate our enablement of the arm timers on having a valid
and initialized gic, so we can simply check if the timers are enabled or
not.

This also gets rid of the ugly "error that's not an error but used to
signal that the timer shouldn't poke the gic" construct we have.

Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7 years agoarm/arm64: Add hyp-stub API documentation
Marc Zyngier [Mon, 3 Apr 2017 18:38:07 +0000 (19:38 +0100)]
arm/arm64: Add hyp-stub API documentation

In order to help people understanding the hyp-stub API that exists
between the host kernel and the hypervisor mode (whether a hypervisor
has been installed or not), let's document said API.

As with any form of documentation, I expect it to become obsolete
and completely misleading within 20 minutes after having being merged.

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: hyp-stub: Zero r0 on successful stub handling
Marc Zyngier [Mon, 3 Apr 2017 18:38:06 +0000 (19:38 +0100)]
ARM: hyp-stub: Zero r0 on successful stub handling

We now return HVC_STUB_ERR when a stub hypercall fails, but we
leave whatever was in r0 on success. Zeroing it on return seems
like a good idea.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: hyp-stub: Zero x0 on successful stub handling
Marc Zyngier [Mon, 3 Apr 2017 18:38:05 +0000 (19:38 +0100)]
arm64: hyp-stub: Zero x0 on successful stub handling

We now return HVC_STUB_ERR when a stub hypercall fails, but we
leave whatever was in x0 on success. Zeroing it on return seems
like a good idea.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: hyp-stub/KVM: Kill __hyp_get_vectors
Marc Zyngier [Mon, 3 Apr 2017 18:38:04 +0000 (19:38 +0100)]
arm64: hyp-stub/KVM: Kill __hyp_get_vectors

Nobody is using __hyp_get_vectors anymore, so let's remove both
implementations (hyp-stub and KVM).

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: hyp-stub/KVM: Kill __hyp_get_vectors
Marc Zyngier [Mon, 3 Apr 2017 18:38:03 +0000 (19:38 +0100)]
ARM: hyp-stub/KVM: Kill __hyp_get_vectors

Nobody is using __hyp_get_vectors anymore, so let's remove both
implementations (hyp-stub and KVM).

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: decompressor: Remove __hyp_get_vectors usage
Marc Zyngier [Mon, 3 Apr 2017 18:38:02 +0000 (19:38 +0100)]
ARM: decompressor: Remove __hyp_get_vectors usage

When the compressed image needs to be relocated to avoid being
overwritten by the decompression process, we need to relocate
the hyp vectors as well so that we can find them once the
decompression has taken effect.

For that, we perform the following calculation:
u32 v = __hyp_get_vectors();
v += offset;
__hyp_set_vectors(v);

But we're guaranteed that the initial value of v as returned by
__hyp_get_vectors is always __hyp_stub_vectors, because we have
just set it by calling __hyp_stub_install.

So let's remove the use of __hyp_get_vectors, and directly use
__hyp_stub_vectors instead.

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode
Marc Zyngier [Mon, 3 Apr 2017 18:38:01 +0000 (19:38 +0100)]
arm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode

Instead of trying to compare the value given by __hyp_get_vectors(),
which doesn't offer any real guarantee to be the stub's address, use
HVC_RESET_VECTORS to make sure we're in a sane state to reinstall
KVM across PM events.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm/arm64: KVM: Remove kvm_get_idmap_start
Marc Zyngier [Mon, 3 Apr 2017 18:38:00 +0000 (19:38 +0100)]
arm/arm64: KVM: Remove kvm_get_idmap_start

With __cpu_reset_hyp_mode having become fairly dumb, there is no
need for kvm_get_idmap_start anymore.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm/arm64: KVM: Use __hyp_reset_vectors() directly
Marc Zyngier [Mon, 3 Apr 2017 18:37:59 +0000 (19:37 +0100)]
arm/arm64: KVM: Use __hyp_reset_vectors() directly

__cpu_reset_hyp_mode doesn't need to be passed any argument now,
as the hyp-stub implementations are self-contained, and is now
reduced to just calling __hyp_reset_vectors(). Let's drop the
wrapper and use the stub hypercall directly.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: KVM: Gracefully handle hyp-stubs being restored from under our feet
Marc Zyngier [Mon, 3 Apr 2017 18:37:58 +0000 (19:37 +0100)]
ARM: KVM: Gracefully handle hyp-stubs being restored from under our feet

Should kvm_reboot() be invoked while guest is running, an IPI
wil be issued, forcing the guest to exit and HYP being reset to
the stubs. We will then try to reenter the guest, only to get
an error (HVC_STUB_ERR).

This patch allows this case to be gracefully handled by exiting
the run loop.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: KVM: Implement HVC_SOFT_RESTART in the init code
Marc Zyngier [Mon, 3 Apr 2017 18:37:57 +0000 (19:37 +0100)]
ARM: KVM: Implement HVC_SOFT_RESTART in the init code

Another missing stub hypercall is HVC_SOFT_RESTART. It turns out
that it is pretty easy to implement in terms of HVC_RESET_VECTORS
(since it needs to turn the MMU off).

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
Marc Zyngier [Mon, 3 Apr 2017 18:37:56 +0000 (19:37 +0100)]
ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors

We are now able to use the hyp stub to reset HYP mode. Time to
kiss __kvm_hyp_reset goodbye, and use __hyp_reset_vectors.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: KVM: Allow the main HYP code to use the init hyp stub implementation
Marc Zyngier [Mon, 3 Apr 2017 18:37:55 +0000 (19:37 +0100)]
ARM: KVM: Allow the main HYP code to use the init hyp stub implementation

We now have a full hyp-stub implementation in the KVM init code,
but the main KVM code only supports HVC_GET_VECTORS, which is not
enough.

Instead of reinventing the wheel, let's reuse the init implementation
by branching to the idmap page when called with a hyp-stub hypercall.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: KVM: Implement HVC_GET_VECTORS in the init code
Marc Zyngier [Mon, 3 Apr 2017 18:37:54 +0000 (19:37 +0100)]
ARM: KVM: Implement HVC_GET_VECTORS in the init code

Now that we have an infrastructure to handle hypercalls in the KVM
init code, let's implement HVC_GET_VECTORS there.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
Marc Zyngier [Mon, 3 Apr 2017 18:37:53 +0000 (19:37 +0100)]
ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code

In order to restore HYP mode to its original condition, KVM currently
implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
defined API, it becomes necessary to implement HVC_RESET_VECTORS.

This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
code, which so far lacked any form of hypercall support.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
Marc Zyngier [Mon, 3 Apr 2017 18:37:52 +0000 (19:37 +0100)]
ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall

Let's define a new stub hypercall that resets the HYP configuration
to its default: hyp-stub vectors, and MMU disabled.

Of course, for the hyp-stub itself, this is a trivial no-op.
Hypervisors will have a bit more work to do.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: hyp-stub: Define a return value for failed stub calls
Marc Zyngier [Mon, 3 Apr 2017 18:37:51 +0000 (19:37 +0100)]
ARM: hyp-stub: Define a return value for failed stub calls

Define a standard return value to be returned when a hyp stub
call fails.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: Expose the VA/IDMAP offset
Marc Zyngier [Mon, 3 Apr 2017 18:37:50 +0000 (19:37 +0100)]
ARM: Expose the VA/IDMAP offset

The KVM code needs to be able to compute the address of
symbols in its idmap page (the equivalent of a virt_to_idmap()
call). Unfortunately, virt_to_idmap is slightly complicated,
depending on the use of arch_phys_to_idmap_offset or not, and
none of that is readily available at HYP.

Instead, expose a single kimage_voffset variable which contains the
offset between a kernel VA and its idmap address, enabling the
VA->IDMAP conversion. This allows the KVM code to behave similarily
to its arm64 counterpart.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: hyp-stub: Use r1 for the soft-restart address
Marc Zyngier [Mon, 3 Apr 2017 18:37:49 +0000 (19:37 +0100)]
ARM: hyp-stub: Use r1 for the soft-restart address

It is not really obvious why the restart address should be in r3
when communicated to the hyp-stub. r1 should be perfectly adequate,
and consistent with the rest of the code.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: Update cpu_v7_reset documentation
Marc Zyngier [Mon, 3 Apr 2017 18:37:48 +0000 (19:37 +0100)]
ARM: Update cpu_v7_reset documentation

cpu_v7_reset() now takes a second parameter indicating whether
we should reboot in HYP or not. Update the documentation to
reflect this.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: KVM: Convert KVM to use HVC_GET_VECTORS
Marc Zyngier [Mon, 3 Apr 2017 18:37:47 +0000 (19:37 +0100)]
ARM: KVM: Convert KVM to use HVC_GET_VECTORS

The conversion of the HYP stub ABI to something similar to arm64
left the KVM code broken, as it doesn't know about the new
stub numbering. Let's move the various #defines to virt.h, and
let KVM use HVC_GET_VECTORS.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: soft-reboot into same mode that we entered the kernel
Russell King [Mon, 3 Apr 2017 18:37:46 +0000 (19:37 +0100)]
ARM: soft-reboot into same mode that we entered the kernel

When we soft-reboot (eg, kexec) from one kernel into the next, we need
to ensure that we enter the new kernel in the same processor mode as
when we were entered, so that (eg) the new kernel can install its own
hypervisor - the old kernel's hypervisor will have been overwritten.

In order to do this, we need to pass a flag to cpu_reset() so it knows
what to do, and we need to modify the kernel's own hypervisor stub to
allow it to handle a soft-reboot.

As we are always guaranteed to install our own hypervisor if we're
entered in HYP32 mode, and KVM will have moved itself out of the way
on kexec/normal reboot, we can assume that our hypervisor is in place
when we want to kexec, so changing our hypervisor API should not be a
problem.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoARM: hyp-stub: improve ABI
Russell King [Mon, 3 Apr 2017 18:37:45 +0000 (19:37 +0100)]
ARM: hyp-stub: improve ABI

Improve the hyp-stub ABI to allow it to do more than just get/set the
vectors.  We follow the example in ARM64, where r0 is used as an opcode
with the other registers as an argument.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: KVM: Implement HVC_SOFT_RESTART in the init code
Marc Zyngier [Mon, 3 Apr 2017 18:37:44 +0000 (19:37 +0100)]
arm64: KVM: Implement HVC_SOFT_RESTART in the init code

Another missing stub hypercall is HVC_SOFT_RESTART. It turns out
that it is pretty easy to implement in terms of HVC_RESET_VECTORS
(since it needs to turn the MMU off).

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
Marc Zyngier [Mon, 3 Apr 2017 18:37:43 +0000 (19:37 +0100)]
arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors

We are now able to use the hyp stub to reset HYP mode. Time to
kiss __kvm_hyp_reset goodbye, and use __hyp_reset_vectors.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: KVM: Allow the main HYP code to use the init hyp stub implementation
Marc Zyngier [Mon, 3 Apr 2017 18:37:42 +0000 (19:37 +0100)]
arm64: KVM: Allow the main HYP code to use the init hyp stub implementation

We now have a full hyp-stub implementation in the KVM init code,
but the main KVM code only supports HVC_GET_VECTORS, which is not
enough.

Instead of reinventing the wheel, let's reuse the init implementation
by branching to the idmap page when called with a hyp-stub hypercall.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: KVM: Implement HVC_GET_VECTORS in the init code
Marc Zyngier [Mon, 3 Apr 2017 18:37:41 +0000 (19:37 +0100)]
arm64: KVM: Implement HVC_GET_VECTORS in the init code

Now that we have an infrastructure to handle hypercalls in the KVM
init code, let's implement HVC_GET_VECTORS there.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
Marc Zyngier [Mon, 3 Apr 2017 18:37:40 +0000 (19:37 +0100)]
arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code

In order to restore HYP mode to its original condition, KVM currently
implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
defined API, it becomes necessary to implement HVC_RESET_VECTORS.

This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
code, which so far lacked any form of hypercall support.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
Marc Zyngier [Mon, 3 Apr 2017 18:37:39 +0000 (19:37 +0100)]
arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall

Let's define a new stub hypercall that resets the HYP configuration
to its default: hyp-stub vectors, and MMU disabled.

Of course, for the hyp-stub itself, this is a trivial no-op.
Hypervisors will have a bit more work to do.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: hyp-stub: Update documentation in asm/virt.h
Marc Zyngier [Mon, 3 Apr 2017 18:37:38 +0000 (19:37 +0100)]
arm64: hyp-stub: Update documentation in asm/virt.h

Comments in asm/virt.h are slightly out of date, so let's align
them with the new behaviour of the code.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: hyp-stub: Define a return value for failed stub calls
Marc Zyngier [Mon, 3 Apr 2017 18:37:37 +0000 (19:37 +0100)]
arm64: hyp-stub: Define a return value for failed stub calls

Define a standard return value to be returned when a hyp stub
call fails, and make KVM use it for ARM_EXCEPTION_HYP_GONE
(instead of using a KVM-specific value).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: hyp-stub: Don't save lr in the EL1 code
Marc Zyngier [Mon, 3 Apr 2017 18:37:36 +0000 (19:37 +0100)]
arm64: hyp-stub: Don't save lr in the EL1 code

The EL2 code is not corrupting lr anymore, so don't bother preserving
it in the EL1 trampoline code.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: KVM: Move lr save/restore to do_el2_call
Marc Zyngier [Mon, 3 Apr 2017 18:37:35 +0000 (19:37 +0100)]
arm64: KVM: Move lr save/restore to do_el2_call

At the moment, we only save/restore lr if on VHE, as we rely only
the EL1 code to have preserved it in the non-VHE case.

As we're about to get rid of the latter, let's move the save/restore
code to the do_el2_call macro, unifying both code paths.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: hyp-stub: Stop pointlessly clobbering lr
Marc Zyngier [Mon, 3 Apr 2017 18:37:34 +0000 (19:37 +0100)]
arm64: hyp-stub: Stop pointlessly clobbering lr

When entering the kernel hyp stub, we check whether or not we've
made it here through an HVC instruction, clobbering lr (aka x30)
in the process.

This is completely pointless, as HVC is the only way to get here
(all traps to EL2 are disabled, no interrupt override is applied).

So let's remove this bit of code whose only point is to corrupt
a valuable register.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm: KVM: Treat CP15 accessors returning false as successful
Marc Zyngier [Mon, 27 Mar 2017 16:03:45 +0000 (17:03 +0100)]
arm: KVM: Treat CP15 accessors returning false as successful

Instead of considering that a CP15 accessor has failed when
returning false, let's consider that it is *always* successful
(after all, we won't stand for an incomplete emulation).

The return value now simply indicates whether we should skip
the instruction (because it has now been emulated), or if we
should leave the PC alone if the emulation has injected an
exception.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoarm: KVM: Make unexpected register accesses inject an undef
Marc Zyngier [Mon, 27 Mar 2017 16:03:44 +0000 (17:03 +0100)]
arm: KVM: Make unexpected register accesses inject an undef

Reads from write-only system registers are generally confined to
EL1 and not propagated to EL2 (that's what the architecture
mantates). In order to be sure that we have a sane behaviour
even in the unlikely event that we have a broken system, we still
handle it in KVM. Same goes for write to RO registers.

In that case, let's inject an undef into the guest.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoarm64: KVM: Do not corrupt registers on failed 64bit CP read
Marc Zyngier [Mon, 27 Mar 2017 16:03:43 +0000 (17:03 +0100)]
arm64: KVM: Do not corrupt registers on failed 64bit CP read

If we fail to emulate a mrrc instruction, we:
1) deliver an exception,
2) spit a nastygram on the console,
3) write back some garbage to Rt/Rt2

While 1) and 2) are perfectly acceptable, 3) is out of the scope of
the architecture... Let's mimick the code in kvm_handle_cp_32 and
be more cautious.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoarm64: KVM: Treat sysreg accessors returning false as successful
Marc Zyngier [Mon, 27 Mar 2017 16:03:42 +0000 (17:03 +0100)]
arm64: KVM: Treat sysreg accessors returning false as successful

Instead of considering that a sysreg accessor has failed when
returning false, let's consider that it is *always* successful
(after all, we won't stand for an incomplete emulation).

The return value now simply indicates whether we should skip
the instruction (because it has now been emulated), or if we
should leave the PC alone if the emulation has injected an
exception.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoarm64: KVM: PMU: Inject UNDEF on read access to PMSWINC_EL0
Marc Zyngier [Mon, 27 Mar 2017 16:03:41 +0000 (17:03 +0100)]
arm64: KVM: PMU: Inject UNDEF on read access to PMSWINC_EL0

PMSWINC_EL0 is a WO register, so let's UNDEF when reading from it
(in the highly hypothetical case where this doesn't UNDEF at EL1).

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoarm64: KVM: Make unexpected reads from WO registers inject an undef
Marc Zyngier [Mon, 27 Mar 2017 16:03:40 +0000 (17:03 +0100)]
arm64: KVM: Make unexpected reads from WO registers inject an undef

Reads from write-only system registers are generally confined to
EL1 and not propagated to EL2 (that's what the architecture
mantates). In order to be sure that we have a sane behaviour
even in the unlikely event that we have a broken system, we still
handle it in KVM.

In that case, let's inject an undef into the guest.

Let's also remove write_to_read_only which isn't used anywhere.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoarm64: KVM: PMU: Inject UNDEF on non-privileged accesses
Marc Zyngier [Mon, 27 Mar 2017 16:03:39 +0000 (17:03 +0100)]
arm64: KVM: PMU: Inject UNDEF on non-privileged accesses

access_pminten() and access_pmuserenr() can only be accessed when
the CPU is in a priviledged mode. If it is not, let's inject an
UNDEF exception.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoarm64: KVM: PMU: Inject UNDEF exception on illegal register access
Marc Zyngier [Mon, 27 Mar 2017 16:03:38 +0000 (17:03 +0100)]
arm64: KVM: PMU: Inject UNDEF exception on illegal register access

Both pmu_*_el0_disabled() and pmu_counter_idx_valid() perform checks
on the validity of an access, but only return a boolean indicating
if the access is valid or not.

Let's allow these functions to also inject an UNDEF exception if
the access was illegal.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
7 years agoarm64: KVM: PMU: Refactor pmu_*_el0_disabled
Marc Zyngier [Mon, 27 Mar 2017 16:03:37 +0000 (17:03 +0100)]
arm64: KVM: PMU: Refactor pmu_*_el0_disabled

There is a lot of duplication in the pmu_*_el0_disabled helpers,
and as we're going to modify them shortly, let's move all the
common stuff in a single function.

No functional change.

Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Improve sync_hwstate performance
Christoffer Dall [Sat, 18 Mar 2017 12:48:42 +0000 (13:48 +0100)]
KVM: arm/arm64: vgic: Improve sync_hwstate performance

There is no need to call any functions to fold LRs when we don't use any
LRs and we don't need to mess with overflow flags, take spinlocks, or
prune the AP list if the AP list is empty.

Note: list_empty is a single atomic read (uses READ_ONCE) and can
therefore check if a list is empty or not without the need to take the
spinlock protecting the list.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Don't check vgic_initialized in sync/flush
Christoffer Dall [Sat, 18 Mar 2017 12:41:54 +0000 (13:41 +0100)]
KVM: arm/arm64: vgic: Don't check vgic_initialized in sync/flush

Now when we do an early init of the static parts of the VGIC data
structures, we can do things like checking if the AP lists are empty
directly without having to explicitly check if the vgic is initialized
and reduce a bit of work in our critical path.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Implement early VGIC init functionality
Christoffer Dall [Sat, 18 Mar 2017 12:40:37 +0000 (13:40 +0100)]
KVM: arm/arm64: vgic: Implement early VGIC init functionality

Implement early initialization for both the distributor and the CPU
interfaces.  The basic idea is that even though the VGIC is not
functional or not requested from user space, the critical path of the
run loop can still call VGIC functions that just won't do anything,
without them having to check additional initialization flags to ensure
they don't look at uninitialized data structures.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Get rid of MISR and EISR fields
Christoffer Dall [Thu, 29 Dec 2016 14:57:31 +0000 (15:57 +0100)]
KVM: arm/arm64: vgic: Get rid of MISR and EISR fields

We don't use these fields anymore so let's nuke them completely.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Get rid of unnecessary save_maint_int_state
Christoffer Dall [Thu, 29 Dec 2016 14:48:57 +0000 (15:48 +0100)]
KVM: arm/arm64: vgic: Get rid of unnecessary save_maint_int_state

Now when we don't look at the MISR and EISR values anymore, we can get
rid of the logic to save them in the GIC save/restore code.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Get rid of unnecessary process_maintenance operation
Christoffer Dall [Thu, 29 Dec 2016 14:44:27 +0000 (15:44 +0100)]
KVM: arm/arm64: vgic: Get rid of unnecessary process_maintenance operation

Since we always read back the LRs that we wrote to the guest and the
MISR and EISR registers simply provide a summary of the configuration of
the bits in the LRs, there is really no need to read back those status
registers and process them.  We might as well just signal the
notifyfd when folding the LR state and save some cycles in the process.
We now clear the underflow bit in the fold_lr_state functions as we only
need to clear this bit if we had used all the LRs, so this is as good a
place as any to do that work.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Only set underflow when actually out of LRs
Christoffer Dall [Tue, 21 Mar 2017 20:16:12 +0000 (21:16 +0100)]
KVM: arm/arm64: vgic: Only set underflow when actually out of LRs

We currently assume that all the interrupts in our AP list will be
queued to LRs, but that's not necessarily the case, because some of them
could have been migrated away to different VCPUs and only the VCPU
thread itself can remove interrupts from its AP list.

Therefore, slightly change the logic to only setting the underflow
interrupt when we actually run out of LRs.

As it turns out, this allows us to further simplify the handling in
vgic_sync_hwstate in later patches.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Get rid of live_lrs
Christoffer Dall [Thu, 22 Dec 2016 23:04:59 +0000 (00:04 +0100)]
KVM: arm/arm64: vgic: Get rid of live_lrs

There is no need to calculate and maintain live_lrs when we always
populate the lowest numbered LRs first on every entry and clear all LRs
on every exit.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Avoid flushing vgic state when there's no pending IRQ
Shih-Wei Li [Wed, 19 Oct 2016 18:12:34 +0000 (18:12 +0000)]
KVM: arm/arm64: vgic: Avoid flushing vgic state when there's no pending IRQ

We do not need to flush vgic states in each world switch unless
there is pending IRQ queued to the vgic's ap list. We can thus reduce
the overhead by not grabbing the spinlock and not making the extra
function call to vgic_flush_lr_state.

Note: list_empty is a single atomic read (uses READ_ONCE) and can
therefore check if a list is empty or not without the need to take the
spinlock protecting the list.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Shih-Wei Li <shihwei@cs.columbia.edu>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
7 years agoKVM: arm/arm64: vgic: Defer touching GICH_VMCR to vcpu_load/put
Christoffer Dall [Thu, 24 Mar 2016 10:21:04 +0000 (11:21 +0100)]
KVM: arm/arm64: vgic: Defer touching GICH_VMCR to vcpu_load/put

We don't have to save/restore the VMCR on every entry to/from the guest,
since on GICv2 we can access the control interface from EL1 and on VHE
systems with GICv3 we can access the control interface from KVM running
in EL2.

GICv3 systems without VHE becomes the rare case, which has to
save/restore the register on each round trip.

Note that userspace accesses may see out-of-date values if the VCPU is
running while accessing the VGIC state via the KVM device API, but this
is already the case and it is up to userspace to quiesce the CPUs before
reading the CPU registers from the GIC for an up-to-date view.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
Signed-off-by: Christoffer Dall <cdall@linaro.org>