s390 updates for 5.3-rc2
- Add ABI to kernel image file which allows e.g. the file utility to figure out the kernel version. - Wire up clone3 system call. - Add support for kasan bitops instrumentation. - uapi header cleanup: use __u{16,32,64} instead of uint{16,32,64}_t. - Provide proper ARCH_ZONE_DMA_BITS so the s390 DMA zone is correctly defined with 2 GB instead of the default value of 1 MB. - Farhan Ali leaves the group of vfio-ccw maintainers. - Various small vfio-ccw fixes. - Add missing locking for airq_areas array in virtio code. - Minor qdio improvements. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJdPBMNAAoJECIOw3kbKW7CNp0QAKcvg0eCNUfP9KuTGZgie4Gt MeRESA4SpF2nS9Wp/cxnENRaMDYfUGdoFwXHJEuTTrUvBhBykaRJ/U0qMU5v25kD nesmHYpuhRYxzHp+Cm5nzzicNID/9pI+Yd3E/eefpUsMt90sLXZ/1vAaPmPQJ/9S AsA8jyE35qKdZ8zeBCF7zGy0jsy3A/afi52C6HIZlhkoDaTHBMChndUORIQ1XIK1 Ce5ssmiqlbFPC0JJ1ZbnSQB/kyRunaE7fF6tdFDOztSqdc19JZ5xxStn4bSZo508 54mqoS3tHR7+fDmu2CH/tIHtPkinPFvQmxbTQemSnz3xRVpf3YPlnxEHmuQcAOp5 edDwdlx28QELRi9OGAPR60t0rtT2iWO32xPeh2hYoakDDHamnDmk1BWKn1FPbBJr IZpvlfzn0t2Mlf96YiEzdRqEYIjBgtw0yl/ozRIRyEsGC4eLhvHOmrqgchCk/tD+ Gy+BeDYCaHj4Lu4hhZdAmUcFAbLJu1dXX1GXijmAMvQ7xFhUMHaj+BxWz7Ou5+cg zpcSHUbRVXUwbLVdDttJ6VGDo9KriYg54aPLOdUZ1rAA3cWBZRjA/iDqT7NIWWe+ HV9IKZ55+lPE/xuVvbbwKn7JucX6yBCzdCRADDmC+VKzwVS78mUdIppaLaq+KY9G 9Zxgd3oVatQ5VMC1yXOk =J+rB -----END PGP SIGNATURE----- Merge tag 's390-5.3-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux Pull s390 updates from Heiko Carstens: - Add ABI to kernel image file which allows e.g. the file utility to figure out the kernel version. - Wire up clone3 system call. - Add support for kasan bitops instrumentation. - uapi header cleanup: use __u{16,32,64} instead of uint{16,32,64}_t. - Provide proper ARCH_ZONE_DMA_BITS so the s390 DMA zone is correctly defined with 2 GB instead of the default value of 1 MB. - Farhan Ali leaves the group of vfio-ccw maintainers. - Various small vfio-ccw fixes. - Add missing locking for airq_areas array in virtio code. - Minor qdio improvements. * tag 's390-5.3-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: MAINTAINERS: vfio-ccw: Remove myself as the maintainer s390/mm: use shared variables for sysctl range check virtio/s390: fix race on airq_areas[] s390/dma: provide proper ARCH_ZONE_DMA_BITS value s390/kasan: add bitops instrumentation s390/bitops: make test functions return bool s390: wire up clone3 system call kbuild: enable arch/s390/include/uapi/asm/zcrypt.h for uapi header test s390: use __u{16,32,64} instead of uint{16,32,64}_t in uapi header s390/hypfs: fix a typo in the name of a function s390/qdio: restrict QAOB usage to IQD unicast queues s390/qdio: add sanity checks to the fast-requeue path s390: enable detection of kernel version from bzImage Documentation: fix vfio-ccw doc vfio-ccw: Update documentation for csch/hsch vfio-ccw: Don't call cp_free if we are processing a channel program vfio-ccw: Set pa_nr to 0 if memory allocation fails for pa_iova_pfn vfio-ccw: Fix memory leak and don't call cp_free in cp_init vfio-ccw: Fix misleading comment when setting orb.cmd.c64alistair/sunxi64-5.4-dsi
commit
43e317c1bb
|
@ -180,6 +180,13 @@ The process of how these work together.
|
||||||
add it to an iommu_group and a vfio_group. Then we could pass through
|
add it to an iommu_group and a vfio_group. Then we could pass through
|
||||||
the mdev to a guest.
|
the mdev to a guest.
|
||||||
|
|
||||||
|
|
||||||
|
VFIO-CCW Regions
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The vfio-ccw driver exposes MMIO regions to accept requests from and return
|
||||||
|
results to userspace.
|
||||||
|
|
||||||
vfio-ccw I/O region
|
vfio-ccw I/O region
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -205,6 +212,25 @@ irb_area stores the I/O result.
|
||||||
|
|
||||||
ret_code stores a return code for each access of the region.
|
ret_code stores a return code for each access of the region.
|
||||||
|
|
||||||
|
This region is always available.
|
||||||
|
|
||||||
|
vfio-ccw cmd region
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The vfio-ccw cmd region is used to accept asynchronous instructions
|
||||||
|
from userspace::
|
||||||
|
|
||||||
|
#define VFIO_CCW_ASYNC_CMD_HSCH (1 << 0)
|
||||||
|
#define VFIO_CCW_ASYNC_CMD_CSCH (1 << 1)
|
||||||
|
struct ccw_cmd_region {
|
||||||
|
__u32 command;
|
||||||
|
__u32 ret_code;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
This region is exposed via region type VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD.
|
||||||
|
|
||||||
|
Currently, CLEAR SUBCHANNEL and HALT SUBCHANNEL use this region.
|
||||||
|
|
||||||
vfio-ccw operation details
|
vfio-ccw operation details
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
@ -306,9 +332,8 @@ Together with the corresponding work in QEMU, we can bring the passed
|
||||||
through DASD/ECKD device online in a guest now and use it as a block
|
through DASD/ECKD device online in a guest now and use it as a block
|
||||||
device.
|
device.
|
||||||
|
|
||||||
While the current code allows the guest to start channel programs via
|
The current code allows the guest to start channel programs via
|
||||||
START SUBCHANNEL, support for HALT SUBCHANNEL or CLEAR SUBCHANNEL is
|
START SUBCHANNEL, and to issue HALT SUBCHANNEL and CLEAR SUBCHANNEL.
|
||||||
not yet implemented.
|
|
||||||
|
|
||||||
vfio-ccw supports classic (command mode) channel I/O only. Transport
|
vfio-ccw supports classic (command mode) channel I/O only. Transport
|
||||||
mode (HPF) is not supported.
|
mode (HPF) is not supported.
|
||||||
|
|
|
@ -13948,7 +13948,6 @@ F: drivers/pci/hotplug/s390_pci_hpc.c
|
||||||
|
|
||||||
S390 VFIO-CCW DRIVER
|
S390 VFIO-CCW DRIVER
|
||||||
M: Cornelia Huck <cohuck@redhat.com>
|
M: Cornelia Huck <cohuck@redhat.com>
|
||||||
M: Farhan Ali <alifm@linux.ibm.com>
|
|
||||||
M: Eric Farman <farman@linux.ibm.com>
|
M: Eric Farman <farman@linux.ibm.com>
|
||||||
R: Halil Pasic <pasic@linux.ibm.com>
|
R: Halil Pasic <pasic@linux.ibm.com>
|
||||||
L: linux-s390@vger.kernel.org
|
L: linux-s390@vger.kernel.org
|
||||||
|
|
|
@ -36,7 +36,7 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
|
||||||
|
|
||||||
obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
|
obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
|
||||||
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
|
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
|
||||||
obj-y += ctype.o text_dma.o
|
obj-y += version.o ctype.o text_dma.o
|
||||||
obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o
|
obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o
|
||||||
obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o
|
obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o
|
||||||
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
|
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
|
||||||
|
|
|
@ -12,6 +12,7 @@ void print_missing_facilities(void);
|
||||||
unsigned long get_random_base(unsigned long safe_addr);
|
unsigned long get_random_base(unsigned long safe_addr);
|
||||||
|
|
||||||
extern int kaslr_enabled;
|
extern int kaslr_enabled;
|
||||||
|
extern const char kernel_version[];
|
||||||
|
|
||||||
unsigned long read_ipl_report(unsigned long safe_offset);
|
unsigned long read_ipl_report(unsigned long safe_offset);
|
||||||
|
|
||||||
|
|
|
@ -361,6 +361,7 @@ ENTRY(startup_kdump)
|
||||||
.quad 0 # INITRD_SIZE
|
.quad 0 # INITRD_SIZE
|
||||||
.quad 0 # OLDMEM_BASE
|
.quad 0 # OLDMEM_BASE
|
||||||
.quad 0 # OLDMEM_SIZE
|
.quad 0 # OLDMEM_SIZE
|
||||||
|
.quad kernel_version # points to kernel version string
|
||||||
|
|
||||||
.org COMMAND_LINE
|
.org COMMAND_LINE
|
||||||
.byte "root=/dev/ram0 ro"
|
.byte "root=/dev/ram0 ro"
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
#include <generated/utsrelease.h>
|
||||||
|
#include <generated/compile.h>
|
||||||
|
#include "boot.h"
|
||||||
|
|
||||||
|
const char kernel_version[] = UTS_RELEASE
|
||||||
|
" (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") " UTS_VERSION;
|
|
@ -118,7 +118,7 @@ do { \
|
||||||
return PTR_ERR(rc); \
|
return PTR_ERR(rc); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
static int hpyfs_vm_create_guest(struct dentry *systems_dir,
|
static int hypfs_vm_create_guest(struct dentry *systems_dir,
|
||||||
struct diag2fc_data *data)
|
struct diag2fc_data *data)
|
||||||
{
|
{
|
||||||
char guest_name[NAME_LEN + 1] = {};
|
char guest_name[NAME_LEN + 1] = {};
|
||||||
|
@ -219,7 +219,7 @@ int hypfs_vm_create_files(struct dentry *root)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
rc = hpyfs_vm_create_guest(dir, &(data[i]));
|
rc = hypfs_vm_create_guest(dir, &(data[i]));
|
||||||
if (rc)
|
if (rc)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include <linux/typecheck.h>
|
#include <linux/typecheck.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/types.h>
|
||||||
#include <asm/atomic_ops.h>
|
#include <asm/atomic_ops.h>
|
||||||
#include <asm/barrier.h>
|
#include <asm/barrier.h>
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ __bitops_byte(unsigned long nr, volatile unsigned long *ptr)
|
||||||
return ((unsigned char *)ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
|
return ((unsigned char *)ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_bit(unsigned long nr, volatile unsigned long *ptr)
|
static inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned long *addr = __bitops_word(nr, ptr);
|
unsigned long *addr = __bitops_word(nr, ptr);
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
|
@ -76,7 +77,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
__atomic64_or(mask, (long *)addr);
|
__atomic64_or(mask, (long *)addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
static inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned long *addr = __bitops_word(nr, ptr);
|
unsigned long *addr = __bitops_word(nr, ptr);
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
|
@ -97,7 +98,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
__atomic64_and(mask, (long *)addr);
|
__atomic64_and(mask, (long *)addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void change_bit(unsigned long nr, volatile unsigned long *ptr)
|
static inline void arch_change_bit(unsigned long nr,
|
||||||
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned long *addr = __bitops_word(nr, ptr);
|
unsigned long *addr = __bitops_word(nr, ptr);
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
|
@ -118,8 +120,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
__atomic64_xor(mask, (long *)addr);
|
__atomic64_xor(mask, (long *)addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline bool arch_test_and_set_bit(unsigned long nr,
|
||||||
test_and_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned long *addr = __bitops_word(nr, ptr);
|
unsigned long *addr = __bitops_word(nr, ptr);
|
||||||
unsigned long old, mask;
|
unsigned long old, mask;
|
||||||
|
@ -129,8 +131,8 @@ test_and_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
return (old & mask) != 0;
|
return (old & mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline bool arch_test_and_clear_bit(unsigned long nr,
|
||||||
test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned long *addr = __bitops_word(nr, ptr);
|
unsigned long *addr = __bitops_word(nr, ptr);
|
||||||
unsigned long old, mask;
|
unsigned long old, mask;
|
||||||
|
@ -140,8 +142,8 @@ test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
return (old & ~mask) != 0;
|
return (old & ~mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline bool arch_test_and_change_bit(unsigned long nr,
|
||||||
test_and_change_bit(unsigned long nr, volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned long *addr = __bitops_word(nr, ptr);
|
unsigned long *addr = __bitops_word(nr, ptr);
|
||||||
unsigned long old, mask;
|
unsigned long old, mask;
|
||||||
|
@ -151,30 +153,31 @@ test_and_change_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
return (old & mask) != 0;
|
return (old & mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr)
|
static inline void arch___set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||||
|
|
||||||
*addr |= 1 << (nr & 7);
|
*addr |= 1 << (nr & 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void arch___clear_bit(unsigned long nr,
|
||||||
__clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||||
|
|
||||||
*addr &= ~(1 << (nr & 7));
|
*addr &= ~(1 << (nr & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr)
|
static inline void arch___change_bit(unsigned long nr,
|
||||||
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||||
|
|
||||||
*addr ^= 1 << (nr & 7);
|
*addr ^= 1 << (nr & 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline bool arch___test_and_set_bit(unsigned long nr,
|
||||||
__test_and_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
|
@ -184,8 +187,8 @@ __test_and_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
return (ch >> (nr & 7)) & 1;
|
return (ch >> (nr & 7)) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline bool arch___test_and_clear_bit(unsigned long nr,
|
||||||
__test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
|
@ -195,8 +198,8 @@ __test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
return (ch >> (nr & 7)) & 1;
|
return (ch >> (nr & 7)) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline bool arch___test_and_change_bit(unsigned long nr,
|
||||||
__test_and_change_bit(unsigned long nr, volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
|
@ -206,7 +209,8 @@ __test_and_change_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||||
return (ch >> (nr & 7)) & 1;
|
return (ch >> (nr & 7)) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int test_bit(unsigned long nr, const volatile unsigned long *ptr)
|
static inline bool arch_test_bit(unsigned long nr,
|
||||||
|
const volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
const volatile unsigned char *addr;
|
const volatile unsigned char *addr;
|
||||||
|
|
||||||
|
@ -215,28 +219,30 @@ static inline int test_bit(unsigned long nr, const volatile unsigned long *ptr)
|
||||||
return (*addr >> (nr & 7)) & 1;
|
return (*addr >> (nr & 7)) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int test_and_set_bit_lock(unsigned long nr,
|
static inline bool arch_test_and_set_bit_lock(unsigned long nr,
|
||||||
volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
if (test_bit(nr, ptr))
|
if (arch_test_bit(nr, ptr))
|
||||||
return 1;
|
return 1;
|
||||||
return test_and_set_bit(nr, ptr);
|
return arch_test_and_set_bit(nr, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void clear_bit_unlock(unsigned long nr,
|
static inline void arch_clear_bit_unlock(unsigned long nr,
|
||||||
volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
smp_mb__before_atomic();
|
smp_mb__before_atomic();
|
||||||
clear_bit(nr, ptr);
|
arch_clear_bit(nr, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __clear_bit_unlock(unsigned long nr,
|
static inline void arch___clear_bit_unlock(unsigned long nr,
|
||||||
volatile unsigned long *ptr)
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
smp_mb();
|
smp_mb();
|
||||||
__clear_bit(nr, ptr);
|
arch___clear_bit(nr, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <asm-generic/bitops-instrumented.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions which use MSB0 bit numbering.
|
* Functions which use MSB0 bit numbering.
|
||||||
* The bits are numbered:
|
* The bits are numbered:
|
||||||
|
@ -261,7 +267,8 @@ static inline void clear_bit_inv(unsigned long nr, volatile unsigned long *ptr)
|
||||||
return clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
return clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int test_and_clear_bit_inv(unsigned long nr, volatile unsigned long *ptr)
|
static inline bool test_and_clear_bit_inv(unsigned long nr,
|
||||||
|
volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
return test_and_clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
return test_and_clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||||
}
|
}
|
||||||
|
@ -276,8 +283,8 @@ static inline void __clear_bit_inv(unsigned long nr, volatile unsigned long *ptr
|
||||||
return __clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
return __clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int test_bit_inv(unsigned long nr,
|
static inline bool test_bit_inv(unsigned long nr,
|
||||||
const volatile unsigned long *ptr)
|
const volatile unsigned long *ptr)
|
||||||
{
|
{
|
||||||
return test_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
return test_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,8 @@ static inline int devmem_is_allowed(unsigned long pfn)
|
||||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
|
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
|
||||||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||||
|
|
||||||
|
#define ARCH_ZONE_DMA_BITS 31
|
||||||
|
|
||||||
#include <asm-generic/memory_model.h>
|
#include <asm-generic/memory_model.h>
|
||||||
#include <asm-generic/getorder.h>
|
#include <asm-generic/getorder.h>
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#define INITRD_SIZE_OFFSET 0x10410
|
#define INITRD_SIZE_OFFSET 0x10410
|
||||||
#define OLDMEM_BASE_OFFSET 0x10418
|
#define OLDMEM_BASE_OFFSET 0x10418
|
||||||
#define OLDMEM_SIZE_OFFSET 0x10420
|
#define OLDMEM_SIZE_OFFSET 0x10420
|
||||||
|
#define KERNEL_VERSION_OFFSET 0x10428
|
||||||
#define COMMAND_LINE_OFFSET 0x10480
|
#define COMMAND_LINE_OFFSET 0x10480
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
@ -74,7 +75,8 @@ struct parmarea {
|
||||||
unsigned long initrd_size; /* 0x10410 */
|
unsigned long initrd_size; /* 0x10410 */
|
||||||
unsigned long oldmem_base; /* 0x10418 */
|
unsigned long oldmem_base; /* 0x10418 */
|
||||||
unsigned long oldmem_size; /* 0x10420 */
|
unsigned long oldmem_size; /* 0x10420 */
|
||||||
char pad1[0x10480 - 0x10428]; /* 0x10428 - 0x10480 */
|
unsigned long kernel_version; /* 0x10428 */
|
||||||
|
char pad1[0x10480 - 0x10430]; /* 0x10430 - 0x10480 */
|
||||||
char command_line[ARCH_COMMAND_LINE_SIZE]; /* 0x10480 */
|
char command_line[ARCH_COMMAND_LINE_SIZE]; /* 0x10480 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,5 +34,6 @@
|
||||||
#define __ARCH_WANT_SYS_FORK
|
#define __ARCH_WANT_SYS_FORK
|
||||||
#define __ARCH_WANT_SYS_VFORK
|
#define __ARCH_WANT_SYS_VFORK
|
||||||
#define __ARCH_WANT_SYS_CLONE
|
#define __ARCH_WANT_SYS_CLONE
|
||||||
|
#define __ARCH_WANT_SYS_CLONE3
|
||||||
|
|
||||||
#endif /* _ASM_S390_UNISTD_H_ */
|
#endif /* _ASM_S390_UNISTD_H_ */
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
/* Name of the zcrypt device driver. */
|
/* Name of the zcrypt device driver. */
|
||||||
#define ZCRYPT_NAME "zcrypt"
|
#define ZCRYPT_NAME "zcrypt"
|
||||||
|
@ -160,17 +161,17 @@ struct ica_xcRB {
|
||||||
* @payload_len: Payload length
|
* @payload_len: Payload length
|
||||||
*/
|
*/
|
||||||
struct ep11_cprb {
|
struct ep11_cprb {
|
||||||
uint16_t cprb_len;
|
__u16 cprb_len;
|
||||||
unsigned char cprb_ver_id;
|
unsigned char cprb_ver_id;
|
||||||
unsigned char pad_000[2];
|
unsigned char pad_000[2];
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
unsigned char func_id[2];
|
unsigned char func_id[2];
|
||||||
uint32_t source_id;
|
__u32 source_id;
|
||||||
uint32_t target_id;
|
__u32 target_id;
|
||||||
uint32_t ret_code;
|
__u32 ret_code;
|
||||||
uint32_t reserved1;
|
__u32 reserved1;
|
||||||
uint32_t reserved2;
|
__u32 reserved2;
|
||||||
uint32_t payload_len;
|
__u32 payload_len;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,8 +180,8 @@ struct ep11_cprb {
|
||||||
* @dom_id: Usage domain id
|
* @dom_id: Usage domain id
|
||||||
*/
|
*/
|
||||||
struct ep11_target_dev {
|
struct ep11_target_dev {
|
||||||
uint16_t ap_id;
|
__u16 ap_id;
|
||||||
uint16_t dom_id;
|
__u16 dom_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,14 +196,14 @@ struct ep11_target_dev {
|
||||||
* @resp: Addr to response block
|
* @resp: Addr to response block
|
||||||
*/
|
*/
|
||||||
struct ep11_urb {
|
struct ep11_urb {
|
||||||
uint16_t targets_num;
|
__u16 targets_num;
|
||||||
uint64_t targets;
|
__u64 targets;
|
||||||
uint64_t weight;
|
__u64 weight;
|
||||||
uint64_t req_no;
|
__u64 req_no;
|
||||||
uint64_t req_len;
|
__u64 req_len;
|
||||||
uint64_t req;
|
__u64 req;
|
||||||
uint64_t resp_len;
|
__u64 resp_len;
|
||||||
uint64_t resp;
|
__u64 resp;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -437,4 +437,4 @@
|
||||||
432 common fsmount sys_fsmount sys_fsmount
|
432 common fsmount sys_fsmount sys_fsmount
|
||||||
433 common fspick sys_fspick sys_fspick
|
433 common fspick sys_fspick sys_fspick
|
||||||
434 common pidfd_open sys_pidfd_open sys_pidfd_open
|
434 common pidfd_open sys_pidfd_open sys_pidfd_open
|
||||||
# 435 reserved for clone3
|
435 common clone3 sys_clone3 sys_clone3
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
|
|
||||||
#ifdef CONFIG_PGSTE
|
#ifdef CONFIG_PGSTE
|
||||||
|
|
||||||
static int page_table_allocate_pgste_min = 0;
|
|
||||||
static int page_table_allocate_pgste_max = 1;
|
|
||||||
int page_table_allocate_pgste = 0;
|
int page_table_allocate_pgste = 0;
|
||||||
EXPORT_SYMBOL(page_table_allocate_pgste);
|
EXPORT_SYMBOL(page_table_allocate_pgste);
|
||||||
|
|
||||||
|
@ -29,8 +27,8 @@ static struct ctl_table page_table_sysctl[] = {
|
||||||
.maxlen = sizeof(int),
|
.maxlen = sizeof(int),
|
||||||
.mode = S_IRUGO | S_IWUSR,
|
.mode = S_IRUGO | S_IWUSR,
|
||||||
.proc_handler = proc_dointvec_minmax,
|
.proc_handler = proc_dointvec_minmax,
|
||||||
.extra1 = &page_table_allocate_pgste_min,
|
.extra1 = SYSCTL_ZERO,
|
||||||
.extra2 = &page_table_allocate_pgste_max,
|
.extra2 = SYSCTL_ONE,
|
||||||
},
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
|
@ -319,9 +319,7 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
|
||||||
int retries = 0, cc;
|
int retries = 0, cc;
|
||||||
unsigned long laob = 0;
|
unsigned long laob = 0;
|
||||||
|
|
||||||
WARN_ON_ONCE(aob && ((queue_type(q) != QDIO_IQDIO_QFMT) ||
|
if (aob) {
|
||||||
!q->u.out.use_cq));
|
|
||||||
if (q->u.out.use_cq && aob != 0) {
|
|
||||||
fc = QDIO_SIGA_WRITEQ;
|
fc = QDIO_SIGA_WRITEQ;
|
||||||
laob = aob;
|
laob = aob;
|
||||||
}
|
}
|
||||||
|
@ -621,9 +619,6 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
|
||||||
{
|
{
|
||||||
unsigned long phys_aob = 0;
|
unsigned long phys_aob = 0;
|
||||||
|
|
||||||
if (!q->use_cq)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!q->aobs[bufnr]) {
|
if (!q->aobs[bufnr]) {
|
||||||
struct qaob *aob = qdio_allocate_aob();
|
struct qaob *aob = qdio_allocate_aob();
|
||||||
q->aobs[bufnr] = aob;
|
q->aobs[bufnr] = aob;
|
||||||
|
@ -1308,6 +1303,8 @@ static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
|
||||||
|
|
||||||
for_each_output_queue(irq_ptr, q, i) {
|
for_each_output_queue(irq_ptr, q, i) {
|
||||||
if (use_cq) {
|
if (use_cq) {
|
||||||
|
if (multicast_outbound(q))
|
||||||
|
continue;
|
||||||
if (qdio_enable_async_operation(&q->u.out) < 0) {
|
if (qdio_enable_async_operation(&q->u.out) < 0) {
|
||||||
use_cq = 0;
|
use_cq = 0;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1553,18 +1550,19 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
|
||||||
/* One SIGA-W per buffer required for unicast HSI */
|
/* One SIGA-W per buffer required for unicast HSI */
|
||||||
WARN_ON_ONCE(count > 1 && !multicast_outbound(q));
|
WARN_ON_ONCE(count > 1 && !multicast_outbound(q));
|
||||||
|
|
||||||
phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
|
if (q->u.out.use_cq)
|
||||||
|
phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
|
||||||
|
|
||||||
rc = qdio_kick_outbound_q(q, phys_aob);
|
rc = qdio_kick_outbound_q(q, phys_aob);
|
||||||
} else if (need_siga_sync(q)) {
|
} else if (need_siga_sync(q)) {
|
||||||
rc = qdio_siga_sync_q(q);
|
rc = qdio_siga_sync_q(q);
|
||||||
|
} else if (count < QDIO_MAX_BUFFERS_PER_Q &&
|
||||||
|
get_buf_state(q, prev_buf(bufnr), &state, 0) > 0 &&
|
||||||
|
state == SLSB_CU_OUTPUT_PRIMED) {
|
||||||
|
/* The previous buffer is not processed yet, tack on. */
|
||||||
|
qperf_inc(q, fast_requeue);
|
||||||
} else {
|
} else {
|
||||||
/* try to fast requeue buffers */
|
rc = qdio_kick_outbound_q(q, 0);
|
||||||
get_buf_state(q, prev_buf(bufnr), &state, 0);
|
|
||||||
if (state != SLSB_CU_OUTPUT_PRIMED)
|
|
||||||
rc = qdio_kick_outbound_q(q, 0);
|
|
||||||
else
|
|
||||||
qperf_inc(q, fast_requeue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in case of SIGA errors we must process the error immediately */
|
/* in case of SIGA errors we must process the error immediately */
|
||||||
|
|
|
@ -72,8 +72,10 @@ static int pfn_array_alloc(struct pfn_array *pa, u64 iova, unsigned int len)
|
||||||
sizeof(*pa->pa_iova_pfn) +
|
sizeof(*pa->pa_iova_pfn) +
|
||||||
sizeof(*pa->pa_pfn),
|
sizeof(*pa->pa_pfn),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (unlikely(!pa->pa_iova_pfn))
|
if (unlikely(!pa->pa_iova_pfn)) {
|
||||||
|
pa->pa_nr = 0;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr;
|
pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr;
|
||||||
|
|
||||||
pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT;
|
pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT;
|
||||||
|
@ -421,7 +423,7 @@ static int ccwchain_loop_tic(struct ccwchain *chain,
|
||||||
static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
|
static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
|
||||||
{
|
{
|
||||||
struct ccwchain *chain;
|
struct ccwchain *chain;
|
||||||
int len;
|
int len, ret;
|
||||||
|
|
||||||
/* Copy 2K (the most we support today) of possible CCWs */
|
/* Copy 2K (the most we support today) of possible CCWs */
|
||||||
len = copy_from_iova(cp->mdev, cp->guest_cp, cda,
|
len = copy_from_iova(cp->mdev, cp->guest_cp, cda,
|
||||||
|
@ -448,7 +450,12 @@ static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
|
||||||
memcpy(chain->ch_ccw, cp->guest_cp, len * sizeof(struct ccw1));
|
memcpy(chain->ch_ccw, cp->guest_cp, len * sizeof(struct ccw1));
|
||||||
|
|
||||||
/* Loop for tics on this new chain. */
|
/* Loop for tics on this new chain. */
|
||||||
return ccwchain_loop_tic(chain, cp);
|
ret = ccwchain_loop_tic(chain, cp);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
ccwchain_free(chain);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop for TICs. */
|
/* Loop for TICs. */
|
||||||
|
@ -642,17 +649,16 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb)
|
||||||
|
|
||||||
/* Build a ccwchain for the first CCW segment */
|
/* Build a ccwchain for the first CCW segment */
|
||||||
ret = ccwchain_handle_ccw(orb->cmd.cpa, cp);
|
ret = ccwchain_handle_ccw(orb->cmd.cpa, cp);
|
||||||
if (ret)
|
|
||||||
cp_free(cp);
|
|
||||||
|
|
||||||
/* It is safe to force: if not set but idals used
|
if (!ret) {
|
||||||
* ccwchain_calc_length returns an error.
|
|
||||||
*/
|
|
||||||
cp->orb.cmd.c64 = 1;
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
cp->initialized = true;
|
cp->initialized = true;
|
||||||
|
|
||||||
|
/* It is safe to force: if it was not set but idals used
|
||||||
|
* ccwchain_calc_length would have returned an error.
|
||||||
|
*/
|
||||||
|
cp->orb.cmd.c64 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
|
||||||
(SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT));
|
(SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT));
|
||||||
if (scsw_is_solicited(&irb->scsw)) {
|
if (scsw_is_solicited(&irb->scsw)) {
|
||||||
cp_update_scsw(&private->cp, &irb->scsw);
|
cp_update_scsw(&private->cp, &irb->scsw);
|
||||||
if (is_final)
|
if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING)
|
||||||
cp_free(&private->cp);
|
cp_free(&private->cp);
|
||||||
}
|
}
|
||||||
mutex_lock(&private->io_mutex);
|
mutex_lock(&private->io_mutex);
|
||||||
|
|
|
@ -145,6 +145,8 @@ struct airq_info {
|
||||||
struct airq_iv *aiv;
|
struct airq_iv *aiv;
|
||||||
};
|
};
|
||||||
static struct airq_info *airq_areas[MAX_AIRQ_AREAS];
|
static struct airq_info *airq_areas[MAX_AIRQ_AREAS];
|
||||||
|
static DEFINE_MUTEX(airq_areas_lock);
|
||||||
|
|
||||||
static u8 *summary_indicators;
|
static u8 *summary_indicators;
|
||||||
|
|
||||||
static inline u8 *get_summary_indicator(struct airq_info *info)
|
static inline u8 *get_summary_indicator(struct airq_info *info)
|
||||||
|
@ -265,9 +267,11 @@ static unsigned long get_airq_indicator(struct virtqueue *vqs[], int nvqs,
|
||||||
unsigned long bit, flags;
|
unsigned long bit, flags;
|
||||||
|
|
||||||
for (i = 0; i < MAX_AIRQ_AREAS && !indicator_addr; i++) {
|
for (i = 0; i < MAX_AIRQ_AREAS && !indicator_addr; i++) {
|
||||||
|
mutex_lock(&airq_areas_lock);
|
||||||
if (!airq_areas[i])
|
if (!airq_areas[i])
|
||||||
airq_areas[i] = new_airq_info(i);
|
airq_areas[i] = new_airq_info(i);
|
||||||
info = airq_areas[i];
|
info = airq_areas[i];
|
||||||
|
mutex_unlock(&airq_areas_lock);
|
||||||
if (!info)
|
if (!info)
|
||||||
return 0;
|
return 0;
|
||||||
write_lock_irqsave(&info->lock, flags);
|
write_lock_irqsave(&info->lock, flags);
|
||||||
|
|
|
@ -101,10 +101,6 @@ ifeq ($(SRCARCH),riscv)
|
||||||
header-test- += linux/bpf_perf_event.h
|
header-test- += linux/bpf_perf_event.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(SRCARCH),s390)
|
|
||||||
header-test- += asm/zcrypt.h
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(SRCARCH),sparc)
|
ifeq ($(SRCARCH),sparc)
|
||||||
header-test- += asm/stat.h
|
header-test- += asm/stat.h
|
||||||
header-test- += asm/uctx.h
|
header-test- += asm/uctx.h
|
||||||
|
|
Loading…
Reference in New Issue