Commit 2a4c0c11 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull s390 updates from Vasily Gorbik:

 - Add support for CONFIG_PAGE_TABLE_CHECK and enable it in
   debug_defconfig. s390 can only tell user from kernel PTEs via the mm,
   so mm_struct is now passed into pxx_user_accessible_page() callbacks

 - Expose the PCI function UID as an arch-specific slot attribute in
   sysfs so a function can be identified by its user-defined id while
   still in standby. Introduces a generic ARCH_PCI_SLOT_GROUPS hook in
   drivers/pci/slot.c

 - Refresh s390 PCI documentation to reflect current behavior and cover
   previously undocumented sysfs attributes

 - zcrypt device driver cleanup series: consistent field types, clearer
   variable naming, a kernel-doc warning fix, and a comment explaining
   the intentional synchronize_rcu() in pkey_handler_register()

 - Provide an s390 arch_raw_cpu_ptr() that avoids the detour via
   get_lowcore() using alternatives, shrinking defconfig by ~27 kB

 - Guard identity-base randomization with kaslr_enabled() so nokaslr
   keeps the identity mapping at 0 even with RANDOMIZE_IDENTITY_BASE=y

 - Build S390_MODULES_SANITY_TEST as a module only by requiring KUNIT &&
   m, since built-in would not exercise module loading

 - Remove the permanently commented-out HMCDRV_DEV_CLASS create_class()
   code in the hmcdrv driver

 - Drop stale ident_map_size extern conflicting with asm/page.h

* tag 's390-7.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/zcrypt: Fix warning about wrong kernel doc comment
  PCI: s390: Expose the UID as an arch specific PCI slot attribute
  docs: s390/pci: Improve and update PCI documentation
  s390/pkey: Add comment about synchronize_rcu() to pkey base
  s390/hmcdrv: Remove commented out code
  s390/zcrypt: Slight rework on the agent_id field
  s390/zcrypt: Explicitly use a card variable in _zcrypt_send_cprb
  s390/zcrypt: Rework MKVP fields and handling
  s390/zcrypt: Make apfs a real unsigned int field
  s390/zcrypt: Rework domain processing within zcrypt device driver
  s390/zcrypt: Move inline function rng_type6cprb_msgx from header to code
  s390/percpu: Provide arch_raw_cpu_ptr()
  s390: Enable page table check for debug_defconfig
  s390/pgtable: Add s390 support for page table check
  s390/pgtable: Use set_pmd_bit() to invalidate PMD entry
  mm/page_table_check: Pass mm_struct to pxx_user_accessible_page()
  s390/boot: Respect kaslr_enabled() for identity randomization
  s390/Kconfig: Make modules sanity test a module-only option
  s390/setup: Drop stale ident_map_size declaration
parents 8fd12b03 8d7ea400
Loading
Loading
Loading
Loading
+108 −51
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ S/390 PCI

Authors:
        - Pierre Morel
        - Niklas Schnelle

Copyright, IBM Corp. 2020

@@ -27,14 +28,16 @@ Command line parameters
debugfs entries
---------------

The S/390 debug feature (s390dbf) generates views to hold various debug results in sysfs directories of the form:
The S/390 debug feature (s390dbf) generates views to hold various debug results
in sysfs directories of the form:

 * /sys/kernel/debug/s390dbf/pci_*/

For example:

  - /sys/kernel/debug/s390dbf/pci_msg/sprintf
    Holds messages from the processing of PCI events, like machine check handling

    holds messages from the processing of PCI events, like machine check handling
    and setting of global functionality, like UID checking.

  Change the level of logging to be more or less verbose by piping
@@ -47,87 +50,141 @@ Sysfs entries

Entries specific to zPCI functions and entries that hold zPCI information.

* /sys/bus/pci/slots/XXXXXXXX
* /sys/bus/pci/slots/XXXXXXXX:

  The slot entries are set up using the function identifier (FID) of the
  PCI function. The format depicted as XXXXXXXX above is 8 hexadecimal digits
  with 0 padding and lower case hexadecimal digits.
  The slot entries are set up using the function identifier (FID) of the PCI
  function as slot name. The format depicted as XXXXXXXX above is 8 hexadecimal
  digits with 0 padding and lower case hexadecimal digits.

  - /sys/bus/pci/slots/XXXXXXXX/power

  In addition to using the FID as the name of the slot, the slot directory
  also contains the following s390-specific slot attributes.

  - uid:
    The User-defined identifier (UID) of the function which may be configured
    by this slot. See also the corresponding attribute of the device.

  A physical function that currently supports a virtual function cannot be
  powered off until all virtual functions are removed with:
  echo 0 > /sys/bus/pci/devices/XXXX:XX:XX.X/sriov_numvf
  echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvf

