Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-03-31 15:05:34 +0200
committerTakashi Iwai <tiwai@suse.de>2017-03-31 15:05:34 +0200
commit1ab68c392df900ec9d6f01f8bed50f4bb6b52f75 (patch)
treee3b58f962b8a597924ee47af9037fa1b9413f820
parentf6b2ccfdca3184b1666e1af9ddd3ded84ed4aa56 (diff)
parent8634093a30578a4610c98a230eb7fcc88f16837d (diff)
Merge branch 'users/ykaukab/SLE12-SP3/for-next' into SLE12-SP3rpm-4.4.57-2
Pull arm64 updates from Mian Yousaf Kaukab (fate#320512). suse-commit: 8874b7e27e61717495a71e3983288780df8d9c98
-rw-r--r--Documentation/watchdog/src/watchdog-test.c14
-rw-r--r--arch/arm64/include/asm/module.h5
-rw-r--r--arch/arm64/kernel/head.S8
-rw-r--r--arch/arm64/kernel/kaslr.c10
-rw-r--r--arch/arm64/kernel/topology.c2
-rw-r--r--arch/arm64/mm/proc.S9
-rw-r--r--drivers/acpi/arm64/iort.c2
-rw-r--r--drivers/iommu/amd_iommu.c2
-rw-r--r--drivers/iommu/arm-smmu-v3.c2
-rw-r--r--drivers/iommu/arm-smmu.c2
-rw-r--r--drivers/iommu/intel-iommu.c2
-rw-r--r--drivers/iommu/iommu.c5
-rw-r--r--drivers/vfio/vfio.c8
-rw-r--r--drivers/vfio/vfio_iommu_type1.c7
-rw-r--r--include/linux/iommu.h18
-rw-r--r--init/Kconfig1
-rw-r--r--kernel/irq/ipi.c3
-rw-r--r--virt/kvm/arm/vgic/vgic-v2.c6
-rw-r--r--virt/kvm/arm/vgic/vgic-v3.c6
-rw-r--r--virt/kvm/arm/vgic/vgic.c6
20 files changed, 83 insertions, 35 deletions
diff --git a/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c
index c69153913722..6983d05097e2 100644
--- a/Documentation/watchdog/src/watchdog-test.c
+++ b/Documentation/watchdog/src/watchdog-test.c
@@ -2,6 +2,7 @@
* Watchdog Driver Test Program
*/
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -35,9 +36,13 @@ static void keep_alive(void)
static void term(int sig)
{
- write(fd, &v, 1);
+ int ret = write(fd, &v, 1);
+
close(fd);
- printf("\nStopping watchdog ticks...\n");
+ if (ret < 0)
+ printf("\nStopping watchdog ticks failed (%d)...\n", errno);
+ else
+ printf("\nStopping watchdog ticks...\n");
exit(0);
}
@@ -45,6 +50,7 @@ int main(int argc, char *argv[])
{
int flags;
unsigned int ping_rate = 1;
+ int ret;
setbuf(stdout, NULL);
@@ -91,7 +97,9 @@ int main(int argc, char *argv[])
sleep(ping_rate);
}
end:
- write(fd, &v, 1);
+ ret = write(fd, &v, 1);
+ if (ret < 0)
+ printf("Stopping watchdog ticks failed (%d)...\n", errno);
close(fd);
return 0;
}
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
index e12af6754634..06ff7fd9e81f 100644
--- a/arch/arm64/include/asm/module.h
+++ b/arch/arm64/include/asm/module.h
@@ -17,6 +17,7 @@
#define __ASM_MODULE_H
#include <asm-generic/module.h>
+#include <asm/memory.h>
#define MODULE_ARCH_VERMAGIC "aarch64"
@@ -32,6 +33,10 @@ u64 module_emit_plt_entry(struct module *mod, const Elf64_Rela *rela,
Elf64_Sym *sym);
#ifdef CONFIG_RANDOMIZE_BASE
+#ifdef CONFIG_MODVERSIONS
+#define ARCH_RELOCATES_KCRCTAB
+#define reloc_start (kimage_vaddr - KIMAGE_VADDR)
+#endif
extern u64 module_alloc_base;
#else
#define module_alloc_base ((u64)_etext - MODULES_VSIZE)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7e1b34b88ec9..361a24accf45 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -766,10 +766,14 @@ ENTRY(__enable_mmu)
isb
bl __create_page_tables // recreate kernel mapping
+ tlbi vmalle1 // Remove any stale TLB entries
+ dsb nsh
+
msr sctlr_el1, x19 // re-enable the MMU
isb
- ic ialluis // flush instructions fetched
- isb // via old mapping
+ ic iallu // flush instructions fetched
+ dsb nsh // via old mapping
+ isb
add x27, x27, x23 // relocated __mmap_switched
#endif
br x27
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 8b32a1f8f09f..0efbf1f9b577 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -126,11 +126,15 @@ u64 __init kaslr_early_init(u64 dt_phys)
/*
* The kernel Image should not extend across a 1GB/32MB/512MB alignment
* boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
- * happens, increase the KASLR offset by the size of the kernel image.
+ * happens, increase the KASLR offset by the size of the kernel image
+ * rounded up by SWAPPER_BLOCK_SIZE.
*/
if ((((u64)_text + offset) >> SWAPPER_TABLE_SHIFT) !=
- (((u64)_end + offset) >> SWAPPER_TABLE_SHIFT))
- offset = (offset + (u64)(_end - _text)) & mask;
+ (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) {
+ u64 kimg_sz = _end - _text;
+ offset = (offset + round_up(kimg_sz, SWAPPER_BLOCK_SIZE))
+ & mask;
+ }
if (IS_ENABLED(CONFIG_KASAN))
/*
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 655e65f38f31..565dd69888cc 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -41,7 +41,6 @@ static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
per_cpu(cpu_scale, cpu) = capacity;
}
-#ifdef CONFIG_PROC_SYSCTL
static ssize_t cpu_capacity_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -98,7 +97,6 @@ static int register_cpu_capacity_sysctl(void)
return 0;
}
subsys_initcall(register_cpu_capacity_sysctl);
-#endif
static u32 capacity_scale;
static u32 *raw_capacity;
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 55a7664956ea..44a26b870302 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -102,7 +102,16 @@ ENTRY(cpu_do_resume)
msr tcr_el1, x8
msr vbar_el1, x9
+
+ /*
+ * __cpu_setup() cleared MDSCR_EL1.MDE and friends, before unmasking
+ * debug exceptions. By restoring MDSCR_EL1 here, we may take a debug
+ * exception. Mask them until local_dbg_restore() in cpu_suspend()
+ * resets them.
+ */
+ disable_dbg
msr mdscr_el1, x10
+
msr sctlr_el1, x12
/*
* Restore oslsr_el1 by writing oslar_el1
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 95d64a327db0..7e8c466ea49d 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -924,7 +924,7 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO);
if (!pdev)
- return PTR_ERR(pdev);
+ return -ENOMEM;
count = ops->iommu_count_resources(node);
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index a6ecd805f721..5eccfdb69a99 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3175,7 +3175,7 @@ static void amd_iommu_get_resv_regions(struct device *dev,
region = iommu_alloc_resv_region(MSI_RANGE_START,
MSI_RANGE_END - MSI_RANGE_START + 1,
- 0, IOMMU_RESV_RESERVED);
+ 0, IOMMU_RESV_MSI);
if (!region)
return;
list_add_tail(&region->list, head);
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index cb4b04579199..279f634a1d84 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1886,7 +1886,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
- prot, IOMMU_RESV_MSI);
+ prot, IOMMU_RESV_SW_MSI);
if (!region)
return;
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a975627346e8..b84eed2e285a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1596,7 +1596,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
- prot, IOMMU_RESV_MSI);
+ prot, IOMMU_RESV_SW_MSI);
if (!region)
return;
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index b5a3b8ce40b5..2232ac7f8059 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5269,7 +5269,7 @@ static void intel_iommu_get_resv_regions(struct device *device,
reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
- 0, IOMMU_RESV_RESERVED);
+ 0, IOMMU_RESV_MSI);
if (!reg)
return;
list_add_tail(&reg->list, head);
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 09ce1599f71d..9753f4c7f9cc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -73,6 +73,7 @@ static const char * const iommu_group_resv_type_string[] = {
[IOMMU_RESV_DIRECT] = "direct",
[IOMMU_RESV_RESERVED] = "reserved",
[IOMMU_RESV_MSI] = "msi",
+ [IOMMU_RESV_SW_MSI] = "msi",
};
#define IOMMU_GROUP_ATTR(_name, _mode, _show, _store) \
@@ -1712,8 +1713,8 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
}
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
- size_t length,
- int prot, int type)
+ size_t length, int prot,
+ enum iommu_resv_type type)
{
struct iommu_resv_region *region;
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 37f0307eb85a..f795910891d6 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1608,8 +1608,8 @@ int vfio_pin_pages(struct device *dev, unsigned long *user_pfn, int npage,
return -E2BIG;
group = vfio_group_get_from_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
+ if (!group)
+ return -ENODEV;
ret = vfio_group_add_container_user(group);
if (ret)
@@ -1657,8 +1657,8 @@ int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn, int npage)
return -E2BIG;
group = vfio_group_get_from_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
+ if (!group)
+ return -ENODEV;
ret = vfio_group_add_container_user(group);
if (ret)
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index bafede92f8c1..d67af8af9445 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -751,8 +751,7 @@ static struct vfio_group *find_iommu_group(struct vfio_domain *domain,
return NULL;
}
-static bool vfio_iommu_has_resv_msi(struct iommu_group *group,
- phys_addr_t *base)
+static bool vfio_iommu_has_sw_msi(struct iommu_group *group, phys_addr_t *base)
{
struct list_head group_resv_regions;
struct iommu_resv_region *region, *next;
@@ -761,7 +760,7 @@ static bool vfio_iommu_has_resv_msi(struct iommu_group *group,
INIT_LIST_HEAD(&group_resv_regions);
iommu_get_group_resv_regions(group, &group_resv_regions);
list_for_each_entry(region, &group_resv_regions, list) {
- if (region->type & IOMMU_RESV_MSI) {
+ if (region->type == IOMMU_RESV_SW_MSI) {
*base = region->start;
ret = true;
goto out;
@@ -826,7 +825,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
if (ret)
goto out_domain;
- resv_msi = vfio_iommu_has_resv_msi(iommu_group, &resv_msi_base);
+ resv_msi = vfio_iommu_has_sw_msi(iommu_group, &resv_msi_base);
INIT_LIST_HEAD(&domain->group_list);
list_add(&group->next, &domain->group_list);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 31cd587b37b9..010b1e38df71 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -117,9 +117,16 @@ enum iommu_attr {
};
/* These are the possible reserved region types */
-#define IOMMU_RESV_DIRECT (1 << 0)
-#define IOMMU_RESV_RESERVED (1 << 1)
-#define IOMMU_RESV_MSI (1 << 2)
+enum iommu_resv_type {
+ /* Memory regions which must be mapped 1:1 at all times */
+ IOMMU_RESV_DIRECT,
+ /* Arbitrary "never map this or give it to a device" address ranges */
+ IOMMU_RESV_RESERVED,
+ /* Hardware MSI region (untranslated) */
+ IOMMU_RESV_MSI,
+ /* Software-managed MSI translation window */
+ IOMMU_RESV_SW_MSI,
+};
/**
* struct iommu_resv_region - descriptor for a reserved memory region
@@ -134,7 +141,7 @@ struct iommu_resv_region {
phys_addr_t start;
size_t length;
int prot;
- int type;
+ enum iommu_resv_type type;
};
#ifdef CONFIG_IOMMU_API
@@ -248,7 +255,8 @@ extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
extern int iommu_request_dm_for_dev(struct device *dev);
extern struct iommu_resv_region *
-iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot, int type);
+iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
+ enum iommu_resv_type type);
extern int iommu_get_group_resv_regions(struct iommu_group *group,
struct list_head *head);
diff --git a/init/Kconfig b/init/Kconfig
index d36a05bfb9c2..aaef2d85e301 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1479,6 +1479,7 @@ config KALLSYMS_ALL
config KALLSYMS_ABSOLUTE_PERCPU
bool
+ depends on KALLSYMS
default X86_64 && SMP
config KALLSYMS_BASE_RELATIVE
diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c
index e5081c551129..b49ca35148e4 100644
--- a/kernel/irq/ipi.c
+++ b/kernel/irq/ipi.c
@@ -94,6 +94,7 @@ int irq_reserve_ipi(struct irq_domain *domain,
data = irq_get_irq_data(virq + i);
cpumask_copy(data->common->affinity, dest);
data->common->ipi_offset = offset;
+ irq_set_status_flags(virq + i, IRQ_NO_BALANCING);
}
return virq;
@@ -124,7 +125,7 @@ int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
domain = data->domain;
if (WARN_ON(domain == NULL))
- return;
+ return -EINVAL;
if (!irq_domain_is_ipi(domain)) {
pr_warn("Trying to destroy a non IPI domain!\n");
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index 0bf6709d1006..6fb4314cec49 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -50,8 +50,10 @@ void vgic_v2_process_maintenance(struct kvm_vcpu *vcpu)
WARN_ON(cpuif->vgic_lr[lr] & GICH_LR_STATE);
- kvm_notify_acked_irq(vcpu->kvm, 0,
- intid - VGIC_NR_PRIVATE_IRQS);
+ /* Only SPIs require notification */
+ if (vgic_valid_spi(vcpu->kvm, intid))
+ kvm_notify_acked_irq(vcpu->kvm, 0,
+ intid - VGIC_NR_PRIVATE_IRQS);
}
}
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 9f0dae397d9c..5c9f9745e6ca 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -41,8 +41,10 @@ void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
WARN_ON(cpuif->vgic_lr[lr] & ICH_LR_STATE);
- kvm_notify_acked_irq(vcpu->kvm, 0,
- intid - VGIC_NR_PRIVATE_IRQS);
+ /* Only SPIs require notification */
+ if (vgic_valid_spi(vcpu->kvm, intid))
+ kvm_notify_acked_irq(vcpu->kvm, 0,
+ intid - VGIC_NR_PRIVATE_IRQS);
}
/*
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index e83b7fe4baae..b465ac6d5d48 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -645,6 +645,9 @@ next:
/* Sync back the hardware VGIC state into our emulation after a guest's run. */
void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
{
+ if (unlikely(!vgic_initialized(vcpu->kvm)))
+ return;
+
vgic_process_maintenance_interrupt(vcpu);
vgic_fold_lr_state(vcpu);
vgic_prune_ap_list(vcpu);
@@ -653,6 +656,9 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
/* Flush our emulation state into the GIC hardware before entering the guest. */
void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
{
+ if (unlikely(!vgic_initialized(vcpu->kvm)))
+ return;
+
spin_lock(&vcpu->arch.vgic_cpu.ap_list_lock);
vgic_flush_lr_state(vcpu);
spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock);