Commit Graph

55 Commits

Author SHA1 Message Date
Marc Zyngier
48762767e1 ARM: KVM: change kvm_tlb_flush_vmid to kvm_tlb_flush_vmid_ipa
v8 is capable of invalidating Stage-2 by IPA, but v7 is not.
Change kvm_tlb_flush_vmid() to take an IPA parameter, which is
then ignored by the invalidation code (and nuke the whole TLB
as it always did).

This allows v8 to implement a more optimized strategy.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:45 -08:00
Marc Zyngier
06fe0b73ff ARM: KVM: move include of asm/idmap.h to kvm_mmu.h
Since the arm64 code doesn't have a global asm/idmap.h file, move
the inclusion to asm/kvm_mmu.h.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:45 -08:00
Marc Zyngier
d7bb077737 ARM: KVM: vgic: decouple alignment restriction from page size
The virtual GIC is supposed to be 4kB aligned. On a 64kB page
system, comparing the alignment to PAGE_SIZE is wrong.

Use SZ_4K instead.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:44 -08:00
Marc Zyngier
cfe3950c2a ARM: KVM: fix fault_ipa computing
The ARM ARM says that HPFAR reports bits [39:12] of the faulting
IPA, and we need to complement it with the bottom 12 bits of the
faulting VA.

This is always 12 bits, irrespective of the page size. Makes it
clearer in the code.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:44 -08:00
Marc Zyngier
728d577d35 ARM: KVM: move kvm_target_cpu to guest.c
guest.c already contains some target-specific checks. Let's move
kvm_target_cpu() over there so arm.c is mostly target agnostic.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:44 -08:00
Marc Zyngier
b4034bde5f ARM: KVM: fix address validation for HYP mappings
__create_hyp_mappings() performs some kind of address validation before
creating the mapping, by verifying that the start address is above
PAGE_OFFSET.

This check is not completely correct for kernel memory (the upper
boundary has to be checked as well so we do not end up with highmem
pages), and wrong for IO mappings (the mapping must exist in the vmalloc
region).

Fix this by using the proper predicates (virt_addr_valid and
is_vmalloc_addr), which also work correctly on ARM64 (where the vmalloc
region is below PAGE_OFFSET).

Also change the BUG_ON() into a less agressive error return.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:44 -08:00
Marc Zyngier
06e8c3b0f3 ARM: KVM: allow HYP mappings to be at an offset from kernel mappings
arm64 cannot represent the kernel VAs in HYP mode, because of the lack
of TTBR1 at EL2. A way to cope with this situation is to have HYP VAs
to be an offset from the kernel VAs.

Introduce macros to convert a kernel VA to a HYP VA, make the HYP
mapping functions use these conversion macros. Also change the
documentation to reflect the existence of the offset.

On ARM, where we can have an identity mapping between kernel and HYP,
the macros are without any effect.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:44 -08:00
Marc Zyngier
9c7a6432fb ARM: KVM: use kvm_kernel_vfp_t as an abstract type for VFP containers
In order to keep the VFP allocation code common, use an abstract type
for the VFP containers. Maps onto struct vfp_hard_struct on ARM.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:44 -08:00
Marc Zyngier
e7858c58d5 ARM: KVM: move hyp init to kvm_host.h
Make the split of the pgd_ptr an implementation specific thing
by moving the init call to an inline function.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:44 -08:00
Marc Zyngier
c62ee2b227 ARM: KVM: abstract most MMU operations
Move low level MMU-related operations to kvm_mmu.h. This makes
the MMU code reusable by the arm64 port.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:44 -08:00
Christoffer Dall
c088f8f008 KVM: ARM: Reintroduce trace_kvm_hvc
This one got lost in the move to handle_exit, so let's reintroduce it
using an accessor to the immediate value field like the other ones.

Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:43 -08:00
Marc Zyngier
3414bbfff9 ARM: KVM: move exit handler selection to a separate file
The exit handler selection code cannot be shared with arm64
(two different modes, more exception classes...).

