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
This commit is contained in:
commit
01acd3efd7
@ -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:
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
* 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)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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)
|
|||||||
* 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
|
|||||||
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)
|
|||||||
@ 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,
|
|||||||
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,
|
|||||||
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[] = {
|
|||||||
},
|
},
|
||||||
[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 @@
|
|||||||
@ 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)
|
|||||||
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)
|
|||||||
|
|
||||||
__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:
|
|||||||
@ 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:
|
|||||||
@ 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
|
||||||
|
Loading…
Reference in New Issue
Block a user