You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "The bulk of the s390 updates for v3.14. New features are the perf support for the CPU-Measurement Sample Facility and the EP11 support for the crypto cards. And the normal cleanups and bug-fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (44 commits) s390/cpum_sf: fix printk format warnings s390: Fix misspellings using 'codespell' tool s390/qdio: bridgeport support - CHSC part s390: delete new instances of __cpuinit usage s390/compat: fix PSW32_USER_BITS definition s390/zcrypt: add support for EP11 coprocessor cards s390/mm: optimize randomize_et_dyn for !PF_RANDOMIZE s390: use IS_ENABLED to check if a CONFIG is set to y or m s390/cio: use device_lock to synchronize calls to the ccwgroup driver s390/cio: use device_lock to synchronize calls to the ccw driver s390/cio: fix unlocked access of online member s390/cpum_sf: Add flag to process full SDBs only s390/cpum_sf: Add raw data sampling to support the diagnostic-sampling function s390/cpum_sf: Filter perf events based event->attr.exclude_* settings s390/cpum_sf: Detect KVM guest samples s390/cpum_sf: Add helper to read TOD from trailer entries s390/cpum_sf: Atomically reset trailer entry fields of sample-data-blocks s390/cpum_sf: Dynamically extend the sampling buffer if overflows occur s390/pci: reenable per default s390/pci/dma: fix accounting of allocated_pages ...
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
/*?
|
||||||
|
* Text: "Cryptographic device %x failed and was set offline\n"
|
||||||
|
* Severity: Error
|
||||||
|
* Parameter:
|
||||||
|
* @1: device index
|
||||||
|
* Description:
|
||||||
|
* A cryptographic device failed to process a cryptographic request.
|
||||||
|
* The cryptographic device driver could not correct the error and
|
||||||
|
* set the device offline. The application that issued the
|
||||||
|
* request received an indication that the request has failed.
|
||||||
|
* User action:
|
||||||
|
* Use the lszcrypt command to confirm that the cryptographic
|
||||||
|
* hardware is still configured to your LPAR or z/VM guest virtual
|
||||||
|
* machine. If the device is available to your Linux instance the
|
||||||
|
* command output contains a line that begins with 'card<device index>',
|
||||||
|
* where <device index> is the two-digit decimal number in the message text.
|
||||||
|
* After ensuring that the device is available, use the chzcrypt command to
|
||||||
|
* set it online again.
|
||||||
|
* If the error persists, contact your support organization.
|
||||||
|
*/
|
||||||
@@ -38,7 +38,8 @@
|
|||||||
|
|
||||||
#define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \
|
#define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \
|
||||||
PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \
|
PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \
|
||||||
PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | PSW32_ASC_HOME)
|
PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \
|
||||||
|
PSW32_ASC_PRIMARY)
|
||||||
|
|
||||||
#define COMPAT_USER_HZ 100
|
#define COMPAT_USER_HZ 100
|
||||||
#define COMPAT_UTS_MACHINE "s390\0\0\0\0"
|
#define COMPAT_UTS_MACHINE "s390\0\0\0\0"
|
||||||
|
|||||||
@@ -56,6 +56,96 @@ struct cpumf_ctr_info {
|
|||||||
u32 reserved2[12];
|
u32 reserved2[12];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/* QUERY SAMPLING INFORMATION block */
|
||||||
|
struct hws_qsi_info_block { /* Bit(s) */
|
||||||
|
unsigned int b0_13:14; /* 0-13: zeros */
|
||||||
|
unsigned int as:1; /* 14: basic-sampling authorization */
|
||||||
|
unsigned int ad:1; /* 15: diag-sampling authorization */
|
||||||
|
unsigned int b16_21:6; /* 16-21: zeros */
|
||||||
|
unsigned int es:1; /* 22: basic-sampling enable control */
|
||||||
|
unsigned int ed:1; /* 23: diag-sampling enable control */
|
||||||
|
unsigned int b24_29:6; /* 24-29: zeros */
|
||||||
|
unsigned int cs:1; /* 30: basic-sampling activation control */
|
||||||
|
unsigned int cd:1; /* 31: diag-sampling activation control */
|
||||||
|
unsigned int bsdes:16; /* 4-5: size of basic sampling entry */
|
||||||
|
unsigned int dsdes:16; /* 6-7: size of diagnostic sampling entry */
|
||||||
|
unsigned long min_sampl_rate; /* 8-15: minimum sampling interval */
|
||||||
|
unsigned long max_sampl_rate; /* 16-23: maximum sampling interval*/
|
||||||
|
unsigned long tear; /* 24-31: TEAR contents */
|
||||||
|
unsigned long dear; /* 32-39: DEAR contents */
|
||||||
|
unsigned int rsvrd0; /* 40-43: reserved */
|
||||||
|
unsigned int cpu_speed; /* 44-47: CPU speed */
|
||||||
|
unsigned long long rsvrd1; /* 48-55: reserved */
|
||||||
|
unsigned long long rsvrd2; /* 56-63: reserved */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/* SET SAMPLING CONTROLS request block */
|
||||||
|
struct hws_lsctl_request_block {
|
||||||
|
unsigned int s:1; /* 0: maximum buffer indicator */
|
||||||
|
unsigned int h:1; /* 1: part. level reserved for VM use*/
|
||||||
|
unsigned long long b2_53:52;/* 2-53: zeros */
|
||||||
|
unsigned int es:1; /* 54: basic-sampling enable control */
|
||||||
|
unsigned int ed:1; /* 55: diag-sampling enable control */
|
||||||
|
unsigned int b56_61:6; /* 56-61: - zeros */
|
||||||
|
unsigned int cs:1; /* 62: basic-sampling activation control */
|
||||||
|
unsigned int cd:1; /* 63: diag-sampling activation control */
|
||||||
|
unsigned long interval; /* 8-15: sampling interval */
|
||||||
|
unsigned long tear; /* 16-23: TEAR contents */
|
||||||
|
unsigned long dear; /* 24-31: DEAR contents */
|
||||||
|
/* 32-63: */
|
||||||
|
unsigned long rsvrd1; /* reserved */
|
||||||
|
unsigned long rsvrd2; /* reserved */
|
||||||
|
unsigned long rsvrd3; /* reserved */
|
||||||
|
unsigned long rsvrd4; /* reserved */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct hws_basic_entry {
|
||||||
|
unsigned int def:16; /* 0-15 Data Entry Format */
|
||||||
|
unsigned int R:4; /* 16-19 reserved */
|
||||||
|
unsigned int U:4; /* 20-23 Number of unique instruct. */
|
||||||
|
unsigned int z:2; /* zeros */
|
||||||
|
unsigned int T:1; /* 26 PSW DAT mode */
|
||||||
|
unsigned int W:1; /* 27 PSW wait state */
|
||||||
|
unsigned int P:1; /* 28 PSW Problem state */
|
||||||
|
unsigned int AS:2; /* 29-30 PSW address-space control */
|
||||||
|
unsigned int I:1; /* 31 entry valid or invalid */
|
||||||
|
unsigned int:16;
|
||||||
|
unsigned int prim_asn:16; /* primary ASN */
|
||||||
|
unsigned long long ia; /* Instruction Address */
|
||||||
|
unsigned long long gpp; /* Guest Program Parameter */
|
||||||
|
unsigned long long hpp; /* Host Program Parameter */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct hws_diag_entry {
|
||||||
|
unsigned int def:16; /* 0-15 Data Entry Format */
|
||||||
|
unsigned int R:14; /* 16-19 and 20-30 reserved */
|
||||||
|
unsigned int I:1; /* 31 entry valid or invalid */
|
||||||
|
u8 data[]; /* Machine-dependent sample data */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct hws_combined_entry {
|
||||||
|
struct hws_basic_entry basic; /* Basic-sampling data entry */
|
||||||
|
struct hws_diag_entry diag; /* Diagnostic-sampling data entry */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct hws_trailer_entry {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned int f:1; /* 0 - Block Full Indicator */
|
||||||
|
unsigned int a:1; /* 1 - Alert request control */
|
||||||
|
unsigned int t:1; /* 2 - Timestamp format */
|
||||||
|
unsigned long long:61; /* 3 - 63: Reserved */
|
||||||
|
};
|
||||||
|
unsigned long long flags; /* 0 - 63: All indicators */
|
||||||
|
};
|
||||||
|
unsigned long long overflow; /* 64 - sample Overflow count */
|
||||||
|
unsigned char timestamp[16]; /* 16 - 31 timestamp */
|
||||||
|
unsigned long long reserved1; /* 32 -Reserved */
|
||||||
|
unsigned long long reserved2; /* */
|
||||||
|
unsigned long long progusage1; /* 48 - reserved for programming use */
|
||||||
|
unsigned long long progusage2; /* */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* Query counter information */
|
/* Query counter information */
|
||||||
static inline int qctri(struct cpumf_ctr_info *info)
|
static inline int qctri(struct cpumf_ctr_info *info)
|
||||||
{
|
{
|
||||||
@@ -99,4 +189,95 @@ static inline int ecctr(u64 ctr, u64 *val)
|
|||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Query sampling information */
|
||||||
|
static inline int qsi(struct hws_qsi_info_block *info)
|
||||||
|
{
|
||||||
|
int cc;
|
||||||
|
cc = 1;
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
"0: .insn s,0xb2860000,0(%1)\n"
|
||||||
|
"1: lhi %0,0\n"
|
||||||
|
"2:\n"
|
||||||
|
EX_TABLE(0b, 2b) EX_TABLE(1b, 2b)
|
||||||
|
: "=d" (cc), "+a" (info)
|
||||||
|
: "m" (*info)
|
||||||
|
: "cc", "memory");
|
||||||
|
|
||||||
|
return cc ? -EINVAL : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load sampling controls */
|
||||||
|
static inline int lsctl(struct hws_lsctl_request_block *req)
|
||||||
|
{
|
||||||
|
int cc;
|
||||||
|
|
||||||
|
cc = 1;
|
||||||
|
asm volatile(
|
||||||
|
"0: .insn s,0xb2870000,0(%1)\n"
|
||||||
|
"1: ipm %0\n"
|
||||||
|
" srl %0,28\n"
|
||||||
|
"2:\n"
|
||||||
|
EX_TABLE(0b, 2b) EX_TABLE(1b, 2b)
|
||||||
|
: "+d" (cc), "+a" (req)
|
||||||
|
: "m" (*req)
|
||||||
|
: "cc", "memory");
|
||||||
|
|
||||||
|
return cc ? -EINVAL : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sampling control helper functions */
|
||||||
|
|
||||||
|
#include <linux/time.h>
|
||||||
|
|
||||||
|
static inline unsigned long freq_to_sample_rate(struct hws_qsi_info_block *qsi,
|
||||||
|
unsigned long freq)
|
||||||
|
{
|
||||||
|
return (USEC_PER_SEC / freq) * qsi->cpu_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long sample_rate_to_freq(struct hws_qsi_info_block *qsi,
|
||||||
|
unsigned long rate)
|
||||||
|
{
|
||||||
|
return USEC_PER_SEC * qsi->cpu_speed / rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SDB_TE_ALERT_REQ_MASK 0x4000000000000000UL
|
||||||
|
#define SDB_TE_BUFFER_FULL_MASK 0x8000000000000000UL
|
||||||
|
|
||||||
|
/* Return TOD timestamp contained in an trailer entry */
|
||||||
|
static inline unsigned long long trailer_timestamp(struct hws_trailer_entry *te)
|
||||||
|
{
|
||||||
|
/* TOD in STCKE format */
|
||||||
|
if (te->t)
|
||||||
|
return *((unsigned long long *) &te->timestamp[1]);
|
||||||
|
|
||||||
|
/* TOD in STCK format */
|
||||||
|
return *((unsigned long long *) &te->timestamp[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return pointer to trailer entry of an sample data block */
|
||||||
|
static inline unsigned long *trailer_entry_ptr(unsigned long v)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
ret = (void *) v;
|
||||||
|
ret += PAGE_SIZE;
|
||||||
|
ret -= sizeof(struct hws_trailer_entry);
|
||||||
|
|
||||||
|
return (unsigned long *) ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return if the entry in the sample data block table (sdbt)
|
||||||
|
* is a link to the next sdbt */
|
||||||
|
static inline int is_link_entry(unsigned long *s)
|
||||||
|
{
|
||||||
|
return *s & 0x1ul ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return pointer to the linked sdbt */
|
||||||
|
static inline unsigned long *get_next_sdbt(unsigned long *s)
|
||||||
|
{
|
||||||
|
return (unsigned long *) (*s & ~0x1ul);
|
||||||
|
}
|
||||||
#endif /* _ASM_S390_CPU_MF_H */
|
#endif /* _ASM_S390_CPU_MF_H */
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ struct css_general_char {
|
|||||||
u32 fcx : 1; /* bit 88 */
|
u32 fcx : 1; /* bit 88 */
|
||||||
u32 : 19;
|
u32 : 19;
|
||||||
u32 alt_ssi : 1; /* bit 108 */
|
u32 alt_ssi : 1; /* bit 108 */
|
||||||
|
u32:1;
|
||||||
|
u32 narf:1; /* bit 110 */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
extern struct css_general_char css_general_characteristics;
|
extern struct css_general_char css_general_characteristics;
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ int clp_disable_fh(struct zpci_dev *);
|
|||||||
void zpci_event_error(void *);
|
void zpci_event_error(void *);
|
||||||
void zpci_event_availability(void *);
|
void zpci_event_availability(void *);
|
||||||
void zpci_rescan(void);
|
void zpci_rescan(void);
|
||||||
|
bool zpci_is_enabled(void);
|
||||||
#else /* CONFIG_PCI */
|
#else /* CONFIG_PCI */
|
||||||
static inline void zpci_event_error(void *e) {}
|
static inline void zpci_event_error(void *e) {}
|
||||||
static inline void zpci_event_availability(void *e) {}
|
static inline void zpci_event_availability(void *e) {}
|
||||||
|
|||||||
@@ -1,21 +1,40 @@
|
|||||||
/*
|
/*
|
||||||
* Performance event support - s390 specific definitions.
|
* Performance event support - s390 specific definitions.
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2009, 2012
|
* Copyright IBM Corp. 2009, 2013
|
||||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||||
* Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
* Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/cpu_mf.h>
|
#ifndef _ASM_S390_PERF_EVENT_H
|
||||||
|
#define _ASM_S390_PERF_EVENT_H
|
||||||
|
|
||||||
/* CPU-measurement counter facility */
|
#ifdef CONFIG_64BIT
|
||||||
#define PERF_CPUM_CF_MAX_CTR 256
|
|
||||||
|
#include <linux/perf_event.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <asm/cpu_mf.h>
|
||||||
|
|
||||||
/* Per-CPU flags for PMU states */
|
/* Per-CPU flags for PMU states */
|
||||||
#define PMU_F_RESERVED 0x1000
|
#define PMU_F_RESERVED 0x1000
|
||||||
#define PMU_F_ENABLED 0x2000
|
#define PMU_F_ENABLED 0x2000
|
||||||
|
#define PMU_F_IN_USE 0x4000
|
||||||
|
#define PMU_F_ERR_IBE 0x0100
|
||||||
|
#define PMU_F_ERR_LSDA 0x0200
|
||||||
|
#define PMU_F_ERR_MASK (PMU_F_ERR_IBE|PMU_F_ERR_LSDA)
|
||||||
|
|
||||||
|
/* Perf defintions for PMU event attributes in sysfs */
|
||||||
|
extern __init const struct attribute_group **cpumf_cf_event_group(void);
|
||||||
|
extern ssize_t cpumf_events_sysfs_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *page);
|
||||||
|
#define EVENT_VAR(_cat, _name) event_attr_##_cat##_##_name
|
||||||
|
#define EVENT_PTR(_cat, _name) (&EVENT_VAR(_cat, _name).attr.attr)
|
||||||
|
|
||||||
|
#define CPUMF_EVENT_ATTR(cat, name, id) \
|
||||||
|
PMU_EVENT_ATTR(name, EVENT_VAR(cat, name), id, cpumf_events_sysfs_show)
|
||||||
|
#define CPUMF_EVENT_PTR(cat, name) EVENT_PTR(cat, name)
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
|
||||||
|
|
||||||
/* Perf callbacks */
|
/* Perf callbacks */
|
||||||
struct pt_regs;
|
struct pt_regs;
|
||||||
@@ -23,4 +42,55 @@ extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
|
|||||||
extern unsigned long perf_misc_flags(struct pt_regs *regs);
|
extern unsigned long perf_misc_flags(struct pt_regs *regs);
|
||||||
#define perf_misc_flags(regs) perf_misc_flags(regs)
|
#define perf_misc_flags(regs) perf_misc_flags(regs)
|
||||||
|
|
||||||
|
/* Perf pt_regs extension for sample-data-entry indicators */
|
||||||
|
struct perf_sf_sde_regs {
|
||||||
|
unsigned char in_guest:1; /* guest sample */
|
||||||
|
unsigned long reserved:63; /* reserved */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Perf PMU definitions for the counter facility */
|
||||||
|
#define PERF_CPUM_CF_MAX_CTR 256
|
||||||
|
|
||||||
|
/* Perf PMU definitions for the sampling facility */
|
||||||
|
#define PERF_CPUM_SF_MAX_CTR 2
|
||||||
|
#define PERF_EVENT_CPUM_SF 0xB0000UL /* Event: Basic-sampling */
|
||||||
|
#define PERF_EVENT_CPUM_SF_DIAG 0xBD000UL /* Event: Combined-sampling */
|
||||||
|
#define PERF_CPUM_SF_BASIC_MODE 0x0001 /* Basic-sampling flag */
|
||||||
|
#define PERF_CPUM_SF_DIAG_MODE 0x0002 /* Diagnostic-sampling flag */
|
||||||
|
#define PERF_CPUM_SF_MODE_MASK (PERF_CPUM_SF_BASIC_MODE| \
|
||||||
|
PERF_CPUM_SF_DIAG_MODE)
|
||||||
|
#define PERF_CPUM_SF_FULL_BLOCKS 0x0004 /* Process full SDBs only */
|
||||||
|
|
||||||
|
#define REG_NONE 0
|
||||||
|
#define REG_OVERFLOW 1
|
||||||
|
#define OVERFLOW_REG(hwc) ((hwc)->extra_reg.config)
|
||||||
|
#define SFB_ALLOC_REG(hwc) ((hwc)->extra_reg.alloc)
|
||||||
|
#define RAWSAMPLE_REG(hwc) ((hwc)->config)
|
||||||
|
#define TEAR_REG(hwc) ((hwc)->last_tag)
|
||||||
|
#define SAMPL_RATE(hwc) ((hwc)->event_base)
|
||||||
|
#define SAMPL_FLAGS(hwc) ((hwc)->config_base)
|
||||||
|
#define SAMPL_DIAG_MODE(hwc) (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_DIAG_MODE)
|
||||||
|
#define SDB_FULL_BLOCKS(hwc) (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_FULL_BLOCKS)
|
||||||
|
|
||||||
|
/* Structure for sampling data entries to be passed as perf raw sample data
|
||||||
|
* to user space. Note that raw sample data must be aligned and, thus, might
|
||||||
|
* be padded with zeros.
|
||||||
|
*/
|
||||||
|
struct sf_raw_sample {
|
||||||
|
#define SF_RAW_SAMPLE_BASIC PERF_CPUM_SF_BASIC_MODE
|
||||||
|
#define SF_RAW_SAMPLE_DIAG PERF_CPUM_SF_DIAG_MODE
|
||||||
|
u64 format;
|
||||||
|
u32 size; /* Size of sf_raw_sample */
|
||||||
|
u16 bsdes; /* Basic-sampling data entry size */
|
||||||
|
u16 dsdes; /* Diagnostic-sampling data entry size */
|
||||||
|
struct hws_basic_entry basic; /* Basic-sampling data entry */
|
||||||
|
struct hws_diag_entry diag; /* Diagnostic-sampling data entry */
|
||||||
|
u8 padding[]; /* Padding to next multiple of 8 */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/* Perf hardware reserve and release functions */
|
||||||
|
int perf_reserve_sampling(void);
|
||||||
|
void perf_release_sampling(void);
|
||||||
|
|
||||||
#endif /* CONFIG_64BIT */
|
#endif /* CONFIG_64BIT */
|
||||||
|
#endif /* _ASM_S390_PERF_EVENT_H */
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
|
|||||||
#define QDIO_FLAG_CLEANUP_USING_HALT 0x02
|
#define QDIO_FLAG_CLEANUP_USING_HALT 0x02
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct qdio_initialize - qdio initalization data
|
* struct qdio_initialize - qdio initialization data
|
||||||
* @cdev: associated ccw device
|
* @cdev: associated ccw device
|
||||||
* @q_format: queue format
|
* @q_format: queue format
|
||||||
* @adapter_name: name for the adapter
|
* @adapter_name: name for the adapter
|
||||||
@@ -378,6 +378,34 @@ struct qdio_initialize {
|
|||||||
struct qdio_outbuf_state *output_sbal_state_array;
|
struct qdio_outbuf_state *output_sbal_state_array;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum qdio_brinfo_entry_type - type of address entry for qdio_brinfo_desc()
|
||||||
|
* @l3_ipv6_addr: entry contains IPv6 address
|
||||||
|
* @l3_ipv4_addr: entry contains IPv4 address
|
||||||
|
* @l2_addr_lnid: entry contains MAC address and VLAN ID
|
||||||
|
*/
|
||||||
|
enum qdio_brinfo_entry_type {l3_ipv6_addr, l3_ipv4_addr, l2_addr_lnid};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct qdio_brinfo_entry_XXX - Address entry for qdio_brinfo_desc()
|
||||||
|
* @nit: Network interface token
|
||||||
|
* @addr: Address of one of the three types
|
||||||
|
*
|
||||||
|
* The struct is passed to the callback function by qdio_brinfo_desc()
|
||||||
|
*/
|
||||||
|
struct qdio_brinfo_entry_l3_ipv6 {
|
||||||
|
u64 nit;
|
||||||
|
struct { unsigned char _s6_addr[16]; } addr;
|
||||||
|
} __packed;
|
||||||
|
struct qdio_brinfo_entry_l3_ipv4 {
|
||||||
|
u64 nit;
|
||||||
|
struct { uint32_t _s_addr; } addr;
|
||||||
|
} __packed;
|
||||||
|
struct qdio_brinfo_entry_l2 {
|
||||||
|
u64 nit;
|
||||||
|
struct { u8 mac[6]; u16 lnid; } addr_lnid;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
#define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */
|
#define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */
|
||||||
#define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_establish */
|
#define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_establish */
|
||||||
#define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */
|
#define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */
|
||||||
@@ -399,5 +427,10 @@ extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *);
|
|||||||
extern int qdio_shutdown(struct ccw_device *, int);
|
extern int qdio_shutdown(struct ccw_device *, int);
|
||||||
extern int qdio_free(struct ccw_device *);
|
extern int qdio_free(struct ccw_device *);
|
||||||
extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *);
|
extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *);
|
||||||
|
extern int qdio_pnso_brinfo(struct subchannel_id schid,
|
||||||
|
int cnc, u16 *response,
|
||||||
|
void (*cb)(void *priv, enum qdio_brinfo_entry_type type,
|
||||||
|
void *entry),
|
||||||
|
void *priv);
|
||||||
|
|
||||||
#endif /* __QDIO_H__ */
|
#endif /* __QDIO_H__ */
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ int sclp_chp_configure(struct chp_id chpid);
|
|||||||
int sclp_chp_deconfigure(struct chp_id chpid);
|
int sclp_chp_deconfigure(struct chp_id chpid);
|
||||||
int sclp_chp_read_info(struct sclp_chp_info *info);
|
int sclp_chp_read_info(struct sclp_chp_info *info);
|
||||||
void sclp_get_ipl_info(struct sclp_ipl_info *info);
|
void sclp_get_ipl_info(struct sclp_ipl_info *info);
|
||||||
bool sclp_has_linemode(void);
|
bool __init sclp_has_linemode(void);
|
||||||
bool sclp_has_vt220(void);
|
bool __init sclp_has_vt220(void);
|
||||||
int sclp_pci_configure(u32 fid);
|
int sclp_pci_configure(u32 fid);
|
||||||
int sclp_pci_deconfigure(u32 fid);
|
int sclp_pci_deconfigure(u32 fid);
|
||||||
int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode);
|
int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode);
|
||||||
|
|||||||
@@ -154,6 +154,67 @@ struct ica_xcRB {
|
|||||||
unsigned short priority_window;
|
unsigned short priority_window;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ep11_cprb - EP11 connectivity programming request block
|
||||||
|
* @cprb_len: CPRB header length [0x0020]
|
||||||
|
* @cprb_ver_id: CPRB version id. [0x04]
|
||||||
|
* @pad_000: Alignment pad bytes
|
||||||
|
* @flags: Admin cmd [0x80] or functional cmd [0x00]
|
||||||
|
* @func_id: Function id / subtype [0x5434]
|
||||||
|
* @source_id: Source id [originator id]
|
||||||
|
* @target_id: Target id [usage/ctrl domain id]
|
||||||
|
* @ret_code: Return code
|
||||||
|
* @reserved1: Reserved
|
||||||
|
* @reserved2: Reserved
|
||||||
|
* @payload_len: Payload length
|
||||||
|
*/
|
||||||
|
struct ep11_cprb {
|
||||||
|
uint16_t cprb_len;
|
||||||
|
unsigned char cprb_ver_id;
|
||||||
|
unsigned char pad_000[2];
|
||||||
|
unsigned char flags;
|
||||||
|
unsigned char func_id[2];
|
||||||
|
uint32_t source_id;
|
||||||
|
uint32_t target_id;
|
||||||
|
uint32_t ret_code;
|
||||||
|
uint32_t reserved1;
|
||||||
|
uint32_t reserved2;
|
||||||
|
uint32_t payload_len;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ep11_target_dev - EP11 target device list
|
||||||
|
* @ap_id: AP device id
|
||||||
|
* @dom_id: Usage domain id
|
||||||
|
*/
|
||||||
|
struct ep11_target_dev {
|
||||||
|
uint16_t ap_id;
|
||||||
|
uint16_t dom_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ep11_urb - EP11 user request block
|
||||||
|
* @targets_num: Number of target adapters
|
||||||
|
* @targets: Addr to target adapter list
|
||||||
|
* @weight: Level of request priority
|
||||||
|
* @req_no: Request id/number
|
||||||
|
* @req_len: Request length
|
||||||
|
* @req: Addr to request block
|
||||||
|
* @resp_len: Response length
|
||||||
|
* @resp: Addr to response block
|
||||||
|
*/
|
||||||
|
struct ep11_urb {
|
||||||
|
uint16_t targets_num;
|
||||||
|
uint64_t targets;
|
||||||
|
uint64_t weight;
|
||||||
|
uint64_t req_no;
|
||||||
|
uint64_t req_len;
|
||||||
|
uint64_t req;
|
||||||
|
uint64_t resp_len;
|
||||||
|
uint64_t resp;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
#define AUTOSELECT ((unsigned int)0xFFFFFFFF)
|
#define AUTOSELECT ((unsigned int)0xFFFFFFFF)
|
||||||
|
|
||||||
#define ZCRYPT_IOCTL_MAGIC 'z'
|
#define ZCRYPT_IOCTL_MAGIC 'z'
|
||||||
@@ -183,6 +244,9 @@ struct ica_xcRB {
|
|||||||
* ZSECSENDCPRB
|
* ZSECSENDCPRB
|
||||||
* Send an arbitrary CPRB to a crypto card.
|
* Send an arbitrary CPRB to a crypto card.
|
||||||
*
|
*
|
||||||
|
* ZSENDEP11CPRB
|
||||||
|
* Send an arbitrary EP11 CPRB to an EP11 coprocessor crypto card.
|
||||||
|
*
|
||||||
* Z90STAT_STATUS_MASK
|
* Z90STAT_STATUS_MASK
|
||||||
* Return an 64 element array of unsigned chars for the status of
|
* Return an 64 element array of unsigned chars for the status of
|
||||||
* all devices.
|
* all devices.
|
||||||
@@ -256,6 +320,7 @@ struct ica_xcRB {
|
|||||||
#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0)
|
#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0)
|
||||||
#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
|
#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
|
||||||
#define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
|
#define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
|
||||||
|
#define ZSENDEP11CPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x04, 0)
|
||||||
|
|
||||||
/* New status calls */
|
/* New status calls */
|
||||||
#define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int)
|
#define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int)
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
|
|||||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||||
|
|
||||||
ifdef CONFIG_64BIT
|
ifdef CONFIG_64BIT
|
||||||
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o
|
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o perf_cpum_sf.o \
|
||||||
|
perf_cpum_cf_events.o
|
||||||
obj-y += runtime_instr.o cache.o
|
obj-y += runtime_instr.o cache.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -412,8 +412,9 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||||||
regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
|
regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
|
||||||
} else {
|
} else {
|
||||||
regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
|
regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
|
||||||
err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
|
if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
|
||||||
(u16 __force __user *)(frame->retcode));
|
(u16 __force __user *)(frame->retcode)))
|
||||||
|
goto give_sigsegv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up backchain. */
|
/* Set up backchain. */
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro LPP newpp
|
.macro LPP newpp
|
||||||
#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
|
#if IS_ENABLED(CONFIG_KVM)
|
||||||
tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP
|
tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP
|
||||||
jz .+8
|
jz .+8
|
||||||
.insn s,0xb2800000,\newpp
|
.insn s,0xb2800000,\newpp
|
||||||
@@ -82,7 +82,7 @@ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro HANDLE_SIE_INTERCEPT scratch,reason
|
.macro HANDLE_SIE_INTERCEPT scratch,reason
|
||||||
#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
|
#if IS_ENABLED(CONFIG_KVM)
|
||||||
tmhh %r8,0x0001 # interrupting from user ?
|
tmhh %r8,0x0001 # interrupting from user ?
|
||||||
jnz .+62
|
jnz .+62
|
||||||
lgr \scratch,%r9
|
lgr \scratch,%r9
|
||||||
@@ -946,7 +946,7 @@ cleanup_idle_insn:
|
|||||||
.quad __critical_end - __critical_start
|
.quad __critical_end - __critical_start
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
|
#if IS_ENABLED(CONFIG_KVM)
|
||||||
/*
|
/*
|
||||||
* sie64a calling convention:
|
* sie64a calling convention:
|
||||||
* %r2 pointer to sie control block
|
* %r2 pointer to sie control block
|
||||||
@@ -975,7 +975,7 @@ sie_done:
|
|||||||
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
|
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
|
||||||
# some program checks are suppressing. C code (e.g. do_protection_exception)
|
# some program checks are suppressing. C code (e.g. do_protection_exception)
|
||||||
# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
|
# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
|
||||||
# instructions beween sie64a and sie_done should not cause program
|
# instructions between sie64a and sie_done should not cause program
|
||||||
# interrupts. So lets use a nop (47 00 00 00) as a landing pad.
|
# interrupts. So lets use a nop (47 00 00 00) as a landing pad.
|
||||||
# See also HANDLE_SIE_INTERCEPT
|
# See also HANDLE_SIE_INTERCEPT
|
||||||
rewind_pad:
|
rewind_pad:
|
||||||
|
|||||||
@@ -680,6 +680,7 @@ static int __init cpumf_pmu_init(void)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpumf_pmu.attr_groups = cpumf_cf_event_group();
|
||||||
rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW);
|
rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc);
|
pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc);
|
||||||
|
|||||||
@@ -0,0 +1,322 @@
|
|||||||
|
/*
|
||||||
|
* Perf PMU sysfs events attributes for available CPU-measurement counters
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/perf_event.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* BEGIN: CPUM_CF COUNTER DEFINITIONS =================================== */
|
||||||
|
|
||||||
|
CPUMF_EVENT_ATTR(cf, CPU_CYCLES, 0x0000);
|
||||||
|
CPUMF_EVENT_ATTR(cf, INSTRUCTIONS, 0x0001);
|
||||||
|
CPUMF_EVENT_ATTR(cf, L1I_DIR_WRITES, 0x0002);
|
||||||
|
CPUMF_EVENT_ATTR(cf, L1I_PENALTY_CYCLES, 0x0003);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_CPU_CYCLES, 0x0020);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_INSTRUCTIONS, 0x0021);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_L1I_DIR_WRITES, 0x0022);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_L1I_PENALTY_CYCLES, 0x0023);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_L1D_DIR_WRITES, 0x0024);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_L1D_PENALTY_CYCLES, 0x0025);
|
||||||
|
CPUMF_EVENT_ATTR(cf, L1D_DIR_WRITES, 0x0004);
|
||||||
|
CPUMF_EVENT_ATTR(cf, L1D_PENALTY_CYCLES, 0x0005);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PRNG_FUNCTIONS, 0x0040);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PRNG_CYCLES, 0x0041);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PRNG_BLOCKED_FUNCTIONS, 0x0042);
|
||||||
|
CPUMF_EVENT_ATTR(cf, PRNG_BLOCKED_CYCLES, 0x0043);
|
||||||
|
CPUMF_EVENT_ATTR(cf, SHA_FUNCTIONS, 0x0044);
|
||||||
|
CPUMF_EVENT_ATTR(cf, SHA_CYCLES, 0x0045);
|
||||||
|
CPUMF_EVENT_ATTR(cf, SHA_BLOCKED_FUNCTIONS, 0x0046);
|
||||||
|
CPUMF_EVENT_ATTR(cf, SHA_BLOCKED_CYCLES, 0x0047);
|
||||||
|
CPUMF_EVENT_ATTR(cf, DEA_FUNCTIONS, 0x0048);
|
||||||
|
CPUMF_EVENT_ATTR(cf, DEA_CYCLES, 0x0049);
|
||||||
|
CPUMF_EVENT_ATTR(cf, DEA_BLOCKED_FUNCTIONS, 0x004a);
|
||||||
|
CPUMF_EVENT_ATTR(cf, DEA_BLOCKED_CYCLES, 0x004b);
|
||||||
|
CPUMF_EVENT_ATTR(cf, AES_FUNCTIONS, 0x004c);
|
||||||
|
CPUMF_EVENT_ATTR(cf, AES_CYCLES, 0x004d);
|
||||||
|
CPUMF_EVENT_ATTR(cf, AES_BLOCKED_FUNCTIONS, 0x004e);
|
||||||
|
CPUMF_EVENT_ATTR(cf, AES_BLOCKED_CYCLES, 0x004f);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1I_L2_SOURCED_WRITES, 0x0080);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1D_L2_SOURCED_WRITES, 0x0081);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1I_L3_LOCAL_WRITES, 0x0082);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1D_L3_LOCAL_WRITES, 0x0083);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1I_L3_REMOTE_WRITES, 0x0084);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1D_L3_REMOTE_WRITES, 0x0085);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1D_LMEM_SOURCED_WRITES, 0x0086);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1I_LMEM_SOURCED_WRITES, 0x0087);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1D_RO_EXCL_WRITES, 0x0088);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L1I_CACHELINE_INVALIDATES, 0x0089);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, ITLB1_WRITES, 0x008a);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, DTLB1_WRITES, 0x008b);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, TLB2_PTE_WRITES, 0x008c);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, TLB2_CRSTE_WRITES, 0x008d);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, TLB2_CRSTE_HPAGE_WRITES, 0x008e);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, ITLB1_MISSES, 0x0091);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, DTLB1_MISSES, 0x0092);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z10, L2C_STORES_SENT, 0x0093);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1D_L2_SOURCED_WRITES, 0x0080);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1I_L2_SOURCED_WRITES, 0x0081);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, DTLB1_MISSES, 0x0082);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, ITLB1_MISSES, 0x0083);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L2C_STORES_SENT, 0x0085);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1D_OFFBOOK_L3_SOURCED_WRITES, 0x0086);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1D_ONBOOK_L4_SOURCED_WRITES, 0x0087);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1I_ONBOOK_L4_SOURCED_WRITES, 0x0088);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1D_RO_EXCL_WRITES, 0x0089);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1D_OFFBOOK_L4_SOURCED_WRITES, 0x008a);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1I_OFFBOOK_L4_SOURCED_WRITES, 0x008b);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, DTLB1_HPAGE_WRITES, 0x008c);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1D_LMEM_SOURCED_WRITES, 0x008d);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1I_LMEM_SOURCED_WRITES, 0x008e);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1I_OFFBOOK_L3_SOURCED_WRITES, 0x008f);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, DTLB1_WRITES, 0x0090);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, ITLB1_WRITES, 0x0091);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, TLB2_PTE_WRITES, 0x0092);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, TLB2_CRSTE_HPAGE_WRITES, 0x0093);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, TLB2_CRSTE_WRITES, 0x0094);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1D_ONCHIP_L3_SOURCED_WRITES, 0x0096);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1D_OFFCHIP_L3_SOURCED_WRITES, 0x0098);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1I_ONCHIP_L3_SOURCED_WRITES, 0x0099);
|
||||||
|
CPUMF_EVENT_ATTR(cf_z196, L1I_OFFCHIP_L3_SOURCED_WRITES, 0x009b);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, DTLB1_MISSES, 0x0080);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, ITLB1_MISSES, 0x0081);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_L2I_SOURCED_WRITES, 0x0082);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_L2I_SOURCED_WRITES, 0x0083);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_L2D_SOURCED_WRITES, 0x0084);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, DTLB1_WRITES, 0x0085);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_LMEM_SOURCED_WRITES, 0x0087);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_LMEM_SOURCED_WRITES, 0x0089);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_RO_EXCL_WRITES, 0x008a);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, DTLB1_HPAGE_WRITES, 0x008b);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, ITLB1_WRITES, 0x008c);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, TLB2_PTE_WRITES, 0x008d);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, TLB2_CRSTE_HPAGE_WRITES, 0x008e);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, TLB2_CRSTE_WRITES, 0x008f);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_ONCHIP_L3_SOURCED_WRITES, 0x0090);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFCHIP_L3_SOURCED_WRITES, 0x0091);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFBOOK_L3_SOURCED_WRITES, 0x0092);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_ONBOOK_L4_SOURCED_WRITES, 0x0093);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFBOOK_L4_SOURCED_WRITES, 0x0094);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, TX_NC_TEND, 0x0095);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_ONCHIP_L3_SOURCED_WRITES_IV, 0x0096);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFCHIP_L3_SOURCED_WRITES_IV, 0x0097);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFBOOK_L3_SOURCED_WRITES_IV, 0x0098);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_ONCHIP_L3_SOURCED_WRITES, 0x0099);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFCHIP_L3_SOURCED_WRITES, 0x009a);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES, 0x009b);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_ONBOOK_L4_SOURCED_WRITES, 0x009c);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFBOOK_L4_SOURCED_WRITES, 0x009d);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, TX_C_TEND, 0x009e);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_ONCHIP_L3_SOURCED_WRITES_IV, 0x009f);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFCHIP_L3_SOURCED_WRITES_IV, 0x00a0);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES_IV, 0x00a1);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, TX_NC_TABORT, 0x00b1);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, TX_C_TABORT_NO_SPECIAL, 0x00b2);
|
||||||
|
CPUMF_EVENT_ATTR(cf_zec12, TX_C_TABORT_SPECIAL, 0x00b3);
|
||||||
|
|
||||||
|
static struct attribute *cpumcf_pmu_event_attr[] = {
|
||||||
|
CPUMF_EVENT_PTR(cf, CPU_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, INSTRUCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, L1I_DIR_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf, L1I_PENALTY_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, PROBLEM_STATE_CPU_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, PROBLEM_STATE_INSTRUCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, PROBLEM_STATE_L1I_DIR_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf, PROBLEM_STATE_L1I_PENALTY_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, PROBLEM_STATE_L1D_DIR_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf, PROBLEM_STATE_L1D_PENALTY_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, L1D_DIR_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf, L1D_PENALTY_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, PRNG_FUNCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, PRNG_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, PRNG_BLOCKED_FUNCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, PRNG_BLOCKED_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, SHA_FUNCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, SHA_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, SHA_BLOCKED_FUNCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, SHA_BLOCKED_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, DEA_FUNCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, DEA_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, DEA_BLOCKED_FUNCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, DEA_BLOCKED_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, AES_FUNCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, AES_CYCLES),
|
||||||
|
CPUMF_EVENT_PTR(cf, AES_BLOCKED_FUNCTIONS),
|
||||||
|
CPUMF_EVENT_PTR(cf, AES_BLOCKED_CYCLES),
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute *cpumcf_z10_pmu_event_attr[] __initdata = {
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1I_L2_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1D_L2_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1I_L3_LOCAL_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1D_L3_LOCAL_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1I_L3_REMOTE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1D_L3_REMOTE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1D_LMEM_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1I_LMEM_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1D_RO_EXCL_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L1I_CACHELINE_INVALIDATES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, ITLB1_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, DTLB1_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, TLB2_PTE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, TLB2_CRSTE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, TLB2_CRSTE_HPAGE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, ITLB1_MISSES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, DTLB1_MISSES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z10, L2C_STORES_SENT),
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute *cpumcf_z196_pmu_event_attr[] __initdata = {
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1D_L2_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1I_L2_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, DTLB1_MISSES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, ITLB1_MISSES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L2C_STORES_SENT),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1D_OFFBOOK_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1D_ONBOOK_L4_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1I_ONBOOK_L4_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1D_RO_EXCL_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1D_OFFBOOK_L4_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1I_OFFBOOK_L4_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, DTLB1_HPAGE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1D_LMEM_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1I_LMEM_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1I_OFFBOOK_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, DTLB1_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, ITLB1_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, TLB2_PTE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, TLB2_CRSTE_HPAGE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, TLB2_CRSTE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1D_ONCHIP_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1D_OFFCHIP_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1I_ONCHIP_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_z196, L1I_OFFCHIP_L3_SOURCED_WRITES),
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute *cpumcf_zec12_pmu_event_attr[] __initdata = {
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, DTLB1_MISSES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, ITLB1_MISSES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_L2I_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_L2I_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_L2D_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, DTLB1_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_LMEM_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_LMEM_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_RO_EXCL_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, DTLB1_HPAGE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, ITLB1_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, TLB2_PTE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, TLB2_CRSTE_HPAGE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, TLB2_CRSTE_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_ONCHIP_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_OFFCHIP_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_OFFBOOK_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_ONBOOK_L4_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_OFFBOOK_L4_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, TX_NC_TEND),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_ONCHIP_L3_SOURCED_WRITES_IV),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_OFFCHIP_L3_SOURCED_WRITES_IV),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1D_OFFBOOK_L3_SOURCED_WRITES_IV),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_ONCHIP_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_OFFCHIP_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_ONBOOK_L4_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_OFFBOOK_L4_SOURCED_WRITES),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, TX_C_TEND),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_ONCHIP_L3_SOURCED_WRITES_IV),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_OFFCHIP_L3_SOURCED_WRITES_IV),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES_IV),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, TX_NC_TABORT),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, TX_C_TABORT_NO_SPECIAL),
|
||||||
|
CPUMF_EVENT_PTR(cf_zec12, TX_C_TABORT_SPECIAL),
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* END: CPUM_CF COUNTER DEFINITIONS ===================================== */
|
||||||
|
|
||||||
|
static struct attribute_group cpumsf_pmu_events_group = {
|
||||||
|
.name = "events",
|
||||||
|
.attrs = cpumcf_pmu_event_attr,
|
||||||
|
};
|
||||||
|
|
||||||
|
PMU_FORMAT_ATTR(event, "config:0-63");
|
||||||
|
|
||||||
|
static struct attribute *cpumsf_pmu_format_attr[] = {
|
||||||
|
&format_attr_event.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute_group cpumsf_pmu_format_group = {
|
||||||
|
.name = "format",
|
||||||
|
.attrs = cpumsf_pmu_format_attr,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group *cpumsf_pmu_attr_groups[] = {
|
||||||
|
&cpumsf_pmu_events_group,
|
||||||
|
&cpumsf_pmu_format_group,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static __init struct attribute **merge_attr(struct attribute **a,
|
||||||
|
struct attribute **b)
|
||||||
|
{
|
||||||
|
struct attribute **new;
|
||||||
|
int j, i;
|
||||||
|
|
||||||
|
for (j = 0; a[j]; j++)
|
||||||
|
;
|
||||||
|
for (i = 0; b[i]; i++)
|
||||||
|
j++;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL);
|
||||||
|
if (!new)
|
||||||
|
return NULL;
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; a[i]; i++)
|
||||||
|
new[j++] = a[i];
|
||||||
|
for (i = 0; b[i]; i++)
|
||||||
|
new[j++] = b[i];
|
||||||
|
new[j] = NULL;
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
__init const struct attribute_group **cpumf_cf_event_group(void)
|
||||||
|
{
|
||||||
|
struct attribute **combined, **model;
|
||||||
|
struct cpuid cpu_id;
|
||||||
|
|
||||||
|
get_cpu_id(&cpu_id);
|
||||||
|
switch (cpu_id.machine) {
|
||||||
|
case 0x2097:
|
||||||
|
case 0x2098:
|
||||||
|
model = cpumcf_z10_pmu_event_attr;
|
||||||
|
break;
|
||||||
|
case 0x2817:
|
||||||
|
case 0x2818:
|
||||||
|
model = cpumcf_z196_pmu_event_attr;
|
||||||
|
break;
|
||||||
|
case 0x2827:
|
||||||
|
case 0x2828:
|
||||||
|
model = cpumcf_zec12_pmu_event_attr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
model = NULL;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!model)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
combined = merge_attr(cpumcf_pmu_event_attr, model);
|
||||||
|
if (combined)
|
||||||
|
cpumsf_pmu_events_group.attrs = combined;
|
||||||
|
out:
|
||||||
|
return cpumsf_pmu_attr_groups;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
+162
-12
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Performance event support for s390x
|
* Performance event support for s390x
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2012
|
* Copyright IBM Corp. 2012, 2013
|
||||||
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -16,15 +16,19 @@
|
|||||||
#include <linux/kvm_host.h>
|
#include <linux/kvm_host.h>
|
||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/sysfs.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/cpu_mf.h>
|
#include <asm/cpu_mf.h>
|
||||||
#include <asm/lowcore.h>
|
#include <asm/lowcore.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
#include <asm/sysinfo.h>
|
||||||
|
|
||||||
const char *perf_pmu_name(void)
|
const char *perf_pmu_name(void)
|
||||||
{
|
{
|
||||||
if (cpum_cf_avail() || cpum_sf_avail())
|
if (cpum_cf_avail() || cpum_sf_avail())
|
||||||
return "CPU-measurement facilities (CPUMF)";
|
return "CPU-Measurement Facilities (CPU-MF)";
|
||||||
return "pmu";
|
return "pmu";
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(perf_pmu_name);
|
EXPORT_SYMBOL(perf_pmu_name);
|
||||||
@@ -35,6 +39,8 @@ int perf_num_counters(void)
|
|||||||
|
|
||||||
if (cpum_cf_avail())
|
if (cpum_cf_avail())
|
||||||
num += PERF_CPUM_CF_MAX_CTR;
|
num += PERF_CPUM_CF_MAX_CTR;
|
||||||
|
if (cpum_sf_avail())
|
||||||
|
num += PERF_CPUM_SF_MAX_CTR;
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
@@ -54,7 +60,7 @@ static bool is_in_guest(struct pt_regs *regs)
|
|||||||
{
|
{
|
||||||
if (user_mode(regs))
|
if (user_mode(regs))
|
||||||
return false;
|
return false;
|
||||||
#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
|
#if IS_ENABLED(CONFIG_KVM)
|
||||||
return instruction_pointer(regs) == (unsigned long) &sie_exit;
|
return instruction_pointer(regs) == (unsigned long) &sie_exit;
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
@@ -83,8 +89,31 @@ static unsigned long perf_misc_guest_flags(struct pt_regs *regs)
|
|||||||
: PERF_RECORD_MISC_GUEST_KERNEL;
|
: PERF_RECORD_MISC_GUEST_KERNEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long perf_misc_flags_sf(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
struct perf_sf_sde_regs *sde_regs;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
sde_regs = (struct perf_sf_sde_regs *) ®s->int_parm_long;
|
||||||
|
if (sde_regs->in_guest)
|
||||||
|
flags = user_mode(regs) ? PERF_RECORD_MISC_GUEST_USER
|
||||||
|
: PERF_RECORD_MISC_GUEST_KERNEL;
|
||||||
|
else
|
||||||
|
flags = user_mode(regs) ? PERF_RECORD_MISC_USER
|
||||||
|
: PERF_RECORD_MISC_KERNEL;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long perf_misc_flags(struct pt_regs *regs)
|
unsigned long perf_misc_flags(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
|
/* Check if the cpum_sf PMU has created the pt_regs structure.
|
||||||
|
* In this case, perf misc flags can be easily extracted. Otherwise,
|
||||||
|
* do regular checks on the pt_regs content.
|
||||||
|
*/
|
||||||
|
if (regs->int_code == 0x1407 && regs->int_parm == CPU_MF_INT_SF_PRA)
|
||||||
|
if (!regs->gprs[15])
|
||||||
|
return perf_misc_flags_sf(regs);
|
||||||
|
|
||||||
if (is_in_guest(regs))
|
if (is_in_guest(regs))
|
||||||
return perf_misc_guest_flags(regs);
|
return perf_misc_guest_flags(regs);
|
||||||
|
|
||||||
@@ -92,27 +121,107 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
|
|||||||
: PERF_RECORD_MISC_KERNEL;
|
: PERF_RECORD_MISC_KERNEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void perf_event_print_debug(void)
|
void print_debug_cf(void)
|
||||||
{
|
{
|
||||||
struct cpumf_ctr_info cf_info;
|
struct cpumf_ctr_info cf_info;
|
||||||
unsigned long flags;
|
int cpu = smp_processor_id();
|
||||||
int cpu;
|
|
||||||
|
|
||||||
if (!cpum_cf_avail())
|
|
||||||
return;
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
|
|
||||||
cpu = smp_processor_id();
|
|
||||||
memset(&cf_info, 0, sizeof(cf_info));
|
memset(&cf_info, 0, sizeof(cf_info));
|
||||||
if (!qctri(&cf_info))
|
if (!qctri(&cf_info))
|
||||||
pr_info("CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n",
|
pr_info("CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n",
|
||||||
cpu, cf_info.cfvn, cf_info.csvn,
|
cpu, cf_info.cfvn, cf_info.csvn,
|
||||||
cf_info.auth_ctl, cf_info.enable_ctl, cf_info.act_ctl);
|
cf_info.auth_ctl, cf_info.enable_ctl, cf_info.act_ctl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_debug_sf(void)
|
||||||
|
{
|
||||||
|
struct hws_qsi_info_block si;
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
|
memset(&si, 0, sizeof(si));
|
||||||
|
if (qsi(&si))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pr_info("CPU[%i] CPUM_SF: basic=%i diag=%i min=%lu max=%lu cpu_speed=%u\n",
|
||||||
|
cpu, si.as, si.ad, si.min_sampl_rate, si.max_sampl_rate,
|
||||||
|
si.cpu_speed);
|
||||||
|
|
||||||
|
if (si.as)
|
||||||
|
pr_info("CPU[%i] CPUM_SF: Basic-sampling: a=%i e=%i c=%i"
|
||||||
|
" bsdes=%i tear=%016lx dear=%016lx\n", cpu,
|
||||||
|
si.as, si.es, si.cs, si.bsdes, si.tear, si.dear);
|
||||||
|
if (si.ad)
|
||||||
|
pr_info("CPU[%i] CPUM_SF: Diagnostic-sampling: a=%i e=%i c=%i"
|
||||||
|
" dsdes=%i tear=%016lx dear=%016lx\n", cpu,
|
||||||
|
si.ad, si.ed, si.cd, si.dsdes, si.tear, si.dear);
|
||||||
|
}
|
||||||
|
|
||||||
|
void perf_event_print_debug(void)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
if (cpum_cf_avail())
|
||||||
|
print_debug_cf();
|
||||||
|
if (cpum_sf_avail())
|
||||||
|
print_debug_sf();
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Service level infrastructure */
|
||||||
|
static void sl_print_counter(struct seq_file *m)
|
||||||
|
{
|
||||||
|
struct cpumf_ctr_info ci;
|
||||||
|
|
||||||
|
memset(&ci, 0, sizeof(ci));
|
||||||
|
if (qctri(&ci))
|
||||||
|
return;
|
||||||
|
|
||||||
|
seq_printf(m, "CPU-MF: Counter facility: version=%u.%u "
|
||||||
|
"authorization=%04x\n", ci.cfvn, ci.csvn, ci.auth_ctl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sl_print_sampling(struct seq_file *m)
|
||||||
|
{
|
||||||
|
struct hws_qsi_info_block si;
|
||||||
|
|
||||||
|
memset(&si, 0, sizeof(si));
|
||||||
|
if (qsi(&si))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!si.as && !si.ad)
|
||||||
|
return;
|
||||||
|
|
||||||
|
seq_printf(m, "CPU-MF: Sampling facility: min_rate=%lu max_rate=%lu"
|
||||||
|
" cpu_speed=%u\n", si.min_sampl_rate, si.max_sampl_rate,
|
||||||
|
si.cpu_speed);
|
||||||
|
if (si.as)
|
||||||
|
seq_printf(m, "CPU-MF: Sampling facility: mode=basic"
|
||||||
|
" sample_size=%u\n", si.bsdes);
|
||||||
|
if (si.ad)
|
||||||
|
seq_printf(m, "CPU-MF: Sampling facility: mode=diagnostic"
|
||||||
|
" sample_size=%u\n", si.dsdes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void service_level_perf_print(struct seq_file *m,
|
||||||
|
struct service_level *sl)
|
||||||
|
{
|
||||||
|
if (cpum_cf_avail())
|
||||||
|
sl_print_counter(m);
|
||||||
|
if (cpum_sf_avail())
|
||||||
|
sl_print_sampling(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct service_level service_level_perf = {
|
||||||
|
.seq_print = service_level_perf_print,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init service_level_perf_register(void)
|
||||||
|
{
|
||||||
|
return register_service_level(&service_level_perf);
|
||||||
|
}
|
||||||
|
arch_initcall(service_level_perf_register);
|
||||||
|
|
||||||
/* See also arch/s390/kernel/traps.c */
|
/* See also arch/s390/kernel/traps.c */
|
||||||
static unsigned long __store_trace(struct perf_callchain_entry *entry,
|
static unsigned long __store_trace(struct perf_callchain_entry *entry,
|
||||||
unsigned long sp,
|
unsigned long sp,
|
||||||
@@ -172,3 +281,44 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry,
|
|||||||
__store_trace(entry, head, S390_lowcore.thread_info,
|
__store_trace(entry, head, S390_lowcore.thread_info,
|
||||||
S390_lowcore.thread_info + THREAD_SIZE);
|
S390_lowcore.thread_info + THREAD_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Perf defintions for PMU event attributes in sysfs */
|
||||||
|
ssize_t cpumf_events_sysfs_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *page)
|
||||||
|
{
|
||||||
|
struct perf_pmu_events_attr *pmu_attr;
|
||||||
|
|
||||||
|
pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
|
||||||
|
return sprintf(page, "event=0x%04llx,name=%s\n",
|
||||||
|
pmu_attr->id, attr->attr.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reserve/release functions for sharing perf hardware */
|
||||||
|
static DEFINE_SPINLOCK(perf_hw_owner_lock);
|
||||||
|
static void *perf_sampling_owner;
|
||||||
|
|
||||||
|
int perf_reserve_sampling(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
spin_lock(&perf_hw_owner_lock);
|
||||||
|
if (perf_sampling_owner) {
|
||||||
|
pr_warn("The sampling facility is already reserved by %p\n",
|
||||||
|
perf_sampling_owner);
|
||||||
|
err = -EBUSY;
|
||||||
|
} else
|
||||||
|
perf_sampling_owner = __builtin_return_address(0);
|
||||||
|
spin_unlock(&perf_hw_owner_lock);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(perf_reserve_sampling);
|
||||||
|
|
||||||
|
void perf_release_sampling(void)
|
||||||
|
{
|
||||||
|
spin_lock(&perf_hw_owner_lock);
|
||||||
|
WARN_ON(!perf_sampling_owner);
|
||||||
|
perf_sampling_owner = NULL;
|
||||||
|
spin_unlock(&perf_hw_owner_lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(perf_release_sampling);
|
||||||
|
|||||||
@@ -261,20 +261,18 @@ static inline unsigned long brk_rnd(void)
|
|||||||
|
|
||||||
unsigned long arch_randomize_brk(struct mm_struct *mm)
|
unsigned long arch_randomize_brk(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
|
unsigned long ret;
|
||||||
|
|
||||||
if (ret < mm->brk)
|
ret = PAGE_ALIGN(mm->brk + brk_rnd());
|
||||||
return mm->brk;
|
return (ret > mm->brk) ? ret : mm->brk;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long randomize_et_dyn(unsigned long base)
|
unsigned long randomize_et_dyn(unsigned long base)
|
||||||
{
|
{
|
||||||
unsigned long ret = PAGE_ALIGN(base + brk_rnd());
|
unsigned long ret;
|
||||||
|
|
||||||
if (!(current->flags & PF_RANDOMIZE))
|
if (!(current->flags & PF_RANDOMIZE))
|
||||||
return base;
|
return base;
|
||||||
if (ret < base)
|
ret = PAGE_ALIGN(base + brk_rnd());
|
||||||
return base;
|
return (ret > base) ? ret : base;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-15
@@ -56,25 +56,26 @@ void update_cr_regs(struct task_struct *task)
|
|||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
/* Take care of the enable/disable of transactional execution. */
|
/* Take care of the enable/disable of transactional execution. */
|
||||||
if (MACHINE_HAS_TE) {
|
if (MACHINE_HAS_TE) {
|
||||||
unsigned long cr[3], cr_new[3];
|
unsigned long cr, cr_new;
|
||||||
|
|
||||||
__ctl_store(cr, 0, 2);
|
__ctl_store(cr, 0, 0);
|
||||||
cr_new[1] = cr[1];
|
|
||||||
/* Set or clear transaction execution TXC bit 8. */
|
/* Set or clear transaction execution TXC bit 8. */
|
||||||
|
cr_new = cr | (1UL << 55);
|
||||||
if (task->thread.per_flags & PER_FLAG_NO_TE)
|
if (task->thread.per_flags & PER_FLAG_NO_TE)
|
||||||
cr_new[0] = cr[0] & ~(1UL << 55);
|
cr_new &= ~(1UL << 55);
|
||||||
else
|
if (cr_new != cr)
|
||||||
cr_new[0] = cr[0] | (1UL << 55);
|
__ctl_load(cr, 0, 0);
|
||||||
/* Set or clear transaction execution TDC bits 62 and 63. */
|
/* Set or clear transaction execution TDC bits 62 and 63. */
|
||||||
cr_new[2] = cr[2] & ~3UL;
|
__ctl_store(cr, 2, 2);
|
||||||
|
cr_new = cr & ~3UL;
|
||||||
if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) {
|
if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) {
|
||||||
if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND)
|
if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND)
|
||||||
cr_new[2] |= 1UL;
|
cr_new |= 1UL;
|
||||||
else
|
else
|
||||||
cr_new[2] |= 2UL;
|
cr_new |= 2UL;
|
||||||
}
|
}
|
||||||
if (memcmp(&cr_new, &cr, sizeof(cr)))
|
if (cr_new != cr)
|
||||||
__ctl_load(cr_new, 0, 2);
|
__ctl_load(cr_new, 2, 2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Copy user specified PER registers */
|
/* Copy user specified PER registers */
|
||||||
@@ -107,15 +108,11 @@ void update_cr_regs(struct task_struct *task)
|
|||||||
void user_enable_single_step(struct task_struct *task)
|
void user_enable_single_step(struct task_struct *task)
|
||||||
{
|
{
|
||||||
set_tsk_thread_flag(task, TIF_SINGLE_STEP);
|
set_tsk_thread_flag(task, TIF_SINGLE_STEP);
|
||||||
if (task == current)
|
|
||||||
update_cr_regs(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void user_disable_single_step(struct task_struct *task)
|
void user_disable_single_step(struct task_struct *task)
|
||||||
{
|
{
|
||||||
clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
|
clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
|
||||||
if (task == current)
|
|
||||||
update_cr_regs(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#ifdef CONFIG_FUNCTION_TRACER
|
#ifdef CONFIG_FUNCTION_TRACER
|
||||||
EXPORT_SYMBOL(_mcount);
|
EXPORT_SYMBOL(_mcount);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
|
#if IS_ENABLED(CONFIG_KVM)
|
||||||
EXPORT_SYMBOL(sie64a);
|
EXPORT_SYMBOL(sie64a);
|
||||||
EXPORT_SYMBOL(sie_exit);
|
EXPORT_SYMBOL(sie_exit);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ static void __init setup_lowcore(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up PSW restart to call ipl.c:do_restart(). Copy the relevant
|
* Set up PSW restart to call ipl.c:do_restart(). Copy the relevant
|
||||||
* restart data to the absolute zero lowcore. This is necesary if
|
* restart data to the absolute zero lowcore. This is necessary if
|
||||||
* PSW restart is done on an offline CPU that has lowcore zero.
|
* PSW restart is done on an offline CPU that has lowcore zero.
|
||||||
*/
|
*/
|
||||||
lc->restart_stack = (unsigned long) restart_stack;
|
lc->restart_stack = (unsigned long) restart_stack;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user