Move it to a separate file (handle_exit.c).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:43 -08:00
Marc Zyngier
c599756329 ARM: KVM: move kvm_condition_valid to emulate.c
This is really hardware emulation, and as such it better be with
its little friends.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:43 -08:00
Marc Zyngier
52d1dba933 ARM: KVM: abstract HSR_EC_IABT away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:43 -08:00
Marc Zyngier
1cc287dd08 ARM: KVM: abstract fault decoding away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:43 -08:00
Marc Zyngier
4926d445eb ARM: KVM: abstract exception class decoding away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:43 -08:00
Marc Zyngier
23b415d61a ARM: KVM: abstract IL decoding away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:43 -08:00
Marc Zyngier
a7123377e7 ARM: KVM: abstract SAS decoding away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:43 -08:00
Marc Zyngier
b37670b0f3 ARM: KVM: abstract S1TW abort detection away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:42 -08:00
Marc Zyngier
78abfcde49 ARM: KVM: abstract (and fix) external abort detection away
Bit 8 is cache maintenance, bit 9 is external abort.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:42 -08:00
Marc Zyngier
d0adf747c9 ARM: KVM: abstract HSR_SRT_{MASK,SHIFT} away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:42 -08:00
Marc Zyngier
7c511b881f ARM: KVM: abstract HSR_SSE away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:42 -08:00
Marc Zyngier
023cc96406 ARM: KVM: abstract HSR_WNR away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:42 -08:00
Marc Zyngier
4a1df28ac0 ARM: KVM: abstract HSR_ISV away
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:42 -08:00
Marc Zyngier
7393b59917 ARM: KVM: abstract fault register accesses
Instead of directly accessing the fault registers, use proper accessors
so the core code can be shared.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:42 -08:00
Marc Zyngier
db730d8d62 ARM: KVM: convert GP registers from u32 to unsigned long
On 32bit ARM, unsigned long is guaranteed to be a 32bit quantity.
On 64bit ARM, it is a 64bit quantity.

In order to be able to share code between the two architectures,
convert the registers to be unsigned long, so the core code can
be oblivious of the change.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-03-06 15:48:42 -08:00
Jonghwan Choi
0b5e3bac30 KVM: ARM: Fix wrong address in comment
hyp_hvc vector offset is 0x14 and hyp_svc vector offset is 0x8.

Signed-off-by: Jonghwan Choi <jhbird.choi@samsung.com>
Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
2013-03-06 15:48:42 -08:00
Marc Zyngier
3b8cd8a015 ARM: KVM: fix compilation after removal of user_alloc from struct kvm_memory_slot
Commit 7a905b1 (KVM: Remove user_alloc from struct kvm_memory_slot)
broke KVM/ARM by removing the user_alloc field from a public structure.

As we only used this field to alert the user that we didn't support
this operation mode, there is no harm in discarding this bit of code
without any remorse.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
2013-02-25 11:48:41 +02:00
Marc Zyngier
bef103aa7d ARM: KVM: fix kvm_arch_{prepare,commit}_memory_region
Commit f82a8cfe9 (KVM: struct kvm_memory_slot.user_alloc -> bool)
broke the ARM KVM port by changing the prototype of two global
functions.

Apply the same change to fix the compilation breakage.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
2013-02-25 11:47:28 +02:00
Marc Zyngier
967f84275b ARM: KVM: arch_timers: Wire the init code and config option
It is now possible to select CONFIG_KVM_ARM_TIMER to enable the
KVM architected timer support.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 19:06:00 +00:00
Marc Zyngier
c7e3ba64ba ARM: KVM: arch_timers: Add timer world switch
Do the necessary save/restore dance for the timers in the world
switch code. In the process, allow the guest to read the physical
counter, which is useful for its own clock_event_device.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 19:05:38 +00:00
Marc Zyngier
53e724067a ARM: KVM: arch_timers: Add guest timer core support
Add some the architected timer related infrastructure, and support timer
interrupt injection, which can happen as a resultof three possible
events:

- The virtual timer interrupt has fired while we were still
  executing the guest
- The timer interrupt hasn't fired, but it expired while we
  were doing the world switch
- A hrtimer we programmed earlier has fired

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 19:05:11 +00:00
Marc Zyngier
75431f9d73 ARM: KVM: Add VGIC configuration option
It is now possible to select the VGIC configuration option.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 19:00:15 +00:00
Marc Zyngier
01ac5e342f ARM: KVM: VGIC initialisation code
Add the init code for the hypervisor, the virtual machine, and
the virtual CPUs.

An interrupt handler is also wired to allow the VGIC maintenance
interrupts, used to deal with level triggered interrupts and LR
underflows.

A CPU hotplug notifier is registered to disable/enable the interrupt
as requested.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 19:00:10 +00:00
Marc Zyngier
348b2b0708 ARM: KVM: VGIC control interface world switch
Enable the VGIC control interface to be save-restored on world switch.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 19:00:03 +00:00
Marc Zyngier
5863c2ce72 ARM: KVM: VGIC interrupt injection
Plug the interrupt injection code. Interrupts can now be generated
from user space.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 18:59:55 +00:00
Marc Zyngier
a1fcb44e26 ARM: KVM: vgic: retire queued, disabled interrupts
An interrupt may have been disabled after being made pending on the
CPU interface (the classic case is a timer running while we're
rebooting the guest - the interrupt would kick as soon as the CPU
interface gets enabled, with deadly consequences).

The solution is to examine already active LRs, and check the
interrupt is still enabled. If not, just retire it.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 18:59:49 +00:00
Marc Zyngier
9d949dce52 ARM: KVM: VGIC virtual CPU interface management
Add VGIC virtual CPU interface code, picking pending interrupts
from the distributor and stashing them in the VGIC control interface
list registers.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 18:59:20 +00:00
Marc Zyngier
b47ef92af8 ARM: KVM: VGIC distributor handling
Add the GIC distributor emulation code. A number of the GIC features
are simply ignored as they are not required to boot a Linux guest.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 18:59:15 +00:00
Christoffer Dall
330690cdce ARM: KVM: VGIC accept vcpu and dist base addresses from user space
User space defines the model to emulate to a guest and should therefore
decide which addresses are used for both the virtual CPU interface
directly mapped in the guest physical address space and for the emulated
distributor interface, which is mapped in software by the in-kernel VGIC
support.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 18:59:01 +00:00
Marc Zyngier
1a89dd9113 ARM: KVM: Initial VGIC infrastructure code
Wire the basic framework code for VGIC support and the initial in-kernel
MMIO support code for the VGIC, used for the distributor emulation.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 18:58:55 +00:00
Marc Zyngier
1638a12d4e ARM: KVM: Keep track of currently running vcpus
When an interrupt occurs for the guest, it is sometimes necessary
to find out which vcpu was running at that point.

Keep track of which vcpu is being run in kvm_arch_vcpu_ioctl_run(),
and allow the data to be retrieved using either:
- kvm_arm_get_running_vcpu(): returns the vcpu running at this point
  on the current CPU. Can only be used in a non-preemptible context.
- kvm_arm_get_running_vcpus(): returns the per-CPU variable holding
  the running vcpus, usable for per-CPU interrupts.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 18:58:48 +00:00
Christoffer Dall
3401d54696 KVM: ARM: Introduce KVM_ARM_SET_DEVICE_ADDR ioctl
On ARM some bits are specific to the model being emulated for the guest and
user space needs a way to tell the kernel about those bits.  An example is mmio
device base addresses, where KVM must know the base address for a given device
to properly emulate mmio accesses within a certain address range or directly
map a device with virtualiation extensions into the guest address space.

We make this API ARM-specific as we haven't yet reached a consensus for a
generic API for all KVM architectures that will allow us to do something like
this.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2013-02-11 18:58:39 +00:00
Marc Zyngier
aa024c2f35 KVM: ARM: Power State Coordination Interface implementation
Implement the PSCI specification (ARM DEN 0022A) to control
virtual CPUs being "powered" on or off.

PSCI/KVM is detected using the KVM_CAP_ARM_PSCI capability.

A virtual CPU can now be initialized in a "powered off" state,
using the KVM_ARM_VCPU_POWER_OFF feature flag.

