Skip to content

Commit

Permalink
Merge tag 'for-linus-4.5-rc0-tag' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/xen/tip

Pull xen updates from David Vrabel:
 "Xen features and fixes for 4.5-rc0:

   - Stolen ticks and PV wallclock support for arm/arm64

   - Add grant copy ioctl to gntdev device"

* tag 'for-linus-4.5-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen/gntdev: add ioctl for grant copy
  x86/xen: don't reset vcpu_info on a cancelled suspend
  xen/gntdev: constify mmu_notifier_ops structures
  xen/grant-table: constify gnttab_ops structure
  xen/time: use READ_ONCE
  xen/x86: convert remaining timespec to timespec64 in xen_pvclock_gtod_notify
  xen/x86: support XENPF_settime64
  xen/arm: set the system time in Xen via the XENPF_settime64 hypercall
  xen/arm: introduce xen_read_wallclock
  arm: extend pvclock_wall_clock with sec_hi
  xen: introduce XENPF_settime64
  xen/arm: introduce HYPERVISOR_platform_op on arm and arm64
  xen: rename dom0_op to platform_op
  xen/arm: account for stolen ticks
  arm64: introduce CONFIG_PARAVIRT, PARAVIRT_TIME_ACCOUNTING and pv_time_ops
  arm: introduce CONFIG_PARAVIRT, PARAVIRT_TIME_ACCOUNTING and pv_time_ops
  missing include asm/paravirt.h in cputime.c
  xen: move xen_setup_runstate_info and get_runstate_snapshot to drivers/xen/time.c
  • Loading branch information
torvalds committed Jan 12, 2016
2 parents 75777c1 + a4cdb55 commit c9bed1c
Show file tree
Hide file tree
Showing 34 changed files with 677 additions and 131 deletions.
20 changes: 20 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1824,6 +1824,25 @@ config SWIOTLB
config IOMMU_HELPER
def_bool SWIOTLB

config PARAVIRT
bool "Enable paravirtualization code"
help
This changes the kernel so it can modify itself when it is run
under a hypervisor, potentially improving performance significantly
over full virtualization.

config PARAVIRT_TIME_ACCOUNTING
bool "Paravirtual steal time accounting"
select PARAVIRT
default n
help
Select this option to enable fine granularity task steal time
accounting. Time spent executing other tasks in parallel with
the current vCPU is discounted from the vCPU power. To account for
that, there can be a small performance impact.

If in doubt, say N here.

config XEN_DOM0
def_bool y
depends on XEN
Expand All @@ -1837,6 +1856,7 @@ config XEN
select ARCH_DMA_ADDR_T_64BIT
select ARM_PSCI
select SWIOTLB_XEN
select PARAVIRT
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.

Expand Down
20 changes: 20 additions & 0 deletions arch/arm/include/asm/paravirt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _ASM_ARM_PARAVIRT_H
#define _ASM_ARM_PARAVIRT_H

#ifdef CONFIG_PARAVIRT
struct static_key;
extern struct static_key paravirt_steal_enabled;
extern struct static_key paravirt_steal_rq_enabled;

struct pv_time_ops {
unsigned long long (*steal_clock)(int cpu);
};
extern struct pv_time_ops pv_time_ops;

static inline u64 paravirt_steal_clock(int cpu)
{
return pv_time_ops.steal_clock(cpu);
}
#endif

#endif
7 changes: 7 additions & 0 deletions arch/arm/include/asm/xen/hypercall.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include <xen/interface/xen.h>
#include <xen/interface/sched.h>
#include <xen/interface/platform.h>

long privcmd_call(unsigned call, unsigned long a1,
unsigned long a2, unsigned long a3,
Expand All @@ -49,6 +50,12 @@ int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
int HYPERVISOR_physdev_op(int cmd, void *arg);
int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args);
int HYPERVISOR_tmem_op(void *arg);
int HYPERVISOR_platform_op_raw(void *arg);
static inline int HYPERVISOR_platform_op(struct xen_platform_op *op)
{
op->interface_version = XENPF_INTERFACE_VERSION;
return HYPERVISOR_platform_op_raw(op);
}
int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr);

static inline int
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/include/asm/xen/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
(hnd).p = val; \
} while (0)

#define __HYPERVISOR_platform_op_raw __HYPERVISOR_platform_op

