* [PATCH v3 01/10] KVM: arm64: Document PV-time interface
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Introduce a paravirtualization interface for KVM/arm64 based on the
"Arm Paravirtualized Time for Arm-Base Systems" specification DEN 0057A.
This only adds the details about "Stolen Time" as the details of "Live
Physical Time" have not been fully agreed.
User space can specify a reserved area of memory for the guest and
inform KVM to populate the memory with information on time that the host
kernel has stolen from the guest.
A hypercall interface is provided for the guest to interrogate the
hypervisor's support for this interface and the location of the shared
memory structures.
Signed-off-by: Steven Price <steven.price@arm.com>
---
Documentation/virt/kvm/arm/pvtime.txt | 100 ++++++++++++++++++++++++++
1 file changed, 100 insertions(+)
create mode 100644 Documentation/virt/kvm/arm/pvtime.txt
diff --git a/Documentation/virt/kvm/arm/pvtime.txt b/Documentation/virt/kvm/arm/pvtime.txt
new file mode 100644
index 000000000000..1ceb118694e7
--- /dev/null
+++ b/Documentation/virt/kvm/arm/pvtime.txt
@@ -0,0 +1,100 @@
+Paravirtualized time support for arm64
+======================================
+
+Arm specification DEN0057/A defined a standard for paravirtualised time
+support for AArch64 guests:
+
+https://developer.arm.com/docs/den0057/a
+
+KVM/arm64 implements the stolen time part of this specification by providing
+some hypervisor service calls to support a paravirtualized guest obtaining a
+view of the amount of time stolen from its execution.
+
+Two new SMCCC compatible hypercalls are defined:
+
+PV_FEATURES 0xC5000020
+PV_TIME_ST 0xC5000022
+
+These are only available in the SMC64/HVC64 calling convention as
+paravirtualized time is not available to 32 bit Arm guests. The existence of
+the PV_FEATURES hypercall should be probed using the SMCCC 1.1 ARCH_FEATURES
+mechanism before calling it.
+
+PV_FEATURES
+ Function ID: (uint32) : 0xC5000020
+ PV_func_id: (uint32) : Either PV_TIME_LPT or PV_TIME_ST
+ Return value: (int32) : NOT_SUPPORTED (-1) or SUCCESS (0) if the relevant
+ PV-time feature is supported by the hypervisor.
+
+PV_TIME_ST
+ Function ID: (uint32) : 0xC5000022
+ Return value: (int64) : IPA of the stolen time data structure for this
+ (V)CPU. On failure:
+ NOT_SUPPORTED (-1)
+
+The IPA returned by PV_TIME_ST should be mapped by the guest as normal memory
+with inner and outer write back caching attributes, in the inner shareable
+domain. A total of 16 bytes from the IPA returned are guaranteed to be
+meaningfully filled by the hypervisor (see structure below).
+
+PV_TIME_ST returns the structure for the calling VCPU.
+
+Stolen Time
+-----------
+
+The structure pointed to by the PV_TIME_ST hypercall is as follows:
+
+ Field | Byte Length | Byte Offset | Description
+ ----------- | ----------- | ----------- | --------------------------
+ Revision | 4 | 0 | Must be 0 for version 0.1
+ Attributes | 4 | 4 | Must be 0
+ Stolen time | 8 | 8 | Stolen time in unsigned
+ | | | nanoseconds indicating how
+ | | | much time this VCPU thread
+ | | | was involuntarily not
+ | | | running on a physical CPU.
+
+The structure will be updated by the hypervisor prior to scheduling a VCPU. It
+will be present within a reserved region of the normal memory given to the
+guest. The guest should not attempt to write into this memory. There is a
+structure per VCPU of the guest.
+
+User space interface
+====================
+
+User space can request that KVM provide the paravirtualized time interface to
+a guest by creating a KVM_DEV_TYPE_ARM_PV_TIME device, for example:
+
+ struct kvm_create_device pvtime_device = {
+ .type = KVM_DEV_TYPE_ARM_PV_TIME,
+ .attr = 0,
+ .flags = 0,
+ };
+
+ pvtime_fd = ioctl(vm_fd, KVM_CREATE_DEVICE, &pvtime_device);
+
+Creation of the device should be done after creating the vCPUs of the virtual
+machine.
+
+The IPA of the structures must be given to KVM. This is the base address
+of an array of stolen time structures (one for each VCPU). The base address
+must be page aligned. The size must be at least 64 * number of VCPUs and be a
+multiple of PAGE_SIZE.
+
+The memory for these structures should be added to the guest in the usual
+manner (e.g. using KVM_SET_USER_MEMORY_REGION).
+
+For example:
+
+ struct kvm_dev_arm_st_region region = {
+ .gpa = <IPA of guest base address>,
+ .size = <size in bytes>
+ };
+
+ struct kvm_device_attr st_base = {
+ .group = KVM_DEV_ARM_PV_TIME_PADDR,
+ .attr = KVM_DEV_ARM_PV_TIME_ST,
+ .addr = (u64)®ion
+ };
+
+ ioctl(pvtime_fd, KVM_SET_DEVICE_ATTR, &st_base);
--
2.20.1
^ permalink raw reply related
* [PATCH v3 05/10] KVM: arm64: Support stolen time reporting via shared structure
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Implement the service call for configuring a shared structure between a
VCPU and the hypervisor in which the hypervisor can write the time
stolen from the VCPU's execution time by other tasks on the host.
The hypervisor allocates memory which is placed at an IPA chosen by user
space. The hypervisor then updates the shared structure using
kvm_put_guest() to ensure single copy atomicity of the 64-bit value
reporting the stolen time in nanoseconds.
Whenever stolen time is enabled by the guest, the stolen time counter is
reset.
The stolen time itself is retrieved from the sched_info structure
maintained by the Linux scheduler code. We enable SCHEDSTATS when
selecting KVM Kconfig to ensure this value is meaningful.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm/include/asm/kvm_host.h | 20 +++++++++
arch/arm64/include/asm/kvm_host.h | 25 +++++++++++-
arch/arm64/kvm/Kconfig | 1 +
include/linux/kvm_types.h | 2 +
virt/kvm/arm/arm.c | 10 +++++
virt/kvm/arm/hypercalls.c | 3 ++
virt/kvm/arm/pvtime.c | 67 +++++++++++++++++++++++++++++++
7 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 369b5d2d54bf..47d2ced99421 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -39,6 +39,7 @@
KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
#define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
+#define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
@@ -329,6 +330,25 @@ static inline int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
return SMCCC_RET_NOT_SUPPORTED;
}
+static inline int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu)
+{
+ return SMCCC_RET_NOT_SUPPORTED;
+}
+
+static inline int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init)
+{
+ return -ENOTSUPP;
+}
+
+static inline void kvm_pvtime_init_vm(struct kvm_arch *kvm_arch)
+{
+}
+
+static inline bool kvm_is_pvtime_enabled(struct kvm_arch *kvm_arch)
+{
+ return false;
+}
+
void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 583b3639062a..b6fa7beffd8a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -44,6 +44,7 @@
KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
#define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
+#define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
@@ -83,6 +84,11 @@ struct kvm_arch {
/* Mandated version of PSCI */
u32 psci_version;
+
+ struct kvm_arch_pvtime {
+ gpa_t st_base;
+ u64 st_size;
+ } pvtime;
};
#define KVM_NR_MEM_OBJS 40
@@ -338,8 +344,13 @@ struct kvm_vcpu_arch {
/* True when deferrable sysregs are loaded on the physical CPU,
* see kvm_vcpu_load_sysregs and kvm_vcpu_put_sysregs. */
bool sysregs_loaded_on_cpu;
-};
+ /* Guest PV state */
+ struct {
+ u64 steal;
+ u64 last_steal;
+ } steal;
+};
/* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
#define vcpu_sve_pffr(vcpu) ((void *)((char *)((vcpu)->arch.sve_state) + \
sve_ffr_offset((vcpu)->arch.sve_max_vl)))
@@ -479,6 +490,18 @@ int kvm_perf_init(void);
int kvm_perf_teardown(void);
int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
+int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu);
+int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init);
+
+static inline void kvm_pvtime_init_vm(struct kvm_arch *kvm_arch)
+{
+ kvm_arch->pvtime.st_base = GPA_INVALID;
+}
+
+static inline bool kvm_is_pvtime_enabled(struct kvm_arch *kvm_arch)
+{
+ return (kvm_arch->pvtime.st_base != GPA_INVALID);
+}
void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome);
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index a67121d419a2..d8b88e40d223 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -39,6 +39,7 @@ config KVM
select IRQ_BYPASS_MANAGER
select HAVE_KVM_IRQ_BYPASS
select HAVE_KVM_VCPU_RUN_PID_CHANGE
+ select SCHEDSTATS
---help---
Support hosting virtualized guest machines.
We don't support KVM with 16K page tables yet, due to the multiple
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index bde5374ae021..1c88e69db3d9 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -35,6 +35,8 @@ typedef unsigned long gva_t;
typedef u64 gpa_t;
typedef u64 gfn_t;
+#define GPA_INVALID (~(gpa_t)0)
+
typedef unsigned long hva_t;
typedef u64 hpa_t;
typedef u64 hfn_t;
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 35a069815baf..5e8343e2dd62 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -40,6 +40,10 @@
#include <asm/kvm_coproc.h>
#include <asm/sections.h>
+#include <kvm/arm_hypercalls.h>
+#include <kvm/arm_pmu.h>
+#include <kvm/arm_psci.h>
+
#ifdef REQUIRES_VIRT
__asm__(".arch_extension virt");
#endif
@@ -135,6 +139,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm->arch.max_vcpus = vgic_present ?
kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
+ kvm_pvtime_init_vm(&kvm->arch);
return ret;
out_free_stage2_pgd:
kvm_free_stage2_pgd(kvm);
@@ -379,6 +384,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
kvm_vcpu_load_sysregs(vcpu);
kvm_arch_vcpu_load_fp(vcpu);
kvm_vcpu_pmu_restore_guest(vcpu);
+ if (kvm_is_pvtime_enabled(&vcpu->kvm->arch))
+ kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
if (single_task_running())
vcpu_clear_wfe_traps(vcpu);
@@ -644,6 +651,9 @@ static void check_vcpu_requests(struct kvm_vcpu *vcpu)
* that a VCPU sees new virtual interrupts.
*/
kvm_check_request(KVM_REQ_IRQ_PENDING, vcpu);
+
+ if (kvm_check_request(KVM_REQ_RECORD_STEAL, vcpu))
+ kvm_update_stolen_time(vcpu, false);
}
}
diff --git a/virt/kvm/arm/hypercalls.c b/virt/kvm/arm/hypercalls.c
index 63ae629c466a..ac678eabf15f 100644
--- a/virt/kvm/arm/hypercalls.c
+++ b/virt/kvm/arm/hypercalls.c
@@ -56,6 +56,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
case ARM_SMCCC_HV_PV_FEATURES:
val = kvm_hypercall_pv_features(vcpu);
break;
+ case ARM_SMCCC_HV_PV_TIME_ST:
+ val = kvm_hypercall_stolen_time(vcpu);
+ break;
default:
return kvm_psci_call(vcpu);
}
diff --git a/virt/kvm/arm/pvtime.c b/virt/kvm/arm/pvtime.c
index 6201d71cb1f8..28603689f6e0 100644
--- a/virt/kvm/arm/pvtime.c
+++ b/virt/kvm/arm/pvtime.c
@@ -3,8 +3,51 @@
#include <linux/arm-smccc.h>
+#include <asm/pvclock-abi.h>
+
#include <kvm/arm_hypercalls.h>
+int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_arch_pvtime *pvtime = &kvm->arch.pvtime;
+ u64 steal;
+ u64 steal_le;
+ u64 offset;
+ int idx;
+ const int stride = sizeof(struct pvclock_vcpu_stolen_time);
+
+ if (pvtime->st_base == GPA_INVALID)
+ return -ENOTSUPP;
+
+ /* Let's do the local bookkeeping */
+ steal = vcpu->arch.steal.steal;
+ steal += current->sched_info.run_delay - vcpu->arch.steal.last_steal;
+ vcpu->arch.steal.last_steal = current->sched_info.run_delay;
+ vcpu->arch.steal.steal = steal;
+
+ offset = stride * kvm_vcpu_get_idx(vcpu);
+
+ if (unlikely(offset + stride > pvtime->st_size))
+ return -EINVAL;
+
+ steal_le = cpu_to_le64(steal);
+ idx = srcu_read_lock(&kvm->srcu);
+ if (init) {
+ struct pvclock_vcpu_stolen_time init_values = {
+ .revision = 0,
+ .attributes = 0
+ };
+ kvm_write_guest(kvm, pvtime->st_base + offset, &init_values,
+ sizeof(init_values));
+ }
+ offset += offsetof(struct pvclock_vcpu_stolen_time, stolen_time);
+ kvm_put_guest(kvm, pvtime->st_base + offset, steal_le, u64);
+ srcu_read_unlock(&kvm->srcu, idx);
+
+ return 0;
+}
+
int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
{
u32 feature = smccc_get_arg1(vcpu);
@@ -12,6 +55,7 @@ int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
switch (feature) {
case ARM_SMCCC_HV_PV_FEATURES:
+ case ARM_SMCCC_HV_PV_TIME_ST:
val = SMCCC_RET_SUCCESS;
break;
}
@@ -19,3 +63,26 @@ int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
return val;
}
+int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu)
+{
+ u64 ret;
+ int err;
+
+ /*
+ * Start counting stolen time from the time the guest requests
+ * the feature enabled.
+ */
+ vcpu->arch.steal.steal = 0;
+ vcpu->arch.steal.last_steal = current->sched_info.run_delay;
+
+ err = kvm_update_stolen_time(vcpu, true);
+
+ if (err)
+ ret = SMCCC_RET_NOT_SUPPORTED;
+ else
+ ret = vcpu->kvm->arch.pvtime.st_base +
+ (sizeof(struct pvclock_vcpu_stolen_time) *
+ kvm_vcpu_get_idx(vcpu));
+
+ return ret;
+}
--
2.20.1
^ permalink raw reply related
* [PATCH v3 02/10] KVM: arm/arm64: Factor out hypercall handling from PSCI code
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel, Christoffer Dall
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
From: Christoffer Dall <christoffer.dall@arm.com>
We currently intertwine the KVM PSCI implementation with the general
dispatch of hypercall handling, which makes perfect sense because PSCI
is the only category of hypercalls we support.
However, as we are about to support additional hypercalls, factor out
this functionality into a separate hypercall handler file.
Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
[steven.price@arm.com: rebased]
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm/kvm/Makefile | 2 +-
arch/arm/kvm/handle_exit.c | 2 +-
arch/arm64/kvm/Makefile | 1 +
arch/arm64/kvm/handle_exit.c | 4 +-
include/kvm/arm_hypercalls.h | 43 ++++++++++++++++++
include/kvm/arm_psci.h | 2 +-
virt/kvm/arm/hypercalls.c | 59 +++++++++++++++++++++++++
virt/kvm/arm/psci.c | 84 +-----------------------------------
8 files changed, 110 insertions(+), 87 deletions(-)
create mode 100644 include/kvm/arm_hypercalls.h
create mode 100644 virt/kvm/arm/hypercalls.c
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index 531e59f5be9c..ef4d01088efc 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -23,7 +23,7 @@ obj-y += kvm-arm.o init.o interrupts.o
obj-y += handle_exit.o guest.o emulate.o reset.o
obj-y += coproc.o coproc_a15.o coproc_a7.o vgic-v3-coproc.o
obj-y += $(KVM)/arm/arm.o $(KVM)/arm/mmu.o $(KVM)/arm/mmio.o
-obj-y += $(KVM)/arm/psci.o $(KVM)/arm/perf.o
+obj-y += $(KVM)/arm/psci.o $(KVM)/arm/perf.o $(KVM)/arm/hypercalls.o
obj-y += $(KVM)/arm/aarch32.o
obj-y += $(KVM)/arm/vgic/vgic.o
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
index 2a6a1394d26e..e58a89d2f13f 100644
--- a/arch/arm/kvm/handle_exit.c
+++ b/arch/arm/kvm/handle_exit.c
@@ -9,7 +9,7 @@
#include <asm/kvm_emulate.h>
#include <asm/kvm_coproc.h>
#include <asm/kvm_mmu.h>
-#include <kvm/arm_psci.h>
+#include <kvm/arm_hypercalls.h>
#include <trace/events/kvm.h>
#include "trace.h"
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 3ac1a64d2fb9..73dce4d47d47 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_KVM_ARM_HOST) += hyp/
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vfio.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arm.o $(KVM)/arm/mmu.o $(KVM)/arm/mmio.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/psci.o $(KVM)/arm/perf.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hypercalls.o
kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o va_layout.o
kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 706cca23f0d2..aacfc55de44c 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -11,8 +11,6 @@
#include <linux/kvm.h>
#include <linux/kvm_host.h>
-#include <kvm/arm_psci.h>
-
#include <asm/esr.h>
#include <asm/exception.h>
#include <asm/kvm_asm.h>
@@ -22,6 +20,8 @@
#include <asm/debug-monitors.h>
#include <asm/traps.h>
+#include <kvm/arm_hypercalls.h>
+
#define CREATE_TRACE_POINTS
#include "trace.h"
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
new file mode 100644
index 000000000000..0e2509d27910
--- /dev/null
+++ b/include/kvm/arm_hypercalls.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2019 Arm Ltd. */
+
+#ifndef __KVM_ARM_HYPERCALLS_H
+#define __KVM_ARM_HYPERCALLS_H
+
+#include <asm/kvm_emulate.h>
+
+int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
+
+static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
+{
+ return vcpu_get_reg(vcpu, 0);
+}
+
+static inline unsigned long smccc_get_arg1(struct kvm_vcpu *vcpu)
+{
+ return vcpu_get_reg(vcpu, 1);
+}
+
+static inline unsigned long smccc_get_arg2(struct kvm_vcpu *vcpu)
+{
+ return vcpu_get_reg(vcpu, 2);
+}
+
+static inline unsigned long smccc_get_arg3(struct kvm_vcpu *vcpu)
+{
+ return vcpu_get_reg(vcpu, 3);
+}
+
+static inline void smccc_set_retval(struct kvm_vcpu *vcpu,
+ unsigned long a0,
+ unsigned long a1,
+ unsigned long a2,
+ unsigned long a3)
+{
+ vcpu_set_reg(vcpu, 0, a0);
+ vcpu_set_reg(vcpu, 1, a1);
+ vcpu_set_reg(vcpu, 2, a2);
+ vcpu_set_reg(vcpu, 3, a3);
+}
+
+#endif
diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h
index 632e78bdef4d..5b58bd2fe088 100644
--- a/include/kvm/arm_psci.h
+++ b/include/kvm/arm_psci.h
@@ -40,7 +40,7 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm)
}
-int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
+int kvm_psci_call(struct kvm_vcpu *vcpu);
struct kvm_one_reg;
diff --git a/virt/kvm/arm/hypercalls.c b/virt/kvm/arm/hypercalls.c
new file mode 100644
index 000000000000..f875241bd030
--- /dev/null
+++ b/virt/kvm/arm/hypercalls.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2019 Arm Ltd.
+
+#include <linux/arm-smccc.h>
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_emulate.h>
+
+#include <kvm/arm_hypercalls.h>
+#include <kvm/arm_psci.h>
+
+int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
+{
+ u32 func_id = smccc_get_function(vcpu);
+ u32 val = SMCCC_RET_NOT_SUPPORTED;
+ u32 feature;
+
+ switch (func_id) {
+ case ARM_SMCCC_VERSION_FUNC_ID:
+ val = ARM_SMCCC_VERSION_1_1;
+ break;
+ case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
+ feature = smccc_get_arg1(vcpu);
+ switch (feature) {
+ case ARM_SMCCC_ARCH_WORKAROUND_1:
+ switch (kvm_arm_harden_branch_predictor()) {
+ case KVM_BP_HARDEN_UNKNOWN:
+ break;
+ case KVM_BP_HARDEN_WA_NEEDED:
+ val = SMCCC_RET_SUCCESS;
+ break;
+ case KVM_BP_HARDEN_NOT_REQUIRED:
+ val = SMCCC_RET_NOT_REQUIRED;
+ break;
+ }
+ break;
+ case ARM_SMCCC_ARCH_WORKAROUND_2:
+ switch (kvm_arm_have_ssbd()) {
+ case KVM_SSBD_FORCE_DISABLE:
+ case KVM_SSBD_UNKNOWN:
+ break;
+ case KVM_SSBD_KERNEL:
+ val = SMCCC_RET_SUCCESS;
+ break;
+ case KVM_SSBD_FORCE_ENABLE:
+ case KVM_SSBD_MITIGATED:
+ val = SMCCC_RET_NOT_REQUIRED;
+ break;
+ }
+ break;
+ }
+ break;
+ default:
+ return kvm_psci_call(vcpu);
+ }
+
+ smccc_set_retval(vcpu, val, 0, 0, 0);
+ return 1;
+}
diff --git a/virt/kvm/arm/psci.c b/virt/kvm/arm/psci.c
index 87927f7e1ee7..17e2bdd4b76f 100644
--- a/virt/kvm/arm/psci.c
+++ b/virt/kvm/arm/psci.c
@@ -15,6 +15,7 @@
#include <asm/kvm_host.h>
#include <kvm/arm_psci.h>
+#include <kvm/arm_hypercalls.h>
/*
* This is an implementation of the Power State Coordination Interface
@@ -23,38 +24,6 @@
#define AFFINITY_MASK(level) ~((0x1UL << ((level) * MPIDR_LEVEL_BITS)) - 1)
-static u32 smccc_get_function(struct kvm_vcpu *vcpu)
-{
- return vcpu_get_reg(vcpu, 0);
-}
-
-static unsigned long smccc_get_arg1(struct kvm_vcpu *vcpu)
-{
- return vcpu_get_reg(vcpu, 1);
-}
-
-static unsigned long smccc_get_arg2(struct kvm_vcpu *vcpu)
-{
- return vcpu_get_reg(vcpu, 2);
-}
-
-static unsigned long smccc_get_arg3(struct kvm_vcpu *vcpu)
-{
- return vcpu_get_reg(vcpu, 3);
-}
-
-static void smccc_set_retval(struct kvm_vcpu *vcpu,
- unsigned long a0,
- unsigned long a1,
- unsigned long a2,
- unsigned long a3)
-{
- vcpu_set_reg(vcpu, 0, a0);
- vcpu_set_reg(vcpu, 1, a1);
- vcpu_set_reg(vcpu, 2, a2);
- vcpu_set_reg(vcpu, 3, a3);
-}
-
static unsigned long psci_affinity_mask(unsigned long affinity_level)
{
if (affinity_level <= 3)
@@ -373,7 +342,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
* Errors:
* -EINVAL: Unrecognized PSCI function
*/
-static int kvm_psci_call(struct kvm_vcpu *vcpu)
+int kvm_psci_call(struct kvm_vcpu *vcpu)
{
switch (kvm_psci_version(vcpu, vcpu->kvm)) {
case KVM_ARM_PSCI_1_0:
@@ -387,55 +356,6 @@ static int kvm_psci_call(struct kvm_vcpu *vcpu)
};
}
-int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
-{
- u32 func_id = smccc_get_function(vcpu);
- u32 val = SMCCC_RET_NOT_SUPPORTED;
- u32 feature;
-
- switch (func_id) {
- case ARM_SMCCC_VERSION_FUNC_ID:
- val = ARM_SMCCC_VERSION_1_1;
- break;
- case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
- feature = smccc_get_arg1(vcpu);
- switch(feature) {
- case ARM_SMCCC_ARCH_WORKAROUND_1:
- switch (kvm_arm_harden_branch_predictor()) {
- case KVM_BP_HARDEN_UNKNOWN:
- break;
- case KVM_BP_HARDEN_WA_NEEDED:
- val = SMCCC_RET_SUCCESS;
- break;
- case KVM_BP_HARDEN_NOT_REQUIRED:
- val = SMCCC_RET_NOT_REQUIRED;
- break;
- }
- break;
- case ARM_SMCCC_ARCH_WORKAROUND_2:
- switch (kvm_arm_have_ssbd()) {
- case KVM_SSBD_FORCE_DISABLE:
- case KVM_SSBD_UNKNOWN:
- break;
- case KVM_SSBD_KERNEL:
- val = SMCCC_RET_SUCCESS;
- break;
- case KVM_SSBD_FORCE_ENABLE:
- case KVM_SSBD_MITIGATED:
- val = SMCCC_RET_NOT_REQUIRED;
- break;
- }
- break;
- }
- break;
- default:
- return kvm_psci_call(vcpu);
- }
-
- smccc_set_retval(vcpu, val, 0, 0, 0);
- return 1;
-}
-
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
{
return 3; /* PSCI version and two workaround registers */
--
2.20.1
^ permalink raw reply related
* [PATCH v3 03/10] KVM: arm64: Implement PV_FEATURES call
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
This provides a mechanism for querying which paravirtualized features
are available in this hypervisor.
Also add the header file which defines the ABI for the paravirtualized
clock features we're about to add.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm/include/asm/kvm_host.h | 6 ++++++
arch/arm64/include/asm/kvm_host.h | 2 ++
arch/arm64/include/asm/pvclock-abi.h | 17 +++++++++++++++++
arch/arm64/kvm/Makefile | 1 +
include/linux/arm-smccc.h | 14 ++++++++++++++
virt/kvm/arm/hypercalls.c | 6 ++++++
virt/kvm/arm/pvtime.c | 21 +++++++++++++++++++++
7 files changed, 67 insertions(+)
create mode 100644 arch/arm64/include/asm/pvclock-abi.h
create mode 100644 virt/kvm/arm/pvtime.c
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 8a37c8e89777..369b5d2d54bf 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -7,6 +7,7 @@
#ifndef __ARM_KVM_HOST_H__
#define __ARM_KVM_HOST_H__
+#include <linux/arm-smccc.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/kvm_types.h>
@@ -323,6 +324,11 @@ static inline int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext)
int kvm_perf_init(void);
int kvm_perf_teardown(void);
+static inline int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
+{
+ return SMCCC_RET_NOT_SUPPORTED;
+}
+
void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f656169db8c3..583b3639062a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -478,6 +478,8 @@ void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
int kvm_perf_init(void);
int kvm_perf_teardown(void);
+int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
+
void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome);
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
diff --git a/arch/arm64/include/asm/pvclock-abi.h b/arch/arm64/include/asm/pvclock-abi.h
new file mode 100644
index 000000000000..c4f1c0a0789c
--- /dev/null
+++ b/arch/arm64/include/asm/pvclock-abi.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2019 Arm Ltd. */
+
+#ifndef __ASM_PVCLOCK_ABI_H
+#define __ASM_PVCLOCK_ABI_H
+
+/* The below structure is defined in ARM DEN0057A */
+
+struct pvclock_vcpu_stolen_time {
+ __le32 revision;
+ __le32 attributes;
+ __le64 stolen_time;
+ /* Structure must be 64 byte aligned, pad to that size */
+ u8 padding[48];
+} __packed;
+
+#endif
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 73dce4d47d47..5ffbdc39e780 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -14,6 +14,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/e
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arm.o $(KVM)/arm/mmu.o $(KVM)/arm/mmio.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/psci.o $(KVM)/arm/perf.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hypercalls.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/pvtime.o
kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o va_layout.o
kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 080012a6f025..e7f129f26ebd 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -45,6 +45,7 @@
#define ARM_SMCCC_OWNER_SIP 2
#define ARM_SMCCC_OWNER_OEM 3
#define ARM_SMCCC_OWNER_STANDARD 4
+#define ARM_SMCCC_OWNER_STANDARD_HYP 5
#define ARM_SMCCC_OWNER_TRUSTED_APP 48
#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
#define ARM_SMCCC_OWNER_TRUSTED_OS 50
@@ -302,5 +303,18 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
#define SMCCC_RET_NOT_SUPPORTED -1
#define SMCCC_RET_NOT_REQUIRED -2
+/* Paravirtualised time calls (defined by ARM DEN0057A) */
+#define ARM_SMCCC_HV_PV_FEATURES \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_STANDARD_HYP, \
+ 0x20)
+
+#define ARM_SMCCC_HV_PV_TIME_ST \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_STANDARD_HYP, \
+ 0x22)
+
#endif /*__ASSEMBLY__*/
#endif /*__LINUX_ARM_SMCCC_H*/
diff --git a/virt/kvm/arm/hypercalls.c b/virt/kvm/arm/hypercalls.c
index f875241bd030..63ae629c466a 100644
--- a/virt/kvm/arm/hypercalls.c
+++ b/virt/kvm/arm/hypercalls.c
@@ -48,8 +48,14 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
break;
}
break;
+ case ARM_SMCCC_HV_PV_FEATURES:
+ val = SMCCC_RET_SUCCESS;
+ break;
}
break;
+ case ARM_SMCCC_HV_PV_FEATURES:
+ val = kvm_hypercall_pv_features(vcpu);
+ break;
default:
return kvm_psci_call(vcpu);
}
diff --git a/virt/kvm/arm/pvtime.c b/virt/kvm/arm/pvtime.c
new file mode 100644
index 000000000000..6201d71cb1f8
--- /dev/null
+++ b/virt/kvm/arm/pvtime.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2019 Arm Ltd.
+
+#include <linux/arm-smccc.h>
+
+#include <kvm/arm_hypercalls.h>
+
+int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
+{
+ u32 feature = smccc_get_arg1(vcpu);
+ u32 val = SMCCC_RET_NOT_SUPPORTED;
+
+ switch (feature) {
+ case ARM_SMCCC_HV_PV_FEATURES:
+ val = SMCCC_RET_SUCCESS;
+ break;
+ }
+
+ return val;
+}
+
--
2.20.1
^ permalink raw reply related
* [PATCH v3 07/10] KVM: arm64: Provide a PV_TIME device to user space
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Allow user space to inform the KVM host where in the physical memory
map the paravirtualized time structures should be located.
A device is created which provides the base address of an array of
Stolen Time (ST) structures, one for each VCPU. There must be (64 *
total number of VCPUs) bytes of memory available at this location.
The address is given in terms of the physical address visible to
the guest and must be page aligned. The guest will discover the address
via a hypercall.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm/include/asm/kvm_host.h | 4 ++
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/include/uapi/asm/kvm.h | 8 +++
include/uapi/linux/kvm.h | 2 +
virt/kvm/arm/arm.c | 1 +
virt/kvm/arm/pvtime.c | 94 +++++++++++++++++++++++++++++++
6 files changed, 110 insertions(+)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 47d2ced99421..b6c8dbc0556b 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -325,6 +325,10 @@ static inline int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext)
int kvm_perf_init(void);
int kvm_perf_teardown(void);
+static inline void kvm_pvtime_init(void)
+{
+}
+
static inline int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
{
return SMCCC_RET_NOT_SUPPORTED;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index b6fa7beffd8a..7b2147f62c16 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -489,6 +489,7 @@ void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
int kvm_perf_init(void);
int kvm_perf_teardown(void);
+void kvm_pvtime_init(void);
int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu);
int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init);
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 9a507716ae2f..209c4de67306 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -367,6 +367,14 @@ struct kvm_vcpu_events {
#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
+/* Device Control API: PV_TIME */
+#define KVM_DEV_ARM_PV_TIME_REGION 0
+#define KVM_DEV_ARM_PV_TIME_ST 0
+struct kvm_dev_arm_st_region {
+ __u64 gpa;
+ __u64 size;
+};
+
#endif
#endif /* __ARM_KVM_H__ */
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 5e3f12d5359e..265156a984f2 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1222,6 +1222,8 @@ enum kvm_device_type {
#define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS
KVM_DEV_TYPE_XIVE,
#define KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_XIVE
+ KVM_DEV_TYPE_ARM_PV_TIME,
+#define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME
KVM_DEV_TYPE_MAX,
};
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 5e8343e2dd62..bfb5a842e6ab 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1494,6 +1494,7 @@ static int init_subsystems(void)
kvm_perf_init();
kvm_coproc_table_init();
+ kvm_pvtime_init();
out:
on_each_cpu(_kvm_arch_hardware_disable, NULL, 1);
diff --git a/virt/kvm/arm/pvtime.c b/virt/kvm/arm/pvtime.c
index 28603689f6e0..3e55c1fb6a49 100644
--- a/virt/kvm/arm/pvtime.c
+++ b/virt/kvm/arm/pvtime.c
@@ -2,7 +2,9 @@
// Copyright (C) 2019 Arm Ltd.
#include <linux/arm-smccc.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_mmu.h>
#include <asm/pvclock-abi.h>
#include <kvm/arm_hypercalls.h>
@@ -86,3 +88,95 @@ int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu)
return ret;
}
+
+static int kvm_arm_pvtime_create(struct kvm_device *dev, u32 type)
+{
+ return 0;
+}
+
+static void kvm_arm_pvtime_destroy(struct kvm_device *dev)
+{
+ struct kvm_arch_pvtime *pvtime = &dev->kvm->arch.pvtime;
+
+ pvtime->st_base = GPA_INVALID;
+ kfree(dev);
+}
+
+static int kvm_arm_pvtime_set_attr(struct kvm_device *dev,
+ struct kvm_device_attr *attr)
+{
+ struct kvm *kvm = dev->kvm;
+ struct kvm_arch_pvtime *pvtime = &kvm->arch.pvtime;
+ u64 __user *user = (u64 __user *)attr->addr;
+ struct kvm_dev_arm_st_region region;
+
+ switch (attr->group) {
+ case KVM_DEV_ARM_PV_TIME_REGION:
+ if (copy_from_user(®ion, user, sizeof(region)))
+ return -EFAULT;
+ if (region.gpa & ~PAGE_MASK)
+ return -EINVAL;
+ if (region.size & ~PAGE_MASK)
+ return -EINVAL;
+ switch (attr->attr) {
+ case KVM_DEV_ARM_PV_TIME_ST:
+ if (pvtime->st_base != GPA_INVALID)
+ return -EEXIST;
+ pvtime->st_base = region.gpa;
+ pvtime->st_size = region.size;
+ return 0;
+ }
+ break;
+ }
+ return -ENXIO;
+}
+
+static int kvm_arm_pvtime_get_attr(struct kvm_device *dev,
+ struct kvm_device_attr *attr)
+{
+ struct kvm_arch_pvtime *pvtime = &dev->kvm->arch.pvtime;
+ u64 __user *user = (u64 __user *)attr->addr;
+ struct kvm_dev_arm_st_region region;
+
+ switch (attr->group) {
+ case KVM_DEV_ARM_PV_TIME_REGION:
+ switch (attr->attr) {
+ case KVM_DEV_ARM_PV_TIME_ST:
+ region.gpa = pvtime->st_base;
+ region.size = pvtime->st_size;
+ if (copy_to_user(user, ®ion, sizeof(region)))
+ return -EFAULT;
+ return 0;
+ }
+ break;
+ }
+ return -ENXIO;
+}
+
+static int kvm_arm_pvtime_has_attr(struct kvm_device *dev,
+ struct kvm_device_attr *attr)
+{
+ switch (attr->group) {
+ case KVM_DEV_ARM_PV_TIME_REGION:
+ switch (attr->attr) {
+ case KVM_DEV_ARM_PV_TIME_ST:
+ return 0;
+ }
+ break;
+ }
+ return -ENXIO;
+}
+
+static const struct kvm_device_ops pvtime_ops = {
+ "Arm PV time",
+ .create = kvm_arm_pvtime_create,
+ .destroy = kvm_arm_pvtime_destroy,
+ .set_attr = kvm_arm_pvtime_set_attr,
+ .get_attr = kvm_arm_pvtime_get_attr,
+ .has_attr = kvm_arm_pvtime_has_attr
+};
+
+void kvm_pvtime_init(void)
+{
+ kvm_register_device_ops(&pvtime_ops, KVM_DEV_TYPE_ARM_PV_TIME);
+}
--
2.20.1
^ permalink raw reply related
* [PATCH v3 10/10] arm64: Retrieve stolen time as paravirtualized guest
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Enable paravirtualization features when running under a hypervisor
supporting the PV_TIME_ST hypercall.
For each (v)CPU, we ask the hypervisor for the location of a shared
page which the hypervisor will use to report stolen time to us. We set
pv_time_ops to the stolen time function which simply reads the stolen
value from the shared page for a VCPU. We guarantee single-copy
atomicity using READ_ONCE which means we can also read the stolen
time for another VCPU than the currently running one while it is
potentially being updated by the hypervisor.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm64/include/asm/paravirt.h | 9 +-
arch/arm64/kernel/paravirt.c | 148 ++++++++++++++++++++++++++++++
arch/arm64/kernel/time.c | 3 +
include/linux/cpuhotplug.h | 1 +
4 files changed, 160 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h
index 799d9dd6f7cc..125c26c42902 100644
--- a/arch/arm64/include/asm/paravirt.h
+++ b/arch/arm64/include/asm/paravirt.h
@@ -21,6 +21,13 @@ static inline u64 paravirt_steal_clock(int cpu)
{
return pv_ops.time.steal_clock(cpu);
}
-#endif
+
+int __init kvm_guest_init(void);
+
+#else
+
+#define kvm_guest_init()
+
+#endif // CONFIG_PARAVIRT
#endif
diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
index 4cfed91fe256..ea8dbbbd3293 100644
--- a/arch/arm64/kernel/paravirt.c
+++ b/arch/arm64/kernel/paravirt.c
@@ -6,13 +6,161 @@
* Author: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
*/
+#define pr_fmt(fmt) "kvmarm-pv: " fmt
+
+#include <linux/arm-smccc.h>
+#include <linux/cpuhotplug.h>
#include <linux/export.h>
+#include <linux/io.h>
#include <linux/jump_label.h>
+#include <linux/printk.h>
+#include <linux/psci.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
#include <linux/types.h>
+
#include <asm/paravirt.h>
+#include <asm/pvclock-abi.h>
+#include <asm/smp_plat.h>
struct static_key paravirt_steal_enabled;
struct static_key paravirt_steal_rq_enabled;
struct paravirt_patch_template pv_ops;
EXPORT_SYMBOL_GPL(pv_ops);
+
+struct kvmarm_stolen_time_region {
+ struct pvclock_vcpu_stolen_time *kaddr;
+};
+
+static DEFINE_PER_CPU(struct kvmarm_stolen_time_region, stolen_time_region);
+
+static bool steal_acc = true;
+static int __init parse_no_stealacc(char *arg)
+{
+ steal_acc = false;
+ return 0;
+}
+
+early_param("no-steal-acc", parse_no_stealacc);
+
+/* return stolen time in ns by asking the hypervisor */
+static u64 kvm_steal_clock(int cpu)
+{
+ struct kvmarm_stolen_time_region *reg;
+
+ reg = per_cpu_ptr(&stolen_time_region, cpu);
+ if (!reg->kaddr) {
+ pr_warn_once("stolen time enabled but not configured for cpu %d\n",
+ cpu);
+ return 0;
+ }
+
+ return le64_to_cpu(READ_ONCE(reg->kaddr->stolen_time));
+}
+
+static int disable_stolen_time_current_cpu(void)
+{
+ struct kvmarm_stolen_time_region *reg;
+
+ reg = this_cpu_ptr(&stolen_time_region);
+ if (!reg->kaddr)
+ return 0;
+
+ memunmap(reg->kaddr);
+ memset(reg, 0, sizeof(*reg));
+
+ return 0;
+}
+
+static int stolen_time_dying_cpu(unsigned int cpu)
+{
+ return disable_stolen_time_current_cpu();
+}
+
+static int init_stolen_time_cpu(unsigned int cpu)
+{
+ struct kvmarm_stolen_time_region *reg;
+ struct arm_smccc_res res;
+
+ reg = this_cpu_ptr(&stolen_time_region);
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_HV_PV_TIME_ST, &res);
+
+ if ((long)res.a0 < 0)
+ return -EINVAL;
+
+ reg->kaddr = memremap(res.a0,
+ sizeof(struct pvclock_vcpu_stolen_time),
+ MEMREMAP_WB);
+
+ if (!reg->kaddr) {
+ pr_warn("Failed to map stolen time data structure\n");
+ return -ENOMEM;
+ }
+
+ if (le32_to_cpu(reg->kaddr->revision) != 0 ||
+ le32_to_cpu(reg->kaddr->attributes) != 0) {
+ pr_warn("Unexpected revision or attributes in stolen time data\n");
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int kvm_arm_init_stolen_time(void)
+{
+ int ret;
+
+ ret = cpuhp_setup_state(CPUHP_AP_ARM_KVMPV_STARTING,
+ "hypervisor/kvmarm/pv:starting",
+ init_stolen_time_cpu, stolen_time_dying_cpu);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static bool has_kvm_steal_clock(void)
+{
+ struct arm_smccc_res res;
+
+ /* To detect the presence of PV time support we require SMCCC 1.1+ */
+ if (psci_ops.smccc_version < SMCCC_VERSION_1_1)
+ return false;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_HV_PV_FEATURES, &res);
+
+ if (res.a0 != SMCCC_RET_SUCCESS)
+ return false;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_HV_PV_FEATURES,
+ ARM_SMCCC_HV_PV_TIME_ST, &res);
+
+ if (res.a0 != SMCCC_RET_SUCCESS)
+ return false;
+
+ return true;
+}
+
+int __init kvm_guest_init(void)
+{
+ int ret = 0;
+
+ if (!has_kvm_steal_clock())
+ return 0;
+
+ ret = kvm_arm_init_stolen_time();
+ if (ret)
+ return ret;
+
+ pv_ops.time.steal_clock = kvm_steal_clock;
+
+ static_key_slow_inc(¶virt_steal_enabled);
+ if (steal_acc)
+ static_key_slow_inc(¶virt_steal_rq_enabled);
+
+ pr_info("using stolen time PV\n");
+
+ return 0;
+}
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index 0b2946414dc9..a52aea14c6ec 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -30,6 +30,7 @@
#include <asm/thread_info.h>
#include <asm/stacktrace.h>
+#include <asm/paravirt.h>
unsigned long profile_pc(struct pt_regs *regs)
{
@@ -65,4 +66,6 @@ void __init time_init(void)
/* Calibrate the delay loop directly */
lpj_fine = arch_timer_rate / HZ;
+
+ kvm_guest_init();
}
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 068793a619ca..89d75edb5750 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -136,6 +136,7 @@ enum cpuhp_state {
/* Must be the last timer callback */
CPUHP_AP_DUMMY_TIMER_STARTING,
CPUHP_AP_ARM_XEN_STARTING,
+ CPUHP_AP_ARM_KVMPV_STARTING,
CPUHP_AP_ARM_CORESIGHT_STARTING,
CPUHP_AP_ARM64_ISNDEP_STARTING,
CPUHP_AP_SMPCFD_DYING,
--
2.20.1
^ permalink raw reply related
* [PATCH v3 09/10] arm/arm64: Make use of the SMCCC 1.1 wrapper
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Rather than directly choosing which function to use based on
psci_ops.conduit, use the new arm_smccc_1_1 wrapper instead.
In some cases we still need to do some operations based on the
conduit, but the code duplication is removed.
No functional change.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm/mm/proc-v7-bugs.c | 13 +++---
arch/arm64/kernel/cpu_errata.c | 80 ++++++++++++----------------------
2 files changed, 33 insertions(+), 60 deletions(-)
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 9a07916af8dd..8eb52f3385e7 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -78,12 +78,13 @@ static void cpu_v7_spectre_init(void)
if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
break;
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+ if ((int)res.a0 != 0)
+ return;
+
switch (psci_ops.conduit) {
case PSCI_CONDUIT_HVC:
- arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- if ((int)res.a0 != 0)
- break;
per_cpu(harden_branch_predictor_fn, cpu) =
call_hvc_arch_workaround_1;
cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
@@ -91,10 +92,6 @@ static void cpu_v7_spectre_init(void)
break;
case PSCI_CONDUIT_SMC:
- arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- if ((int)res.a0 != 0)
- break;
per_cpu(harden_branch_predictor_fn, cpu) =
call_smc_arch_workaround_1;
cpu_do_switch_mm = cpu_v7_smc_switch_mm;
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 1e43ba5c79b7..400a49aaae85 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -215,40 +215,31 @@ static int detect_harden_bp_fw(void)
if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
return -1;
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+
+ switch ((int)res.a0) {
+ case 1:
+ /* Firmware says we're just fine */
+ return 0;
+ case 0:
+ break;
+ default:
+ return -1;
+ }
+
switch (psci_ops.conduit) {
case PSCI_CONDUIT_HVC:
- arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- switch ((int)res.a0) {
- case 1:
- /* Firmware says we're just fine */
- return 0;
- case 0:
- cb = call_hvc_arch_workaround_1;
- /* This is a guest, no need to patch KVM vectors */
- smccc_start = NULL;
- smccc_end = NULL;
- break;
- default:
- return -1;
- }
+ cb = call_hvc_arch_workaround_1;
+ /* This is a guest, no need to patch KVM vectors */
+ smccc_start = NULL;
+ smccc_end = NULL;
break;
case PSCI_CONDUIT_SMC:
- arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- switch ((int)res.a0) {
- case 1:
- /* Firmware says we're just fine */
- return 0;
- case 0:
- cb = call_smc_arch_workaround_1;
- smccc_start = __smccc_workaround_1_smc_start;
- smccc_end = __smccc_workaround_1_smc_end;
- break;
- default:
- return -1;
- }
+ cb = call_smc_arch_workaround_1;
+ smccc_start = __smccc_workaround_1_smc_start;
+ smccc_end = __smccc_workaround_1_smc_end;
break;
default:
@@ -338,6 +329,7 @@ void __init arm64_enable_wa2_handling(struct alt_instr *alt,
void arm64_set_ssbd_mitigation(bool state)
{
+ int conduit;
if (!IS_ENABLED(CONFIG_ARM64_SSBD)) {
pr_info_once("SSBD disabled by kernel configuration\n");
return;
@@ -351,19 +343,10 @@ void arm64_set_ssbd_mitigation(bool state)
return;
}
- switch (psci_ops.conduit) {
- case PSCI_CONDUIT_HVC:
- arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
- break;
+ conduit = arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_WORKAROUND_2, state,
+ NULL);
- case PSCI_CONDUIT_SMC:
- arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
- break;
-
- default:
- WARN_ON_ONCE(1);
- break;
- }
+ WARN_ON_ONCE(conduit == PSCI_CONDUIT_NONE);
}
static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
@@ -373,6 +356,7 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
bool required = true;
s32 val;
bool this_cpu_safe = false;
+ int conduit;
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
@@ -397,18 +381,10 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
return false;
}
- switch (psci_ops.conduit) {
- case PSCI_CONDUIT_HVC:
- arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_2, &res);
- break;
-
- case PSCI_CONDUIT_SMC:
- arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_2, &res);
- break;
+ conduit = arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_2, &res);
- default:
+ if (conduit == PSCI_CONDUIT_NONE) {
ssbd_state = ARM64_SSBD_UNKNOWN;
if (!this_cpu_safe)
__ssb_safe = false;
--
2.20.1
^ permalink raw reply related
* [PATCH v3 08/10] arm/arm64: Provide a wrapper for SMCCC 1.1 calls
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
SMCCC 1.1 calls may use either HVC or SMC depending on the PSCI
conduit. Rather than coding this in every call site provide a macro
which uses the correct instruction. The macro also handles the case
where no PSCI conduit is configured returning a not supported error
in res, along with returning the conduit used for the call.
This allow us to remove some duplicated code and will be useful later
when adding paravirtualized time hypervisor calls.
Signed-off-by: Steven Price <steven.price@arm.com>
Acked-by: Will Deacon <will@kernel.org>
---
include/linux/arm-smccc.h | 44 +++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index e7f129f26ebd..eee1e832221d 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -303,6 +303,50 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
#define SMCCC_RET_NOT_SUPPORTED -1
#define SMCCC_RET_NOT_REQUIRED -2
+/* Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
+ * Used when the PSCI conduit is not defined. The empty asm statement
+ * avoids compiler warnings about unused variables.
+ */
+#define __fail_smccc_1_1(...) \
+ do { \
+ __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
+ asm ("" __constraints(__count_args(__VA_ARGS__))); \
+ if (___res) \
+ ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
+ } while (0)
+
+/*
+ * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
+ *
+ * This is a variadic macro taking one to eight source arguments, and
+ * an optional return structure.
+ *
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ *
+ * This macro will make either an HVC call or an SMC call depending on the
+ * current PSCI conduit. If no valid conduit is available then -1
+ * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
+ *
+ * The return value also provides the conduit that was used.
+ */
+#define arm_smccc_1_1_invoke(...) ({ \
+ int method = psci_ops.conduit; \
+ switch (method) { \
+ case PSCI_CONDUIT_HVC: \
+ arm_smccc_1_1_hvc(__VA_ARGS__); \
+ break; \
+ case PSCI_CONDUIT_SMC: \
+ arm_smccc_1_1_smc(__VA_ARGS__); \
+ break; \
+ default: \
+ __fail_smccc_1_1(__VA_ARGS__); \
+ method = PSCI_CONDUIT_NONE; \
+ break; \
+ } \
+ method; \
+ })
+
/* Paravirtualised time calls (defined by ARM DEN0057A) */
#define ARM_SMCCC_HV_PV_FEATURES \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
--
2.20.1
^ permalink raw reply related
* [PATCH v3 06/10] KVM: Allow kvm_device_ops to be const
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Currently a kvm_device_ops structure cannot be const without triggering
compiler warnings. However the structure doesn't need to be written to
and, by marking it const, it can be read-only in memory. Add some more
const keywords to allow this.
Signed-off-by: Steven Price <steven.price@arm.com>
---
include/linux/kvm_host.h | 4 ++--
virt/kvm/kvm_main.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index e154a1897e20..c5c1a923f21b 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1262,7 +1262,7 @@ extern unsigned int halt_poll_ns_grow_start;
extern unsigned int halt_poll_ns_shrink;
struct kvm_device {
- struct kvm_device_ops *ops;
+ const struct kvm_device_ops *ops;
struct kvm *kvm;
void *private;
struct list_head vm_node;
@@ -1315,7 +1315,7 @@ struct kvm_device_ops {
void kvm_device_get(struct kvm_device *dev);
void kvm_device_put(struct kvm_device *dev);
struct kvm_device *kvm_device_from_filp(struct file *filp);
-int kvm_register_device_ops(struct kvm_device_ops *ops, u32 type);
+int kvm_register_device_ops(const struct kvm_device_ops *ops, u32 type);
void kvm_unregister_device_ops(u32 type);
extern struct kvm_device_ops kvm_mpic_ops;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c6a91b044d8d..75488ebb87c9 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3046,14 +3046,14 @@ struct kvm_device *kvm_device_from_filp(struct file *filp)
return filp->private_data;
}
-static struct kvm_device_ops *kvm_device_ops_table[KVM_DEV_TYPE_MAX] = {
+static const struct kvm_device_ops *kvm_device_ops_table[KVM_DEV_TYPE_MAX] = {
#ifdef CONFIG_KVM_MPIC
[KVM_DEV_TYPE_FSL_MPIC_20] = &kvm_mpic_ops,
[KVM_DEV_TYPE_FSL_MPIC_42] = &kvm_mpic_ops,
#endif
};
-int kvm_register_device_ops(struct kvm_device_ops *ops, u32 type)
+int kvm_register_device_ops(const struct kvm_device_ops *ops, u32 type)
{
if (type >= ARRAY_SIZE(kvm_device_ops_table))
return -ENOSPC;
@@ -3074,7 +3074,7 @@ void kvm_unregister_device_ops(u32 type)
static int kvm_ioctl_create_device(struct kvm *kvm,
struct kvm_create_device *cd)
{
- struct kvm_device_ops *ops = NULL;
+ const struct kvm_device_ops *ops = NULL;
struct kvm_device *dev;
bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
int type;
--
2.20.1
^ permalink raw reply related
* [PATCH v3 04/10] KVM: Implement kvm_put_guest()
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
kvm_put_guest() is analogous to put_user() - it writes a single value to
the guest physical address. The implementation is built upon put_user()
and so it has the same single copy atomic properties.
Signed-off-by: Steven Price <steven.price@arm.com>
---
include/linux/kvm_host.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index fcb46b3374c6..e154a1897e20 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -746,6 +746,30 @@ int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
unsigned long len);
int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
gpa_t gpa, unsigned long len);
+
+#define __kvm_put_guest(kvm, gfn, offset, value, type) \
+({ \
+ unsigned long __addr = gfn_to_hva(kvm, gfn); \
+ type __user *__uaddr = (type __user *)(__addr + offset); \
+ int __ret = 0; \
+ \
+ if (kvm_is_error_hva(__addr)) \
+ __ret = -EFAULT; \
+ else \
+ __ret = put_user(value, __uaddr); \
+ if (!__ret) \
+ mark_page_dirty(kvm, gfn); \
+ __ret; \
+})
+
+#define kvm_put_guest(kvm, gpa, value, type) \
+({ \
+ gpa_t __gpa = gpa; \
+ struct kvm *__kvm = kvm; \
+ __kvm_put_guest(__kvm, __gpa >> PAGE_SHIFT, \
+ offset_in_page(__gpa), (value), type); \
+})
+
int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len);
struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);
--
2.20.1
^ permalink raw reply related
* [PATCH v3 00/10] arm64: Stolen time support
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Steven Price, Catalin Marinas, Paolo Bonzini,
Radim Krčmář, Russell King, James Morse,
Julien Thierry, Suzuki K Pouloze, Mark Rutland, kvm, linux-doc,
linux-kernel
This series add support for paravirtualized time for arm64 guests and
KVM hosts following the specification in Arm's document DEN 0057A:
https://developer.arm.com/docs/den0057/a
It implements support for stolen time, allowing the guest to
identify time when it is forcibly not executing.
It doesn't implement support for Live Physical Time (LPT) as there are
some concerns about the overheads and approach in the above
specification, and I expect an updated version of the specification to
be released soon with just the stolen time parts.
NOTE: Patches 8 and 9 will conflict with Mark Rutland's series[1] cleaning
up the SMCCC conduit. I do feel that the addition of an _invoke() call
makes a number of call sites cleaner and it should be possible to
integrate both this and Mark's other cleanups.
[1] https://lore.kernel.org/linux-arm-kernel/20190809132245.43505-1-mark.rutland@arm.com/
Also available as a git tree:
git://linux-arm.org/linux-sp.git stolen_time/v3
Changes from v2:
https://lore.kernel.org/lkml/20190819140436.12207-1-steven.price@arm.com/
* Switched from using gfn_to_hva_cache to a new macro kvm_put_guest()
that can provide the single-copy atomicity required (on arm64). This
macro is added in patch 4.
* Tidied up the locking for kvm_update_stolen_time().
pagefault_disable() was unnecessary and the caller didn't need to
take kvm->srcu as the function does it itself.
* Removed struct kvm_arch_pvtime from the arm implementation, replaced
instead with inline static functions which are empty for arm.
* Fixed a few checkpatch --strict warnings.
Changes from v1:
https://lore.kernel.org/lkml/20190802145017.42543-1-steven.price@arm.com/
* Host kernel no longer allocates the stolen time structure, instead it
is allocated by user space. This means the save/restore functionality
can be removed.
* Refactored the code so arm has stub implementations and to avoid
initcall
* Rebased to pick up Documentation/{virt->virtual} change
* Bunch of typo fixes
Christoffer Dall (1):
KVM: arm/arm64: Factor out hypercall handling from PSCI code
Steven Price (9):
KVM: arm64: Document PV-time interface
KVM: arm64: Implement PV_FEATURES call
KVM: Implement kvm_put_guest()
KVM: arm64: Support stolen time reporting via shared structure
KVM: Allow kvm_device_ops to be const
KVM: arm64: Provide a PV_TIME device to user space
arm/arm64: Provide a wrapper for SMCCC 1.1 calls
arm/arm64: Make use of the SMCCC 1.1 wrapper
arm64: Retrieve stolen time as paravirtualized guest
Documentation/virt/kvm/arm/pvtime.txt | 100 ++++++++++++++
arch/arm/include/asm/kvm_host.h | 30 +++++
arch/arm/kvm/Makefile | 2 +-
arch/arm/kvm/handle_exit.c | 2 +-
arch/arm/mm/proc-v7-bugs.c | 13 +-
arch/arm64/include/asm/kvm_host.h | 28 +++-
arch/arm64/include/asm/paravirt.h | 9 +-
arch/arm64/include/asm/pvclock-abi.h | 17 +++
arch/arm64/include/uapi/asm/kvm.h | 8 ++
arch/arm64/kernel/cpu_errata.c | 80 ++++-------
arch/arm64/kernel/paravirt.c | 148 +++++++++++++++++++++
arch/arm64/kernel/time.c | 3 +
arch/arm64/kvm/Kconfig | 1 +
arch/arm64/kvm/Makefile | 2 +
arch/arm64/kvm/handle_exit.c | 4 +-
include/kvm/arm_hypercalls.h | 43 ++++++
include/kvm/arm_psci.h | 2 +-
include/linux/arm-smccc.h | 58 ++++++++
include/linux/cpuhotplug.h | 1 +
include/linux/kvm_host.h | 28 +++-
include/linux/kvm_types.h | 2 +
include/uapi/linux/kvm.h | 2 +
virt/kvm/arm/arm.c | 11 ++
virt/kvm/arm/hypercalls.c | 68 ++++++++++
virt/kvm/arm/psci.c | 84 +-----------
virt/kvm/arm/pvtime.c | 182 ++++++++++++++++++++++++++
virt/kvm/kvm_main.c | 6 +-
27 files changed, 780 insertions(+), 154 deletions(-)
create mode 100644 Documentation/virt/kvm/arm/pvtime.txt
create mode 100644 arch/arm64/include/asm/pvclock-abi.h
create mode 100644 include/kvm/arm_hypercalls.h
create mode 100644 virt/kvm/arm/hypercalls.c
create mode 100644 virt/kvm/arm/pvtime.c
--
2.20.1
^ permalink raw reply
* Re: [PATCH v8 02/27] x86/cpufeatures: Add CET CPU feature flags for Control-flow Enforcement Technology (CET)
From: Yu-cheng Yu @ 2019-08-21 14:46 UTC (permalink / raw)
To: Borislav Petkov
Cc: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
Andy Lutomirski, Balbir Singh, Cyrill Gorcunov, Dave Hansen,
Eugene Syromiatnikov, Florian Weimer, H.J. Lu, Jann Horn,
Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
In-Reply-To: <20190821102052.GD6752@zn.tnic>
On Wed, 2019-08-21 at 12:20 +0200, Borislav Petkov wrote:
> On Tue, Aug 13, 2019 at 01:52:00PM -0700, Yu-cheng Yu wrote:
> > Add CPU feature flags for Control-flow Enforcement Technology (CET).
> >
> > [...]
> > diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-
> > deps.c
> > index b5353244749b..9bf35f081080 100644
> > --- a/arch/x86/kernel/cpu/cpuid-deps.c
> > +++ b/arch/x86/kernel/cpu/cpuid-deps.c
> > @@ -68,6 +68,8 @@ static const struct cpuid_dep cpuid_deps[] = {
> > { X86_FEATURE_CQM_MBM_TOTAL, X86_FEATURE_CQM_LLC },
> > { X86_FEATURE_CQM_MBM_LOCAL, X86_FEATURE_CQM_LLC },
> > { X86_FEATURE_AVX512_BF16, X86_FEATURE_AVX512VL },
> > + { X86_FEATURE_SHSTK, X86_FEATURE_XSAVES },
> > + { X86_FEATURE_IBT, X86_FEATURE_XSAVES },
>
> This hunk needs re-tabbing after:
>
> 1e0c08e3034d ("cpu/cpuid-deps: Add a tab to cpuid dependent features")
Thanks, I will fix it.
Yu-cheng
^ permalink raw reply
* Re: [PATCH v8 03/27] x86/fpu/xstate: Change names to separate XSAVES system and user states
From: Borislav Petkov @ 2019-08-21 14:45 UTC (permalink / raw)
To: Yu-cheng Yu
Cc: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
Andy Lutomirski, Balbir Singh, Cyrill Gorcunov, Dave Hansen,
Eugene Syromiatnikov, Florian Weimer, H.J. Lu, Jann Horn,
Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
In-Reply-To: <20190813205225.12032-4-yu-cheng.yu@intel.com>
On Tue, Aug 13, 2019 at 01:52:01PM -0700, Yu-cheng Yu wrote:
> Control-flow Enforcement (CET) MSR contents are XSAVES system states.
> To support CET, introduce XSAVES system states first.
>
> XSAVES is a "supervisor" instruction and, comparing to XSAVE, saves
> additional "supervisor" states that can be modified only from CPL 0.
> However, these states are per-task and not kernel's own. Rename
> "supervisor" states to "system" states to clearly separate them from
> "user" states.
>
> Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
> ---
> arch/x86/include/asm/fpu/internal.h | 4 +-
> arch/x86/include/asm/fpu/xstate.h | 20 +++----
> arch/x86/kernel/fpu/init.c | 2 +-
> arch/x86/kernel/fpu/signal.c | 10 ++--
> arch/x86/kernel/fpu/xstate.c | 86 ++++++++++++++---------------
> 5 files changed, 60 insertions(+), 62 deletions(-)
...
> diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
> index e5cb67d67c03..d560e8861a3c 100644
> --- a/arch/x86/kernel/fpu/xstate.c
> +++ b/arch/x86/kernel/fpu/xstate.c
> @@ -54,13 +54,16 @@ static short xsave_cpuid_features[] __initdata = {
> };
>
> /*
> - * Mask of xstate features supported by the CPU and the kernel:
> + * XSAVES system states can only be modified from CPL 0 and saved by
> + * XSAVES. The rest are user states. The following is a mask of
> + * supported user state features derived from boot_cpu_has() and
...derived from detected CPUID feature flags and
SUPPORTED_XFEATURES_MASK.
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
^ permalink raw reply
* Re: [PATCH v5 10/17] net: sgi: ioc3-eth: rework skb rx handling
From: Thomas Bogendoerfer @ 2019-08-21 14:28 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Jonathan Corbet, Ralf Baechle, Paul Burton, James Hogan,
Dmitry Torokhov, Lee Jones, David S. Miller, Srinivas Kandagatla,
Alessandro Zummo, Alexandre Belloni, Greg Kroah-Hartman,
Jiri Slaby, Evgeniy Polyakov, linux-doc, linux-kernel, linux-mips,
linux-input, netdev, linux-rtc, linux-serial
In-Reply-To: <20190819165522.451f2ea2@cakuba.netronome.com>
On Mon, 19 Aug 2019 16:55:22 -0700
Jakub Kicinski <jakub.kicinski@netronome.com> wrote:
> On Mon, 19 Aug 2019 18:31:33 +0200, Thomas Bogendoerfer wrote:
> > Buffers alloacted by alloc_skb() are already cache aligned so there
> > is no need for an extra align done by ioc3_alloc_skb. And instead
> > of skb_put/skb_trim simply use one skb_put after frame size is known
> > during receive.
> [...]
> > -/* We use this to acquire receive skb's that we can DMA directly into. */
> > -
> > -#define IOC3_CACHELINE 128UL
>
> Is the cache line on the platform this driver works on 128B?
right now yes, in theory IOC3 CAD DUO cards might work in SGI O2 systems,
but the current Linux PCI implementation for O2 will not detect that card.
On X86 usually the BIOS will choke up on that cards.
> This looks like a DMA engine alignment requirement, more than an
> optimization.
that true, there are two constraints for the rx buffers, start must be aligned
to 128 bytes and a buffer must not cross a 16kbyte boundary. I was already
thinking of allocating pages and chop them up. Is there a Linux API available,
which could help for implementing this ?
I'll probably drop this patch or only change the skb_put stuff plus RX_BUF_SIZE
define.
Thomas.
--
SUSE Linux GmbH
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)
^ permalink raw reply
* Re: [PATCH] docs: mtd: Update spi nor reference driver
From: John Garry @ 2019-08-21 13:39 UTC (permalink / raw)
To: Mark Brown
Cc: Vignesh Raghavendra, Schrempf Frieder, corbet@lwn.net,
mchehab+samsung@kernel.org, linux-mtd@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
marek.vasut@gmail.com, tudor.ambarus@microchip.com,
miquel.raynal@bootlin.com, richard@nod.at, wanghuiqiang
In-Reply-To: <20190820165826.GF4738@sirena.co.uk>
On 20/08/2019 17:58, Mark Brown wrote:
> On Tue, Aug 20, 2019 at 03:09:15PM +0100, John Garry wrote:
>> On 19/08/2019 05:39, Vignesh Raghavendra wrote:
>>> On 16/08/19 3:50 PM, John Garry wrote:
>
>>>> About the child spi flash devices, is the recommendation to just use
>>>> PRP0001 HID and "jedec,spi-nor" compatible?
>
>>> I am not quite familiar with ACPI systems, but child flash device should
>>> use "jedec,spi-nor" as compatible.
>
>> Right, so to use SPI MEM framework, it looks like I will have to use PRP0001
>> and "jedec,spi-nor" as compatible.
>
>> My reluctance in using PRP0001 and compatible "jedec,spi-nor" is how other
>> OS can understand this.
>
Hi Mark,
> Last I heard Windows wasn't doing anything with PRP0001 but on the other
> hand the idiomatic way to handle this for ACPI is as far as I can tell
> to have what is essentially a board file loaded based on DMI information
> without any real enumerability so there's no real conflict between the
> two methods.
Fine, I'll consider this alt method further.
Thanks,
John
>
^ permalink raw reply
* Re: [f2fs-dev] [PATCH v4 3/3] f2fs: Support case-insensitive file name lookups
From: Chao Yu @ 2019-08-21 13:15 UTC (permalink / raw)
To: Daniel Rosenberg, Jaegeuk Kim, Chao Yu, Jonathan Corbet,
linux-f2fs-devel
Cc: linux-doc, linux-api, linux-kernel, linux-fsdevel, kernel-team
In-Reply-To: <20190723230529.251659-4-drosen@google.com>
On 2019-7-24 7:05, Daniel Rosenberg via Linux-f2fs-devel wrote:
> +static int f2fs_d_compare(const struct dentry *dentry, unsigned int len,
> + const char *str, const struct qstr *name)
> +{
> + struct qstr qstr = {.name = str, .len = len };
> +
> + if (!IS_CASEFOLDED(dentry->d_parent->d_inode)) {
> + if (len != name->len)
> + return -1;
> + return memcmp(str, name, len);
66883da1eee8 ("ext4: fix dcache lookup of !casefolded directories")
memcmp(str, name->name, len);
^ permalink raw reply
* Re: [PATCH v5 11/17] net: sgi: ioc3-eth: no need to stop queue set_multicast_list
From: Thomas Bogendoerfer @ 2019-08-21 12:40 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Jonathan Corbet, Ralf Baechle, Paul Burton, James Hogan,
Dmitry Torokhov, Lee Jones, David S. Miller, Srinivas Kandagatla,
Alessandro Zummo, Alexandre Belloni, Greg Kroah-Hartman,
Jiri Slaby, Evgeniy Polyakov, linux-doc, linux-kernel, linux-mips,
linux-input, netdev, linux-rtc, linux-serial
In-Reply-To: <20190819170440.37ff18d4@cakuba.netronome.com>
On Mon, 19 Aug 2019 17:04:53 -0700
Jakub Kicinski <jakub.kicinski@netronome.com> wrote:
> On Mon, 19 Aug 2019 18:31:34 +0200, Thomas Bogendoerfer wrote:
> > netif_stop_queue()/netif_wake_qeue() aren't needed for changing
> > multicast filters. Use spinlocks instead for proper protection
> > of private struct.
> >
>
> I thought it may protect ip->emcr, but that one is accessed with no
> locking from the ioc3_timer() -> ioc3_setup_duplex() path..
it should protect ip->emcr ... I'll add spin_lock/unlock to setup_duplex and
respin the patch.
Thomas.
--
SUSE Linux GmbH
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)
^ permalink raw reply
* [PATCH v3] arm64: implement KPROBES_ON_FTRACE
From: Jisheng Zhang @ 2019-08-21 10:46 UTC (permalink / raw)
To: Catalin Marinas, Jonathan Corbet, Will Deacon, Thomas Gleixner,
Masami Hiramatsu, Naveen N. Rao, Peter Zijlstra
Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Steven Rostedt, Ingo Molnar
KPROBES_ON_FTRACE avoids much of the overhead with regular kprobes as it
eliminates the need for a trap, as well as the need to emulate or
single-step instructions.
Tested on berlin arm64 platform.
~ # mount -t debugfs debugfs /sys/kernel/debug/
~ # cd /sys/kernel/debug/
/sys/kernel/debug # echo 'p _do_fork' > tracing/kprobe_events
before the patch:
/sys/kernel/debug # cat kprobes/list
ffffff801009fe28 k _do_fork+0x0 [DISABLED]
after the patch:
/sys/kernel/debug # cat kprobes/list
ffffff801009ff54 k _do_fork+0x4 [DISABLED][FTRACE]
Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
---
KPROBES_ON_FTRACE avoids much of the overhead with regular kprobes as it
eliminates the need for a trap, as well as the need to emulate or
single-step instructions.
Applied after arm64 FTRACE_WITH_REGS:
http://lists.infradead.org/pipermail/linux-arm-kernel/2019-August/674404.html
Changes since v2:
- remove patch1, make it a single cleanup patch
- remove "This patch" in the change log
- implement arm64's kprobe_lookup_name() and arch_kprobe_on_func_entry instead
patching the common kprobes code
Changes since v1:
- make the kprobes/x86: use instruction_pointer and instruction_pointer_set
as patch1
- add Masami's ACK to patch1
- add some description about KPROBES_ON_FTRACE and why we need it on
arm64
- correct the log before the patch
- remove the consolidation patch, make it as TODO
- only adjust kprobe's addr when KPROBE_FLAG_FTRACE is set
- if KPROBES_ON_FTRACE, ftrace_call_adjust() the kprobe's addr before
calling ftrace_location()
- update the kprobes-on-ftrace/arch-support.txt in doc
.../debug/kprobes-on-ftrace/arch-support.txt | 2 +-
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/probes/Makefile | 1 +
arch/arm64/kernel/probes/ftrace.c | 60 +++++++++++++++++++
arch/arm64/kernel/probes/kprobes.c | 23 +++++++
5 files changed, 86 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/kernel/probes/ftrace.c
diff --git a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
index 68f266944d5f..e8358a38981c 100644
--- a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
+++ b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
@@ -9,7 +9,7 @@
| alpha: | TODO |
| arc: | TODO |
| arm: | TODO |
- | arm64: | TODO |
+ | arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 663392d1eae2..928700f15e23 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -167,6 +167,7 @@ config ARM64
select HAVE_STACKPROTECTOR
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_KPROBES
+ select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES
select HAVE_GENERIC_VDSO
select IOMMU_DMA if IOMMU_SUPPORT
diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
index 8e4be92e25b1..4020cfc66564 100644
--- a/arch/arm64/kernel/probes/Makefile
+++ b/arch/arm64/kernel/probes/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o \
simulate-insn.o
obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o \
simulate-insn.o
+obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
diff --git a/arch/arm64/kernel/probes/ftrace.c b/arch/arm64/kernel/probes/ftrace.c
new file mode 100644
index 000000000000..1f0c09d02bb8
--- /dev/null
+++ b/arch/arm64/kernel/probes/ftrace.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Dynamic Ftrace based Kprobes Optimization
+ *
+ * Copyright (C) Hitachi Ltd., 2012
+ * Copyright (C) 2019 Jisheng Zhang <jszhang@kernel.org>
+ * Synaptics Incorporated
+ */
+
+#include <linux/kprobes.h>
+
+/* Ftrace callback handler for kprobes -- called under preepmt disabed */
+void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+ struct ftrace_ops *ops, struct pt_regs *regs)
+{
+ struct kprobe *p;
+ struct kprobe_ctlblk *kcb;
+
+ /* Preempt is disabled by ftrace */
+ p = get_kprobe((kprobe_opcode_t *)ip);
+ if (unlikely(!p) || kprobe_disabled(p))
+ return;
+
+ kcb = get_kprobe_ctlblk();
+ if (kprobe_running()) {
+ kprobes_inc_nmissed_count(p);
+ } else {
+ unsigned long orig_ip = instruction_pointer(regs);
+ /* Kprobe handler expects regs->pc = pc + 4 as breakpoint hit */
+ instruction_pointer_set(regs, ip + sizeof(kprobe_opcode_t));
+
+ __this_cpu_write(current_kprobe, p);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+ if (!p->pre_handler || !p->pre_handler(p, regs)) {
+ /*
+ * Emulate singlestep (and also recover regs->pc)
+ * as if there is a nop
+ */
+ instruction_pointer_set(regs,
+ (unsigned long)p->addr + MCOUNT_INSN_SIZE);
+ if (unlikely(p->post_handler)) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ p->post_handler(p, regs, 0);
+ }
+ instruction_pointer_set(regs, orig_ip);
+ }
+ /*
+ * If pre_handler returns !0, it changes regs->pc. We have to
+ * skip emulating post_handler.
+ */
+ __this_cpu_write(current_kprobe, NULL);
+ }
+}
+NOKPROBE_SYMBOL(kprobe_ftrace_handler);
+
+int arch_prepare_kprobe_ftrace(struct kprobe *p)
+{
+ p->ainsn.api.insn = NULL;
+ return 0;
+}
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index c4452827419b..f2bf8c70da79 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -551,6 +551,29 @@ void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
return (void *)orig_ret_address;
}
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
+{
+ unsigned long addr = kallsyms_lookup_name(name);
+ unsigned long faddr;
+
+ /*
+ * with -fpatchable-function-entry=2, the first 4 bytes is the
+ * LR saver, then the actual call insn. So ftrace location is
+ * always on the first 4 bytes offset.
+ */
+ faddr = ftrace_location_range(addr, addr + AARCH64_INSN_SIZE);
+ if (faddr)
+ return (kprobe_opcode_t *)faddr;
+ return (kprobe_opcode_t *)addr;
+}
+
+bool arch_kprobe_on_func_entry(unsigned long offset)
+{
+ return offset <= AARCH64_INSN_SIZE;
+}
+#endif
+
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
--
2.23.0.rc1
^ permalink raw reply related
* Re: [PATCH v2 4/9] KVM: arm64: Support stolen time reporting via shared structure
From: Steven Price @ 2019-08-21 10:27 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Catalin Marinas, Paolo Bonzini, Radim Krčmář,
Russell King, James Morse, Julien Thierry, Suzuki K Pouloze,
Mark Rutland, kvm, linux-doc, linux-kernel
In-Reply-To: <f6fad4fa-323d-306c-c582-de07464f4d00@kernel.org>
On 19/08/2019 17:40, Marc Zyngier wrote:
> Hi Steven,
>
> On 19/08/2019 15:04, Steven Price wrote:
>> Implement the service call for configuring a shared structure between a
>> VCPU and the hypervisor in which the hypervisor can write the time
>> stolen from the VCPU's execution time by other tasks on the host.
>>
>> The hypervisor allocates memory which is placed at an IPA chosen by user
>> space. The hypervisor then uses WRITE_ONCE() to update the shared
>> structure ensuring single copy atomicity of the 64-bit unsigned value
>> that reports stolen time in nanoseconds.
>>
>> Whenever stolen time is enabled by the guest, the stolen time counter is
>> reset.
>>
>> The stolen time itself is retrieved from the sched_info structure
>> maintained by the Linux scheduler code. We enable SCHEDSTATS when
>> selecting KVM Kconfig to ensure this value is meaningful.
>>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>> ---
>> arch/arm/include/asm/kvm_host.h | 15 +++++++
>> arch/arm64/include/asm/kvm_host.h | 16 ++++++-
>> arch/arm64/kvm/Kconfig | 1 +
>> include/linux/kvm_types.h | 2 +
>> virt/kvm/arm/arm.c | 19 +++++++++
>> virt/kvm/arm/hypercalls.c | 3 ++
>> virt/kvm/arm/pvtime.c | 71 +++++++++++++++++++++++++++++++
>> 7 files changed, 126 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
>> index 369b5d2d54bf..14d61a84c270 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -39,6 +39,7 @@
>> KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
>> #define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
>> #define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
>> +#define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
>>
>> DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
>>
>> @@ -77,6 +78,12 @@ struct kvm_arch {
>>
>> /* Mandated version of PSCI */
>> u32 psci_version;
>> +
>> + struct kvm_arch_pvtime {
>> + struct gfn_to_hva_cache st_ghc;
>> + gpa_t st_base;
>> + u64 st_size;
>> + } pvtime;
>
> It'd be good if we could avoid having this in the 32bit vcpu structure,
> given that it serves no real purpose (other than being able to compile
> things).
Good point - I think I can fix that with a couple more static inline
functions... It's a little tricky due to header file include order, but
I think I can make it work.
[...]
>> +int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init)
>> +{
>> + struct kvm *kvm = vcpu->kvm;
>> + struct kvm_arch_pvtime *pvtime = &kvm->arch.pvtime;
>> + u64 steal;
>> + u64 steal_le;
>> + u64 offset;
>> + int idx;
>> + const int stride = sizeof(struct pvclock_vcpu_stolen_time);
>> +
>> + if (pvtime->st_base == GPA_INVALID)
>> + return -ENOTSUPP;
>> +
>> + /* Let's do the local bookkeeping */
>> + steal = vcpu->arch.steal.steal;
>> + steal += current->sched_info.run_delay - vcpu->arch.steal.last_steal;
>> + vcpu->arch.steal.last_steal = current->sched_info.run_delay;
>> + vcpu->arch.steal.steal = steal;
>> +
>> + offset = stride * kvm_vcpu_get_idx(vcpu);
>> +
>> + if (unlikely(offset + stride > pvtime->st_size))
>> + return -EINVAL;
>> +
>> + steal_le = cpu_to_le64(steal);
>> + pagefault_disable();
>
> What's the reason for doing a pagefault_disable()? What I'd expect is
> for the userspace page to be faulted in and written to, and doing a
> pagefault_disable() seems to be going against this idea.
Umm... this is me screwing up the locking...
The current code is very confused about which locks should/can be held
when kvm_update_stolen_time() is called. vcpu_req_record_steal()
explicitly takes the kvm->srcu read lock - which is then taken again
here. But kvm_hypercall_stolen_time doesn't hold any lock. And obviously
at some point in time I expected this to be called in atomic context...
In general the page is likely to be faulted in (as a guest which is
using stolen time is surely looking at the numbers there). But there's
no need for the pagefault_disable(). It also shouldn't be the callers
responsibility to hold kvm->srcu.
Steve
^ permalink raw reply
* Re: [PATCH v8 02/27] x86/cpufeatures: Add CET CPU feature flags for Control-flow Enforcement Technology (CET)
From: Borislav Petkov @ 2019-08-21 10:20 UTC (permalink / raw)
To: Yu-cheng Yu
Cc: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
Andy Lutomirski, Balbir Singh, Cyrill Gorcunov, Dave Hansen,
Eugene Syromiatnikov, Florian Weimer, H.J. Lu, Jann Horn,
Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
In-Reply-To: <20190813205225.12032-3-yu-cheng.yu@intel.com>
On Tue, Aug 13, 2019 at 01:52:00PM -0700, Yu-cheng Yu wrote:
> Add CPU feature flags for Control-flow Enforcement Technology (CET).
>
> CPUID.(EAX=7,ECX=0):ECX[bit 7] Shadow stack
> CPUID.(EAX=7,ECX=0):EDX[bit 20] Indirect branch tracking
>
> Reviewed-by: Borislav Petkov <bp@suse.de>
> Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
> ---
> arch/x86/include/asm/cpufeatures.h | 2 ++
> arch/x86/kernel/cpu/cpuid-deps.c | 2 ++
> 2 files changed, 4 insertions(+)
>
> diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
> index e880f2408e29..122265ab46c1 100644
> --- a/arch/x86/include/asm/cpufeatures.h
> +++ b/arch/x86/include/asm/cpufeatures.h
> @@ -334,6 +334,7 @@
> #define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
> #define X86_FEATURE_WAITPKG (16*32+ 5) /* UMONITOR/UMWAIT/TPAUSE Instructions */
> #define X86_FEATURE_AVX512_VBMI2 (16*32+ 6) /* Additional AVX512 Vector Bit Manipulation Instructions */
> +#define X86_FEATURE_SHSTK (16*32+ 7) /* Shadow Stack */
> #define X86_FEATURE_GFNI (16*32+ 8) /* Galois Field New Instructions */
> #define X86_FEATURE_VAES (16*32+ 9) /* Vector AES */
> #define X86_FEATURE_VPCLMULQDQ (16*32+10) /* Carry-Less Multiplication Double Quadword */
> @@ -358,6 +359,7 @@
> #define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */
> #define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */
> #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
> +#define X86_FEATURE_IBT (18*32+20) /* Indirect Branch Tracking */
> #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
> #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
> #define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */
> diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
> index b5353244749b..9bf35f081080 100644
> --- a/arch/x86/kernel/cpu/cpuid-deps.c
> +++ b/arch/x86/kernel/cpu/cpuid-deps.c
> @@ -68,6 +68,8 @@ static const struct cpuid_dep cpuid_deps[] = {
> { X86_FEATURE_CQM_MBM_TOTAL, X86_FEATURE_CQM_LLC },
> { X86_FEATURE_CQM_MBM_LOCAL, X86_FEATURE_CQM_LLC },
> { X86_FEATURE_AVX512_BF16, X86_FEATURE_AVX512VL },
> + { X86_FEATURE_SHSTK, X86_FEATURE_XSAVES },
> + { X86_FEATURE_IBT, X86_FEATURE_XSAVES },
This hunk needs re-tabbing after:
1e0c08e3034d ("cpu/cpuid-deps: Add a tab to cpuid dependent features")
Thx.
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
^ permalink raw reply
* [PATCH 3/4] kbuild: pkg: rename scripts/package/Makefile to scripts/Makefile.package
From: Masahiro Yamada @ 2019-08-21 7:02 UTC (permalink / raw)
To: linux-kbuild
Cc: Masahiro Yamada, Heiko Carstens, Jonathan Corbet, Michal Marek,
Sam Ravnborg, linux-doc, linux-kernel
In-Reply-To: <20190821070205.8297-1-yamada.masahiro@socionext.com>
scripts/package/Makefile does not use $(obj) or $(src) at all.
It actually generates files and directories in the top of $(objtree).
I do not see much sense in descending into scripts/package/.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
Documentation/kbuild/makefiles.rst | 16 ++++------------
Makefile | 8 +++-----
scripts/Makefile.clean | 14 +-------------
scripts/{package/Makefile => Makefile.package} | 5 ++++-
scripts/kconfig/Makefile | 2 +-
usr/include/Makefile | 4 +---
6 files changed, 14 insertions(+), 35 deletions(-)
rename scripts/{package/Makefile => Makefile.package} (99%)
diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst
index 68ed20ef37dd..78aa51a6fcd4 100644
--- a/Documentation/kbuild/makefiles.rst
+++ b/Documentation/kbuild/makefiles.rst
@@ -765,7 +765,8 @@ Files matching the patterns "*.[oas]", "*.ko", plus some additional files
generated by kbuild are deleted all over the kernel src tree when
"make clean" is executed.
-Additional files can be specified in kbuild makefiles by use of $(clean-files).
+Additional files or directories can be specified in kbuild makefiles by use of
+$(clean-files).
Example::
@@ -776,17 +777,8 @@ When executing "make clean", the file "crc32table.h" will be deleted.
Kbuild will assume files to be in the same relative directory as the
Makefile, except if prefixed with $(objtree).
-To delete a directory hierarchy use:
-
- Example::
-
- #scripts/package/Makefile
- clean-dirs := $(objtree)/debian/
-
-This will delete the directory debian in the toplevel directory, including all
-subdirectories.
-
-To exclude certain files from make clean, use the $(no-clean-files) variable.
+To exclude certain files or directories from make clean, use the
+$(no-clean-files) variable.
Usually kbuild descends down in subdirectories due to "obj-* := dir/",
but in the architecture makefiles where the kbuild infrastructure
diff --git a/Makefile b/Makefile
index e88d4fcd5e87..ec2a6b85a0fa 100644
--- a/Makefile
+++ b/Makefile
@@ -1448,13 +1448,11 @@ distclean: mrproper
# Packaging of the kernel to various formats
# ---------------------------------------------------------------------------
-package-dir := scripts/package
%src-pkg: FORCE
- $(Q)$(MAKE) $(build)=$(package-dir) $@
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@
%pkg: include/config/kernel.release FORCE
- $(Q)$(MAKE) $(build)=$(package-dir) $@
-
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@
# Brief documentation of the typical targets used
# ---------------------------------------------------------------------------
@@ -1526,7 +1524,7 @@ help:
@echo ' or "cd tools; make help"'
@echo ''
@echo 'Kernel packaging:'
- @$(MAKE) $(build)=$(package-dir) help
+ @$(MAKE) -f $(srctree)/scripts/Makefile.package help
@echo ''
@echo 'Documentation targets:'
@$(MAKE) -f $(srctree)/Documentation/Makefile dochelp
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 0b80e3207b20..798e8717c1d9 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -52,26 +52,14 @@ __clean-files := $(wildcard \
$(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \
$(filter $(objtree)/%, $(__clean-files)))
-# same as clean-files
-
-__clean-dirs := $(wildcard \
- $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(clean-dirs))) \
- $(filter $(objtree)/%, $(clean-dirs)))
-
# ==========================================================================
quiet_cmd_clean = CLEAN $(obj)
- cmd_clean = rm -f $(__clean-files)
-quiet_cmd_cleandir = CLEAN $(__clean-dirs)
- cmd_cleandir = rm -rf $(__clean-dirs)
-
+ cmd_clean = rm -rf $(__clean-files)
__clean: $(subdir-ymn)
ifneq ($(strip $(__clean-files)),)
+$(call cmd,clean)
-endif
-ifneq ($(strip $(__clean-dirs)),)
- +$(call cmd,cleandir)
endif
@:
diff --git a/scripts/package/Makefile b/scripts/Makefile.package
similarity index 99%
rename from scripts/package/Makefile
rename to scripts/Makefile.package
index 407189d9942a..56eadcc48d46 100644
--- a/scripts/package/Makefile
+++ b/scripts/Makefile.package
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
# Makefile for the different targets used to generate full packages of a kernel
-# It uses the generic clean infrastructure of kbuild
+
+include $(srctree)/scripts/Kbuild.include
# RPM target
# ---------------------------------------------------------------------------
@@ -154,3 +155,5 @@ help:
@echo ' perf-targz-src-pkg - Build $(perf-tar).tar.gz source tarball'
@echo ' perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball'
@echo ' perf-tarxz-src-pkg - Build $(perf-tar).tar.xz source tarball'
+
+.PHONY: $(PHONY)
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 7656e1137b6b..bed7a5a2fbe9 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -114,7 +114,7 @@ testconfig: $(obj)/conf
$(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \
-o cache_dir=$(abspath $(obj)/tests/.cache) \
$(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no)
-clean-dirs += tests/.cache
+clean-files += tests/.cache
# Help text used by make help
help:
diff --git a/usr/include/Makefile b/usr/include/Makefile
index 1fb6abe29b2f..05c71ef42f51 100644
--- a/usr/include/Makefile
+++ b/usr/include/Makefile
@@ -115,6 +115,4 @@ header-test-y += $(filter-out $(header-test-), \
$(patsubst $(obj)/%,%, $(wildcard \
$(addprefix $(obj)/, *.h */*.h */*/*.h */*/*/*.h))))
-# For GNU Make <= 4.2.1, $(wildcard $(obj)/*/) matches to not only directories
-# but also regular files. Use $(filter %/, ...) just in case.
-clean-dirs += $(patsubst $(obj)/%/,%,$(filter %/, $(wildcard $(obj)/*/)))
+clean-files += $(filter-out Makefile, $(notdir $(wildcard $(obj)/*)))
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v5 1/9] fpga: dfl: make init callback optional
From: Wu Hao @ 2019-08-21 5:12 UTC (permalink / raw)
To: Moritz Fischer
Cc: gregkh, linux-fpga, linux-kernel, linux-api, linux-doc, atull
In-Reply-To: <20190821032406.GA28625@archbox>
On Tue, Aug 20, 2019 at 08:24:06PM -0700, Moritz Fischer wrote:
> Hi,
>
> On Mon, Aug 12, 2019 at 10:49:56AM +0800, Wu Hao wrote:
> > This patch makes init callback of sub features optional. With
> > this change, people don't need to prepare any empty init callback.
> >
> > Signed-off-by: Wu Hao <hao.wu@intel.com>
>
> Acked-by: Moritz Fischer <mdf@kernel.org>
> > ---
> > drivers/fpga/dfl.c | 10 ++++++----
> > 1 file changed, 6 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
> > index c0512af..96a2b82 100644
> > --- a/drivers/fpga/dfl.c
> > +++ b/drivers/fpga/dfl.c
> > @@ -271,11 +271,13 @@ static int dfl_feature_instance_init(struct platform_device *pdev,
> > struct dfl_feature *feature,
> > struct dfl_feature_driver *drv)
> > {
> > - int ret;
> > + int ret = 0;
> >
> > - ret = drv->ops->init(pdev, feature);
> > - if (ret)
> > - return ret;
> > + if (drv->ops->init) {
> > + ret = drv->ops->init(pdev, feature);
> > + if (ret)
> > + return ret;
> > + }
> >
> > feature->ops = drv->ops;
>
> You could swap it around maybe like so:
>
> int dfl_feature_instance_init() ...
> {
> feature->ops = drv->ops;
> if (drv->ops->init)
> return drv->ops->init(pdev, feature);
>
> return 0;
> }
>
> With the caveat that feature->ops gets always set ...
>
> Your call.
Hi Moritz,
Thanks a lot for the review and comments. It does simplify the code,
will modify it.
Thanks
Hao
>
> Thanks,
> Moritz
^ permalink raw reply
* Zdravstvujte! Vas interesujut klientskie bazy dannyh?
From: prodawez @ 2019-08-20 21:44 UTC (permalink / raw)
To: prodawez
Zdravstvujte! Vas interesujut klientskie bazy dannyh?
^ permalink raw reply
* Re: [RFC 01/19] kbuild: Fixes to rules for host-cshlib and host-cxxshlib
From: Knut Omang @ 2019-08-21 4:03 UTC (permalink / raw)
To: Masahiro Yamada
Cc: open list:KERNEL SELFTEST FRAMEWORK, Linux Kernel Mailing List,
open list:DOCUMENTATION, Linux Kbuild mailing list, Shuah Khan,
Jonathan Corbet, Michal Marek, Greg Kroah-Hartman,
Shreyans Devendra Doshi, Alan Maguire, Brendan Higgins,
Kevin Hilman, Hidenori Yamaji, Frank Rowand, Timothy Bird,
Luis Chamberlain, Theodore Ts'o, Daniel Vetter, Stephen Boyd
In-Reply-To: <CAK7LNATp2tNSUakQ1j81AC40QVJUoDaA6hJ7duLwqCOgkXObJg@mail.gmail.com>
On Wed, 2019-08-21 at 10:47 +0900, Masahiro Yamada wrote:
> On Wed, Aug 14, 2019 at 9:53 PM Knut Omang <knut.omang@oracle.com> wrote:
> >
> > On Wed, 2019-08-14 at 07:52 +0200, Knut Omang wrote:
> > > On Wed, 2019-08-14 at 11:02 +0900, Masahiro Yamada wrote:
> > > > Hi Knut,
> > > >
> > > > On Wed, Aug 14, 2019 at 1:19 AM Knut Omang <knut.omang@oracle.com> wrote:
> > > > > On Tue, 2019-08-13 at 23:01 +0900, Masahiro Yamada wrote:
> > > > > > On Tue, Aug 13, 2019 at 3:13 PM Knut Omang <knut.omang@oracle.com> wrote:
> > > > > > > C++ libraries interfacing to C APIs might sometimes need some glue
> > > > > > > logic more easily written in C.
> > > > > > > Allow a C++ library to also contain 0 or more C objects.
> > > > > > >
> > > > > > > Also fix rules for both C and C++ shared libraries:
> > > > > > > - C++ shared libraries depended on .c instead of .cc files
> > > > > > > - Rules were referenced as -objs instead of the intended
> > > > > > > -cobjs and -cxxobjs following the pattern from hostprogs*.
> > > > > > >
> > > > > > > Signed-off-by: Knut Omang <knut.omang@oracle.com>
> > > > > >
> > > > > > How is this patch related to the rest of this series?
> > > > >
> > > > > This is just my (likely naive) way I to get what I had working
> > > > > using autotools in the Github version of KTF) translated into something
> > > > > comparable using kbuild only. We need to build a shared library consisting
> > > > > of a few C++ files and a very simple C file, and a couple of simple binaries,
> > > > > and the rule in there does seem to take .c files and subject them to the
> > > > > C++ compiler, which makes this difficult to achieve?
> > > >
> > > > Looking at the diff stat of the cover-letter,
> > > > the rest of this patch series is touching only
> > > > Documentation/ and tools/testing/kselftests/.
> > > >
> > > > So, this one is unused by the rest of the changes, isn't it?
> > > > Am I missing something?
> > > >
> > > >
> > > >
> > > > > > This patch breaks GCC-plugins.
> > > > > > Did you really compile-test this patch before the submission?
> > > > >
> > > > > Sorry for my ignorance here:
> > > > > I ran through the kernel build and installed the resulting kernel
> > > > > on a VM that I used to test this, if that's what you are asking
> > > > > about?
> > > > >
> > > > > Do I need some unusual .config options or run a special make target
> > > > > to trigger the problem you see?
> > > > >
> > > > > I used a recent Fedora config with default values for new options,
> > > > > and ran the normal default make target (also with O=) and make selftests
> > > > > to test the patch itself.
> > > >
> > > > I just built allmodconfig for arm.
> > > >
> > > > (The 0-day bot tests allmodconfig for most of architectures,
> > > > so you may receive error reports anyway.)
> > > >
> > > >
> > > > With your patch, I got the following:
> > > >
> > > >
> > > > masahiro@grover:~/ref/linux$ make ARCH=arm
> > > > CROSS_COMPILE=- allmodconfig all
> > > > HOSTCC scripts/basic/fixdep
> > > > HOSTCC scripts/kconfig/conf.o
> > > > HOSTCC scripts/kconfig/confdata.o
> > > > HOSTCC scripts/kconfig/expr.o
> > > > LEX scripts/kconfig/lexer.lex.c
> > > > YACC scripts/kconfig/parser.tab.h
> > > > HOSTCC scripts/kconfig/lexer.lex.o
> > > > YACC scripts/kconfig/parser.tab.c
> > > > HOSTCC scripts/kconfig/parser.tab.o
> > > > HOSTCC scripts/kconfig/preprocess.o
> > > > HOSTCC scripts/kconfig/symbol.o
> > > > HOSTLD scripts/kconfig/conf
> > > > scripts/kconfig/conf --allmodconfig Kconfig
> > > > #
> > > > # configuration written to .config
> > > > #
> > > > SYSHDR arch/arm/include/generated/uapi/asm/unistd-common.h
> > > > SYSHDR arch/arm/include/generated/uapi/asm/unistd-oabi.h
> > > > SYSHDR arch/arm/include/generated/uapi/asm/unistd-eabi.h
> > > > HOSTCC scripts/dtc/dtc.o
> > > > HOSTCC scripts/dtc/flattree.o
> > > > HOSTCC scripts/dtc/fstree.o
> > > > HOSTCC scripts/dtc/data.o
> > > > HOSTCC scripts/dtc/livetree.o
> > > > HOSTCC scripts/dtc/treesource.o
> > > > HOSTCC scripts/dtc/srcpos.o
> > > > HOSTCC scripts/dtc/checks.o
> > > > HOSTCC scripts/dtc/util.o
> > > > LEX scripts/dtc/dtc-lexer.lex.c
> > > > YACC scripts/dtc/dtc-parser.tab.h
> > > > HOSTCC scripts/dtc/dtc-lexer.lex.o
> > > > YACC scripts/dtc/dtc-parser.tab.c
> > > > HOSTCC scripts/dtc/dtc-parser.tab.o
> > > > HOSTCC scripts/dtc/yamltree.o
> > > > HOSTLD scripts/dtc/dtc
> > > > CC scripts/gcc-plugins/latent_entropy_plugin.o
> > > > cc1: error: cannot load plugin ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so
> > > > ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: cannot open
> > > > shared object file: No such file or directory
> > > > cc1: error: cannot load plugin ./scripts/gcc-plugins/structleak_plugin.so
> > > > ./scripts/gcc-plugins/structleak_plugin.so: cannot open shared
> > > > object file: No such file or directory
> > > > cc1: error: cannot load plugin ./scripts/gcc-plugins/latent_entropy_plugin.so
> > > > ./scripts/gcc-plugins/latent_entropy_plugin.so: cannot open shared
> > > > object file: No such file or directory
> > > > cc1: error: cannot load plugin ./scripts/gcc-plugins/randomize_layout_plugin.so
> > > > ./scripts/gcc-plugins/randomize_layout_plugin.so: cannot open
> > > > shared object file: No such file or directory
> > > > make[3]: *** [scripts/Makefile.build;281:
> > > > scripts/gcc-plugins/latent_entropy_plugin.o] Error 1
> > > > make[2]: *** [scripts/Makefile.build;497: scripts/gcc-plugins] Error 2
> > > > make[1]: *** [Makefile;1097: scripts] Error 2
> > > > make: *** [Makefile;330: __build_one_by_one] Error 2
> > >
> > > Ok, I see!
> > >
> > > I'll recall this target and look into it!
> >
> > Ok, so I have tried installing the arm-linux-gnueabihf cross compiler and compiled the
> kernel for arm,
> > but allmodconfig does not seem to enable any GCC plugins per default even on ARM and I
> haven't been able
> > to figure out how to enable any.
>
>
> Linaro toolchain supports gcc plugins.
>
> https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/
>
>
> kernel.org one supports it as well.
>
> https://mirrors.edge.kernel.org/pub/tools/crosstool/
>
>
>
>
>
> > A plain allmodconfig generated config compiles perfectly for me both native x86 and
> w/arm cross compile,
> > but it doesn't seem to enable any gcc plugins.
> >
> > Anyway, maybe I am getting this wrong anyway:
> > Having played with cross compile, it starts to become clear to me that HOSTCC rules
> > might not be the right rules to use, as it will generate host user land binaries as
> opposed to
> > target user land binaries (in a cross compile world obviously these differ)
> >
> > Now, I started off with using the rules in the selftests makefiles for this, but they
> do not play that well with
> > kernel module building. My goal is to be able to do both user land and kernel module
> **target** compiles
> > from the same subtree. Any hints on how to accomplish this appreciated :-)
>
>
> tools/ is out of scope of kbuild because it adopted a different (more
> adhoc) build system.
That resonates with my understanding, thanks!
I think that's what I am trying to understand how to improve:
To sum up, my conclusion so far is that there's a need for a set of more integrated Kbuild
rules for target platform binaries and libraries similar to the host* rules. The rules in
tools/ could then be modified to use that generic support instead of the current adhoc
approach. That would allow the needs of tests that have both user space and kernel space
code to be more nicely co-located, with several benefits IMHO.
Any further insights appreciated!
> I have no idea. Please talk to the kselftest maintainer.
She's on the Cc:-list, I was hoping to get a some of the challenges/choices highlighted
here ;-)
Thanks!
Knut
^ permalink raw reply
* Re: [PATCH v5 2/9] fpga: dfl: fme: convert platform_driver to use dev_groups
From: Moritz Fischer @ 2019-08-21 3:28 UTC (permalink / raw)
To: Wu Hao; +Cc: gregkh, mdf, linux-fpga, linux-kernel, linux-api, linux-doc,
atull
In-Reply-To: <1565578204-13969-3-git-send-email-hao.wu@intel.com>
Hi Hao,
On Mon, Aug 12, 2019 at 10:49:57AM +0800, Wu Hao wrote:
> This patch takes advantage of driver core which helps to create
> and remove sysfs attribute files, so there is no need to register
> sysfs entries manually in dfl-fme platform river code.
Nit: s/river/driver
>
> Signed-off-by: Wu Hao <hao.wu@intel.com>
Acked-by: Moritz Fischer <mdf@kernel.org>
> ---
> drivers/fpga/dfl-fme-main.c | 29 ++---------------------------
> 1 file changed, 2 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/fpga/dfl-fme-main.c b/drivers/fpga/dfl-fme-main.c
> index f033f1c..bf8114d 100644
> --- a/drivers/fpga/dfl-fme-main.c
> +++ b/drivers/fpga/dfl-fme-main.c
> @@ -129,30 +129,6 @@ static ssize_t socket_id_show(struct device *dev,
> };
> ATTRIBUTE_GROUPS(fme_hdr);
>
> -static int fme_hdr_init(struct platform_device *pdev,
> - struct dfl_feature *feature)
> -{
> - void __iomem *base = feature->ioaddr;
> - int ret;
> -
> - dev_dbg(&pdev->dev, "FME HDR Init.\n");
> - dev_dbg(&pdev->dev, "FME cap %llx.\n",
> - (unsigned long long)readq(base + FME_HDR_CAP));
> -
> - ret = device_add_groups(&pdev->dev, fme_hdr_groups);
> - if (ret)
> - return ret;
> -
> - return 0;
> -}
> -
> -static void fme_hdr_uinit(struct platform_device *pdev,
> - struct dfl_feature *feature)
> -{
> - dev_dbg(&pdev->dev, "FME HDR UInit.\n");
> - device_remove_groups(&pdev->dev, fme_hdr_groups);
> -}
> -
> static long fme_hdr_ioctl_release_port(struct dfl_feature_platform_data *pdata,
> unsigned long arg)
> {
> @@ -199,8 +175,6 @@ static long fme_hdr_ioctl(struct platform_device *pdev,
> };
>
> static const struct dfl_feature_ops fme_hdr_ops = {
> - .init = fme_hdr_init,
> - .uinit = fme_hdr_uinit,
> .ioctl = fme_hdr_ioctl,
> };
>
> @@ -361,7 +335,8 @@ static int fme_remove(struct platform_device *pdev)
>
> static struct platform_driver fme_driver = {
> .driver = {
> - .name = DFL_FPGA_FEATURE_DEV_FME,
> + .name = DFL_FPGA_FEATURE_DEV_FME,
> + .dev_groups = fme_hdr_groups,
> },
> .probe = fme_probe,
> .remove = fme_remove,
> --
> 1.8.3.1
>
Thanks,
Moritz
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox