Skip to content

Commit

Permalink
Merge tag 'powerpc-5.16-2' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/powerpc/linux

Pull more powerpc fixes from Michael Ellerman:

 - Fix a bug in copying of sigset_t for 32-bit systems, which caused X
   to not start.

 - Fix handling of shared LSIs (rare) with the xive interrupt controller
   (Power9/10).

 - Fix missing TOC setup in some KVM code, which could result in oopses
   depending on kernel data layout.

 - Fix DMA mapping when we have persistent memory and only one DMA
   window available.

 - Fix further problems with STRICT_KERNEL_RWX on 8xx, exposed by a
   recent fix.

 - A couple of other minor fixes.

Thanks to Alexey Kardashevskiy, Aneesh Kumar K.V, Cédric Le Goater,
Christian Zigotzky, Christophe Leroy, Daniel Axtens, Finn Thain, Greg
Kurz, Masahiro Yamada, Nicholas Piggin, and Uwe Kleine-König.

* tag 'powerpc-5.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/xive: Change IRQ domain to a tree domain
  powerpc/8xx: Fix pinned TLBs with CONFIG_STRICT_KERNEL_RWX
  powerpc/signal32: Fix sigset_t copy
  powerpc/book3e: Fix TLBCAM preset at boot
  powerpc/pseries/ddw: Do not try direct mapping with persistent memory and one window
  powerpc/pseries/ddw: simplify enable_ddw()
  powerpc/pseries/ddw: Revert "Extend upper limit for huge DMA window for persistent memory"
  powerpc/pseries: Fix numa FORM2 parsing fallback code
  powerpc/pseries: rename numa_dist_table to form2_distances
  powerpc: clean vdso32 and vdso64 directories
  powerpc/83xx/mpc8349emitx: Drop unused variable
  KVM: PPC: Book3S HV: Use GLOBAL_TOC for kvmppc_h_set_dabr/xdabr()
  • Loading branch information
Linus Torvalds committed Nov 21, 2021
2 parents 61eb495 + 8e80a73 commit 75603b1
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 59 deletions.
3 changes: 3 additions & 0 deletions arch/powerpc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,6 @@ clean-files := vmlinux.lds
# Force dependency (incbin is bad)
$(obj)/vdso32_wrapper.o : $(obj)/vdso32/vdso32.so.dbg
$(obj)/vdso64_wrapper.o : $(obj)/vdso64/vdso64.so.dbg

# for cleaning
subdir- += vdso32 vdso64
13 changes: 7 additions & 6 deletions arch/powerpc/kernel/head_8xx.S
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@ _GLOBAL(mmu_pin_tlb)
#ifdef CONFIG_PIN_TLB_DATA
LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET)
LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED)
li r8, 0
#ifdef CONFIG_PIN_TLB_IMMR
li r0, 3
#else
Expand All @@ -741,26 +742,26 @@ _GLOBAL(mmu_pin_tlb)
mtctr r0
cmpwi r4, 0
beq 4f
LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
LOAD_REG_ADDR(r9, _sinittext)

2: ori r0, r6, MD_EVALID
ori r12, r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT
mtspr SPRN_MD_CTR, r5
mtspr SPRN_MD_EPN, r0
mtspr SPRN_MD_TWC, r7
mtspr SPRN_MD_RPN, r8
mtspr SPRN_MD_RPN, r12
addi r5, r5, 0x100
addis r6, r6, SZ_8M@h
addis r8, r8, SZ_8M@h
cmplw r6, r9
bdnzt lt, 2b

4: LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
4:
2: ori r0, r6, MD_EVALID
ori r12, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT
mtspr SPRN_MD_CTR, r5
mtspr SPRN_MD_EPN, r0
mtspr SPRN_MD_TWC, r7
mtspr SPRN_MD_RPN, r8
mtspr SPRN_MD_RPN, r12
addi r5, r5, 0x100
addis r6, r6, SZ_8M@h
addis r8, r8, SZ_8M@h
Expand All @@ -781,7 +782,7 @@ _GLOBAL(mmu_pin_tlb)
#endif
#if defined(CONFIG_PIN_TLB_IMMR) || defined(CONFIG_PIN_TLB_DATA)
lis r0, (MD_RSV4I | MD_TWAM)@h
mtspr SPRN_MI_CTR, r0
mtspr SPRN_MD_CTR, r0
#endif
mtspr SPRN_SRR1, r10
mtspr SPRN_SRR0, r11
Expand Down
10 changes: 8 additions & 2 deletions arch/powerpc/kernel/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src)

