Next: , Previous: Data Transfer, Up: Virtual Memory Interface

5.4 Memory Attributes

— Function: kern_return_t vm_region (vm_task_t target_task, vm_address_t *address, vm_size_t *size, vm_prot_t *protection, vm_prot_t *max_protection, vm_inherit_t *inheritance, boolean_t *shared, memory_object_name_t *object_name, vm_offset_t *offset)

The function vm_region returns a description of the specified region of target_task's virtual address space. vm_region begins at address and looks forward through memory until it comes to an allocated region. If address is within a region, then that region is used. Various bits of information about the region are returned. If address was not within a region, then address is set to the start of the first region which follows the incoming value. In this way an entire address space can be scanned.

The size returned is the size of the located region in bytes. protection is the current protection of the region, max_protection is the maximum allowable protection for this region. inheritance is the inheritance attribute for this region. shared tells if the region is shared or not. The port object_name identifies the memory object associated with this region, and offset is the offset into the pager object that this region begins at.

The function returns KERN_SUCCESS if the memory region was successfully located and the information returned and KERN_NO_SPACE if there is no region at or above address in the specified task.

— Function: kern_return_t vm_protect (vm_task_t target_task, vm_address_t address, vm_size_t size, boolean_t set_maximum, vm_prot_t new_protection)

The function vm_protect sets the virtual memory access privileges for a range of allocated addresses in target_task's virtual address space. The protection argument describes a combination of read, write, and execute accesses that should be permitted.

address is the starting address, which will be rounded down to a page boundary. size is the size in bytes of the region for which protection is to change, and will be rounded up to give a page boundary. If set_maximum is set, make the protection change apply to the maximum protection associated with this address range; otherwise, the current protection on this range is changed. If the maximum protection is reduced below the current protection, both will be changed to reflect the new maximum. new_protection is the new protection value for this region; a set of: VM_PROT_READ, VM_PROT_WRITE, VM_PROT_EXECUTE.

The enforcement of virtual memory protection is machine-dependent. Nominally read access requires VM_PROT_READ permission, write access requires VM_PROT_WRITE permission, and execute access requires VM_PROT_EXECUTE permission. However, some combinations of access rights may not be supported. In particular, the kernel interface allows write access to require VM_PROT_READ and VM_PROT_WRITE permission and execute access to require VM_PROT_READ permission.

The function returns KERN_SUCCESS if the memory was successfully protected, KERN_INVALID_ADDRESS if an invalid or non-allocated address was specified and KERN_PROTECTION_FAILURE if an attempt was made to increase the current or maximum protection beyond the existing maximum protection value.

— Function: kern_return_t vm_inherit (vm_task_t target_task, vm_address_t address, vm_size_t size, vm_inherit_t new_inheritance)

The function vm_inherit specifies how a region of target_task's address space is to be passed to child tasks at the time of task creation. Inheritance is an attribute of virtual pages, so address to start from will be rounded down to a page boundary and size, the size in bytes of the region for which inheritance is to change, will be rounded up to give a page boundary. How this memory is to be inherited in child tasks is specified by new_inheritance. Inheritance is specified by using one of these following three values:

Child tasks will share this memory with this task.
Child tasks will receive a copy of this region.
This region will be absent from child tasks.

Setting vm_inherit to VM_INHERIT_SHARE and forking a child task is the only way two Mach tasks can share physical memory. Remember that all the threads of a given task share all the same memory.

The function returns KERN_SUCCESS if the memory inheritance was successfully set and KERN_INVALID_ADDRESS if an invalid or non-allocated address was specified.

— Function: kern_return_t vm_wire (host_priv_t host_priv, vm_task_t target_task, vm_address_t address, vm_size_t size, vm_prot_t access)

The function vm_wire allows privileged applications to control memory pageability. host_priv is the privileged host port for the host on which target_task resides. address is the starting address, which will be rounded down to a page boundary. size is the size in bytes of the region for which protection is to change, and will be rounded up to give a page boundary. access specifies the types of accesses that must not cause page faults.

The semantics of a successful vm_wire operation are that memory in the specified range will not cause page faults for any accesses included in access. Data memory can be made non-pageable (wired) with a access argument of VM_PROT_READ | VM_PROT_WRITE. A special case is that VM_PROT_NONE makes the memory pageable.

The function returns KERN_SUCCESS if the call succeeded, KERN_INVALID_HOST if host_priv was not the privileged host port, KERN_INVALID_TASK if task was not a valid task, KERN_INVALID_VALUE if access specified an invalid access mode, KERN_FAILURE if some memory in the specified range is not present or has an inappropriate protection value, and KERN_INVALID_ARGUMENT if unwiring (access is VM_PROT_NONE) and the memory is not already wired.

The vm_wire call is actually an RPC to host_priv, normally a send right for a privileged host port, but potentially any send right. In addition to the normal diagnostic return codes from the call's server (normally the kernel), the call may return mach_msg return codes.

— Function: kern_return_t vm_machine_attribute (vm_task_t task, vm_address_t address, vm_size_t size, vm_prot_t access, vm_machine_attribute_t attribute, vm_machine_attribute_val_t value)

The function vm_machine_attribute specifies machine-specific attributes for a VM mapping, such as cachability, migrability, replicability. This is used on machines that allow the user control over the cache (this is the case for MIPS architectures) or placement of memory pages as in NUMA architectures (Non-Uniform Memory Access time) such as the IBM ACE multiprocessor.

Machine-specific attributes can be consider additions to the machine-independent ones such as protection and inheritance, but they are not guaranteed to be supported by any given machine. Moreover, implementations of Mach on new architectures might find the need for new attribute types and or values besides the ones defined in the initial implementation.

The types currently defined are

Controls caching of memory pages
Controls migrability of memory pages
Controls replication of memory pages

Corresponding values, and meaning of a specific call to vm_machine_attribute

Enables the attribute. Being enabled is the default value for any applicable attribute.
Disables the attribute, making memory non-cached, or non-migratable, or non-replicatable.
Returns the current value of the attribute for the memory segment. If the attribute does not apply uniformly to the given range the value returned applies to the initial portion of the segment only.
Flush the memory pages from the Cache. The size value in this case might be meaningful even if not a multiple of the page size, depending on the implementation.
Same as above, applied to the Instruction Cache alone.
Same as above, applied to the Data Cache alone.

The function returns KERN_SUCCESS if call succeeded, and KERN_INVALID_ARGUMENT if task is not a task, or address and size do not define a valid address range in task, or attribute is not a valid attribute type, or it is not implemented, or value is not a permissible value for attribute.