Commit 01acd3ef authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm

Pull ARM fixes from Russell King:
 "A number of fixes:

  Patrik found a problem with preempt counting in the VFP assembly
  functions which can cause the preempt count to be upset.

  Nicolas fixed a problem with the parsing of the DT when it straddles a
  1MB boundary.

  Subhash Jadavani reported a problem with sparsemem and our highmem
  support for cache maintanence for DMA areas, and TI found a bug in
  their strongly ordered memory mapping type.

  Also, three fixes by way of Will Deacon's tree from Dave Martin for
  instruction compatibility and Marc Zyngier to fix hypervisor boot mode
  issues."

* 'fixes' of git://git.linaro.org/people/rmk/linux-arm:
  ARM: 7629/1: mm: Fix missing XN flag for for MT_MEMORY_SO
  ARM: DMA: Fix struct page iterator in dma_cache_maint() to work with sparsemem
  ARM: 7628/1: head.S: map one extra section for the ATAG/DTB area
  ARM: 7627/1: Predicate preempt logic on PREEMP_COUNT not PREEMPT alone
  ARM: virt: simplify __hyp_stub_install epilog
  ARM: virt: boot secondary CPUs through the right entry point
  ARM: virt: Avoid bx instruction for compatibility with <=ARMv4
parents 1496ec13 210b1847
...@@ -246,6 +246,7 @@ __create_page_tables: ...@@ -246,6 +246,7 @@ __create_page_tables:
/* /*
* Then map boot params address in r2 if specified. * Then map boot params address in r2 if specified.
* We map 2 sections in case the ATAGs/DTB crosses a section boundary.
*/ */
mov r0, r2, lsr #SECTION_SHIFT mov r0, r2, lsr #SECTION_SHIFT
movs r0, r0, lsl #SECTION_SHIFT movs r0, r0, lsl #SECTION_SHIFT
...@@ -253,6 +254,8 @@ __create_page_tables: ...@@ -253,6 +254,8 @@ __create_page_tables:
addne r3, r3, #PAGE_OFFSET addne r3, r3, #PAGE_OFFSET
addne r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER) addne r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
orrne r6, r7, r0 orrne r6, r7, r0
strne r6, [r3], #1 << PMD_ORDER
addne r6, r6, #1 << SECTION_SHIFT
strne r6, [r3] strne r6, [r3]
#ifdef CONFIG_DEBUG_LL #ifdef CONFIG_DEBUG_LL
...@@ -331,7 +334,7 @@ ENTRY(secondary_startup) ...@@ -331,7 +334,7 @@ ENTRY(secondary_startup)
* as it has already been validated by the primary processor. * as it has already been validated by the primary processor.
*/ */
#ifdef CONFIG_ARM_VIRT_EXT #ifdef CONFIG_ARM_VIRT_EXT
bl __hyp_stub_install bl __hyp_stub_install_secondary
#endif #endif
safe_svcmode_maskall r9 safe_svcmode_maskall r9
......
...@@ -99,7 +99,7 @@ ENTRY(__hyp_stub_install_secondary) ...@@ -99,7 +99,7 @@ ENTRY(__hyp_stub_install_secondary)
* immediately. * immediately.
*/ */
compare_cpu_mode_with_primary r4, r5, r6, r7 compare_cpu_mode_with_primary r4, r5, r6, r7
bxne lr movne pc, lr
/* /*
* Once we have given up on one CPU, we do not try to install the * Once we have given up on one CPU, we do not try to install the
...@@ -111,7 +111,7 @@ ENTRY(__hyp_stub_install_secondary) ...@@ -111,7 +111,7 @@ ENTRY(__hyp_stub_install_secondary)
*/ */
cmp r4, #HYP_MODE cmp r4, #HYP_MODE
bxne lr @ give up if the CPU is not in HYP mode movne pc, lr @ give up if the CPU is not in HYP mode
/* /*
* Configure HSCTLR to set correct exception endianness/instruction set * Configure HSCTLR to set correct exception endianness/instruction set
...@@ -120,7 +120,8 @@ ENTRY(__hyp_stub_install_secondary) ...@@ -120,7 +120,8 @@ ENTRY(__hyp_stub_install_secondary)
* Eventually, CPU-specific code might be needed -- assume not for now * Eventually, CPU-specific code might be needed -- assume not for now
* *
* This code relies on the "eret" instruction to synchronize the * This code relies on the "eret" instruction to synchronize the
* various coprocessor accesses. * various coprocessor accesses. This is done when we switch to SVC
* (see safe_svcmode_maskall).
*/ */
@ Now install the hypervisor stub: @ Now install the hypervisor stub:
adr r7, __hyp_stub_vectors adr r7, __hyp_stub_vectors
...@@ -155,14 +156,7 @@ THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE ...@@ -155,14 +156,7 @@ THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE
1: 1:
#endif #endif
bic r7, r4, #MODE_MASK bx lr @ The boot CPU mode is left in r4.
orr r7, r7, #SVC_MODE
THUMB( orr r7, r7, #PSR_T_BIT )
msr spsr_cxsf, r7 @ This is SPSR_hyp.
__MSR_ELR_HYP(14) @ msr elr_hyp, lr
__ERET @ return, switching to SVC mode
@ The boot CPU mode is left in r4.
ENDPROC(__hyp_stub_install_secondary) ENDPROC(__hyp_stub_install_secondary)
__hyp_stub_do_trap: __hyp_stub_do_trap:
...@@ -200,7 +194,7 @@ ENDPROC(__hyp_get_vectors) ...@@ -200,7 +194,7 @@ ENDPROC(__hyp_get_vectors)
@ fall through @ fall through
ENTRY(__hyp_set_vectors) ENTRY(__hyp_set_vectors)
__HVC(0) __HVC(0)
bx lr mov pc, lr
ENDPROC(__hyp_set_vectors) ENDPROC(__hyp_set_vectors)
#ifndef ZIMAGE #ifndef ZIMAGE
......
...@@ -774,25 +774,27 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, ...@@ -774,25 +774,27 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
size_t size, enum dma_data_direction dir, size_t size, enum dma_data_direction dir,
void (*op)(const void *, size_t, int)) void (*op)(const void *, size_t, int))
{ {
unsigned long pfn;
size_t left = size;
pfn = page_to_pfn(page) + offset / PAGE_SIZE;
offset %= PAGE_SIZE;
/* /*
* A single sg entry may refer to multiple physically contiguous * A single sg entry may refer to multiple physically contiguous
* pages. But we still need to process highmem pages individually. * pages. But we still need to process highmem pages individually.
* If highmem is not configured then the bulk of this loop gets * If highmem is not configured then the bulk of this loop gets
* optimized out. * optimized out.
*/ */
size_t left = size;
do { do {
size_t len = left; size_t len = left;
void *vaddr; void *vaddr;
page = pfn_to_page(pfn);
if (PageHighMem(page)) { if (PageHighMem(page)) {
if (len + offset > PAGE_SIZE) { if (len + offset > PAGE_SIZE)
if (offset >= PAGE_SIZE) {
page += offset / PAGE_SIZE;
offset %= PAGE_SIZE;
}
len = PAGE_SIZE - offset; len = PAGE_SIZE - offset;
}
vaddr = kmap_high_get(page); vaddr = kmap_high_get(page);
if (vaddr) { if (vaddr) {
vaddr += offset; vaddr += offset;
...@@ -809,7 +811,7 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, ...@@ -809,7 +811,7 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
op(vaddr, len, dir); op(vaddr, len, dir);
} }
offset = 0; offset = 0;
page++; pfn++;
left -= len; left -= len;
} while (left); } while (left);
} }
......
...@@ -283,7 +283,7 @@ static struct mem_type mem_types[] = { ...@@ -283,7 +283,7 @@ static struct mem_type mem_types[] = {
}, },
[MT_MEMORY_SO] = { [MT_MEMORY_SO] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
L_PTE_MT_UNCACHED, L_PTE_MT_UNCACHED | L_PTE_XN,
.prot_l1 = PMD_TYPE_TABLE, .prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_S | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_S |
PMD_SECT_UNCACHED | PMD_SECT_XN, PMD_SECT_UNCACHED | PMD_SECT_XN,
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
@ IRQs disabled. @ IRQs disabled.
@ @
ENTRY(do_vfp) ENTRY(do_vfp)
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT_COUNT
ldr r4, [r10, #TI_PREEMPT] @ get preempt count ldr r4, [r10, #TI_PREEMPT] @ get preempt count
add r11, r4, #1 @ increment it add r11, r4, #1 @ increment it
str r11, [r10, #TI_PREEMPT] str r11, [r10, #TI_PREEMPT]
...@@ -35,7 +35,7 @@ ENTRY(do_vfp) ...@@ -35,7 +35,7 @@ ENTRY(do_vfp)
ENDPROC(do_vfp) ENDPROC(do_vfp)
ENTRY(vfp_null_entry) ENTRY(vfp_null_entry)
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT_COUNT
get_thread_info r10 get_thread_info r10
ldr r4, [r10, #TI_PREEMPT] @ get preempt count ldr r4, [r10, #TI_PREEMPT] @ get preempt count
sub r11, r4, #1 @ decrement it sub r11, r4, #1 @ decrement it
...@@ -53,7 +53,7 @@ ENDPROC(vfp_null_entry) ...@@ -53,7 +53,7 @@ ENDPROC(vfp_null_entry)
__INIT __INIT
ENTRY(vfp_testing_entry) ENTRY(vfp_testing_entry)
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT_COUNT
get_thread_info r10 get_thread_info r10
ldr r4, [r10, #TI_PREEMPT] @ get preempt count ldr r4, [r10, #TI_PREEMPT] @ get preempt count
sub r11, r4, #1 @ decrement it sub r11, r4, #1 @ decrement it
......
...@@ -168,7 +168,7 @@ vfp_hw_state_valid: ...@@ -168,7 +168,7 @@ vfp_hw_state_valid:
@ else it's one 32-bit instruction, so @ else it's one 32-bit instruction, so
@ always subtract 4 from the following @ always subtract 4 from the following
@ instruction address. @ instruction address.
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT_COUNT
get_thread_info r10 get_thread_info r10
ldr r4, [r10, #TI_PREEMPT] @ get preempt count ldr r4, [r10, #TI_PREEMPT] @ get preempt count
sub r11, r4, #1 @ decrement it sub r11, r4, #1 @ decrement it
...@@ -192,7 +192,7 @@ look_for_VFP_exceptions: ...@@ -192,7 +192,7 @@ look_for_VFP_exceptions:
@ not recognised by VFP @ not recognised by VFP
DBGSTR "not VFP" DBGSTR "not VFP"
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT_COUNT
get_thread_info r10 get_thread_info r10
ldr r4, [r10, #TI_PREEMPT] @ get preempt count ldr r4, [r10, #TI_PREEMPT] @ get preempt count
sub r11, r4, #1 @ decrement it sub r11, r4, #1 @ decrement it
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment