kernel/vm: Remove default kernel read/write flags

`fix_protection` will not apply `B_KERNEL_READ_AREA` and
`B_KERNEL_WRITE_AREA` by default.

Kernel drivers that directly call `create_area` or `create_area_etc`
and do not pass any protection flags have been updated to
apply `B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA` instead.

Bug: #17751
Change-Id: I43e7ee6b5396e0309cdcff750e28262942c6d01c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5330
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Trung Nguyen
2022-05-24 16:37:29 +00:00
committed by waddlesplash
parent 9e991b61fe
commit 956f45070d
14 changed files with 32 additions and 29 deletions
@@ -589,7 +589,7 @@ Aperture::AllocateMemory(aperture_memory *memory, uint32 flags)
void *address;
memory->area = create_area("GART memory", &address, B_ANY_KERNEL_ADDRESS,
size, B_FULL_LOCK | ((flags & B_APERTURE_NEED_PHYSICAL) != 0
? B_CONTIGUOUS : 0), 0);
? B_CONTIGUOUS : 0), B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (memory->area < B_OK) {
ERROR("Aperture::AllocateMemory(): create_area() failed\n");
return B_NO_MEMORY;
@@ -219,7 +219,8 @@ scsi_create_autosense_request(scsi_device_info *device)
// allocate buffer for space sense data and S/G list
device->auto_sense_area = create_area("auto_sense", (void**)&buffer,
B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_32_BIT_FULL_LOCK, 0);
B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_32_BIT_FULL_LOCK,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
// TODO: Use B_FULL_LOCK, if addresses >= 4 GB are supported!
if (device->auto_sense_area < 0)
goto err;
@@ -193,7 +193,8 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)
// TODO: Use 64 bit addresses, if possible!
#endif
buffer->area = create_area_etc(B_SYSTEM_TEAM, "DMA buffer", size,
B_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, &physicalRestrictions,
B_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, 0,
&virtualRestrictions, &physicalRestrictions,
(void**)&buffer->address);
if (buffer->area < 0) {
@@ -207,7 +208,7 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)
// we can live with a fragmented buffer - very nice
buffer->area = create_area("DMA buffer",
(void **)&buffer->address, B_ANY_KERNEL_ADDRESS, size,
B_32_BIT_FULL_LOCK, 0);
B_32_BIT_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
// TODO: Use B_FULL_LOCK, if possible!
if (buffer->area < 0) {
SHOW_ERROR(2, "Cannot create DMA buffer of %" B_PRIu32 " bytes",
@@ -226,7 +227,7 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)
buffer->sg_list_area = create_area("DMA buffer S/G table",
(void **)&buffer->sg_list, B_ANY_KERNEL_ADDRESS, sg_list_size,
B_32_BIT_FULL_LOCK, 0);
B_32_BIT_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
// TODO: Use B_FULL_LOCK, if possible!
if (buffer->sg_list_area < 0) {
SHOW_ERROR( 2, "Cannot create DMA buffer S/G list of %" B_PRIuSIZE
@@ -287,7 +288,7 @@ scsi_alloc_dma_buffer_sg_orig(dma_buffer *buffer, size_t size)
buffer->sg_orig = create_area("S/G to original data",
(void **)&buffer->sg_list_orig,
B_ANY_KERNEL_ADDRESS, size,
B_NO_LOCK, 0);
B_NO_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (buffer->sg_orig < 0) {
SHOW_ERROR(2, "Cannot S/G list buffer to original data of %" B_PRIuSIZE
" bytes", size);
@@ -74,8 +74,8 @@ scsi_init_emulation_buffer(scsi_device_info *device, size_t buffer_size)
physical_address_restrictions physicalRestrictions = {};
physicalRestrictions.alignment = buffer_size;
device->buffer_area = create_area_etc(B_SYSTEM_TEAM, "ATAPI buffer",
total_size, B_32_BIT_CONTIGUOUS, 0, 0, 0, &virtualRestrictions,
&physicalRestrictions, &address);
total_size, B_32_BIT_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
0, 0, &virtualRestrictions, &physicalRestrictions, &address);
// TODO: Use B_CONTIGUOUS, if possible!
if (device->buffer_area < 0) {
@@ -331,7 +331,7 @@ Stack::AllocateArea(void **logicalAddress, phys_addr_t *physicalAddress, size_t
void *logAddress;
size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
area_id area = create_area(name, &logAddress, B_ANY_KERNEL_ADDRESS, size,
B_32_BIT_CONTIGUOUS, 0);
B_32_BIT_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
// TODO: Use B_CONTIGUOUS when the TODOs regarding 64 bit physical
// addresses are fixed (if possible).
@@ -90,8 +90,8 @@ TransferDescriptor::TransferDescriptor(VirtioQueue* queue, uint16 indirectMaxSiz
if (indirectMaxSize > 0) {
fAreaSize = indirectMaxSize * sizeof(struct vring_desc);
fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize, 0,
"virtqueue");
fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, "virtqueue");
if (fArea < B_OK) {
fStatus = fArea;
return;
@@ -156,8 +156,8 @@ VirtioQueue::VirtioQueue(VirtioDevice* device, uint16 queueNumber,
uint8* virtAddr;
phys_addr_t physAddr;
fAreaSize = vring_size(fRingSize, device->Alignment());
fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize, 0,
"virtqueue");
fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, "virtqueue");
if (fArea < B_OK) {
fStatus = fArea;
return;
@@ -454,7 +454,8 @@ channel_init(device_node *node, void **_channelCookie)
// used.
prdtSize = (ATA_ADAPTER_MAX_SG_COUNT * sizeof(prd_entry) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1);
channel->prd_area = create_area("prd", (void **)&channel->prdt,
B_ANY_KERNEL_ADDRESS, prdtSize, B_32_BIT_CONTIGUOUS, 0);
B_ANY_KERNEL_ADDRESS, prdtSize, B_32_BIT_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (channel->prd_area < B_OK) {
TRACE("creating prd_area failed\n");
goto err;
@@ -131,7 +131,8 @@ AHCIController::Init()
return B_ERROR;
}
fRegsArea = map_mem((void **)&fRegs, addr, size, 0, "AHCI HBA regs");
fRegsArea = map_mem((void **)&fRegs, addr, size, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
"AHCI HBA regs");
if (fRegsArea < B_OK) {
TRACE("mapping registers failed\n");
return B_ERROR;
@@ -338,7 +338,7 @@ geode_stream_setup_buffers(geode_stream* stream, const char* desc)
stream->buffer_descriptors_area = create_area("geode buffer descriptors",
(void**)&bufferDescriptors, B_ANY_KERNEL_ADDRESS, alloc,
B_32_BIT_CONTIGUOUS, 0);
B_32_BIT_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
// TODO: The rest of the code doesn't deal correctly with physical
// addresses > 4 GB, so we have to force 32 bit addresses here.
if (stream->buffer_descriptors_area < B_OK) {
@@ -570,7 +570,8 @@ init_corb_rirb_pos(hda_controller* controller, uint32 quirks)
// Allocate memory area
controller->corb_rirb_pos_area = create_area("hda corb/rirb/pos",
(void**)&controller->corb, B_ANY_KERNEL_ADDRESS, memSize,
controller->is_64_bit ? B_CONTIGUOUS : B_32_BIT_CONTIGUOUS, 0);
controller->is_64_bit ? B_CONTIGUOUS : B_32_BIT_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (controller->corb_rirb_pos_area < 0)
return controller->corb_rirb_pos_area;
@@ -914,7 +915,8 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
bdl_entry_t* bufferDescriptors;
stream->buffer_descriptors_area = create_area("hda buffer descriptors",
(void**)&bufferDescriptors, B_ANY_KERNEL_ADDRESS, alloc,
stream->controller->is_64_bit ? B_CONTIGUOUS : B_32_BIT_CONTIGUOUS, 0);
stream->controller->is_64_bit ? B_CONTIGUOUS : B_32_BIT_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (stream->buffer_descriptors_area < B_OK) {
delete_area(stream->buffer_area);
return stream->buffer_descriptors_area;
@@ -414,7 +414,7 @@ ata_adapter_init_channel(device_node *node,
// used.
prdt_size = (ATA_ADAPTER_MAX_SG_COUNT * sizeof( prd_entry ) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1);
channel->prd_area = create_area("prd", (void **)&channel->prdt, B_ANY_KERNEL_ADDRESS,
prdt_size, B_32_BIT_CONTIGUOUS, 0);
prdt_size, B_32_BIT_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (channel->prd_area < B_OK) {
res = channel->prd_area;
goto err2;
@@ -117,7 +117,7 @@ enlarge_pool(locked_pool *pool, int numBlocks)
status = area = create_area(pool->name,
(void **)&chunk, B_ANY_KERNEL_ADDRESS, chunkSize,
pool->lock_flags, 0);
pool->lock_flags, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (status < B_OK) {
dprintf("cannot enlarge pool (%s)\n", strerror(status));
// TODO: we should wait a bit and try again!
+2 -2
View File
@@ -112,8 +112,8 @@ bus_alloc_mem_resource(device_t dev, struct resource *res, pci_info *info,
void *virtualAddr;
res->r_mapped_area = map_mem(&virtualAddr, addr, size, 0,
"bus_alloc_resource(MEMORY)");
res->r_mapped_area = map_mem(&virtualAddr, addr, size,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, "bus_alloc_resource(MEMORY)");
if (res->r_mapped_area < B_OK)
return -1;
+4 -7
View File
@@ -5099,9 +5099,7 @@ vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type)
/*! This function enforces some protection properties:
- kernel areas must be W^X (after kernel startup)
- if B_WRITE_AREA is set, B_KERNEL_WRITE_AREA is set as well
- if only B_READ_AREA has been set, B_KERNEL_READ_AREA is also set
- if no protection is specified, it defaults to B_KERNEL_READ_AREA
and B_KERNEL_WRITE_AREA.
- if B_READ_AREA has been set, B_KERNEL_READ_AREA is also set
*/
static void
fix_protection(uint32* protection)
@@ -5113,10 +5111,9 @@ fix_protection(uint32* protection)
panic("kernel areas cannot be both writable and executable!");
if ((*protection & B_KERNEL_PROTECTION) == 0) {
if ((*protection & B_USER_PROTECTION) == 0
|| (*protection & B_WRITE_AREA) != 0)
*protection |= B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA;
else
if ((*protection & B_WRITE_AREA) != 0)
*protection |= B_KERNEL_WRITE_AREA;
if ((*protection & B_READ_AREA) != 0)
*protection |= B_KERNEL_READ_AREA;
}
}