Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b5628ab authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ARM virtualization changes:
 "This contains parts of the ARM KVM support that have dependencies on
  other patches merged through the arm-soc tree.  In combination with
  patches coming through Russell's tree, this will finally add full
  support for the kernel based virtual machine on ARM, which has been
  awaited for some time now.

  Further, we now have a separate platform for virtual machines and qemu
  booting that is used by both Xen and KVM, separating these from the
  Versatile Express reference implementation.  Obviously, this new
  platform is multiplatform capable so it can be combined with existing
  machines in the same kernel."

* tag 'virt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (38 commits)
  ARM: arch_timer: include linux/errno.h
  arm: arch_timer: add missing inline in stub function
  ARM: KVM: arch_timers: Wire the init code and config option
  ARM: KVM: arch_timers: Add timer world switch
  ARM: KVM: arch_timers: Add guest timer core support
  ARM: KVM: Add VGIC configuration option
  ARM: KVM: VGIC initialisation code
  ARM: KVM: VGIC control interface world switch
  ARM: KVM: VGIC interrupt injection
  ARM: KVM: vgic: retire queued, disabled interrupts
  ARM: KVM: VGIC virtual CPU interface management
  ARM: KVM: VGIC distributor handling
  ARM: KVM: VGIC accept vcpu and dist base addresses from user space
  ARM: KVM: Initial VGIC infrastructure code
  ARM: KVM: Keep track of currently running vcpus
  KVM: ARM: Introduce KVM_ARM_SET_DEVICE_ADDR ioctl
  ARM: gic: add __ASSEMBLY__ guard to C definitions
  ARM: gic: define GICH offsets for VGIC support
  ARM: gic: add missing distributor defintions
  ARM: mach-virt: fixup machine descriptor after removal of sys_timer
  ...
parents a8f3740f fe7dc720
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
* ARM architected timer

ARM Cortex-A7 and Cortex-A15 have a per-core architected timer, which
provides per-cpu timers.
ARM cores may have a per-core architected timer, which provides per-cpu timers.

The timer is attached to a GIC to deliver its per-processor interrupts.

** Timer node properties:

- compatible : Should at least contain "arm,armv7-timer".
- compatible : Should at least contain one of
	"arm,armv7-timer"
	"arm,armv8-timer"

- interrupts : Interrupt list for secure, non-secure, virtual and
  hypervisor timers, in that order.
+38 −0
Original line number Diff line number Diff line
@@ -2210,6 +2210,44 @@ This ioctl returns the guest registers that are supported for the
KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.


4.80 KVM_ARM_SET_DEVICE_ADDR

Capability: KVM_CAP_ARM_SET_DEVICE_ADDR
Architectures: arm
Type: vm ioctl
Parameters: struct kvm_arm_device_address (in)
Returns: 0 on success, -1 on error
Errors:
  ENODEV: The device id is unknown
  ENXIO:  Device not supported on current system
  EEXIST: Address already set
  E2BIG:  Address outside guest physical address space
  EBUSY:  Address overlaps with other device range

struct kvm_arm_device_addr {
	__u64 id;
	__u64 addr;
};

Specify a device address in the guest's physical address space where guests
can access emulated or directly exposed devices, which the host kernel needs
to know about. The id field is an architecture specific identifier for a
specific device.

ARM divides the id field into two parts, a device id and an address type id
specific to the individual device.

  bits:  | 63        ...       32 | 31    ...    16 | 15    ...    0 |
  field: |        0x00000000      |     device id   |  addr type id  |

ARM currently only require this when using the in-kernel GIC support for the
hardware VGIC features, using KVM_ARM_DEVICE_VGIC_V2 as the device id.  When
setting the base address for the guest's mapping of the VGIC virtual CPU
and distributor interface, the ioctl must be called after calling
KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs.  Calling
this ioctl twice for any of the base addresses will return -EEXIST.


5. The kvm_run structure
------------------------

+5 −1
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ config ARM
	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
	select ARCH_HAVE_CUSTOM_GPIO_H
	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
	select ARCH_WANT_IPC_PARSE_VERSION
	select BUILDTIME_EXTABLE_SORT if MMU
	select CPU_PM if (SUSPEND || CPU_IDLE)