* /sys/bus/pci/devices/XXXX:XX:XX.X/
* /sys/bus/pci/devices/DDDD:BB:dd.f/:

  - function_id
    A zPCI function identifier that uniquely identifies the function in the Z server.
  - function_id:
    The zPCI function identifier (FID) is a 32-bit hexadecimal value that
    uniquely identifies the PCI function. Unless the hypervisor provides
    a virtual FID e.g. on KVM this identifier is unique across the machine even
    between different partitions.

  - function_handle
    Low-level identifier used for a configured PCI function.
    It might be useful for debugging.
  - function_handle:
    This 32-bit hexadecimal value is a low-level identifier used for a PCI
    function. Note that the function handle may be changed and become invalid
    on PCI events and when enabling/disabling the PCI function.

  - pchid
    Model-dependent location of the I/O adapter.
  - pchid:
    This 16-bit hexadecimal value encodes a model-dependent location for
    the PCI function.

  - pfgid
    PCI function group ID, functions that share identical functionality
  - pfgid:
    PCI function group ID; functions that share identical functionality
    use a common identifier.
    A PCI group defines interrupts, IOMMU, IOTLB, and DMA specifics.

  - vfn
  - vfn:
    The virtual function number, from 1 to N for virtual functions,
    0 for physical functions.

  - pft
    The PCI function type

  - port
    The port corresponds to the physical port the function is attached to.
    It also gives an indication of the physical function a virtual function
    is attached to.

  - uid
    The user identifier (UID) may be defined as part of the machine
    configuration or the z/VM or KVM guest configuration. If the accompanying
    uid_is_unique attribute is 1 the platform guarantees that the UID is unique
    within that instance and no devices with the same UID can be attached
    during the lifetime of the system.

  - uid_is_unique
    Indicates whether the user identifier (UID) is guaranteed to be and remain
    unique within this Linux instance.

  - pfip/segmentX
  - pft:
    The PCI function type is an s390-specific type attribute. It indicates
    a more general, usage oriented, type than PCI Specification
    class/vendor/device identifiers. That is PCI functions with the same pft
    value may be backed by different hardware implementations. At the same time
    apart from unclassified functions (pft is 0x00) the same pft value
    generally implies a similar usage model. At the same time the same
    PCI hardware device may appear with different pft values when in a
    different usage model. For example NETD and NETH VFs may be implemented
    by the same PCI hardware device but in NETD the parent Physical Function
    is user managed while with NETH it is platform managed.

    Currently the following PFT values are defined:

    - 0x00 (UNC): Unclassified
    - 0x02 (ROCE): RoCE Express
    - 0x05 (ISM): Internal Shared Memory
    - 0x0a (ROC2): RoCE Express 2
    - 0x0b (NVMe): NVMe
    - 0x0c (NETH): Network Express hybrid
    - 0x0d (CNW): Cloud Network Adapter
    - 0x0f (NETD): Network Express direct

  - port:
    The port is a decimal value corresponding to the physical port the function
    is attached to. Virtual Functions (VFs) share the port with their parent
    Physical Function (PF). A value of 0 indicates that the port attribute is
    not applicable for that PCI function type.

  - uid:
    The user-defined identifier (UID) for a PCI function is a 32-bit
    hexadecimal value. It is defined on a per instance basis as part of the
    partition, KVM guest, or z/VM guest configuration. If UID Checking is
    enabled the platform ensures that the UID is unique within that instance
    and no two PCI functions with the same UID will be visible to the instance.

    Independent of this guarantee and unlike the function ID (FID) the UID may
    be the same in different partitions within the same machine. This allows to
    create PCI configurations in multiple partitions to be identical in the
    UID-namespace.

  - uid_is_unique:
    A 0 or 1 flag indicating whether the user-defined identifier (UID) is
    guaranteed to be and remain unique within this Linux instance. This
    platform feature is called UID Checking.

  - pfip/segmentX:
    The segments determine the isolation of a function.
    They correspond to the physical path to the function.
    The more the segments are different, the more the functions are isolated.

  - fidparm:
    Contains an 8-bit-per-PCI function parameter field in hexadecimal provided
    by the platform. The meaning of this field is PCI function type specific.
    For NETH VFs a value of 0x01 indicates that the function supports
    promiscuous mode.

