MIPS and SSB fixes for 4.0-stable
Subsystems (7)
cover MIPS and SSB fixes for 4.0-stable
This is a large number of fixes for MIPS plus one patch for the SSB bus that didn't make 4.0. All of these patches are in 4.1.
Ralf
Aaro Koskinen (2):
MIPS: OCTEON: dma-octeon: fix OHCI USB config check
MIPS: OCTEON: fix PCI interrupt mapping for D-Link DSR-1000N
Adrien Schildknecht (1):
SSB: fix Kconfig dependencies
Alexander Sverdlin (1):
MIPS: Octeon: Remove udelay() causing huge IRQ latency
Chandrakala Chavva (1):
MIPS: OCTEON: Use correct CSR to soft reset
Ganesan Ramalingam (1):
MIPS: Netlogic: Fix for SATA PHY init
Huacai Chen (2):
MIPS: Loongson-3: Add IRQF_NO_SUSPEND to Cascade irqaction
MIPS: Hibernate: flush TLB entries earlier
James Hogan (1):
MIPS: lose_fpu(): Disable FPU when MSA enabled
John Crispin (2):
MIPS: ralink: Fix bad config symbol in PCI makefile.
MIPS: ralink: add missing symbol for RALINK_ILL_ACC
Lars Persson (2):
Revert "MIPS: Remove race window in page fault handling"
MIPS: Fix race condition in lazy cache flushing.
Markos Chandras (12):
MIPS: asm: asm-eva: Introduce kernel load/store variants
MIPS: unaligned: Prevent EVA instructions on kernel unaligned accesses
MIPS: unaligned: Surround load/store macros in do {} while statements
MIPS: unaligned: Fix regular load/store instruction emulation for EVA
MIPS: Kconfig: Fix typo for the r2-to-r6 emulator kernel parameter
MIPS: r4kcache: Use correct base register for MIPS R6 cache flushes
MIPS: asm: spinlock: Fix addiu instruction for R10000_LLSC_WAR case
MIPS: kernel: entry.S: Set correct ISA level for mips_ihb
MIPS: Malta: Detect and fix bad memsize values
MIPS: Kconfig: Disable SMP/CPS for 64-bit
MIPS: asm: elf: Set O32 default FPU flags
MIPS: Makefile: Fix MIPS ASE detection code
Nicolas Schichan (1):
MIPS: BCM63xx: Move bcm63xx_gpio_init() to bcm63xx_register_devices().
Niklas Cassel (1):
MIPS: smp-cps: cpu_set FPU mask if FPU present
Rafał Miłecki (1):
MIPS: BCM47XX: Fix detecting Microsoft MN-700 & Asus WL500G
Ralf Baechle (3):
MIPS: Fix cpu_has_mips_r2_exec_hazard.
MIPS: Octeon: Delete override of cpu_has_mips_r2_exec_hazard. Revert "MIPS: Avoid pipeline stalls on some MIPS32R2 cores."
arch/mips/Kconfig | 4 +- arch/mips/Makefile | 14 +- arch/mips/bcm47xx/board.c | 4 +- arch/mips/bcm63xx/prom.c | 4 - arch/mips/bcm63xx/setup.c | 4 + arch/mips/cavium-octeon/dma-octeon.c | 2 +- arch/mips/cavium-octeon/setup.c | 5 +- arch/mips/include/asm/asm-eva.h | 137 ++++++--- arch/mips/include/asm/cacheflush.h | 38 ++- arch/mips/include/asm/cpu-features.h | 33 +- arch/mips/include/asm/elf.h | 5 + arch/mips/include/asm/fpu.h | 1 + .../asm/mach-cavium-octeon/cpu-feature-overrides.h | 1 - arch/mips/include/asm/octeon/cvmx.h | 8 - arch/mips/include/asm/octeon/pci-octeon.h | 3 - arch/mips/include/asm/pgtable.h | 9 +- arch/mips/include/asm/r4kcache.h | 89 +++--- arch/mips/include/asm/spinlock.h | 2 +- arch/mips/kernel/entry.S | 3 +- arch/mips/kernel/smp-cps.c | 6 + arch/mips/kernel/unaligned.c | 340 ++++++++++++++------- arch/mips/loongson/loongson-3/irq.c | 1 + arch/mips/mm/cache.c | 39 +-- arch/mips/mm/tlbex.c | 21 +- arch/mips/mti-malta/malta-memory.c | 6 + arch/mips/netlogic/xlp/ahci-init-xlp2.c | 13 + arch/mips/pci/Makefile | 2 +- arch/mips/pci/pci-octeon.c | 8 +- arch/mips/pci/pcie-octeon.c | 8 - arch/mips/power/hibernate.S | 3 +- arch/mips/ralink/Kconfig | 5 + drivers/ssb/Kconfig | 1 + 32 files changed, 520 insertions(+), 299 deletions(-)
Signature · 1 line
1.9.3
PATCH 1/31 MIPS: BCM63xx: Move bcm63xx_gpio_init() to bcm63xx_register_devices().
From: Nicolas Schichan <[email protected]>
When called from prom init code, bcm63xx_gpio_init() will fail as it will call gpiochip_add() which relies on a working kmalloc() to alloc the gpio_desc array and kmalloc is not useable yet at prom init time.
Move bcm63xx_gpio_init() to bcm63xx_register_devices() (an arch_initcall) where kmalloc works.
Patchwork: https://patchwork.linux-mips.org/patch/9530/
--- arch/mips/bcm63xx/prom.c | 4 ---- arch/mips/bcm63xx/setup.c | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-)
arch/mips/bcm63xx/prom.c +0 -4
@@ -17,7 +17,6 @@#include <bcm63xx_cpu.h> #include <bcm63xx_io.h> #include <bcm63xx_regs.h> -#include <bcm63xx_gpio.h> void __init prom_init (void ) {
@@ -53,9 +52,6 @@ void __init prom_init(void) reg &= ~mask;bcm_perf_writel (reg,PERF_CKCTL_REG ); -/* register gpiochip */ -bcm63xx_gpio_init (); -/* do low level board init */ board_prom_init ();
arch/mips/bcm63xx/setup.c +4 -0
@@ -20,6 +20,7 @@#include <bcm63xx_cpu.h> #include <bcm63xx_regs.h> #include <bcm63xx_io.h> +#include <bcm63xx_gpio.h> void bcm63xx_machine_halt (void ) {
@@ -160,6 +161,9 @@ void __init plat_mem_setup(void)int __init bcm63xx_register_devices (void ) { +/* register gpiochip */ +bcm63xx_gpio_init (); +return board_register_devices (); }
Signature · 1 line
1.9.3
PATCH 2/31 MIPS: Loongson-3: Add IRQF_NO_SUSPEND to Cascade irqaction
In reply to Ralf BaechleFrom: Huacai Chen <[email protected]>
HPET irq is routed to i8259 and then to MIPS CPU irq (cascade). After commit a3e6c1eff5 (MIPS: IRQ: Fix disable_irq on CPU IRQs), if without IRQF_NO_SUSPEND in cascade_irqaction, HPET interrupts will lost during suspend. The result is machine cannot be waken up.
Patchwork: https://patchwork.linux-mips.org/patch/9528/
--- arch/mips/loongson/loongson-3/irq.c | 1 + 1 file changed, 1 insertion(+)
arch/mips/loongson/loongson-3/irq.c +1 -0
@@ -44,6 +44,7 @@ void mach_irq_dispatch(unsigned int pending)static struct irqaction cascade_irqaction = { .handler = no_action, + .flags =IRQF_NO_SUSPEND , .name ="cascade" , };
Signature · 1 line
1.9.3
PATCH 3/31 MIPS: OCTEON: dma-octeon: fix OHCI USB config check
In reply to Ralf BaechleFrom: Aaro Koskinen <[email protected]>
CONFIG_USB_OCTEON_OHCI is deprecated and no longer needed to use OHCI on OCTEON II. Instead, CONFIG_USB_OHCI_HCD_PLATFORM should be used.
Patchwork: https://patchwork.linux-mips.org/patch/9421/
--- arch/mips/cavium-octeon/dma-octeon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/cavium-octeon/dma-octeon.c +1 -1
@@ -306,7 +306,7 @@ void __init plat_swiotlb_setup(void) swiotlbsize = 64 * (1<<20); }#endif -#ifdef CONFIG_USB_OCTEON_OHCI +#ifdef CONFIG_USB_OHCI_HCD_PLATFORM /* OCTEON II ohci is only 32-bit. */ if (OCTEON_IS_OCTEON2 () && max_addr >=0x100000000ul ) swiotlbsize =64 * (1 <<20 );
Signature · 1 line
1.9.3
PATCH 4/31 MIPS: OCTEON: Use correct CSR to soft reset
In reply to Ralf BaechleFrom: Chandrakala Chavva <[email protected]>
Also delete unused cvmx_reset_octeon()
This fixes reboot for Octeon III boards
Patchwork: https://patchwork.linux-mips.org/patch/9471/
--- arch/mips/cavium-octeon/setup.c | 5 ++++- arch/mips/include/asm/octeon/cvmx.h | 8 -------- 2 files changed, 4 insertions(+), 9 deletions(-)
arch/mips/cavium-octeon/setup.c +4 -1
@@ -413,7 +413,10 @@ static void octeon_restart(char *command)mb ();while (1 ) -cvmx_write_csr (CVMX_CIU_SOFT_RST ,1 ); +if (OCTEON_IS_OCTEON3 ()) +cvmx_write_csr (CVMX_RST_SOFT_RST ,1 ); +else +cvmx_write_csr (CVMX_CIU_SOFT_RST ,1 ); }
arch/mips/include/asm/octeon/cvmx.h +0 -8
@@ -436,14 +436,6 @@ static inline uint64_t cvmx_get_cycle_global(void)/***************************************************************************/ -static inline void cvmx_reset_octeon (void ) -{ -union cvmx_ciu_soft_rst ciu_soft_rst; - ciu_soft_rst.u64 =0 ; - ciu_soft_rst.s.soft_rst =1 ; -cvmx_write_csr (CVMX_CIU_SOFT_RST , ciu_soft_rst.u64); -} -/* Return the number of cores available in the chip */ static inline uint32_t cvmx_octeon_num_cores (void ) {
Signature · 1 line
1.9.3
PATCH 5/31 Revert "MIPS: Remove race window in page fault handling"
In reply to Ralf BaechleFrom: Lars Persson <[email protected]>
Revert commit 2a4a8b1e5d9d ("MIPS: Remove race window in page fault handling") because it increased the number of flushed dcache pages and became a performance problem for some workloads.
Patchwork: https://patchwork.linux-mips.org/patch/9345/
--- arch/mips/include/asm/pgtable.h | 9 +++++---- arch/mips/mm/cache.c | 27 ++++++++------------------- 2 files changed, 13 insertions(+), 23 deletions(-)
arch/mips/include/asm/pgtable.h +5 -4
@@ -127,10 +127,6 @@ do { \ } \ } while(0) - -extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, -pte_t pteval); -#if defined(CONFIG_PHYS_ADDR_T_64BIT ) && defined(CONFIG_CPU_MIPS32 )#define pte_none (pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL))
@@ -152,6 +148,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte) buddy->pte_high |= _PAGE_GLOBAL; } } +#define set_pte_at (mm, addr, ptep, pteval) set_pte(ptep, pteval)static inline void pte_clear (struct mm_struct *mm,unsigned long addr,pte_t *ptep) {
@@ -190,6 +187,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) }#endif } +#define set_pte_at (mm, addr, ptep, pteval) set_pte(ptep, pteval)static inline void pte_clear (struct mm_struct *mm,unsigned long addr,pte_t *ptep) {
@@ -399,12 +397,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)extern void __update_tlb (struct vm_area_struct *vma,unsigned long address,pte_t pte); +extern void __update_cache (struct vm_area_struct *vma,unsigned long address, +pte_t pte);static inline void update_mmu_cache (struct vm_area_struct *vma,unsigned long address,pte_t *ptep) {pte_t pte = *ptep;__update_tlb (vma, address, pte); +__update_cache (vma, address, pte); } static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
arch/mips/mm/cache.c +8 -19
@@ -119,36 +119,25 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)EXPORT_SYMBOL (__flush_anon_page); -static void mips_flush_dcache_from_pte (pte_t pteval,unsigned long address) +void __update_cache (struct vm_area_struct *vma,unsigned long address, +pte_t pte) {struct page *page; -unsigned long pfn =pte_pfn (pteval); +unsigned long pfn, addr; +int exec = (vma->vm_flags &VM_EXEC ) && !cpu_has_ic_fills_f_dc; + pfn =pte_pfn (pte);if (unlikely (!pfn_valid (pfn)))return ; - page =pfn_to_page (pfn);if (page_mapping (page) &&Page_dcache_dirty (page)) { -unsigned long page_addr = (unsigned long )page_address (page); - -if (!cpu_has_ic_fills_f_dc || -pages_do_alias (page_addr, address &PAGE_MASK )) -flush_data_cache_page (page_addr); + addr = (unsigned long )page_address (page); +if (exec ||pages_do_alias (addr, address &PAGE_MASK )) +flush_data_cache_page (addr);ClearPageDcacheDirty (page); } } -void set_pte_at (struct mm_struct *mm,unsigned long addr, -pte_t *ptep,pte_t pteval) -{ -if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) { -if (pte_present (pteval)) -mips_flush_dcache_from_pte (pteval, addr); - } - -set_pte (ptep, pteval); -} -unsigned long _page_cachable_default;EXPORT_SYMBOL (_page_cachable_default);
Signature · 1 line
1.9.3
PATCH 6/31 MIPS: Fix race condition in lazy cache flushing.
In reply to Ralf BaechleFrom: Lars Persson <[email protected]>
The lazy cache flushing implemented in the MIPS kernel suffers from a race condition that is exposed by do_set_pte() in mm/memory.c.
A pre-condition is a file-system that writes to the page from the CPU in its readpage method and then calls flush_dcache_page(). One example is ubifs. Another pre-condition is that the dcache flush is postponed in __flush_dcache_page().
Upon a page fault for an executable mapping not existing in the page-cache, the following will happen:
1. Write to the page
2. flush_dcache_page
3. flush_icache_page
4. set_pte_at
5. update_mmu_cache (commits the flush of a dcache-dirty page)
Between steps 4 and 5 another thread can hit the same page and it will encounter a valid pte. Because the data still is in the L1 dcache the CPU will fetch stale data from L2 into the icache and execute garbage.
This fix moves the commit of the cache flush to step 3 to close the race window. It also reduces the amount of flushes on non-executable mappings because we never enter __flush_dcache_page() for non-aliasing CPUs.
Regressions can occur in drivers that mistakenly relies on the flush_dcache_page() in get_user_pages() for DMA operations.
[[email protected]: Folded in patch 9346 to fix highmem issue.]
Patchwork: https://patchwork.linux-mips.org/patch/9346/
Patchwork: https://patchwork.linux-mips.org/patch/9738/
--- arch/mips/include/asm/cacheflush.h | 38 +++++++++++++++++++++++--------------- arch/mips/mm/cache.c | 12 ++++++++++++ 2 files changed, 35 insertions(+), 15 deletions(-)
arch/mips/include/asm/cacheflush.h +23 -15
@@ -29,6 +29,20 @@* - flush_icache_all() flush the entire instruction cache * - flush_data_cache_page() flushes a page from the data cache */ + +/* +* This flag is used to indicate that the page pointed to by a pte +* is dirty and requires cleaning before returning it to the user. +*/ +#define PG_dcache_dirty PG_arch_1 + +#define Page_dcache_dirty (page) \ + test_bit(PG_dcache_dirty, &(page)->flags) +#define SetPageDcacheDirty (page) \ + set_bit(PG_dcache_dirty, &(page)->flags) +#define ClearPageDcacheDirty (page) \ + clear_bit(PG_dcache_dirty, &(page)->flags) +extern void (*flush_cache_all)(void );extern void (*__flush_cache_all)(void );extern void (*flush_cache_mm)(struct mm_struct *mm);
@@ -37,13 +51,15 @@ extern void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, unsigned long end);extern void (*flush_cache_page)(struct vm_area_struct *vma,unsigned long page,unsigned long pfn);extern void __flush_dcache_page (struct page *page); +extern void __flush_icache_page (struct vm_area_struct *vma,struct page *page);#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1static inline void flush_dcache_page (struct page *page) { -if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) +if (cpu_has_dc_aliases)__flush_dcache_page (page); - +else if (!cpu_has_ic_fills_f_dc) +SetPageDcacheDirty (page); }#define flush_dcache_mmap_lock (mapping) do { } while (0)
@@ -61,6 +77,11 @@ static inline void flush_anon_page(struct vm_area_struct *vma,static inline void flush_icache_page (struct vm_area_struct *vma,struct page *page) { +if (!cpu_has_ic_fills_f_dc && (vma->vm_flags &VM_EXEC ) && +Page_dcache_dirty (page)) { +__flush_icache_page (vma, page); +ClearPageDcacheDirty (page); + } }extern void (*flush_icache_range)(unsigned long start,unsigned long end);
@@ -95,19 +116,6 @@ extern void (*flush_icache_all)(void);extern void (*local_flush_data_cache_page)(void * addr);extern void (*flush_data_cache_page)(unsigned long addr); -/* -* This flag is used to indicate that the page pointed to by a pte -* is dirty and requires cleaning before returning it to the user. -*/ -#define PG_dcache_dirty PG_arch_1 - -#define Page_dcache_dirty (page) \ - test_bit(PG_dcache_dirty, &(page)->flags) -#define SetPageDcacheDirty (page) \ - set_bit(PG_dcache_dirty, &(page)->flags) -#define ClearPageDcacheDirty (page) \ - clear_bit(PG_dcache_dirty, &(page)->flags) -/* Run kernel code uncached, useful for cache probing functions. */ unsigned long run_uncached (void *func);
arch/mips/mm/cache.c +12 -0
@@ -119,6 +119,18 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)EXPORT_SYMBOL (__flush_anon_page); +void __flush_icache_page (struct vm_area_struct *vma,struct page *page) +{ +unsigned long addr; + +if (PageHighMem (page)) +return ; + + addr = (unsigned long )page_address (page); +flush_data_cache_page (addr); +} +EXPORT_SYMBOL_GPL (__flush_icache_page); +void __update_cache (struct vm_area_struct *vma,unsigned long address,pte_t pte) {
Signature · 1 line
1.9.3
PATCH 7/31 MIPS: Octeon: Remove udelay() causing huge IRQ latency
In reply to Ralf BaechleFrom: Alexander Sverdlin <[email protected]>
udelay() in PCI/PCIe read/write callbacks cause 30ms IRQ latency on Octeon platforms because these operations are called from PCI_OP_READ() and PCI_OP_WRITE() under raw_spin_lock_irqsave().
Patchwork: https://patchwork.linux-mips.org/patch/9576/
--- arch/mips/include/asm/octeon/pci-octeon.h | 3 --- arch/mips/pci/pci-octeon.c | 6 ------ arch/mips/pci/pcie-octeon.c | 8 -------- 3 files changed, 17 deletions(-)
arch/mips/include/asm/octeon/pci-octeon.h +0 -3
@@ -11,9 +11,6 @@#include <linux/pci.h> -/* Some PCI cards require delays when accessing config space. */ -#define PCI_CONFIG_SPACE_DELAY 10000 -/* * The physical memory base mapped by BAR1. 256MB at the end of the * first 4GB.
arch/mips/pci/pci-octeon.c +0 -6
@@ -271,9 +271,6 @@ static int octeon_read_config(struct pci_bus *bus, unsigned int devfn, pci_addr.s.func = devfn &0x7 ; pci_addr.s.reg = reg; -#if PCI_CONFIG_SPACE_DELAY -udelay (PCI_CONFIG_SPACE_DELAY ); -#endif switch (size) {case 4 : *val =le32_to_cpu (cvmx_read64_uint32 (pci_addr.u64));
@@ -308,9 +305,6 @@ static int octeon_write_config(struct pci_bus *bus, unsigned int devfn, pci_addr.s.func = devfn &0x7 ; pci_addr.s.reg = reg; -#if PCI_CONFIG_SPACE_DELAY -udelay (PCI_CONFIG_SPACE_DELAY ); -#endif switch (size) {case 4 :cvmx_write64_uint32 (pci_addr.u64,cpu_to_le32 (val));
arch/mips/pci/pcie-octeon.c +0 -8
@@ -1762,14 +1762,6 @@ static int octeon_pcie_write_config(unsigned int pcie_port, struct pci_bus *bus,default :return PCIBIOS_FUNC_NOT_SUPPORTED ; } -#if PCI_CONFIG_SPACE_DELAY -/* -* Delay on writes so that devices have time to come up. Some -* bridges need this to allow time for the secondary busses to -* work -*/ -udelay (PCI_CONFIG_SPACE_DELAY ); -#endif return PCIBIOS_SUCCESSFUL ; }
Signature · 1 line
1.9.3
PATCH 8/31 MIPS: OCTEON: fix PCI interrupt mapping for D-Link DSR-1000N
In reply to Ralf BaechleFrom: Aaro Koskinen <[email protected]>
Fix PCI interrupt mapping for DSR1000N. This will get the PCI slot interrupts working. The mapping is based on D-Link GPL tarball.
Patchwork: https://patchwork.linux-mips.org/patch/9593/
--- arch/mips/pci/pci-octeon.c | 2 ++ 1 file changed, 2 insertions(+)
arch/mips/pci/pci-octeon.c +2 -0
@@ -214,6 +214,8 @@ const char *octeon_get_pci_interrupts(void)return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ;case CVMX_BOARD_TYPE_BBGW_REF :return "AABCD" ; +case CVMX_BOARD_TYPE_CUST_DSR1000N : +return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" ;case CVMX_BOARD_TYPE_THUNDER :case CVMX_BOARD_TYPE_EBH3000 :default :
Signature · 1 line
1.9.3
PATCH 9/31 MIPS: Netlogic: Fix for SATA PHY init
In reply to Ralf BaechleFrom: Ganesan Ramalingam <[email protected]>
Update to the SATA PHY initialization. This is needed for SATA detection to succeed in all configurations.
Patchwork: https://patchwork.linux-mips.org/patch/8886/
--- arch/mips/netlogic/xlp/ahci-init-xlp2.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
arch/mips/netlogic/xlp/ahci-init-xlp2.c +13 -0
@@ -203,6 +203,7 @@ static u8 read_phy_reg(u64 regbase, u32 addr, u32 physel)static void config_sata_phy (u64 regbase) {u32 port, i, reg; +u8 val;for (port =0 ; port <2 ; port++) {for (i =0 , reg =RXCDRCALFOSC0 ; reg <=CALDUTY ; reg++, i++)
@@ -210,6 +211,18 @@ static void config_sata_phy(u64 regbase)for (i =0 , reg =RXDPIF ; reg <=PPMDRIFTMAX_HI ; reg++, i++)write_phy_reg (regbase, reg, port, sata_phy_config2[i]); + +/* Fix for PHY link up failures at lower temperatures */ +write_phy_reg (regbase,0x800F , port,0x1f ); + + val =read_phy_reg (regbase,0x0029 , port); +write_phy_reg (regbase,0x0029 , port, val | (0x7 <<1 )); + + val =read_phy_reg (regbase,0x0056 , port); +write_phy_reg (regbase,0x0056 , port, val & ~(1 <<3 )); + + val =read_phy_reg (regbase,0x0018 , port); +write_phy_reg (regbase,0x0018 , port, val & ~(0x7 <<0 )); } }
Signature · 1 line
1.9.3
PATCH 10/31 MIPS: asm: asm-eva: Introduce kernel load/store variants
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
Introduce new macros for kernel load/store variants which will be used to perform regular kernel space load/store operations in EVA mode.
Patchwork: https://patchwork.linux-mips.org/patch/9500/
--- arch/mips/include/asm/asm-eva.h | 137 +++++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 44 deletions(-)
arch/mips/include/asm/asm-eva.h +93 -44
@@ -11,6 +11,36 @@#define __ASM_ASM_EVA_H#ifndef __ASSEMBLY__ + +/* Kernel variants */ + +#define kernel_cache (op, base) "cache " op ", " base "\n" +#define kernel_ll (reg, addr) "ll " reg ", " addr "\n" +#define kernel_sc (reg, addr) "sc " reg ", " addr "\n" +#define kernel_lw (reg, addr) "lw " reg ", " addr "\n" +#define kernel_lwl (reg, addr) "lwl " reg ", " addr "\n" +#define kernel_lwr (reg, addr) "lwr " reg ", " addr "\n" +#define kernel_lh (reg, addr) "lh " reg ", " addr "\n" +#define kernel_lb (reg, addr) "lb " reg ", " addr "\n" +#define kernel_lbu (reg, addr) "lbu " reg ", " addr "\n" +#define kernel_sw (reg, addr) "sw " reg ", " addr "\n" +#define kernel_swl (reg, addr) "swl " reg ", " addr "\n" +#define kernel_swr (reg, addr) "swr " reg ", " addr "\n" +#define kernel_sh (reg, addr) "sh " reg ", " addr "\n" +#define kernel_sb (reg, addr) "sb " reg ", " addr "\n" + +#ifdef CONFIG_32BIT +/* +* No 'sd' or 'ld' instructions in 32-bit but the code will +* do the correct thing +*/ +#define kernel_sd (reg, addr) user_sw(reg, addr) +#define kernel_ld (reg, addr) user_lw(reg, addr) +#else +#define kernel_sd (reg, addr) "sd " reg", " addr "\n" +#define kernel_ld (reg, addr) "ld " reg", " addr "\n" +#endif /* CONFIG_32BIT */ +#ifdef CONFIG_EVA #define __BUILD_EVA_INSN (insn, reg, addr) \
@@ -41,37 +71,60 @@#else -#define user_cache (op, base) "cache " op ", " base "\n" -#define user_ll (reg, addr) "ll " reg ", " addr "\n" -#define user_sc (reg, addr) "sc " reg ", " addr "\n" -#define user_lw (reg, addr) "lw " reg ", " addr "\n" -#define user_lwl (reg, addr) "lwl " reg ", " addr "\n" -#define user_lwr (reg, addr) "lwr " reg ", " addr "\n" -#define user_lh (reg, addr) "lh " reg ", " addr "\n" -#define user_lb (reg, addr) "lb " reg ", " addr "\n" -#define user_lbu (reg, addr) "lbu " reg ", " addr "\n" -#define user_sw (reg, addr) "sw " reg ", " addr "\n" -#define user_swl (reg, addr) "swl " reg ", " addr "\n" -#define user_swr (reg, addr) "swr " reg ", " addr "\n" -#define user_sh (reg, addr) "sh " reg ", " addr "\n" -#define user_sb (reg, addr) "sb " reg ", " addr "\n" +#define user_cache (op, base) kernel_cache(op, base) +#define user_ll (reg, addr) kernel_ll(reg, addr) +#define user_sc (reg, addr) kernel_sc(reg, addr) +#define user_lw (reg, addr) kernel_lw(reg, addr) +#define user_lwl (reg, addr) kernel_lwl(reg, addr) +#define user_lwr (reg, addr) kernel_lwr(reg, addr) +#define user_lh (reg, addr) kernel_lh(reg, addr) +#define user_lb (reg, addr) kernel_lb(reg, addr) +#define user_lbu (reg, addr) kernel_lbu(reg, addr) +#define user_sw (reg, addr) kernel_sw(reg, addr) +#define user_swl (reg, addr) kernel_swl(reg, addr) +#define user_swr (reg, addr) kernel_swr(reg, addr) +#define user_sh (reg, addr) kernel_sh(reg, addr) +#define user_sb (reg, addr) kernel_sb(reg, addr)#ifdef CONFIG_32BIT -/* -* No 'sd' or 'ld' instructions in 32-bit but the code will -* do the correct thing -*/ -#define user_sd (reg, addr) user_sw(reg, addr) -#define user_ld (reg, addr) user_lw(reg, addr) +#define user_sd (reg, addr) kernel_sw(reg, addr) +#define user_ld (reg, addr) kernel_lw(reg, addr)#else -#define user_sd (reg, addr) "sd " reg", " addr "\n" -#define user_ld (reg, addr) "ld " reg", " addr "\n" +#define user_sd (reg, addr) kernel_sd(reg, addr) +#define user_ld (reg, addr) kernel_ld(reg, addr)#endif /* CONFIG_32BIT */ #endif /* CONFIG_EVA */ #else /* __ASSEMBLY__ */ +#define kernel_cache (op, base) cache op, base +#define kernel_ll (reg, addr) ll reg, addr +#define kernel_sc (reg, addr) sc reg, addr +#define kernel_lw (reg, addr) lw reg, addr +#define kernel_lwl (reg, addr) lwl reg, addr +#define kernel_lwr (reg, addr) lwr reg, addr +#define kernel_lh (reg, addr) lh reg, addr +#define kernel_lb (reg, addr) lb reg, addr +#define kernel_lbu (reg, addr) lbu reg, addr +#define kernel_sw (reg, addr) sw reg, addr +#define kernel_swl (reg, addr) swl reg, addr +#define kernel_swr (reg, addr) swr reg, addr +#define kernel_sh (reg, addr) sh reg, addr +#define kernel_sb (reg, addr) sb reg, addr + +#ifdef CONFIG_32BIT +/* +* No 'sd' or 'ld' instructions in 32-bit but the code will +* do the correct thing +*/ +#define kernel_sd (reg, addr) user_sw(reg, addr) +#define kernel_ld (reg, addr) user_lw(reg, addr) +#else +#define kernel_sd (reg, addr) sd reg, addr +#define kernel_ld (reg, addr) ld reg, addr +#endif /* CONFIG_32BIT */ +#ifdef CONFIG_EVA #define __BUILD_EVA_INSN (insn, reg, addr) \
@@ -101,31 +154,27 @@#define user_sd (reg, addr) user_sw(reg, addr)#else -#define user_cache (op, base) cache op, base -#define user_ll (reg, addr) ll reg, addr -#define user_sc (reg, addr) sc reg, addr -#define user_lw (reg, addr) lw reg, addr -#define user_lwl (reg, addr) lwl reg, addr -#define user_lwr (reg, addr) lwr reg, addr -#define user_lh (reg, addr) lh reg, addr -#define user_lb (reg, addr) lb reg, addr -#define user_lbu (reg, addr) lbu reg, addr -#define user_sw (reg, addr) sw reg, addr -#define user_swl (reg, addr) swl reg, addr -#define user_swr (reg, addr) swr reg, addr -#define user_sh (reg, addr) sh reg, addr -#define user_sb (reg, addr) sb reg, addr +#define user_cache (op, base) kernel_cache(op, base) +#define user_ll (reg, addr) kernel_ll(reg, addr) +#define user_sc (reg, addr) kernel_sc(reg, addr) +#define user_lw (reg, addr) kernel_lw(reg, addr) +#define user_lwl (reg, addr) kernel_lwl(reg, addr) +#define user_lwr (reg, addr) kernel_lwr(reg, addr) +#define user_lh (reg, addr) kernel_lh(reg, addr) +#define user_lb (reg, addr) kernel_lb(reg, addr) +#define user_lbu (reg, addr) kernel_lbu(reg, addr) +#define user_sw (reg, addr) kernel_sw(reg, addr) +#define user_swl (reg, addr) kernel_swl(reg, addr) +#define user_swr (reg, addr) kernel_swr(reg, addr) +#define user_sh (reg, addr) kernel_sh(reg, addr) +#define user_sb (reg, addr) kernel_sb(reg, addr)#ifdef CONFIG_32BIT -/* -* No 'sd' or 'ld' instructions in 32-bit but the code will -* do the correct thing -*/ -#define user_sd (reg, addr) user_sw(reg, addr) -#define user_ld (reg, addr) user_lw(reg, addr) +#define user_sd (reg, addr) kernel_sw(reg, addr) +#define user_ld (reg, addr) kernel_lw(reg, addr)#else -#define user_sd (reg, addr) sd reg, addr -#define user_ld (reg, addr) ld reg, addr +#define user_sd (reg, addr) kernel_sd(reg, addr) +#define user_ld (reg, addr) kernel_sd(reg, addr)#endif /* CONFIG_32BIT */ #endif /* CONFIG_EVA */
Signature · 1 line
1.9.3
PATCH 11/31 MIPS: unaligned: Prevent EVA instructions on kernel unaligned accesses
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
Commit c1771216ab48 ("MIPS: kernel: unaligned: Handle unaligned accesses for EVA") allowed unaligned accesses to be emulated for EVA. However, when emulating regular load/store unaligned accesses, we need to use the appropriate "address space" instructions for that. Previously, an unaligned load/store instruction in kernel space would have used the corresponding EVA instructions to emulate it which led to segmentation faults because of the address translation that happens with EVA instructions. This is now fixed by using the EVA instruction only when emulating EVA unaligned accesses.
Patchwork: https://patchwork.linux-mips.org/patch/9501/
--- arch/mips/kernel/unaligned.c | 172 +++++++++++++++++++++++-------------------- 1 file changed, 94 insertions(+), 78 deletions(-)
arch/mips/kernel/unaligned.c +94 -78
@@ -109,10 +109,10 @@ static u32 unaligned_action;extern void show_registers (struct pt_regs *regs);#ifdef __BIG_ENDIAN -#define LoadHW (addr, value, res) \ +#define _LoadHW (addr, value, res, type) \ __asm__ __volatile__ (".set\tnoat\n" \ - "1:\t"user_lb("%0", "0(%2)")"\n" \ - "2:\t"user_lbu("$1", "1(%2)")"\n\t" \ + "1:\t"type##_lb("%0", "0(%2)")"\n" \ + "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \
@@ -130,10 +130,10 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#ifndef CONFIG_CPU_MIPSR6 -#define LoadW (addr, value, res) \ +#define _LoadW (addr, value, res, type) \ __asm__ __volatile__ ( \ - "1:\t"user_lwl("%0", "(%2)")"\n" \ - "2:\t"user_lwr("%0", "3(%2)")"\n\t" \ + "1:\t"type##_lwl("%0", "(%2)")"\n" \ + "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \
@@ -149,18 +149,18 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#else /* MIPSR6 has no lwl instruction */ -#define LoadW (addr, value, res) \ +#define _LoadW (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tpush\n" \ ".set\tnoat\n\t" \ - "1:"user_lb("%0", "0(%2)")"\n\t" \ - "2:"user_lbu("$1", "1(%2)")"\n\t" \ + "1:"type##_lb("%0", "0(%2)")"\n\t" \ + "2:"type##_lbu("$1", "1(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ - "3:"user_lbu("$1", "2(%2)")"\n\t" \ + "3:"type##_lbu("$1", "2(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ - "4:"user_lbu("$1", "3(%2)")"\n\t" \ + "4:"type##_lbu("$1", "3(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \
@@ -181,11 +181,11 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#endif /* CONFIG_CPU_MIPSR6 */ -#define LoadHWU (addr, value, res) \ +#define _LoadHWU (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ - "1:\t"user_lbu("%0", "0(%2)")"\n" \ - "2:\t"user_lbu("$1", "1(%2)")"\n\t" \ + "1:\t"type##_lbu("%0", "0(%2)")"\n" \ + "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \
@@ -204,10 +204,10 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#ifndef CONFIG_CPU_MIPSR6 -#define LoadWU (addr, value, res) \ +#define _LoadWU (addr, value, res, type) \ __asm__ __volatile__ ( \ - "1:\t"user_lwl("%0", "(%2)")"\n" \ - "2:\t"user_lwr("%0", "3(%2)")"\n\t" \ + "1:\t"type##_lwl("%0", "(%2)")"\n" \ + "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\ "dsll\t%0, %0, 32\n\t" \ "dsrl\t%0, %0, 32\n\t" \ "li\t%1, 0\n" \
@@ -224,7 +224,7 @@ extern void show_registers(struct pt_regs *regs); : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); -#define LoadDW (addr, value, res) \ +#define _LoadDW (addr, value, res) \ __asm__ __volatile__ ( \ "1:\tldl\t%0, (%2)\n" \ "2:\tldr\t%0, 7(%2)\n\t" \
@@ -243,18 +243,18 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#else /* MIPSR6 has not lwl and ldl instructions */ -#define LoadWU (addr, value, res) \ +#define _LoadWU (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ - "1:"user_lbu("%0", "0(%2)")"\n\t" \ - "2:"user_lbu("$1", "1(%2)")"\n\t" \ + "1:"type##_lbu("%0", "0(%2)")"\n\t" \ + "2:"type##_lbu("$1", "1(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ - "3:"user_lbu("$1", "2(%2)")"\n\t" \ + "3:"type##_lbu("$1", "2(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ - "4:"user_lbu("$1", "3(%2)")"\n\t" \ + "4:"type##_lbu("$1", "3(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \
@@ -274,7 +274,7 @@ extern void show_registers(struct pt_regs *regs); : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); -#define LoadDW (addr, value, res) \ +#define _LoadDW (addr, value, res) \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -323,12 +323,12 @@ extern void show_registers(struct pt_regs *regs);#endif /* CONFIG_CPU_MIPSR6 */ -#define StoreHW (addr, value, res) \ +#define _StoreHW (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ - "1:\t"user_sb("%1", "1(%2)")"\n" \ + "1:\t"type##_sb("%1", "1(%2)")"\n" \ "srl\t$1, %1, 0x8\n" \ - "2:\t"user_sb("$1", "0(%2)")"\n" \ + "2:\t"type##_sb("$1", "0(%2)")"\n" \ ".set\tat\n\t" \ "li\t%0, 0\n" \ "3:\n\t" \
@@ -345,10 +345,10 @@ extern void show_registers(struct pt_regs *regs); : "r" (value), "r" (addr), "i" (-EFAULT));#ifndef CONFIG_CPU_MIPSR6 -#define StoreW (addr, value, res) \ +#define _StoreW (addr, value, res, type) \ __asm__ __volatile__ ( \ - "1:\t"user_swl("%1", "(%2)")"\n" \ - "2:\t"user_swr("%1", "3(%2)")"\n\t" \ + "1:\t"type##_swl("%1", "(%2)")"\n" \ + "2:\t"type##_swr("%1", "3(%2)")"\n\t"\ "li\t%0, 0\n" \ "3:\n\t" \ ".insn\n\t" \
@@ -363,7 +363,7 @@ extern void show_registers(struct pt_regs *regs); : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT)); -#define StoreDW (addr, value, res) \ +#define _StoreDW (addr, value, res) \ __asm__ __volatile__ ( \ "1:\tsdl\t%1,(%2)\n" \ "2:\tsdr\t%1, 7(%2)\n\t" \
@@ -382,17 +382,17 @@ extern void show_registers(struct pt_regs *regs); : "r" (value), "r" (addr), "i" (-EFAULT));#else /* MIPSR6 has no swl and sdl instructions */ -#define StoreW (addr, value, res) \ +#define _StoreW (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ - "1:"user_sb("%1", "3(%2)")"\n\t" \ + "1:"type##_sb("%1", "3(%2)")"\n\t" \ "srl\t$1, %1, 0x8\n\t" \ - "2:"user_sb("$1", "2(%2)")"\n\t" \ + "2:"type##_sb("$1", "2(%2)")"\n\t" \ "srl\t$1, $1, 0x8\n\t" \ - "3:"user_sb("$1", "1(%2)")"\n\t" \ + "3:"type##_sb("$1", "1(%2)")"\n\t" \ "srl\t$1, $1, 0x8\n\t" \ - "4:"user_sb("$1", "0(%2)")"\n\t" \ + "4:"type##_sb("$1", "0(%2)")"\n\t" \ ".set\tpop\n\t" \ "li\t%0, 0\n" \ "10:\n\t" \
@@ -456,10 +456,10 @@ extern void show_registers(struct pt_regs *regs);#else /* __BIG_ENDIAN */ -#define LoadHW (addr, value, res) \ +#define _LoadHW (addr, value, res, type) \ __asm__ __volatile__ (".set\tnoat\n" \ - "1:\t"user_lb("%0", "1(%2)")"\n" \ - "2:\t"user_lbu("$1", "0(%2)")"\n\t" \ + "1:\t"type##_lb("%0", "1(%2)")"\n" \ + "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \
@@ -477,10 +477,10 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#ifndef CONFIG_CPU_MIPSR6 -#define LoadW (addr, value, res) \ +#define _LoadW (addr, value, res, type) \ __asm__ __volatile__ ( \ - "1:\t"user_lwl("%0", "3(%2)")"\n" \ - "2:\t"user_lwr("%0", "(%2)")"\n\t" \ + "1:\t"type##_lwl("%0", "3(%2)")"\n" \ + "2:\t"type##_lwr("%0", "(%2)")"\n\t"\ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \
@@ -496,18 +496,18 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#else /* MIPSR6 has no lwl instruction */ -#define LoadW (addr, value, res) \ +#define _LoadW (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tpush\n" \ ".set\tnoat\n\t" \ - "1:"user_lb("%0", "3(%2)")"\n\t" \ - "2:"user_lbu("$1", "2(%2)")"\n\t" \ + "1:"type##_lb("%0", "3(%2)")"\n\t" \ + "2:"type##_lbu("$1", "2(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ - "3:"user_lbu("$1", "1(%2)")"\n\t" \ + "3:"type##_lbu("$1", "1(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ - "4:"user_lbu("$1", "0(%2)")"\n\t" \ + "4:"type##_lbu("$1", "0(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \
@@ -529,11 +529,11 @@ extern void show_registers(struct pt_regs *regs);#endif /* CONFIG_CPU_MIPSR6 */ -#define LoadHWU (addr, value, res) \ +#define _LoadHWU (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ - "1:\t"user_lbu("%0", "1(%2)")"\n" \ - "2:\t"user_lbu("$1", "0(%2)")"\n\t" \ + "1:\t"type##_lbu("%0", "1(%2)")"\n" \ + "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \
@@ -552,10 +552,10 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#ifndef CONFIG_CPU_MIPSR6 -#define LoadWU (addr, value, res) \ +#define _LoadWU (addr, value, res, type) \ __asm__ __volatile__ ( \ - "1:\t"user_lwl("%0", "3(%2)")"\n" \ - "2:\t"user_lwr("%0", "(%2)")"\n\t" \ + "1:\t"type##_lwl("%0", "3(%2)")"\n" \ + "2:\t"type##_lwr("%0", "(%2)")"\n\t"\ "dsll\t%0, %0, 32\n\t" \ "dsrl\t%0, %0, 32\n\t" \ "li\t%1, 0\n" \
@@ -572,7 +572,7 @@ extern void show_registers(struct pt_regs *regs); : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); -#define LoadDW (addr, value, res) \ +#define _LoadDW (addr, value, res) \ __asm__ __volatile__ ( \ "1:\tldl\t%0, 7(%2)\n" \ "2:\tldr\t%0, (%2)\n\t" \
@@ -591,18 +591,18 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#else /* MIPSR6 has not lwl and ldl instructions */ -#define LoadWU (addr, value, res) \ +#define _LoadWU (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ - "1:"user_lbu("%0", "3(%2)")"\n\t" \ - "2:"user_lbu("$1", "2(%2)")"\n\t" \ + "1:"type##_lbu("%0", "3(%2)")"\n\t" \ + "2:"type##_lbu("$1", "2(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ - "3:"user_lbu("$1", "1(%2)")"\n\t" \ + "3:"type##_lbu("$1", "1(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ - "4:"user_lbu("$1", "0(%2)")"\n\t" \ + "4:"type##_lbu("$1", "0(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \
@@ -622,7 +622,7 @@ extern void show_registers(struct pt_regs *regs); : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); -#define LoadDW (addr, value, res) \ +#define _LoadDW (addr, value, res) \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -670,12 +670,12 @@ extern void show_registers(struct pt_regs *regs); : "r" (addr), "i" (-EFAULT));#endif /* CONFIG_CPU_MIPSR6 */ -#define StoreHW (addr, value, res) \ +#define _StoreHW (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ - "1:\t"user_sb("%1", "0(%2)")"\n" \ + "1:\t"type##_sb("%1", "0(%2)")"\n" \ "srl\t$1,%1, 0x8\n" \ - "2:\t"user_sb("$1", "1(%2)")"\n" \ + "2:\t"type##_sb("$1", "1(%2)")"\n" \ ".set\tat\n\t" \ "li\t%0, 0\n" \ "3:\n\t" \
@@ -691,10 +691,10 @@ extern void show_registers(struct pt_regs *regs); : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT));#ifndef CONFIG_CPU_MIPSR6 -#define StoreW (addr, value, res) \ +#define _StoreW (addr, value, res, type) \ __asm__ __volatile__ ( \ - "1:\t"user_swl("%1", "3(%2)")"\n" \ - "2:\t"user_swr("%1", "(%2)")"\n\t" \ + "1:\t"type##_swl("%1", "3(%2)")"\n" \ + "2:\t"type##_swr("%1", "(%2)")"\n\t"\ "li\t%0, 0\n" \ "3:\n\t" \ ".insn\n\t" \
@@ -709,7 +709,7 @@ extern void show_registers(struct pt_regs *regs); : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT)); -#define StoreDW (addr, value, res) \ +#define _StoreDW (addr, value, res) \ __asm__ __volatile__ ( \ "1:\tsdl\t%1, 7(%2)\n" \ "2:\tsdr\t%1, (%2)\n\t" \
@@ -728,17 +728,17 @@ extern void show_registers(struct pt_regs *regs); : "r" (value), "r" (addr), "i" (-EFAULT));#else /* MIPSR6 has no swl and sdl instructions */ -#define StoreW (addr, value, res) \ +#define _StoreW (addr, value, res, type) \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ - "1:"user_sb("%1", "0(%2)")"\n\t" \ + "1:"type##_sb("%1", "0(%2)")"\n\t" \ "srl\t$1, %1, 0x8\n\t" \ - "2:"user_sb("$1", "1(%2)")"\n\t" \ + "2:"type##_sb("$1", "1(%2)")"\n\t" \ "srl\t$1, $1, 0x8\n\t" \ - "3:"user_sb("$1", "2(%2)")"\n\t" \ + "3:"type##_sb("$1", "2(%2)")"\n\t" \ "srl\t$1, $1, 0x8\n\t" \ - "4:"user_sb("$1", "3(%2)")"\n\t" \ + "4:"type##_sb("$1", "3(%2)")"\n\t" \ ".set\tpop\n\t" \ "li\t%0, 0\n" \ "10:\n\t" \
@@ -757,7 +757,7 @@ extern void show_registers(struct pt_regs *regs); : "r" (value), "r" (addr), "i" (-EFAULT) \ : "memory"); -#define StoreDW (addr, value, res) \ +#define _StoreDW (addr, value, res) \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -801,6 +801,22 @@ extern void show_registers(struct pt_regs *regs);#endif /* CONFIG_CPU_MIPSR6 */ #endif +#define LoadHWU (addr, value, res) _LoadHWU(addr, value, res, kernel) +#define LoadHWUE (addr, value, res) _LoadHWU(addr, value, res, user) +#define LoadWU (addr, value, res) _LoadWU(addr, value, res, kernel) +#define LoadWUE (addr, value, res) _LoadWU(addr, value, res, user) +#define LoadHW (addr, value, res) _LoadHW(addr, value, res, kernel) +#define LoadHWE (addr, value, res) _LoadHW(addr, value, res, user) +#define LoadW (addr, value, res) _LoadW(addr, value, res, kernel) +#define LoadWE (addr, value, res) _LoadW(addr, value, res, user) +#define LoadDW (addr, value, res) _LoadDW(addr, value, res) + +#define StoreHW (addr, value, res) _StoreHW(addr, value, res, kernel) +#define StoreHWE (addr, value, res) _StoreHW(addr, value, res, user) +#define StoreW (addr, value, res) _StoreW(addr, value, res, kernel) +#define StoreWE (addr, value, res) _StoreW(addr, value, res, user) +#define StoreDW (addr, value, res) _StoreDW(addr, value, res) +static void emulate_load_store_insn (struct pt_regs *regs,void __user *addr,unsigned int __user *pc) {
@@ -872,7 +888,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,set_fs (seg); goto sigbus; } -LoadHW (addr, value, res); +LoadHWE (addr, value, res);if (res) {set_fs (seg); goto fault;
@@ -885,7 +901,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,set_fs (seg); goto sigbus; } -LoadW (addr, value, res); +LoadWE (addr, value, res);if (res) {set_fs (seg); goto fault;
@@ -898,7 +914,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,set_fs (seg); goto sigbus; } -LoadHWU (addr, value, res); +LoadHWUE (addr, value, res);if (res) {set_fs (seg); goto fault;
@@ -913,7 +929,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, }compute_return_epc (regs); value = regs->regs[insn.spec3_format.rt]; -StoreHW (addr, value, res); +StoreHWE (addr, value, res);if (res) {set_fs (seg); goto fault;
@@ -926,7 +942,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, }compute_return_epc (regs); value = regs->regs[insn.spec3_format.rt]; -StoreW (addr, value, res); +StoreWE (addr, value, res);if (res) {set_fs (seg); goto fault;
Signature · 1 line
1.9.3
PATCH 12/31 MIPS: unaligned: Surround load/store macros in do {} while statements
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
It's best to surround such complex macros with do {} while statements so they can appear as independent logical blocks when used within other control blocks.
Patchwork: https://patchwork.linux-mips.org/patch/9502/
--- arch/mips/kernel/unaligned.c | 116 +++++++++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 26 deletions(-)
arch/mips/kernel/unaligned.c +90 -26
@@ -110,6 +110,7 @@ extern void show_registers(struct pt_regs *regs);#ifdef __BIG_ENDIAN#define _LoadHW (addr, value, res, type) \ +do { \ __asm__ __volatile__ (".set\tnoat\n" \ "1:\t"type##_lb("%0", "0(%2)")"\n" \ "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
@@ -127,10 +128,12 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#ifndef CONFIG_CPU_MIPSR6 #define _LoadW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ "1:\t"type##_lwl("%0", "(%2)")"\n" \ "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
@@ -146,10 +149,13 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0) +#else /* MIPSR6 has no lwl instruction */ #define _LoadW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n" \ ".set\tnoat\n\t" \
@@ -178,10 +184,13 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0) +#endif /* CONFIG_CPU_MIPSR6 */ #define _LoadHWU (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ "1:\t"type##_lbu("%0", "0(%2)")"\n" \
@@ -201,10 +210,12 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#ifndef CONFIG_CPU_MIPSR6 #define _LoadWU (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ "1:\t"type##_lwl("%0", "(%2)")"\n" \ "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
@@ -222,9 +233,11 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#define _LoadDW (addr, value, res) \ +do { \ __asm__ __volatile__ ( \ "1:\tldl\t%0, (%2)\n" \ "2:\tldr\t%0, 7(%2)\n\t" \
@@ -240,10 +253,13 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0) +#else /* MIPSR6 has not lwl and ldl instructions */ #define _LoadWU (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -272,9 +288,11 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#define _LoadDW (addr, value, res) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -319,11 +337,14 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t8b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0) +#endif /* CONFIG_CPU_MIPSR6 */ #define _StoreHW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ "1:\t"type##_sb("%1", "1(%2)")"\n" \
@@ -342,10 +363,12 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); + : "r" (value), "r" (addr), "i" (-EFAULT));\ +} while(0)#ifndef CONFIG_CPU_MIPSR6 #define _StoreW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ "1:\t"type##_swl("%1", "(%2)")"\n" \ "2:\t"type##_swr("%1", "3(%2)")"\n\t"\
@@ -361,9 +384,11 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); + : "r" (value), "r" (addr), "i" (-EFAULT)); \ +} while(0)#define _StoreDW (addr, value, res) \ +do { \ __asm__ __volatile__ ( \ "1:\tsdl\t%1,(%2)\n" \ "2:\tsdr\t%1, 7(%2)\n\t" \
@@ -379,10 +404,13 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); + : "r" (value), "r" (addr), "i" (-EFAULT)); \ +} while(0) +#else /* MIPSR6 has no swl and sdl instructions */ #define _StoreW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -409,9 +437,11 @@ extern void show_registers(struct pt_regs *regs);".previous" \ : "=&r" (res) \: " r" (value), " r" (addr), " i" (-EFAULT) \ - : "memory"); + : "memory"); \ +} while(0) #define StoreDW(addr, value, res) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -451,12 +481,15 @@ extern void show_registers(struct pt_regs *regs); ".previous" \ : "=&r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT) \ - : "memory"); + : "memory"); \ +} while(0) + #endif /* CONFIG_CPU_MIPSR6 */ #else /* __BIG_ENDIAN */ #define _LoadHW(addr, value, res, type) \ +do { \ __asm__ __volatile__ (".set\tnoat\n" \ "1:\t"type##_lb("%0", "1(%2)")"\n" \ "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
@@ -474,10 +507,12 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#ifndef CONFIG_CPU_MIPSR6 #define _LoadW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ "1:\t"type##_lwl("%0", "3(%2)")"\n" \ "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
@@ -493,10 +528,13 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0) +#else /* MIPSR6 has no lwl instruction */ #define _LoadW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n" \ ".set\tnoat\n\t" \
@@ -525,11 +563,14 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0) +#endif /* CONFIG_CPU_MIPSR6 */ #define _LoadHWU (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ "1:\t"type##_lbu("%0", "1(%2)")"\n" \
@@ -549,10 +590,12 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#ifndef CONFIG_CPU_MIPSR6 #define _LoadWU (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ "1:\t"type##_lwl("%0", "3(%2)")"\n" \ "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
@@ -570,9 +613,11 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#define _LoadDW (addr, value, res) \ +do { \ __asm__ __volatile__ ( \ "1:\tldl\t%0, 7(%2)\n" \ "2:\tldr\t%0, (%2)\n\t" \
@@ -588,10 +633,13 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0) +#else /* MIPSR6 has not lwl and ldl instructions */ #define _LoadWU (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -620,9 +668,11 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#define _LoadDW (addr, value, res) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -667,10 +717,12 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t8b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); + : "r" (addr), "i" (-EFAULT)); \ +} while(0)#endif /* CONFIG_CPU_MIPSR6 */ #define _StoreHW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ "1:\t"type##_sb("%1", "0(%2)")"\n" \
@@ -689,9 +741,12 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); + : "r" (value), "r" (addr), "i" (-EFAULT));\ +} while(0) +#ifndef CONFIG_CPU_MIPSR6 #define _StoreW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ "1:\t"type##_swl("%1", "3(%2)")"\n" \ "2:\t"type##_swr("%1", "(%2)")"\n\t"\
@@ -707,9 +762,11 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); + : "r" (value), "r" (addr), "i" (-EFAULT)); \ +} while(0)#define _StoreDW (addr, value, res) \ +do { \ __asm__ __volatile__ ( \ "1:\tsdl\t%1, 7(%2)\n" \ "2:\tsdr\t%1, (%2)\n\t" \
@@ -725,10 +782,13 @@ extern void show_registers(struct pt_regs *regs); STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); + : "r" (value), "r" (addr), "i" (-EFAULT)); \ +} while(0) +#else /* MIPSR6 has no swl and sdl instructions */ #define _StoreW (addr, value, res, type) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -755,9 +815,11 @@ extern void show_registers(struct pt_regs *regs);".previous" \ : "=&r" (res) \: " r" (value), " r" (addr), " i" (-EFAULT) \ - : "memory"); + : "memory"); \ +} while(0) #define _StoreDW(addr, value, res) \ +do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \
@@ -797,7 +859,9 @@ extern void show_registers(struct pt_regs *regs); ".previous" \ : "=&r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT) \ - : "memory"); + : "memory"); \ +} while(0) + #endif /* CONFIG_CPU_MIPSR6 */ #endif
Signature · 1 line
1.9.3
PATCH 13/31 MIPS: unaligned: Fix regular load/store instruction emulation for EVA
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
When emulating a regular lh/lw/lhu/sh/sw we need to use the appropriate instruction if we are in EVA mode. This is necessary for userspace applications which trigger alignment exceptions. In such case, the userspace load/store instruction needs to be emulated with the correct eva/non-eva instruction by the kernel emulator.
Patchwork: https://patchwork.linux-mips.org/patch/9503/
--- arch/mips/kernel/unaligned.c | 52 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-)
arch/mips/kernel/unaligned.c +47 -5
@@ -1023,7 +1023,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,if (!access_ok (VERIFY_READ , addr,2 )) goto sigbus; -LoadHW (addr, value, res); +if (config_enabled (CONFIG_EVA )) { +if (segment_eq (get_fs (),get_ds ())) +LoadHW (addr, value, res); +else +LoadHWE (addr, value, res); + }else { +LoadHW (addr, value, res); + } +if (res) goto fault;compute_return_epc (regs);
@@ -1034,7 +1042,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,if (!access_ok (VERIFY_READ , addr,4 )) goto sigbus; -LoadW (addr, value, res); +if (config_enabled (CONFIG_EVA )) { +if (segment_eq (get_fs (),get_ds ())) +LoadW (addr, value, res); +else +LoadWE (addr, value, res); + }else { +LoadW (addr, value, res); + } +if (res) goto fault;compute_return_epc (regs);
@@ -1045,7 +1061,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,if (!access_ok (VERIFY_READ , addr,2 )) goto sigbus; -LoadHWU (addr, value, res); +if (config_enabled (CONFIG_EVA )) { +if (segment_eq (get_fs (),get_ds ())) +LoadHWU (addr, value, res); +else +LoadHWUE (addr, value, res); + }else { +LoadHWU (addr, value, res); + } +if (res) goto fault;compute_return_epc (regs);
@@ -1104,7 +1128,16 @@ static void emulate_load_store_insn(struct pt_regs *regs,compute_return_epc (regs); value = regs->regs[insn.i_format.rt]; -StoreHW (addr, value, res); + +if (config_enabled (CONFIG_EVA )) { +if (segment_eq (get_fs (),get_ds ())) +StoreHW (addr, value, res); +else +StoreHWE (addr, value, res); + }else { +StoreHW (addr, value, res); + } +if (res) goto fault;break ;
@@ -1115,7 +1148,16 @@ static void emulate_load_store_insn(struct pt_regs *regs,compute_return_epc (regs); value = regs->regs[insn.i_format.rt]; -StoreW (addr, value, res); + +if (config_enabled (CONFIG_EVA )) { +if (segment_eq (get_fs (),get_ds ())) +StoreW (addr, value, res); +else +StoreWE (addr, value, res); + }else { +StoreW (addr, value, res); + } +if (res) goto fault;break ;
Signature · 1 line
1.9.3
PATCH 14/31 MIPS: Kconfig: Fix typo for the r2-to-r6 emulator kernel parameter
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
Commit b0a668fb2038 ("MIPS: kernel: mips-r2-to-r6-emul: Add R2 emulator for MIPS R6") added the mips r2-to-r6 emulator so an R2 userland can be executed on R6 kernels. This needed both build time and runtime support. The runtime support needed the "mipsr2emu" kernel parameter instead of the "mipsr2emul" listed in the Kconfig help message.
Patchwork: https://patchwork.linux-mips.org/patch/9504/
--- arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/Kconfig +1 -1
@@ -2107,7 +2107,7 @@ config MIPSR2_TO_R6_EMULATOR help Choose this option if you want to run non-R6 MIPS userland code. Even if you say 'Y' here, the emulator will still be disabled by - default. You can enable it using the 'mipsr2emul' kernel option. + default. You can enable it using the 'mipsr2emu' kernel option. The only reason this is a build-time option is to save ~14K from the final kernel image. comment "MIPS R2-to-R6 emulator is only available for UP kernels"
Signature · 1 line
1.9.3
PATCH 15/31 MIPS: r4kcache: Use correct base register for MIPS R6 cache flushes
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
Commit 934c79231c1b("MIPS: asm: r4kcache: Add MIPS R6 cache unroll functions") added support for MIPS R6 cache flushes but it used the wrong base address register to perform the flushes so the same lines were flushed over and over. Moreover, replace the "addiu" instructions with LONG_ADDIU so the correct base address is calculated for 64-bit cores.
Patchwork: https://patchwork.linux-mips.org/patch/9384/
--- arch/mips/include/asm/r4kcache.h | 89 ++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 44 deletions(-)
arch/mips/include/asm/r4kcache.h +45 -44
@@ -12,6 +12,8 @@#ifndef _ASM_R4KCACHE_H#define _ASM_R4KCACHE_H +#include <linux/stringify.h> +#include <asm/asm.h> #include <asm/cacheops.h> #include <asm/compiler.h>
@@ -344,7 +346,7 @@ static inline void invalidate_tcache_page(unsigned long addr)" cache %1, 0x0a0(%0); cache %1, 0x0b0(%0)\n" \" cache %1, 0x0c0(%0); cache %1, 0x0d0(%0)\n" \" cache %1, 0x0e0(%0); cache %1, 0x0f0(%0)\n" \ -" addiu $1, $0, 0x100 \n" \ + " "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x010($1)\n" \" cache %1, 0x020($1); cache %1, 0x030($1)\n" \" cache %1, 0x040($1); cache %1, 0x050($1)\n" \
@@ -368,17 +370,17 @@ static inline void invalidate_tcache_page(unsigned long addr)" cache %1, 0x040(%0); cache %1, 0x060(%0)\n" \" cache %1, 0x080(%0); cache %1, 0x0a0(%0)\n" \" cache %1, 0x0c0(%0); cache %1, 0x0e0(%0)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x020($1)\n" \" cache %1, 0x040($1); cache %1, 0x060($1)\n" \" cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \" cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \ -" addiu $1, $1, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x020($1)\n" \" cache %1, 0x040($1); cache %1, 0x060($1)\n" \" cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \" cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \ -" addiu $1, $1, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100\n" \" cache %1, 0x000($1); cache %1, 0x020($1)\n" \" cache %1, 0x040($1); cache %1, 0x060($1)\n" \" cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \
@@ -396,25 +398,25 @@ static inline void invalidate_tcache_page(unsigned long addr)" .set noat\n" \" cache %1, 0x000(%0); cache %1, 0x040(%0)\n" \" cache %1, 0x080(%0); cache %1, 0x0c0(%0)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x040($1)\n" \" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x040($1)\n" \" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x040($1)\n" \" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x040($1)\n" \" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x040($1)\n" \" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x040($1)\n" \" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \" cache %1, 0x000($1); cache %1, 0x040($1)\n" \" cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \" .set pop\n" \
@@ -429,39 +431,38 @@ static inline void invalidate_tcache_page(unsigned long addr)" .set mips64r6\n" \" .set noat\n" \" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ -" cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ -" addiu $1, %0, 0x100\n" \ + " "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ +" cache %1, 0x000($1); cache %1, 0x080($1)\n" \ + " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ + " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ " .set pop\n" \ : \ : "r" (base), \
Signature · 1 line
1.9.3
PATCH 16/31 MIPS: asm: spinlock: Fix addiu instruction for R10000_LLSC_WAR case
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
Commit 5753762cbd1c("MIPS: asm: spinlock: Replace "sub" instruction with "addiu") replaced the "sub" instruction with addiu but it did not update the immediate value in the R10000_LLSC_WAR case.
Patchwork: https://patchwork.linux-mips.org/patch/9385/
--- arch/mips/include/asm/spinlock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/include/asm/spinlock.h +1 -1
@@ -263,7 +263,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)if (R10000_LLSC_WAR ) { __asm__ __volatile__("1: ll %1, %2 # arch_read_unlock \n" -" addiu %1, 1 \n" +" addiu %1, -1 \n" " sc %1, %0 \n" " beqzl %1, 1b \n" : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp)
Signature · 1 line
1.9.3
PATCH 17/31 MIPS: kernel: entry.S: Set correct ISA level for mips_ihb
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
Commit 6ebb496ffc7e("MIPS: kernel: entry.S: Add MIPS R6 related definitions") added the MIPSR6 definition but it did not update the ISA level of the actual assembly code so a pre-MIPSR6 jr.hb instruction was generated instead. Fix this by using the MISP_ISA_LEVEL_RAW macro.
Patchwork: https://patchwork.linux-mips.org/patch/9386/
--- arch/mips/kernel/entry.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/mips/kernel/entry.S +2 -1
@@ -10,6 +10,7 @@ #include <asm/asm.h> #include <asm/asmmacro.h> +#include <asm/compiler.h> #include <asm/regdef.h> #include <asm/mipsregs.h> #include <asm/stackframe.h>
@@ -185,7 +186,7 @@ syscall_exit_work: * For C code use the inline version named instruction_hazard(). */ LEAF(mips_ihb) - .set mips32r2 + .set MIPS_ISA_LEVEL_RAW jr.hb ra nop END(mips_ihb)
Signature · 1 line
1.9.3
PATCH 18/31 MIPS: Fix cpu_has_mips_r2_exec_hazard.
In reply to Ralf BaechleReturns a non-zero value if the current processor implementation requires an IHB instruction to deal with an instruction hazard as per MIPS R2 architecture specification, zero otherwise.
For a discussion, see http://patchwork.linux-mips.org/patch/9539/.
--- arch/mips/include/asm/cpu-features.h | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-)
arch/mips/include/asm/cpu-features.h +32 -1
@@ -238,8 +238,39 @@/* MIPSR2 and MIPSR6 have a lot of similarities */ #define cpu_has_mips_r2_r6 (cpu_has_mips_r2 | cpu_has_mips_r6) +/* +* cpu_has_mips_r2_exec_hazard - return if IHB is required on current processor +* +* Returns non-zero value if the current processor implementation requires +* an IHB instruction to deal with an instruction hazard as per MIPS R2 +* architecture specification, zero otherwise. +*/ #ifndef cpu_has_mips_r2_exec_hazard -#define cpu_has_mips_r2_exec_hazard (cpu_has_mips_r2 | cpu_has_mips_r6) +#define cpu_has_mips_r2_exec_hazard \ +({ \ + int __res; \ + \ + switch (current_cpu_type()) { \ + case CPU_M14KC: \ + case CPU_74K: \ + case CPU_1074K: \ + case CPU_PROAPTIV: \ + case CPU_P5600: \ + case CPU_M5150: \ + case CPU_QEMU_GENERIC: \ + case CPU_CAVIUM_OCTEON: \ + case CPU_CAVIUM_OCTEON_PLUS: \ + case CPU_CAVIUM_OCTEON2: \ + case CPU_CAVIUM_OCTEON3: \ + __res = 0; \ + break; \ + \ + default: \ + __res = 1; \ + } \ + \ + __res; \ +})#endif /*
Signature · 1 line
1.9.3
PATCH 19/31 MIPS: Octeon: Delete override of cpu_has_mips_r2_exec_hazard.
In reply to Ralf BaechleThis is no longer needed with the fixed, new and improved definition of cpu_has_mips_r2_exec_hazard in <asm/cpu-features.h>.
For a discussion, see http://patchwork.linux-mips.org/patch/9539/.
--- arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h | 1 - 1 file changed, 1 deletion(-)
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +0 -1
@@ -50,7 +50,6 @@#define cpu_has_mips32r2 0#define cpu_has_mips64r1 0#define cpu_has_mips64r2 1 -#define cpu_has_mips_r2_exec_hazard 0#define cpu_has_dsp 0#define cpu_has_dsp2 0#define cpu_has_mipsmt 0
Signature · 1 line
1.9.3
PATCH 20/31 Revert "MIPS: Avoid pipeline stalls on some MIPS32R2 cores."
In reply to Ralf BaechleFor a discussion, see http://patchwork.linux-mips.org/patch/9539/.
This reverts commit 625c0a21700bdb90844d926a1508a17a77e369c9.
--- arch/mips/mm/tlbex.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-)
arch/mips/mm/tlbex.c +2 -19
@@ -512,26 +512,9 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,case tlb_indexed: tlbw = uasm_i_tlbwi;break ; } -if (cpu_has_mips_r2_exec_hazard) { -/* -* The architecture spec says an ehb is required here, -* but a number of cores do not have the hazard and -* using an ehb causes an expensive pipeline stall. -*/ -switch (current_cpu_type ()) { -case CPU_M14KC : -case CPU_74K : -case CPU_1074K : -case CPU_PROAPTIV : -case CPU_P5600 : -case CPU_M5150 : -case CPU_QEMU_GENERIC : -break ; - -default : +if (cpu_has_mips_r2_r6) { +if (cpu_has_mips_r2_exec_hazard)uasm_i_ehb (p); -break ; - }tlbw (p);return ; }
Signature · 1 line
1.9.3
PATCH 21/31 MIPS: Malta: Detect and fix bad memsize values
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
memsize denotes the amount of RAM we can access from kseg{0,1} and that should be up to 256M. In case the bootloader reports a value higher than that (perhaps reporting all the available RAM) it's best if we fix it ourselves and just warn the user about that. This is usually a problem with the bootloader and/or its environment.
[[email protected]: Remove useless parens as suggested bei Sergei. Reformat long pr_warn statement to fit into 80 column limit.]
Patchwork: https://patchwork.linux-mips.org/patch/9362/
--- arch/mips/mti-malta/malta-memory.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/mips/mti-malta/malta-memory.c +6 -0
@@ -53,6 +53,12 @@ fw_memblock_t * __init fw_getmdesc(int eva)pr_warn ("memsize not set in YAMON, set to default (32Mb)\n" ); physical_memsize =0x02000000 ; }else { +if (memsize > (256 <<20 )) {/* memsize should be capped to 256M */ +pr_warn ("Unsupported memsize value (0x%lx) detected! " +"Using 0x10000000 (256M) instead\n" , + memsize); + memsize =256 <<20 ; + }/* If ememsize is set, then set physical_memsize to that */ physical_memsize = ememsize ? : memsize; }
Signature · 1 line
1.9.3
PATCH 22/31 SSB: fix Kconfig dependencies
In reply to Ralf BaechleFrom: Adrien Schildknecht <[email protected]>
The commit 21400f252a97 ("MIPS: BCM47XX: Make ssb init NVRAM instead of bcm47xx polling it") introduces a dependency to SSB_SFLASH but did not add it to the Kconfig.
drivers/ssb/driver_mipscore.c:216:36: error: 'struct ssb_mipscore' has no member named 'sflash'
struct ssb_sflash *sflash = &mcore->sflash;
^
drivers/ssb/driver_mipscore.c:249:12: error: dereferencing pointer to
incomplete type
if (sflash->present) {
^Patchwork: https://patchwork.linux-mips.org/patch/9598/
--- drivers/ssb/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/ssb/Kconfig +1 -0
@@ -130,6 +130,7 @@ config SSB_DRIVER_MIPS bool "SSB Broadcom MIPS core driver" depends on SSB && MIPS select SSB_SERIAL + select SSB_SFLASH help Driver for the Sonics Silicon Backplane attached Broadcom MIPS core.
Signature · 1 line
1.9.3
PATCH 23/31 MIPS: ralink: Fix bad config symbol in PCI makefile.
In reply to Ralf BaechleFrom: John Crispin <[email protected]>
A wrong symbol is referenced by commit 187c26ddf0b2 ("MIPS: ralink: add rt2880 pci driver"). Fix this by changing it to the correct symbol.
Patchwork: https://patchwork.linux-mips.org/patch/9298/
--- arch/mips/pci/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/pci/Makefile +1 -1
@@ -43,7 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o obj-$(CONFIG_LANTIQ) += fixup-lantiq.o obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o -obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o +obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
Signature · 1 line
1.9.3
PATCH 24/31 MIPS: ralink: add missing symbol for RALINK_ILL_ACC
In reply to Ralf BaechleFrom: John Crispin <[email protected]>
A driver was added in commit 5433acd81e87 ("MIPS: ralink: add illegal access driver") without the Kconfig section being added. Fix this by adding the symbol to the Kconfig file.
Patchwork: https://patchwork.linux-mips.org/patch/9299/
--- arch/mips/ralink/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
arch/mips/ralink/Kconfig +5 -0
@@ -7,6 +7,11 @@ config CLKEVT_RT3352 select CLKSRC_OF select CLKSRC_MMIO +config RALINK_ILL_ACC + bool + depends on SOC_RT305X + default y + choice prompt "Ralink SoC selection" default SOC_RT305X
Signature · 1 line
1.9.3
PATCH 25/31 MIPS: lose_fpu(): Disable FPU when MSA enabled
In reply to Ralf BaechleFrom: James Hogan <[email protected]>
The lose_fpu() function only disables the FPU in CP0_Status.CU1 if the FPU is in use and MSA isn't enabled.
This isn't necessarily a problem because KSTK_STATUS(current), the version of CP0_Status stored on the kernel stack on entry from user mode, does always get updated and gets restored when returning to user mode, but I don't think it was intended, and it is inconsistent with the case of only the FPU being in use. Sometimes leaving the FPU enabled may also mask kernel bugs where FPU operations are executed when the FPU might not be enabled.
So lets disable the FPU in the MSA case too.
Patchwork: https://patchwork.linux-mips.org/patch/9323/
--- arch/mips/include/asm/fpu.h | 1 + 1 file changed, 1 insertion(+)
arch/mips/include/asm/fpu.h +1 -0
@@ -170,6 +170,7 @@ static inline void lose_fpu(int save) }disable_msa ();clear_thread_flag (TIF_USEDMSA ); +__disable_fpu (); }else if (is_fpu_owner ()) {if (save)_save_fp (current);
Signature · 1 line
1.9.3
PATCH 26/31 MIPS: smp-cps: cpu_set FPU mask if FPU present
In reply to Ralf BaechleFrom: Niklas Cassel <[email protected]>
If we have an FPU, enroll ourselves in the FPU-full mask. Matching the MT_SMP and CMP implementations of smp_setup.
Patchwork: https://patchwork.linux-mips.org/patch/8948/
--- arch/mips/kernel/smp-cps.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/mips/kernel/smp-cps.c +6 -0
@@ -88,6 +88,12 @@ static void __init cps_smp_setup(void)/* Make core 0 coherent with everything */ write_gcr_cl_coherence (0xff ); + +#ifdef CONFIG_MIPS_MT_FPAFF +/* If we have an FPU, enroll ourselves in the FPU-full mask */ +if (cpu_has_fpu) +cpu_set (0 , mt_fpu_cpumask); +#endif /* CONFIG_MIPS_MT_FPAFF */ }static void __init cps_prepare_cpus (unsigned int max_cpus)
Signature · 1 line
1.9.3
PATCH 27/31 MIPS: Hibernate: flush TLB entries earlier
In reply to Ralf BaechleFrom: Huacai Chen <[email protected]>
We found that TLB mismatch not only happens after kernel resume, but also happens during snapshot restore. So move it to the beginning of swsusp_arch_suspend().
Patchwork: https://patchwork.linux-mips.org/patch/9621/
--- arch/mips/power/hibernate.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/mips/power/hibernate.S +2 -1
@@ -30,6 +30,8 @@ LEAF(swsusp_arch_suspend) END(swsusp_arch_suspend) LEAF(swsusp_arch_resume) + /* Avoid TLB mismatch during and after kernel resume */ + jal local_flush_tlb_all PTR_L t0, restore_pblist 0: PTR_L t1, PBE_ADDRESS(t0) /* source */
@@ -43,7 +45,6 @@ LEAF(swsusp_arch_resume) bne t1, t3, 1b PTR_L t0, PBE_NEXT(t0) bnez t0, 0b - jal local_flush_tlb_all /* Avoid TLB mismatch after kernel resume */ PTR_LA t0, saved_regs PTR_L ra, PT_R31(t0) PTR_L sp, PT_R29(t0)
Signature · 1 line
1.9.3
PATCH 28/31 MIPS: Kconfig: Disable SMP/CPS for 64-bit
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
A 64-bit build for Malta produces far too many build problems when SMP/CPS is selected. Moreover, there is currently no 64-bit product with SMP/CPS so we disable SMP/CPS when building for 64-bit until it is properly supported.
Patchwork: https://patchwork.linux-mips.org/patch/8573/
--- arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/Kconfig +1 -1
@@ -2177,7 +2177,7 @@ config MIPS_CMP config MIPS_CPS bool "MIPS Coherent Processing System support" - depends on SYS_SUPPORTS_MIPS_CPS + depends on SYS_SUPPORTS_MIPS_CPS && !64BIT select MIPS_CM select MIPS_CPC select MIPS_CPS_PM if HOTPLUG_CPU
Signature · 1 line
1.9.3
PATCH 29/31 MIPS: BCM47XX: Fix detecting Microsoft MN-700 & Asus WL500G
In reply to Ralf BaechleFrom: Rafał Miłecki <[email protected]>
Since the day of adding this code it was broken. We were iterating over a wrong array and checking for wrong NVRAM entry.
Patchwork: https://patchwork.linux-mips.org/patch/9654/
--- arch/mips/bcm47xx/board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/mips/bcm47xx/board.c +2 -2
@@ -247,8 +247,8 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void) }if (bcm47xx_nvram_getenv ("hardware_version" , buf1,sizeof (buf1)) >=0 && -bcm47xx_nvram_getenv ("boardtype" , buf2,sizeof (buf2)) >=0 ) { -for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) { +bcm47xx_nvram_getenv ("boardnum" , buf2,sizeof (buf2)) >=0 ) { +for (e2 = bcm47xx_board_list_hw_version_num; e2->value1; e2++) {if (!strstarts (buf1, e2->value1) && !strcmp (buf2, e2->value2))return &e2->board;
Signature · 1 line
1.9.3
PATCH 30/31 MIPS: asm: elf: Set O32 default FPU flags
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
Set good default FPU flags (FR0) for O32 binaries similar to what the kernel does for the N64/N32 ones. This also fixes a regression introduced in commit 46490b572544 ("MIPS: kernel: elf: Improve the overall ABI and FPU mode checks") when MIPS_O32_FP64_SUPPORT is disabled. In that case, the mips_set_personality_fp() did not set the FPU mode at all because it assumed that the FPU mode was already set properly. That led to O32 userland problems.
Patchwork: http://patchwork.linux-mips.org/patch/9344/
--- arch/mips/include/asm/elf.h | 5 +++++ 1 file changed, 5 insertions(+)
arch/mips/include/asm/elf.h +5 -0
@@ -294,6 +294,9 @@ do { \if (personality (current->personality) !=PER_LINUX ) \set_personality (PER_LINUX ); \ \ +clear_thread_flag (TIF_HYBRID_FPREGS ); \ +set_thread_flag (TIF_32BIT_FPREGS ); \ + \mips_set_personality_fp (state); \ \ current->thread.abi = &mips_abi; \
@@ -319,6 +322,8 @@ do { \ do { \ set_thread_flag(TIF_32BIT_REGS); \ set_thread_flag(TIF_32BIT_ADDR); \ + clear_thread_flag(TIF_HYBRID_FPREGS); \ + set_thread_flag(TIF_32BIT_FPREGS); \ \ mips_set_personality_fp(state); \ \
Signature · 1 line
1.9.3
PATCH 31/31 MIPS: Makefile: Fix MIPS ASE detection code
In reply to Ralf BaechleFrom: Markos Chandras <[email protected]>
Commit 32098ec7bcba ("MIPS: Makefile: Move the ASEs checks after setting the core's CFLAGS") re-arranged the MIPS ASE detection code and also added the current cflags to the detection logic. However, this introduced a few bugs. First of all, the mips-cflags should not be quoted since that ends up being passed as a string to subsequent commands leading to broken detection from the cc-option-* tools. Moreover, in order to avoid duplicating the cflags-y because of how cc-option works, we rework the logic so we pass only those cflags which are needed by the selected ASE. Finally, fix some typos resulting in MSA not being detected correctly.
Patchwork: https://patchwork.linux-mips.org/patch/9661/
--- arch/mips/Makefile | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
arch/mips/Makefile +10 -4
@@ -197,11 +197,17 @@ endif # Warning: the 64-bit MIPS architecture does not support the `smartmips' extension # Pass -Wa,--no-warn to disable all assembler warnings until the kernel code has # been fixed properly. -mips-cflags := "$(cflags-y)" -cflags-$(CONFIG_CPU_HAS_SMARTMIPS) += $(call cc-option,$(mips-cflags),-msmartmips) -Wa,--no-warn -cflags-$(CONFIG_CPU_MICROMIPS) += $(call cc-option,$(mips-cflags),-mmicromips) +mips-cflags := $(cflags-y) +ifeq ($(CONFIG_CPU_HAS_SMARTMIPS),y) +smartmips-ase := $(call cc-option-yn,$(mips-cflags) -msmartmips) +cflags-$(smartmips-ase) += -msmartmips -Wa,--no-warn +endif +ifeq ($(CONFIG_CPU_MICROMIPS),y) +micromips-ase := $(call cc-option-yn,$(mips-cflags) -mmicromips) +cflags-$(micromips-ase) += -mmicromips +endif ifeq ($(CONFIG_CPU_HAS_MSA),y) -toolchain-msa := $(call cc-option-yn,-$(mips-cflags),mhard-float -mfp64 -Wa$(comma)-mmsa) +toolchain-msa := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$(comma)-mmsa) cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA endif
Signature · 1 line
1.9.3