@@ -1112,6 +1113,8 @@ source "arch/arm/mach-versatile/Kconfig"
source "arch/arm/mach-vexpress/Kconfig"
source "arch/arm/plat-versatile/Kconfig"

source "arch/arm/mach-virt/Kconfig"

source "arch/arm/mach-vt8500/Kconfig"

source "arch/arm/mach-w90x900/Kconfig"
@@ -1560,9 +1563,10 @@ config HAVE_ARM_SCU
	help
	  This option enables support for the ARM system coherency unit

config ARM_ARCH_TIMER
config HAVE_ARM_ARCH_TIMER
	bool "Architected timer support"
	depends on CPU_V7
	select ARM_ARCH_TIMER
	help
	  This option enables support for the ARM architected timer

+1 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ machine-$(CONFIG_ARCH_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_SPEAR13XX)	+= spear13xx
machine-$(CONFIG_ARCH_SPEAR3XX)		+= spear3xx
machine-$(CONFIG_MACH_SPEAR600)		+= spear6xx
machine-$(CONFIG_ARCH_VIRT)		+= virt
machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
machine-$(CONFIG_ARCH_SUNXI)		+= sunxi

+103 −6
Original line number Diff line number Diff line
#ifndef __ASMARM_ARCH_TIMER_H
#define __ASMARM_ARCH_TIMER_H

#include <asm/barrier.h>
#include <asm/errno.h>
#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/types.h>

#include <clocksource/arm_arch_timer.h>

#ifdef CONFIG_ARM_ARCH_TIMER
int arch_timer_of_register(void);
int arch_timer_sched_clock_init(void);
struct timecounter *arch_timer_get_timecounter(void);

/*
 * These register accessors are marked inline so the compiler can
 * nicely work out which register we want, and chuck away the rest of
 * the code. At least it does so with a recent GCC (4.6.3).
 */
static inline void arch_timer_reg_write(const int access, const int reg, u32 val)
{
	if (access == ARCH_TIMER_PHYS_ACCESS) {
		switch (reg) {
		case ARCH_TIMER_REG_CTRL:
			asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
			break;
		case ARCH_TIMER_REG_TVAL:
			asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
			break;
		}
	}

	if (access == ARCH_TIMER_VIRT_ACCESS) {
		switch (reg) {
		case ARCH_TIMER_REG_CTRL:
			asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
			break;
		case ARCH_TIMER_REG_TVAL:
			asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
			break;
		}
	}

	isb();
}

static inline u32 arch_timer_reg_read(const int access, const int reg)
{
	u32 val = 0;

	if (access == ARCH_TIMER_PHYS_ACCESS) {
		switch (reg) {
		case ARCH_TIMER_REG_CTRL:
			asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
			break;
		case ARCH_TIMER_REG_TVAL:
			asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
			break;
		}
	}

	if (access == ARCH_TIMER_VIRT_ACCESS) {
		switch (reg) {
		case ARCH_TIMER_REG_CTRL:
			asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
			break;
		case ARCH_TIMER_REG_TVAL:
			asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
			break;
		}
	}

	return val;
}

static inline u32 arch_timer_get_cntfrq(void)
{
	u32 val;
	asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
	return val;
}

static inline u64 arch_counter_get_cntpct(void)
{
	u64 cval;

	isb();
	asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
	return cval;
}

static inline u64 arch_counter_get_cntvct(void)
{
	u64 cval;

	isb();
	asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
	return cval;
}

static inline void __cpuinit arch_counter_set_user_access(void)
{
	u32 cntkctl;

	asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));

	/* disable user access to everything */
	cntkctl &= ~((3 << 8) | (7 << 0));

	asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
}
#else
static inline int arch_timer_of_register(void)
{
@@ -18,11 +120,6 @@ static inline int arch_timer_sched_clock_init(void)
{
	return -ENXIO;
}

static inline struct timecounter *arch_timer_get_timecounter(void)
{
	return NULL;
}
#endif

#endif
Loading