#ifndef __ASSEMBLY__
/* Explicitly size integers that represent pfns in the interface with
* Xen so that we can have one ABI that works for 32 and 64 bit guests.
Expand Down Expand Up @@ -76,6 +78,7 @@ struct pvclock_wall_clock {
u32 version;
u32 sec;
u32 nsec;
u32 sec_hi;
} __attribute__((__packed__));
#endif

Expand Down
1 change: 1 addition & 0 deletions arch/arm/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ obj-$(CONFIG_EFI) += efi.o
ifneq ($(CONFIG_ARCH_EBSA110),y)
obj-y += io.o
endif
obj-$(CONFIG_PARAVIRT) += paravirt.o

head-y := head$(MMUEXT).o
obj-$(CONFIG_DEBUG_LL) += debug.o
Expand Down
25 changes: 25 additions & 0 deletions arch/arm/kernel/paravirt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Copyright (C) 2013 Citrix Systems
*
* Author: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
*/

#include <linux/export.h>
#include <linux/jump_label.h>
#include <linux/types.h>
#include <asm/paravirt.h>

struct static_key paravirt_steal_enabled;
struct static_key paravirt_steal_rq_enabled;

struct pv_time_ops pv_time_ops;
EXPORT_SYMBOL_GPL(pv_time_ops);
95 changes: 95 additions & 0 deletions arch/arm/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <xen/page.h>
#include <xen/interface/sched.h>
#include <xen/xen-ops.h>
#include <asm/paravirt.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include <asm/system_misc.h>
Expand All @@ -25,6 +26,10 @@
#include <linux/cpufreq.h>
#include <linux/cpu.h>
#include <linux/console.h>
#include <linux/pvclock_gtod.h>
#include <linux/time64.h>
#include <linux/timekeeping.h>
#include <linux/timekeeper_internal.h>

#include <linux/mm.h>

Expand Down Expand Up @@ -79,6 +84,83 @@ int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
}
EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range);

static unsigned long long xen_stolen_accounting(int cpu)
{
struct vcpu_runstate_info state;

BUG_ON(cpu != smp_processor_id());

xen_get_runstate_snapshot(&state);

WARN_ON(state.state != RUNSTATE_running);

return state.time[RUNSTATE_runnable] + state.time[RUNSTATE_offline];
}

static void xen_read_wallclock(struct timespec64 *ts)
{
u32 version;
struct timespec64 now, ts_monotonic;
struct shared_info *s = HYPERVISOR_shared_info;
struct pvclock_wall_clock *wall_clock = &(s->wc);

/* get wallclock at system boot */
do {
version = wall_clock->version;
rmb(); /* fetch version before time */
now.tv_sec = ((uint64_t)wall_clock->sec_hi << 32) | wall_clock->sec;
now.tv_nsec = wall_clock->nsec;
rmb(); /* fetch time before checking version */
} while ((wall_clock->version & 1) || (version != wall_clock->version));

/* time since system boot */
ktime_get_ts64(&ts_monotonic);
*ts = timespec64_add(now, ts_monotonic);
}

static int xen_pvclock_gtod_notify(struct notifier_block *nb,
unsigned long was_set, void *priv)
{
/* Protected by the calling core code serialization */
static struct timespec64 next_sync;

struct xen_platform_op op;
struct timespec64 now, system_time;
struct timekeeper *tk = priv;

now.tv_sec = tk->xtime_sec;
now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
system_time = timespec64_add(now, tk->wall_to_monotonic);

/*
* We only take the expensive HV call when the clock was set
* or when the 11 minutes RTC synchronization time elapsed.
*/
if (!was_set && timespec64_compare(&now, &next_sync) < 0)
return NOTIFY_OK;

op.cmd = XENPF_settime64;
op.u.settime64.mbz = 0;
op.u.settime64.secs = now.tv_sec;
op.u.settime64.nsecs = now.tv_nsec;
op.u.settime64.system_time = timespec64_to_ns(&system_time);
(void)HYPERVISOR_platform_op(&op);

/*
* Move the next drift compensation time 11 minutes
* ahead. That's emulating the sync_cmos_clock() update for
* the hardware RTC.
*/
next_sync = now;
next_sync.tv_sec += 11 * 60;

return NOTIFY_OK;
}

static struct notifier_block xen_pvclock_gtod_notifier = {
.notifier_call = xen_pvclock_gtod_notify,
};

static void xen_percpu_init(void)
{
struct vcpu_register_vcpu_info info;
Expand All @@ -104,6 +186,8 @@ static void xen_percpu_init(void)
BUG_ON(err);
per_cpu(xen_vcpu, cpu) = vcpup;

xen_setup_runstate_info(cpu);

after_register_vcpu_info:
enable_percpu_irq(xen_events_irq, 0);
put_cpu();
Expand Down Expand Up @@ -271,6 +355,11 @@ static int __init xen_guest_init(void)

register_cpu_notifier(&xen_cpu_notifier);

pv_time_ops.steal_clock = xen_stolen_accounting;
static_key_slow_inc(&paravirt_steal_enabled);
if (xen_initial_domain())
pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);