* /sys/firmware/clp/uid_checking:

  In addition to the per-device uid_is_unique attribute this presents a
  global indication of whether UID Checking is enabled. This allows users
  to check for UID Checking even when no PCI functions are configured.

Enumeration and hotplug
=======================

The PCI address consists of four parts: domain, bus, device and function,
and is of this form: DDDD:BB:dd.f
and is of this form: DDDD:BB:dd.f.

* When not using multi-functions (norid is set, or the firmware does not
  support multi-functions):
* For a PCI function for which the platform does not expose the RID, the
  pci=norid kernel parameter is used, or a so-called isolated Virtual Function
  which does have RID information but is used without its parent Physical
  Function being part of the same PCI configuration:

  - There is only one function per domain.

  - The domain is set from the zPCI function's UID as defined during the
    LPAR creation.
  - The domain is set from the zPCI function's UID if UID Checking is on;
    otherwise the domain ID is generated dynamically and is not stable
    across reboots or hot plug.

* When using multi-functions (norid parameter is not set),
  zPCI functions are addressed differently:
* For a PCI function for which the platform exposes the RID and which
  is not an Isolated Virtual Function:

  - There is still only one bus per domain.

  - There can be up to 256 functions per bus.
  - There can be up to 256 PCI functions per bus.

  - The domain part of the address of all functions for
    a multi-Function device is set from the zPCI function's UID as defined
    in the LPAR creation for the function zero.
  - The domain part of the address of all functions within the same topology is
    that of the configured PCI function with the lowest devfn within that
    topology.

  - New functions will only be ready for use after the function zero
    (the function with devfn 0) has been enumerated.
  - Virtual Functions generated by an SR-IOV capable Physical Function only
    become visible once SR-IOV is enabled.
+3 −3
Original line number Diff line number Diff line
@@ -1276,17 +1276,17 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
#endif

#ifdef CONFIG_PAGE_TABLE_CHECK
static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
{
	return pte_valid(pte) && (pte_user(pte) || pte_user_exec(pte));
}

static inline bool pmd_user_accessible_page(pmd_t pmd, unsigned long addr)
static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
{
	return pmd_valid(pmd) && !pmd_table(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
}

static inline bool pud_user_accessible_page(pud_t pud, unsigned long addr)
static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
{
	return pud_valid(pud) && !pud_table(pud) && (pud_user(pud) || pud_user_exec(pud));
}
+1 −1
Original line number Diff line number Diff line
@@ -438,7 +438,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
	return true;
}

static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
{
	return pte_present(pte) && !is_kernel_addr(addr);
}
+5 −5
Original line number Diff line number Diff line
@@ -549,7 +549,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
	return arch_pte_access_permitted(pte_val(pte), write, 0);
}

static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
{
	return pte_present(pte) && pte_user(pte);
}
@@ -925,9 +925,9 @@ static inline bool pud_access_permitted(pud_t pud, bool write)
}

#define pud_user_accessible_page pud_user_accessible_page
static inline bool pud_user_accessible_page(pud_t pud, unsigned long addr)
static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
{
	return pud_leaf(pud) && pte_user_accessible_page(pud_pte(pud), addr);
	return pud_leaf(pud) && pte_user_accessible_page(mm, addr, pud_pte(pud));
}

#define __p4d_raw(x)	((p4d_t) { __pgd_raw(x) })
@@ -1096,9 +1096,9 @@ static inline bool pmd_access_permitted(pmd_t pmd, bool write)
}

#define pmd_user_accessible_page pmd_user_accessible_page
static inline bool pmd_user_accessible_page(pmd_t pmd, unsigned long addr)
static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
{
	return pmd_leaf(pmd) && pte_user_accessible_page(pmd_pte(pmd), addr);
	return pmd_leaf(pmd) && pte_user_accessible_page(mm, addr, pmd_pte(pmd));
}

#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+1 −1
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
	return true;
}

static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
{
	return pte_present(pte) && !is_kernel_addr(addr);
}
Loading