The guest can use either SMC or HVC to execute a PSCI function.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
2013-01-23 13:29:18 -05:00
Christoffer Dall
45e96ea6b3 KVM: ARM: Handle I/O aborts
When the guest accesses I/O memory this will create data abort
exceptions and they are handled by decoding the HSR information
(physical address, read/write, length, register) and forwarding reads
and writes to QEMU which performs the device emulation.

Certain classes of load/store operations do not support the syndrome
information provided in the HSR.  We don't support decoding these (patches
are available elsewhere), so we report an error to user space in this case.

This requires changing the general flow somewhat since new calls to run
the VCPU must check if there's a pending MMIO load and perform the write
after userspace has made the data available.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
2013-01-23 13:29:17 -05:00
Christoffer Dall
94f8e6418d KVM: ARM: Handle guest faults in KVM
Handles the guest faults in KVM by mapping in corresponding user pages
in the 2nd stage page tables.

We invalidate the instruction cache by MVA whenever we map a page to the
guest (no, we cannot only do it when we have an iabt because the guest
may happily read/write a page before hitting the icache) if the hardware
uses VIPT or PIPT.  In the latter case, we can invalidate only that
physical page.  In the first case, all bets are off and we simply must
invalidate the whole affair.  Not that VIVT icaches are tagged with
vmids, and we are out of the woods on that one.  Alexander Graf was nice
enough to remind us of this massive pain.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
2013-01-23 13:29:16 -05:00
Rusty Russell
4fe21e4c6d KVM: ARM: VFP userspace interface
We use space #18 for floating point regs.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
2013-01-23 13:29:15 -05:00
Christoffer Dall
c27581ed32 KVM: ARM: Demux CCSIDR in the userspace API
The Cache Size Selection Register (CSSELR) selects the current Cache
Size ID Register (CCSIDR).  You write which cache you are interested
in to CSSELR, and read the information out of CCSIDR.

Which cache numbers are valid is known by reading the Cache Level ID
Register (CLIDR).

To export this state to userspace, we add a KVM_REG_ARM_DEMUX
numberspace (17), which uses 8 bits to represent which register is
being demultiplexed (0 for CCSIDR), and the lower 8 bits to represent
this demultiplexing (in our case, the CSSELR value, which is 4 bits).

Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
2013-01-23 13:29:14 -05:00
Christoffer Dall
1138245ccf KVM: ARM: User space API for getting/setting co-proc registers
The following three ioctls are implemented:
 -  KVM_GET_REG_LIST
 -  KVM_GET_ONE_REG
 -  KVM_SET_ONE_REG

Now we have a table for all the cp15 registers, we can drive a generic
API.

The register IDs carry the following encoding:

ARM registers are mapped using the lower 32 bits.  The upper 16 of that
is the register group type, or coprocessor number:

ARM 32-bit CP15 registers have the following id bit patterns:
  0x4002 0000 000F <zero:1> <crn:4> <crm:4> <opc1:4> <opc2:3>

ARM 64-bit CP15 registers have the following id bit patterns:
  0x4003 0000 000F <zero:1> <zero:4> <crm:4> <opc1:4> <zero:3>

For futureproofing, we need to tell QEMU about the CP15 registers the
host lets the guest access.

It will need this information to restore a current guest on a future
CPU or perhaps a future KVM which allow some of these to be changed.

We use a separate table for these, as they're only for the userspace API.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
2013-01-23 13:29:14 -05:00
Christoffer Dall
5b3e5e5bf2 KVM: ARM: Emulation framework and CP15 emulation
Adds a new important function in the main KVM/ARM code called
handle_exit() which is called from kvm_arch_vcpu_ioctl_run() on returns
from guest execution. This function examines the Hyp-Syndrome-Register
(HSR), which contains information telling KVM what caused the exit from
the guest.

Some of the reasons for an exit are CP15 accesses, which are
not allowed from the guest and this commit handles these exits by
emulating the intended operation in software and skipping the guest
instruction.

Minor notes about the coproc register reset:
1) We reserve a value of 0 as an invalid cp15 offset, to catch bugs in our
   table, at cost of 4 bytes per vcpu.

2) Added comments on the table indicating how we handle each register, for
   simplicity of understanding.

Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
2013-01-23 13:29:13 -05:00