return 0;
}
early_initcall(xen_guest_init);
Expand All @@ -282,6 +371,11 @@ static int __init xen_pm_init(void)

pm_power_off = xen_power_off;
arm_pm_restart = xen_restart;
if (!xen_initial_domain()) {
struct timespec64 ts;
xen_read_wallclock(&ts);
do_settimeofday64(&ts);
}

return 0;
}
Expand All @@ -307,5 +401,6 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
EXPORT_SYMBOL_GPL(privcmd_call);
1 change: 1 addition & 0 deletions arch/arm/xen/hypercall.S
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ HYPERCALL2(memory_op);
HYPERCALL2(physdev_op);
HYPERCALL3(vcpu_op);
HYPERCALL1(tmem_op);
HYPERCALL1(platform_op_raw);
HYPERCALL2(multicall);

ENTRY(privcmd_call)
Expand Down
20 changes: 20 additions & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,25 @@ config SECCOMP
and the task is only allowed to execute a few safe syscalls
defined by each seccomp mode.

config PARAVIRT
bool "Enable paravirtualization code"
help
This changes the kernel so it can modify itself when it is run
under a hypervisor, potentially improving performance significantly
over full virtualization.

config PARAVIRT_TIME_ACCOUNTING
bool "Paravirtual steal time accounting"
select PARAVIRT
default n
help
Select this option to enable fine granularity task steal time
accounting. Time spent executing other tasks in parallel with
the current vCPU is discounted from the vCPU power. To account for
that, there can be a small performance impact.

If in doubt, say N here.

config XEN_DOM0
def_bool y
depends on XEN
Expand All @@ -563,6 +582,7 @@ config XEN
bool "Xen guest support on ARM64"
depends on ARM64 && OF
select SWIOTLB_XEN
select PARAVIRT
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64.

Expand Down
20 changes: 20 additions & 0 deletions arch/arm64/include/asm/paravirt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _ASM_ARM64_PARAVIRT_H
#define _ASM_ARM64_PARAVIRT_H

#ifdef CONFIG_PARAVIRT
struct static_key;
extern struct static_key paravirt_steal_enabled;
extern struct static_key paravirt_steal_rq_enabled;

struct pv_time_ops {
unsigned long long (*steal_clock)(int cpu);
};
extern struct pv_time_ops pv_time_ops;

static inline u64 paravirt_steal_clock(int cpu)
{
return pv_time_ops.steal_clock(cpu);
}
#endif

#endif
1 change: 1 addition & 0 deletions arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o
arm64-obj-$(CONFIG_PCI) += pci.o
arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
arm64-obj-$(CONFIG_ACPI) += acpi.o
arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o

obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m)
Expand Down
25 changes: 25 additions & 0 deletions arch/arm64/kernel/paravirt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Copyright (C) 2013 Citrix Systems
*
* Author: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
*/

#include <linux/export.h>
#include <linux/jump_label.h>
#include <linux/types.h>
#include <asm/paravirt.h>

struct static_key paravirt_steal_enabled;
struct static_key paravirt_steal_rq_enabled;

struct pv_time_ops pv_time_ops;
EXPORT_SYMBOL_GPL(pv_time_ops);
1 change: 1 addition & 0 deletions arch/arm64/xen/hypercall.S
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ HYPERCALL2(memory_op);
HYPERCALL2(physdev_op);
HYPERCALL3(vcpu_op);
HYPERCALL1(tmem_op);
HYPERCALL1(platform_op_raw);
HYPERCALL2(multicall);

ENTRY(privcmd_call)
Expand Down
6 changes: 3 additions & 3 deletions arch/x86/include/asm/xen/hypercall.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,10 @@ HYPERVISOR_mca(struct xen_mc *mc_op)
}

static inline int
HYPERVISOR_dom0_op(struct xen_platform_op *platform_op)
HYPERVISOR_platform_op(struct xen_platform_op *op)
{
platform_op->interface_version = XENPF_INTERFACE_VERSION;
return _hypercall1(int, dom0_op, platform_op);
op->interface_version = XENPF_INTERFACE_VERSION;
return _hypercall1(int, platform_op, op);
}

static inline int
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/xen/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static u32 xen_apic_read(u32 reg)
if (reg != APIC_ID)
return 0;

ret = HYPERVISOR_dom0_op(&op);
ret = HYPERVISOR_platform_op(&op);
if (ret)
return 0;

Expand Down
Loading

0 comments on commit c9bed1c

Please sign in to comment.