mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
s390 fixes for 7.3-rc2
- Use jiffies instead of jiffies_64 to address a data-race reported by KCSAN - Unpoison cpacf instruction results to address KMSAN reports - Drop unused member from ap_device_id - Fix potential NULL pointer dereferences in IPL code - Add missing length check to SCLP error report handling - Add missing length check to zcrypt CCA code - Fix return code handling in diag324 code - Handle multiple PMU stop callback invocations in perf pai code correctly - Reduce excessive debug feature size in perf pai code from 32 MiB to 4KiB - Switch to common CPU capacity code in topology code to get rid of few lines of code - Address various bugs in corner cases in boot code - Simplify/Rework crst_table_upgrade() to address a potential NULL pointer dereference in case of an allocation failure - Initialize padding bytes in CRT key structure in zcrypt code -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEECMNfWEw3SLnmiLkZIg7DeRspbsIFAmqZpREACgkQIg7DeRsp bsImgxAAqulDVrRQjCWBEG3PkC9/JNyyOhVmWW688hGS3n6zGTqsw/8791u4RB3S JepdWVPd9xs+xRKClSbdUHVAlr1A7zC8oczPPOji08DlXfbaQeUXXB9Dtt6ah5Eo CvHKzCO6MWNh2XpQ1g+LTAUWuXrLuhWF8c7VDC4iijXniEL6SFpnsrTWCyW8erlZ Tm6uP4K2xb6GQzMXmDcFH0SRao+EZD0n/CRp4dVOXOudO2v02BXMskTZEnzlnDNj FiDGm6HGUKZJrjYdq/YWfWH0N2wIz/IiyX86lsSQft4rLvxvI494EqNtkyAJK8X+ UgjM7+p2iYfXDfSMUmvqi8u3p9aq65y6w9lS3W8rI2VJ8wJBSOrElBU0UlRyTxQX bCAcYkdTW+/euaceqCgiMhevYMwJ2K1BA8f2Ob3ChI8MC1HkF9xnQ6cZOpJjaj4l imAv8mthWvacyV/33aNv0V/pS2CeLhdNnGfIB8KaHZIQxnmv44wuFNEvbyuSMOx8 GnwFF0zG6c4x/6BSXDgfoWFOVVhdxkZf1PVywwREwNJcyuTslhQ4jyl/NrDl1cMQ +vlKAqm0tuleNq4oIfWlEl2eocheFe97GjtV0Db66jkNCtnHVz1v21VIx3UgDcFB lHOW/BwM9e7jDa6SheGfTHHcPgw+PLPZXyLlasucAma5xkPqY48= =LHgC -----END PGP SIGNATURE----- Merge tag 's390-7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux Pull s390 fixes from Heiko Carstens: - Use jiffies instead of jiffies_64 to address a data-race reported by KCSAN - Unpoison cpacf instruction results to address KMSAN reports - Drop unused member from ap_device_id - Fix potential NULL pointer dereferences in IPL code - Add missing length check to SCLP error report handling - Add missing length check to zcrypt CCA code - Fix return code handling in diag324 code - Handle multiple PMU stop callback invocations in perf pai code correctly - Reduce excessive debug feature size in perf pai code from 32 MiB to 4KiB - Switch to common CPU capacity code in topology code to get rid of few lines of code - Address various bugs in corner cases in boot code - Simplify/Rework crst_table_upgrade() to address a potential NULL pointer dereference in case of an allocation failure - Initialize padding bytes in CRT key structure in zcrypt code * tag 's390-7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/zcrypt: Fix uninitialized padding in CRT key structure s390/mm: Simplify crst_table_upgrade() s390/boot: Bound command line facility ranges s390/boot: Avoid IPL parameter append past command line s390/boot: Fix physical memory search range s390/topology: Switch to common cpu capacity code s390/pai: Reduce excessive debug feature size s390/pai: Handle multiple PMU stop callback invocations s390/diag324: Preserve -EBUSY return code s390/zcrypt: Validate length in reply before using it s390/pci: Fix leak of uninitialized kernel data in SCLP report s390/ipl: Fix NULL deref in dump_reipl without re-IPL parm block s390/ipl: Fix NULL deref in kdump without re-IPL parm block s390/ap: Drop unused member from ap_device_id s390/cpacf: Unpoison instruction results s390/time: Use jiffies instead of jiffies_64
This commit is contained in:
commit
841e384b84
|
|
@ -45,11 +45,12 @@ static void alt_debug_modify(int type, unsigned int nr, bool clear)
|
|||
|
||||
static char *alt_debug_parse(int type, char *str)
|
||||
{
|
||||
unsigned long val, endval;
|
||||
unsigned long val, endval, limit;
|
||||
char *endp;
|
||||
bool clear;
|
||||
int i;
|
||||
|
||||
limit = type == ALT_TYPE_FACILITY ? MAX_FACILITY_BIT : MAX_MFEATURE_BIT;
|
||||
if (*str == ':') {
|
||||
str++;
|
||||
} else {
|
||||
|
|
@ -73,7 +74,7 @@ static char *alt_debug_parse(int type, char *str)
|
|||
if (str == endp)
|
||||
break;
|
||||
str = endp;
|
||||
while (val <= endval) {
|
||||
while (val <= endval && val < limit) {
|
||||
alt_debug_modify(type, val, clear);
|
||||
val++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ struct parmarea parmarea __section(".parmarea") = {
|
|||
};
|
||||
|
||||
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
|
||||
static char command_line_buf[COMMAND_LINE_SIZE];
|
||||
|
||||
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
|
||||
struct ipl_parameter_block __bootdata_preserved(ipl_block);
|
||||
|
|
@ -135,31 +136,29 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
|
|||
|
||||
static void append_ipl_block_parm(void)
|
||||
{
|
||||
char *parm, *delim;
|
||||
size_t len, rc = 0;
|
||||
size_t len, extra = 0;
|
||||
char *delim;
|
||||
|
||||
len = strlen(early_command_line);
|
||||
|
||||
delim = early_command_line + len; /* '\0' character position */
|
||||
parm = early_command_line + len + 1; /* append right after '\0' */
|
||||
delim = early_command_line + len; /* '\0' character position */
|
||||
|
||||
switch (ipl_block.pb0_hdr.pbt) {
|
||||
case IPL_PBT_CCW:
|
||||
rc = ipl_block_get_ascii_vmparm(
|
||||
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
|
||||
extra = ipl_block_get_ascii_vmparm(command_line_buf, sizeof(command_line_buf), &ipl_block);
|
||||
break;
|
||||
case IPL_PBT_FCP:
|
||||
case IPL_PBT_NVME:
|
||||
case IPL_PBT_ECKD:
|
||||
rc = ipl_block_get_ascii_scpdata(
|
||||
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
|
||||
extra = ipl_block_get_ascii_scpdata(command_line_buf, sizeof(command_line_buf), &ipl_block);
|
||||
break;
|
||||
}
|
||||
if (rc) {
|
||||
if (*parm == '=')
|
||||
memmove(early_command_line, parm + 1, rc);
|
||||
else
|
||||
if (extra) {
|
||||
if (command_line_buf[0] == '=') {
|
||||
memmove(early_command_line, command_line_buf + 1, extra);
|
||||
} else if (len < COMMAND_LINE_SIZE - 2) {
|
||||
*delim = ' '; /* replace '\0' with space */
|
||||
sized_strscpy(delim + 1, command_line_buf, COMMAND_LINE_SIZE - len - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +230,7 @@ static void modify_fac_list(char *str)
|
|||
if (str == endp)
|
||||
break;
|
||||
str = endp;
|
||||
while (val <= endval) {
|
||||
while (val <= endval && val < MAX_FACILITY_BIT) {
|
||||
modify_facility(val, clear);
|
||||
val++;
|
||||
}
|
||||
|
|
@ -245,7 +244,6 @@ static void modify_fac_list(char *str)
|
|||
check_cleared_facilities();
|
||||
}
|
||||
|
||||
static char command_line_buf[COMMAND_LINE_SIZE];
|
||||
void parse_boot_command_line(void)
|
||||
{
|
||||
char *param, *val;
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ static int tprot(unsigned long addr)
|
|||
|
||||
static unsigned long search_mem_end(void)
|
||||
{
|
||||
unsigned long range = 1 << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
|
||||
unsigned long range = 1UL << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
|
||||
unsigned long offset = 0;
|
||||
unsigned long pivot;
|
||||
|
||||
|
|
|
|||
|
|
@ -301,6 +301,7 @@ static __always_inline void __cpacf_query(unsigned int opcode,
|
|||
cpacf_mask_t *mask)
|
||||
{
|
||||
__cpacf_query_insn(opcode, mask, CPACF_FC_QUERY);
|
||||
kmsan_unpoison_memory(mask, sizeof(*mask));
|
||||
}
|
||||
|
||||
static __always_inline int __cpacf_check_opcode(unsigned int opcode)
|
||||
|
|
@ -370,6 +371,7 @@ static __always_inline int cpacf_query_func(unsigned int opcode,
|
|||
static __always_inline void __cpacf_qai(unsigned int opcode, cpacf_qai_t *qai)
|
||||
{
|
||||
__cpacf_query_insn(opcode, qai, CPACF_FC_QUERY_AUTH_INFO);
|
||||
kmsan_unpoison_memory(qai, sizeof(*qai));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -422,6 +424,7 @@ static inline int cpacf_km(unsigned long func, void *param,
|
|||
[opc] "i" (CPACF_KM)
|
||||
: "cc", "memory", "0", "1");
|
||||
|
||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
||||
return src_len - s.odd;
|
||||
}
|
||||
|
||||
|
|
@ -454,6 +457,7 @@ static inline int cpacf_kmc(unsigned long func, void *param,
|
|||
[opc] "i" (CPACF_KMC)
|
||||
: "cc", "memory", "0", "1");
|
||||
|
||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
||||
return src_len - s.odd;
|
||||
}
|
||||
|
||||
|
|
@ -587,6 +591,7 @@ static inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
|
|||
[opc] "i" (CPACF_KMCTR)
|
||||
: "cc", "memory", "0", "1");
|
||||
|
||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
||||
return src_len - s.odd;
|
||||
}
|
||||
|
||||
|
|
@ -619,6 +624,7 @@ static inline void cpacf_prno(unsigned long func, void *param,
|
|||
: [fc] "d" (func), [pba] "d" ((unsigned long)param),
|
||||
[seed] "d" (s.pair), [opc] "i" (CPACF_PRNO)
|
||||
: "cc", "memory", "0", "1");
|
||||
kmsan_unpoison_memory(dest, dest_len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ struct pcpu {
|
|||
unsigned long ec_mask; /* bit mask for ec_xxx functions */
|
||||
unsigned long ec_clk; /* sigp timestamp for ec_xxx */
|
||||
unsigned long flags; /* per CPU flags */
|
||||
unsigned long capacity; /* cpu capacity for scheduler */
|
||||
signed char state; /* physical cpu state */
|
||||
signed char polarization; /* physical polarization */
|
||||
u16 address; /* physical cpu address */
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static __always_inline unsigned int raw_smp_processor_id(void)
|
|||
return cpu;
|
||||
}
|
||||
|
||||
#define arch_scale_cpu_capacity smp_cpu_get_capacity
|
||||
#define arch_scale_cpu_capacity topology_get_cpu_scale
|
||||
|
||||
extern struct mutex smp_cpu_state_mutex;
|
||||
extern unsigned int smp_cpu_mt_shift;
|
||||
|
|
@ -53,9 +53,7 @@ extern void smp_save_dump_secondary_cpus(void);
|
|||
extern void smp_yield_cpu(int cpu);
|
||||
extern void smp_cpu_set_polarization(int cpu, int val);
|
||||
extern int smp_cpu_get_polarization(int cpu);
|
||||
extern void smp_cpu_set_capacity(int cpu, unsigned long val);
|
||||
extern void smp_set_core_capacity(int cpu, unsigned long val);
|
||||
extern unsigned long smp_cpu_get_capacity(int cpu);
|
||||
extern int smp_cpu_get_cpu_address(int cpu);
|
||||
extern void smp_fill_possible_mask(void);
|
||||
extern void smp_detect_cpus(void);
|
||||
|
|
|
|||
|
|
@ -182,8 +182,7 @@ long diag324_pibbuf(unsigned long arg)
|
|||
goto out;
|
||||
rc = copy_to_user((void __user *)address, data->pib, data->pib->len);
|
||||
rc |= put_user(data->sequence, &udata->sequence);
|
||||
if (rc)
|
||||
rc = -EFAULT;
|
||||
rc = rc ? -EFAULT : data->rc;
|
||||
out:
|
||||
mutex_unlock(&pibmutex);
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -1157,6 +1157,8 @@ static struct attribute_group reipl_nss_attr_group = {
|
|||
|
||||
void set_os_info_reipl_block(void)
|
||||
{
|
||||
if (!reipl_block_actual)
|
||||
return;
|
||||
os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
|
||||
reipl_block_actual->hdr.len);
|
||||
}
|
||||
|
|
@ -1927,7 +1929,8 @@ static struct shutdown_action __refdata dump_action = {
|
|||
static void dump_reipl_run(struct shutdown_trigger *trigger)
|
||||
{
|
||||
struct lowcore *abs_lc;
|
||||
unsigned int csum;
|
||||
unsigned long ipib = 0;
|
||||
unsigned int csum = 0;
|
||||
|
||||
/*
|
||||
* Set REIPL_CLEAR flag in os_info flags entry indicating
|
||||
|
|
@ -1943,9 +1946,12 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
|
|||
reipl_type == IPL_TYPE_UNKNOWN)
|
||||
os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
|
||||
os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
|
||||
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
|
||||
if (reipl_block_actual) {
|
||||
ipib = __pa(reipl_block_actual);
|
||||
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
|
||||
}
|
||||
abs_lc = get_abs_lowcore();
|
||||
abs_lc->ipib = __pa(reipl_block_actual);
|
||||
abs_lc->ipib = ipib;
|
||||
abs_lc->ipib_checksum = csum;
|
||||
put_abs_lowcore(abs_lc);
|
||||
dump_run(trigger);
|
||||
|
|
|
|||
|
|
@ -464,6 +464,7 @@ static void pai_start(struct perf_event *event, int flags,
|
|||
cpump->event = event;
|
||||
}
|
||||
}
|
||||
event->hw.state &= ~PERF_HES_STOPPED;
|
||||
}
|
||||
|
||||
static void paicrypt_start(struct perf_event *event, int flags)
|
||||
|
|
@ -510,6 +511,13 @@ static void pai_stop(struct perf_event *event, int flags)
|
|||
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
|
||||
struct pai_map *cpump = mp->mapptr;
|
||||
|
||||
/* Cope with multiple invocations:
|
||||
* 1. perf_event_throttle() --> PMU->stop()
|
||||
* 2. task schedules out --> PMU->stop()
|
||||
* Check for event already stopped.
|
||||
*/
|
||||
if (event->hw.state & PERF_HES_STOPPED)
|
||||
return;
|
||||
if (!event->attr.sample_period) { /* Counting */
|
||||
pai_pmu[idx].pmu->read(event);
|
||||
} else { /* Sampling */
|
||||
|
|
@ -672,9 +680,9 @@ static void pai_have_samples(int idx)
|
|||
{
|
||||
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
|
||||
struct pai_map *cpump = mp->mapptr;
|
||||
struct perf_event *event;
|
||||
struct perf_event *event, *e2;
|
||||
|
||||
list_for_each_entry(event, &cpump->syswide_list, hw.tp_list)
|
||||
list_for_each_entry_safe(event, e2, &cpump->syswide_list, hw.tp_list)
|
||||
pai_have_sample(event, cpump);
|
||||
}
|
||||
|
||||
|
|
@ -691,6 +699,17 @@ static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx,
|
|||
pai_have_samples(PAI_PMU_CRYPTO);
|
||||
}
|
||||
|
||||
/* Prevent ioctl(fd, PERF_EVENT_IOC_PERIOD, ...) call.
|
||||
* It sets perf_event::event_limit to a positive value and causes
|
||||
* perf_event_overflow() to invoke pai_stop() call back function when
|
||||
* perf_event::event_limit hits zero. This is not supported because the
|
||||
* sample events CRYPTO_ALL and NNPA_ALL are always taken at schedule out
|
||||
* of a task.
|
||||
*/
|
||||
static int pai_check_period(struct perf_event *event, u64 value)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
/* ============================= paiext ====================================*/
|
||||
|
||||
static void paiext_event_destroy(struct perf_event *event)
|
||||
|
|
@ -804,6 +823,7 @@ static struct pmu paicrypt = {
|
|||
.stop = paicrypt_stop,
|
||||
.read = paicrypt_read,
|
||||
.sched_task = paicrypt_sched_task,
|
||||
.check_period = pai_check_period,
|
||||
.attr_groups = paicrypt_attr_groups
|
||||
};
|
||||
|
||||
|
|
@ -1015,6 +1035,7 @@ static struct pmu paiext = {
|
|||
.stop = paiext_stop,
|
||||
.read = paiext_read,
|
||||
.sched_task = paiext_sched_task,
|
||||
.check_period = pai_check_period,
|
||||
.attr_groups = paiext_attr_groups,
|
||||
};
|
||||
|
||||
|
|
@ -1221,7 +1242,7 @@ static int __init paipmu_setup(void)
|
|||
static int __init pai_init(void)
|
||||
{
|
||||
/* Setup s390dbf facility */
|
||||
paidbg = debug_register("pai", 32, 256, 128);
|
||||
paidbg = debug_register("pai", 1, 1, 128);
|
||||
if (!paidbg) {
|
||||
pr_err("Registration of s390dbf pai failed\n");
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -659,23 +659,13 @@ int smp_cpu_get_polarization(int cpu)
|
|||
return per_cpu(pcpu_devices, cpu).polarization;
|
||||
}
|
||||
|
||||
void smp_cpu_set_capacity(int cpu, unsigned long val)
|
||||
{
|
||||
per_cpu(pcpu_devices, cpu).capacity = val;
|
||||
}
|
||||
|
||||
unsigned long smp_cpu_get_capacity(int cpu)
|
||||
{
|
||||
return per_cpu(pcpu_devices, cpu).capacity;
|
||||
}
|
||||
|
||||
void smp_set_core_capacity(int cpu, unsigned long val)
|
||||
{
|
||||
int i;
|
||||
|
||||
cpu = smp_get_base_cpu(cpu);
|
||||
for (i = cpu; (i <= cpu + smp_cpu_mtid) && (i < nr_cpu_ids); i++)
|
||||
smp_cpu_set_capacity(i, val);
|
||||
topology_set_cpu_scale(i, val);
|
||||
}
|
||||
|
||||
int smp_cpu_get_cpu_address(int cpu)
|
||||
|
|
@ -727,7 +717,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
|
|||
else
|
||||
pcpu->state = CPU_STATE_STANDBY;
|
||||
smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
|
||||
smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
|
||||
topology_set_cpu_scale(cpu, CPU_CAPACITY_HIGH);
|
||||
set_cpu_present(cpu, true);
|
||||
if (!early && arch_register_cpu(cpu))
|
||||
set_cpu_present(cpu, false);
|
||||
|
|
@ -967,7 +957,7 @@ void __init smp_prepare_boot_cpu(void)
|
|||
ipl_pcpu->state = CPU_STATE_CONFIGURED;
|
||||
lc->pcpu = (unsigned long)ipl_pcpu;
|
||||
smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
|
||||
smp_cpu_set_capacity(0, CPU_CAPACITY_HIGH);
|
||||
topology_set_cpu_scale(0, CPU_CAPACITY_HIGH);
|
||||
}
|
||||
|
||||
void __init smp_setup_processor_id(void)
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ static void add_cpus_to_mask(struct topology_core *tl_core,
|
|||
cpumask_set_cpu(cpu, &book->mask);
|
||||
cpumask_set_cpu(cpu, &socket->mask);
|
||||
smp_cpu_set_polarization(cpu, tl_core->pp);
|
||||
smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
|
||||
topology_set_cpu_scale(cpu, CPU_CAPACITY_HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ static atomic64_t virt_timer_elapsed;
|
|||
DEFINE_PER_CPU(u64, mt_cycles[8]);
|
||||
static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
|
||||
static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
|
||||
static DEFINE_PER_CPU(u64, mt_scaling_jiffies);
|
||||
static DEFINE_PER_CPU(unsigned long, mt_scaling_jiffies);
|
||||
|
||||
static inline void set_vtimer(u64 expires)
|
||||
{
|
||||
|
|
@ -81,7 +81,7 @@ static void update_mt_scaling(void)
|
|||
memcpy(cycles_old, cycles_new,
|
||||
sizeof(u64) * (smp_cpu_mtid + 1));
|
||||
}
|
||||
__this_cpu_write(mt_scaling_jiffies, jiffies_64);
|
||||
__this_cpu_write(mt_scaling_jiffies, jiffies);
|
||||
}
|
||||
|
||||
static inline u64 update_tsk_timer(unsigned long *tsk_vtime, u64 new)
|
||||
|
|
@ -144,7 +144,7 @@ static int do_account_vtime(struct task_struct *tsk)
|
|||
lc->system_timer += timer;
|
||||
|
||||
/* Update MT utilization calculation */
|
||||
if (smp_cpu_mtid && time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies)))
|
||||
if (smp_cpu_mtid && time_after(jiffies, __this_cpu_read(mt_scaling_jiffies)))
|
||||
update_mt_scaling();
|
||||
|
||||
/* Calculate cputime delta */
|
||||
|
|
|
|||
|
|
@ -55,63 +55,46 @@ static void __crst_table_upgrade(void *arg)
|
|||
|
||||
int crst_table_upgrade(struct mm_struct *mm, unsigned long end)
|
||||
{
|
||||
unsigned long *pgd = NULL, *p4d = NULL, *__pgd;
|
||||
unsigned long asce_limit = mm->context.asce_limit;
|
||||
unsigned long *table, *pgd;
|
||||
int rc, notify;
|
||||
|
||||
mmap_assert_write_locked(mm);
|
||||
|
||||
/* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */
|
||||
VM_BUG_ON(asce_limit < _REGION2_SIZE);
|
||||
|
||||
if (end <= asce_limit)
|
||||
return 0;
|
||||
|
||||
if (asce_limit == _REGION2_SIZE) {
|
||||
p4d = crst_table_alloc(mm);
|
||||
if (unlikely(!p4d))
|
||||
goto err_p4d;
|
||||
crst_table_init(p4d, _REGION2_ENTRY_EMPTY);
|
||||
pagetable_p4d_ctor(virt_to_ptdesc(p4d));
|
||||
VM_BUG_ON(mm->context.asce_limit < _REGION2_SIZE);
|
||||
rc = 0;
|
||||
notify = 0;
|
||||
while (mm->context.asce_limit < end) {
|
||||
table = crst_table_alloc(mm);
|
||||
if (!table) {
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
spin_lock_bh(&mm->page_table_lock);
|
||||
pgd = (unsigned long *)mm->pgd;
|
||||
if (mm->context.asce_limit == _REGION2_SIZE) {
|
||||
crst_table_init(table, _REGION2_ENTRY_EMPTY);
|
||||
p4d_populate(mm, (p4d_t *)table, (pud_t *)pgd);
|
||||
pagetable_p4d_ctor(virt_to_ptdesc(table));
|
||||
mm->pgd = (pgd_t *)table;
|
||||
mm->context.asce_limit = _REGION1_SIZE;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
||||
mm_inc_nr_puds(mm);
|
||||
} else {
|
||||
crst_table_init(table, _REGION1_ENTRY_EMPTY);
|
||||
pgd_populate(mm, (pgd_t *)table, (p4d_t *)pgd);
|
||||
pagetable_pgd_ctor(virt_to_ptdesc(table));
|
||||
mm->pgd = (pgd_t *)table;
|
||||
mm->context.asce_limit = TASK_SIZE_MAX;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
|
||||
}
|
||||
notify = 1;
|
||||
spin_unlock_bh(&mm->page_table_lock);
|
||||
}
|
||||
if (end > _REGION1_SIZE) {
|
||||
pgd = crst_table_alloc(mm);
|
||||
if (unlikely(!pgd))
|
||||
goto err_pgd;
|
||||
crst_table_init(pgd, _REGION1_ENTRY_EMPTY);
|
||||
pagetable_pgd_ctor(virt_to_ptdesc(pgd));
|
||||
}
|
||||
|
||||
spin_lock_bh(&mm->page_table_lock);
|
||||
|
||||
if (p4d) {
|
||||
__pgd = (unsigned long *) mm->pgd;
|
||||
p4d_populate(mm, (p4d_t *) p4d, (pud_t *) __pgd);
|
||||
mm->pgd = (pgd_t *) p4d;
|
||||
mm->context.asce_limit = _REGION1_SIZE;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
||||
mm_inc_nr_puds(mm);
|
||||
}
|
||||
if (pgd) {
|
||||
__pgd = (unsigned long *) mm->pgd;
|
||||
pgd_populate(mm, (pgd_t *) pgd, (p4d_t *) __pgd);
|
||||
mm->pgd = (pgd_t *) pgd;
|
||||
mm->context.asce_limit = TASK_SIZE_MAX;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&mm->page_table_lock);
|
||||
|
||||
on_each_cpu(__crst_table_upgrade, mm, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
err_pgd:
|
||||
pagetable_dtor(virt_to_ptdesc(p4d));
|
||||
crst_table_free(mm, p4d);
|
||||
err_p4d:
|
||||
return -ENOMEM;
|
||||
if (notify)
|
||||
on_each_cpu(__crst_table_upgrade, mm, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
unsigned long *page_table_alloc_noprof(struct mm_struct *mm)
|
||||
|
|
|
|||
|
|
@ -153,6 +153,9 @@ static ssize_t report_error_write(struct file *filp, struct kobject *kobj,
|
|||
if (off || (count < sizeof(*report)))
|
||||
return -EINVAL;
|
||||
|
||||
if (count < (report->length + sizeof(*report)))
|
||||
return -EINVAL;
|
||||
|
||||
ret = sclp_pci_report(report, zdev->fh, zdev->fid);
|
||||
|
||||
return ret ? ret : count;
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p)
|
|||
copy_from_user(key->key_parts + 2 * long_len + 2 * short_len,
|
||||
crt->u_mult_inv, long_len))
|
||||
return -EFAULT;
|
||||
memset(key->key_parts + 3 * long_len + 2 * short_len, 0, pad_len);
|
||||
memset(key->key_parts + 3 * long_len + 2 * short_len + pad_len,
|
||||
0xff, crt->inputdatalength);
|
||||
pub = (struct cca_public_sec *)(key->key_parts + key_len);
|
||||
|
|
|
|||
|
|
@ -1158,8 +1158,21 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
|
|||
|
||||
/* do not check the key here, it may be incomplete */
|
||||
|
||||
/* copy the vlsc key token back */
|
||||
/*
|
||||
* Copy the vlsc key token back.
|
||||
* The available space in the destination (key_token) and the source
|
||||
* (t) buffer is always larger as the valid range of prepparm->kb.len.
|
||||
* Validate t->len by comparing it with the length information in the
|
||||
* param block of the request (prepparm->kb.len)
|
||||
* The value range of prepparm->kb.len has been checked above.
|
||||
*/
|
||||
t = (struct cipherkeytoken *)prepparm->kb.tlv1.key_token;
|
||||
if (t->len != prepparm->kb.len - 3 * sizeof(uint16_t)) {
|
||||
ZCRYPT_DBF_ERR("%s reply with invalid key_token length %u\n",
|
||||
__func__, t->len);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
memcpy(key_token, t, t->len);
|
||||
*key_token_size = t->len;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/types.h>
|
||||
typedef unsigned long kernel_ulong_t;
|
||||
#endif
|
||||
|
||||
#define AP_DEVICE_ID_MATCH_CARD_TYPE 0x01
|
||||
|
|
@ -14,7 +13,6 @@ typedef unsigned long kernel_ulong_t;
|
|||
struct ap_device_id {
|
||||
__u16 match_flags; /* which fields to match against */
|
||||
__u8 dev_type; /* device type */
|
||||
kernel_ulong_t driver_info;
|
||||
};
|
||||
|
||||
#endif /* ifndef LINUX_DEVICE_ID_AP_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user