/Documentation/arm/msm/emulate_domain_manager.txt
https://bitbucket.org/sammyz/iscream_thunderc-2.6.35-rebase · Plain Text · 282 lines · 203 code · 79 blank · 0 comment · 0 complexity · 4d0044513d85543797d88b089dd9be0e MD5 · raw file
- Copyright (c) 2009, Code Aurora Forum. All rights reserved.
- Redistribution and use in source form and compiled forms (SGML, HTML, PDF,
- PostScript, RTF and so forth) with or without modification, are permitted
- provided that the following conditions are met:
- Redistributions in source form must retain the above copyright notice, this
- list of conditions and the following disclaimer as the first lines of this
- file unmodified.
- Redistributions in compiled form (transformed to other DTDs, converted to
- PDF, PostScript, RTF and other formats) must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- THIS DOCUMENTATION IS PROVIDED BY THE CODE AURORA FORUM "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD
- DOCUMENTATION PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- Introduction
- ============
- 8x50 chipset requires the ability to disable HW domain manager function.
- The ARM MMU architecture has a feature known as domain manager mode.
- Briefly each page table, section, or supersection is assigned a domain.
- Each domain can be globally configured to NoAccess, Client, or Manager
- mode. These global configurations allow the access permissions of the
- entire domain to be changed simultaneously.
- The domain manger emulation is required to fix a HW problem on the 8x50
- chipset. The problem is simple to repair except when domain manager mode
- is enabled. The emulation allows the problem to be completely resolved.
- Hardware description
- ====================
- When domain manager mode is enabled on a specific domain, the MMU
- hardware ignores the access permission bits and the execute never bit. All
- accesses, to memory in the domain, are granted full read, write,
- execute permissions.
- The mode of each domain is controlled by a field in the cp15 dacr register.
- Each domain can be globally configured to NoAccess, Client, or Manager mode.
- See: ARMv7 Architecture Reference Manual
- Software description
- ====================
- In order to disable domain manager mode the equivalent HW functionality must
- be emulated in SW. Any attempts to enable domain manager mode, must be
- intercepted.
- Because domain manager mode is not enabled, permissions for the
- associated domain will remain restricted. Permission faults will be generated.
- The permission faults will be intercepted. The faulted pages/sections will
- be modified to grant full access and execute permissions.
- The modified page tables must be restored when exiting domain manager mode.
- Design
- ======
- Design Goals:
- Disable Domain Manager Mode
- Exact SW emulation of Domain Manager Mode
- Minimal Kernel changes
- Minimal Security Risk
- Design Decisions:
- Detect kernel page table modifications on restore
- Direct ARMv7 HW MMU table manipulation
- Restore emulation modified MMU entries on context switch
- No need to restore MMU entries for MMU entry copy operations
- Invalidate TLB entries on modification
- Store Domain Manager bits in memory
- 8 entry MMU entry cache
- Use spin_lock_irqsave to protect domain manipulation
- Assume no split MMU table
- Design Discussion:
- Detect kernel page table modifications on restore -
- When restoring original page/section permission faults, the submitted design
- verifies the MMU entry has not been modified. The kernel modifies MMU
- entries for the following purposes : create a memory mapping, release a
- memory mapping, add permissions during a permission fault, and map a page
- during a translation fault. The submitted design works with the listed
- scenarios. The translation fault and permission faults simply do not happen on
- relevant entries (valid entries with full access permissions). The alternative
- would be to hook every MMU table modification. The alternative greatly
- increases complexity and code maintenance issues.
- Direct ARMv7 HW MMU table manipulation -
- The natural choice would be to use the kernel provided mechanism to manipulate
- MMU page table entries. The ARM MMU interface is described in pgtable.h.
- This interface is complicated by the Linux implementation. The level 1 pgd
- entries are treated and manipulated as entry pairs. The level 2 entries are
- shadowed and cloned. The compromise was chosen to actually use the ARMv7 HW
- registers to walk and modify the MMU table entries. The choice limits the
- usage of this implementation to ARMv7 and similar ARM MMU architectures. Since
- this implementation is targeted at fixing an issue in 8x50 ARMv7, the choice is
- logical. The HW manipulation is in distinct low level functions. These could
- easily be replaced or generalized to support other architectures as necessary.
- Restore emulation modified MMU entries on context switch -
- This additional hook was added to minimize performance impact. By guaranteeing
- the ASID will not change during the emulation, the emulation may invalidate each
- entry by MVA & ASID. Only the affected page table entries will be removed from
- the TLB cache. The performance cost of the invalidate on context switch is near
- zero. Typically on context switch the domain mode would also change, forcing a
- complete restore of all modified MMU entries. The alternative would be to
- invalidate the entire TLB every time a table entry is restored.
- No need to restore MMU entries for copy operations -
- Operations which copy MMU entries are relatively rare in the kernel. Because
- we modify the level 2 pte entries directly in hardware, the Linux shadow copies
- are left untouched. The kernel treats the shadow copies as the primary pte
- entry. Any pte copy operations would be unaffected by the HW modification.
- On translation section fault, pgd entries are copied from the kernel master
- page table to the current thread page table. Since we restore MMU entries on
- context switch, we guarantee the master table will not contain modifications,
- while faulting on a process local entry. Other read, modify write operations
- occur during permission fault handling. Since we open permission on modified
- entries, these do not need to be restored, because we guarantee these
- permission fault operations will not happen.
- Invalidate TLB entries on modification -
- No real choice here. This is more of a design requirement. On permission
- fault, the MMU entry with restricted permissions will be in the TLB. To open
- access permissions, the TLB entry must be invalidated. Otherwise the access
- will permission fault again. Upon restoring original MMU entries, the TLB
- must be invalidated to restrict memory access.
- Store Domain Manager bits in memory -
- There was only one alternative here. 2.6.29 kernel only uses 3 of 16
- possible domains. Additional bits in dacr could be used to store the
- manager bits. This would allow faster access to the manager bits.
- Overall this would reduce any performance impact. The performance
- needs did not seem to justify the added weirdness.
- 8 entry MMU entry cache-
- The size of the modified MMU entry cache is somewhat arbitrary. The thought
- process is that typically, a thread is using two pointers to perform a copy
- operation. In this case only 2 entries would be required. One could imagine
- a more complicated operation, a masked copy for instance, which would require
- more pointers. 8 pointer seemed to be large enough to minimize risk of
- permission fault thrashing. The disadvantage of a larger cache would simply
- be a longer list of entries to restore.
- Use spin_lock_irqsave to protect domain manipulation -
- The obvious choice.
- Assume no split MMU table -
- This same assumption is documented in cpu_v7_switch_mm.
- Power Management
- ================
- Not affected.
- SMP/multi-core
- ==============
- SMP/multicore not supported. This is intended as a 8x50 workaround.
- Security
- ========
- MMU page/section permissions must be manipulated correctly to emulate domain
- manager mode. If page permission are left in full access mode, any process
- can read associated memory.
- Performance
- ===========
- Performance should be impacted only minimally. When emulating domain manager
- mode, there is overhead added to MMU table/context switches, set_domain()
- calls, data aborts, and prefetch aborts.
- Normally the kernel operates with domain != DOMAIN_MANAGER. In this case the
- overhead is minimal. An additional check is required to see if domain manager
- mode is on. This minimal code is added to each of emulation entry points :
- set, data abort, prefetch abort, and MMU table/context switch.
- Initial accesses to a MMU protected page/section will generate a permission
- fault. The page will be manipulated to grant full access permissions and
- the access will be retried. This will typically require 2-3 page table
- walks.
- On a context switch, all modified MMU entries will be restored. On thread
- resume, additional accesses will be treated as initial accesses.
- Interface
- =========
- The emulation does not have clients. It is hooked to the kernel through a
- small list of functions.
- void emulate_domain_manager_set(u32 domain);
- int emulate_domain_manager_data_abort(u32 dfsr, u32 dfar);
- int emulate_domain_manager_prefetch_abort(u32 ifsr, u32 ifar);
- void emulate_domain_manager_switch_mm(
- unsigned long pgd_phys,
- struct mm_struct *mm,
- void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *));
- emulate_domain_manager_set() is the set_domain handler. This replaces the
- direct manipulation of CP15 dacr with a function call. This allows emulation
- to prevent setting dacr manager bits. It also allows emulation to restore
- page/section permissions when domain manger is disabled.
- emulate_domain_manager_data_abort() handles data aborts caused by domain
- not being set in HW, and handles section/page manipulation.
- emulate_domain_manager_prefetch_abort() is the similar prefetch abort handler.
- emulate_domain_manager_switch_mm() handles MMU table and context switches.
- This notifies the emulation that the MMU context is changing. Allowing the
- emulation to restore page table entry permission before switching contexts.
- Config options
- ==============
- This option is enable/disable by the EMULATE_DOMAIN_MANAGER_V7 option.
- Dependencies
- ============
- Implementation is for ARMv7, MMU, and !SMP. Targets solving issue for 8x50
- chipset.
- User space utilities
- ====================
- None
- Other
- =====
- Code is implemented in kernel/arch/arm/mm.
- arch/arm/mm/emulate_domain_manager.c contains comments. No additional public
- documentation available or planned.
- Known issues
- ============
- No intent to support SMP or non ARMv7 architectures
- To do
- =====
- None