return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]);
}
#define unsafe_get_user_sigset(dst, src, label) \
unsafe_get_user((dst)->sig[0], (u64 __user *)&(src)->sig[0], label)
#define unsafe_get_user_sigset(dst, src, label) do { \
sigset_t *__dst = dst; \
const sigset_t __user *__src = src; \
int i; \
\
for (i = 0; i < _NSIG_WORDS; i++) \
unsafe_get_user(__dst->sig[i], &__src->sig[i], label); \
} while (0)

#ifdef CONFIG_VSX
extern unsigned long copy_vsx_to_user(void __user *to,
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/kvm/book3s_hv_rmhandlers.S
Original file line number Diff line number Diff line change
Expand Up @@ -2005,7 +2005,7 @@ hcall_real_table:
.globl hcall_real_table_end
hcall_real_table_end:

_GLOBAL(kvmppc_h_set_xdabr)
_GLOBAL_TOC(kvmppc_h_set_xdabr)
EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr)
andi. r0, r5, DABRX_USER | DABRX_KERNEL
beq 6f
Expand All @@ -2015,7 +2015,7 @@ EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr)
6: li r3, H_PARAMETER
blr

_GLOBAL(kvmppc_h_set_dabr)
_GLOBAL_TOC(kvmppc_h_set_dabr)
EXPORT_SYMBOL_GPL(kvmppc_h_set_dabr)
li r5, DABRX_USER | DABRX_KERNEL
3:
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/mm/nohash/kaslr_booke.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ static unsigned long __init kaslr_choose_location(void *dt_ptr, phys_addr_t size
pr_warn("KASLR: No safe seed for randomizing the kernel base.\n");

ram = min_t(phys_addr_t, __max_low_memory, size);
ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true, false);
ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true, true);
linear_sz = min_t(unsigned long, ram, SZ_512M);

/* If the linear size is smaller than 64M, do not randmize */
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/mm/nohash/tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ static void early_init_this_mmu(void)

if (map)
linear_map_top = map_mem_in_cams(linear_map_top,
num_cams, true, true);
num_cams, false, true);
}
#endif

Expand Down Expand Up @@ -766,7 +766,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;

linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
false, true);
true, true);

ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
} else
Expand Down
44 changes: 20 additions & 24 deletions arch/powerpc/mm/numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,9 +376,9 @@ static void initialize_form2_numa_distance_lookup_table(void)
{
int i, j;
struct device_node *root;
const __u8 *numa_dist_table;
const __u8 *form2_distances;
const __be32 *numa_lookup_index;
int numa_dist_table_length;
int form2_distances_length;
int max_numa_index, distance_index;

if (firmware_has_feature(FW_FEATURE_OPAL))
Expand All @@ -392,45 +392,41 @@ static void initialize_form2_numa_distance_lookup_table(void)
max_numa_index = of_read_number(&numa_lookup_index[0], 1);

/* first element of the array is the size and is encode-int */
numa_dist_table = of_get_property(root, "ibm,numa-distance-table", NULL);
numa_dist_table_length = of_read_number((const __be32 *)&numa_dist_table[0], 1);
form2_distances = of_get_property(root, "ibm,numa-distance-table", NULL);
form2_distances_length = of_read_number((const __be32 *)&form2_distances[0], 1);
/* Skip the size which is encoded int */
numa_dist_table += sizeof(__be32);
form2_distances += sizeof(__be32);

pr_debug("numa_dist_table_len = %d, numa_dist_indexes_len = %d\n",
numa_dist_table_length, max_numa_index);
pr_debug("form2_distances_len = %d, numa_dist_indexes_len = %d\n",
form2_distances_length, max_numa_index);

for (i = 0; i < max_numa_index; i++)
/* +1 skip the max_numa_index in the property */
numa_id_index_table[i] = of_read_number(&numa_lookup_index[i + 1], 1);


if (numa_dist_table_length != max_numa_index * max_numa_index) {
if (form2_distances_length != max_numa_index * max_numa_index) {
WARN(1, "Wrong NUMA distance information\n");
/* consider everybody else just remote. */
for (i = 0; i < max_numa_index; i++) {
for (j = 0; j < max_numa_index; j++) {
int nodeA = numa_id_index_table[i];
int nodeB = numa_id_index_table[j];

if (nodeA == nodeB)
numa_distance_table[nodeA][nodeB] = LOCAL_DISTANCE;
else
numa_distance_table[nodeA][nodeB] = REMOTE_DISTANCE;
}
}
form2_distances = NULL; // don't use it
}

distance_index = 0;
for (i = 0; i < max_numa_index; i++) {
for (j = 0; j < max_numa_index; j++) {
int nodeA = numa_id_index_table[i];
int nodeB = numa_id_index_table[j];

numa_distance_table[nodeA][nodeB] = numa_dist_table[distance_index++];
pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, numa_distance_table[nodeA][nodeB]);
int dist;

if (form2_distances)
dist = form2_distances[distance_index++];
else if (nodeA == nodeB)
dist = LOCAL_DISTANCE;
else
dist = REMOTE_DISTANCE;
numa_distance_table[nodeA][nodeB] = dist;
pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, dist);
}
}

of_node_put(root);
}

Expand Down
1 change: 0 additions & 1 deletion arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ static int mcu_probe(struct i2c_client *client)
static int mcu_remove(struct i2c_client *client)
{
struct mcu *mcu = i2c_get_clientdata(client);
int ret;

kthread_stop(shutdown_thread);

Expand Down
26 changes: 8 additions & 18 deletions arch/powerpc/platforms/pseries/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1094,15 +1094,6 @@ static phys_addr_t ddw_memory_hotplug_max(void)
phys_addr_t max_addr = memory_hotplug_max();
struct device_node *memory;

/*
* The "ibm,pmemory" can appear anywhere in the address space.
* Assuming it is still backed by page structs, set the upper limit
* for the huge DMA window as MAX_PHYSMEM_BITS.
*/
if (of_find_node_by_type(NULL, "ibm,pmemory"))
return (sizeof(phys_addr_t) * 8 <= MAX_PHYSMEM_BITS) ?
(phys_addr_t) -1 : (1ULL << MAX_PHYSMEM_BITS);

for_each_node_by_type(memory, "memory") {
unsigned long start, size;
int n_mem_addr_cells, n_mem_size_cells, len;
Expand Down Expand Up @@ -1238,7 +1229,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
u32 ddw_avail[DDW_APPLICABLE_SIZE];
struct dma_win *window;
struct property *win64;
bool ddw_enabled = false;
struct failed_ddw_pdn *fpdn;
bool default_win_removed = false, direct_mapping = false;
bool pmem_present;
Expand All @@ -1253,7 +1243,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)

if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) {
direct_mapping = (len >= max_ram_len);
ddw_enabled = true;
goto out_unlock;
}

Expand Down Expand Up @@ -1367,8 +1356,10 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
len = order_base_2(query.largest_available_block << page_shift);
win_name = DMA64_PROPNAME;
} else {
direct_mapping = true;
win_name = DIRECT64_PROPNAME;
direct_mapping = !default_win_removed ||
(len == MAX_PHYSMEM_BITS) ||
(!pmem_present && (len == max_ram_len));
win_name = direct_mapping ? DIRECT64_PROPNAME : DMA64_PROPNAME;
}

ret = create_ddw(dev, ddw_avail, &create, page_shift, len);
Expand Down Expand Up @@ -1406,8 +1397,8 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
dev_info(&dev->dev, "failed to map DMA window for %pOF: %d\n",
dn, ret);

/* Make sure to clean DDW if any TCE was set*/
clean_dma_window(pdn, win64->value);
/* Make sure to clean DDW if any TCE was set*/
clean_dma_window(pdn, win64->value);
goto out_del_list;
}
} else {
Expand Down Expand Up @@ -1454,7 +1445,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
spin_unlock(&dma_win_list_lock);

dev->dev.archdata.dma_offset = win_addr;
ddw_enabled = true;
goto out_unlock;

out_del_list:
Expand Down Expand Up @@ -1490,10 +1480,10 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
* as RAM, then we failed to create a window to cover persistent
* memory and need to set the DMA limit.
*/
if (pmem_present && ddw_enabled && direct_mapping && len == max_ram_len)
if (pmem_present && direct_mapping && len == max_ram_len)
dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset + (1ULL << len);

return ddw_enabled && direct_mapping;
return direct_mapping;
}

static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
Expand Down
1 change: 0 additions & 1 deletion arch/powerpc/sysdev/xive/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ config PPC_XIVE
bool
select PPC_SMP_MUXED_IPI
select HARDIRQS_SW_RESEND
select IRQ_DOMAIN_NOMAP

config PPC_XIVE_NATIVE
bool
Expand Down
3 changes: 1 addition & 2 deletions arch/powerpc/sysdev/xive/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,8 +1443,7 @@ static const struct irq_domain_ops xive_irq_domain_ops = {

static void __init xive_init_host(struct device_node *np)
{
xive_irq_domain = irq_domain_add_nomap(np, XIVE_MAX_IRQ,
&xive_irq_domain_ops, NULL);
xive_irq_domain = irq_domain_add_tree(np, &xive_irq_domain_ops, NULL);
if (WARN_ON(xive_irq_domain == NULL))
return;
irq_set_default_host(xive_irq_domain);
Expand Down

0 comments on commit 75603b1

Please sign in to comment.