Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.openwrt.org/project/libubox.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2023-12-04 15:26:07 +0300
committerFelix Fietkau <nbd@nbd.name>2023-12-04 15:26:08 +0300
commitdf5b7147f47ae3bca23bde18f3d432f5ce26a2ff (patch)
tree01f3d594610dcf450381a86a5e0991162eb32801
parentd27acfe416d67f9425d40b5e758949cd7ff9acfa (diff)
udebug: add mips specific quirk
On some MIPS systems, mmap addresses need to be aligned to multiple pages, in order to avoid issues with data cache aliases. Add an arch specific quirk to allocate memory in 32 KiB chunks and align addresses returned by mmap. Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--udebug.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/udebug.c b/udebug.c
index 0d8d0d4..81afc78 100644
--- a/udebug.c
+++ b/udebug.c
@@ -37,6 +37,7 @@
#define UDEBUG_MIN_ALLOC_LEN 128
static struct blob_buf b;
+static unsigned int page_size;
static void __randname(char *template)
{
@@ -114,13 +115,21 @@ uint64_t udebug_timestamp(void)
static int
__udebug_buf_map(struct udebug_buf *buf)
{
+ unsigned int pad = 0;
void *ptr, *ptr2;
- ptr = mmap(NULL, buf->head_size + 2 * buf->data_size, PROT_NONE,
+#ifdef mips
+ pad = page_size;
+#endif
+ ptr = mmap(NULL, buf->head_size + 2 * buf->data_size + pad, PROT_NONE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (ptr == MAP_FAILED)
return -1;
+#ifdef mips
+ ptr = (void *)ALIGN((unsigned long)ptr, page_size);
+#endif
+
ptr2 = mmap(ptr, buf->head_size + buf->data_size,
PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, buf->fd, 0);
if (ptr2 != ptr)
@@ -394,18 +403,31 @@ udebug_buf_msg(struct udebug_buf *buf, enum udebug_client_msg_type type)
udebug_wait_for_response(buf->ctx, &msg, NULL);
}
-static size_t __udebug_headsize(unsigned int ring_size, unsigned int page_size)
+static size_t __udebug_headsize(unsigned int ring_size)
{
ring_size *= sizeof(struct udebug_ptr);
return ALIGN(sizeof(struct udebug_hdr) + ring_size, page_size);
}
+static void udebug_init_page_size(void)
+{
+ if (page_size)
+ return;
+ page_size = sysconf(_SC_PAGESIZE);
+#ifdef mips
+ /* leave extra alignment room to account for data cache aliases */
+ if (page_size < 32 * 1024)
+ page_size = 32 * 1024;
+#endif
+}
+
int udebug_buf_open(struct udebug_buf *buf, int fd, uint32_t ring_size, uint32_t data_size)
{
+ udebug_init_page_size();
INIT_LIST_HEAD(&buf->list);
buf->fd = fd;
buf->ring_size = ring_size;
- buf->head_size = __udebug_headsize(ring_size, sysconf(_SC_PAGESIZE));
+ buf->head_size = __udebug_headsize(ring_size);
buf->data_size = data_size;
if (buf->ring_size > (1U << 24) || buf->data_size > (1U << 29))
@@ -426,16 +448,16 @@ int udebug_buf_open(struct udebug_buf *buf, int fd, uint32_t ring_size, uint32_t
int udebug_buf_init(struct udebug_buf *buf, size_t entries, size_t size)
{
- uint32_t pagesz = sysconf(_SC_PAGESIZE);
char filename[] = "/udebug.XXXXXX";
unsigned int order = 12;
uint8_t ring_order = 5;
size_t head_size;
int fd;
+ udebug_init_page_size();
INIT_LIST_HEAD(&buf->list);
- if (size < pagesz)
- size = pagesz;
+ if (size < page_size)
+ size = page_size;
while(size > 1U << order)
order++;
size = 1 << order;
@@ -446,8 +468,8 @@ int udebug_buf_init(struct udebug_buf *buf, size_t entries, size_t size)
if (size > (1U << 29) || entries > (1U << 24))
return -1;
- head_size = __udebug_headsize(entries, pagesz);
- while (ALIGN(sizeof(*buf->hdr) + (entries * 2) * sizeof(struct udebug_ptr), pagesz) == head_size)
+ head_size = __udebug_headsize(entries);
+ while (ALIGN(sizeof(*buf->hdr) + (entries * 2) * sizeof(struct udebug_ptr), page_size) == head_size)
entries *= 2;
fd = shm_open_anon(filename);