hw/timer/armv7m_systick: Forbid non-privileged accesses

Like most of the v7M memory mapped system registers, the systick
registers are accessible to privileged code only and user accesses
must generate a BusFault. We implement that for registers in
the NVIC proper already, but missed it for systick since we
implement it as a separate device. Correct the omission.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190617175317.27557-6-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2019-07-04 17:14:44 +01:00
parent 2884fbb604
commit 9bed521ec8

View File

@ -75,11 +75,17 @@ static void systick_timer_tick(void *opaque)
} }
} }
static uint64_t systick_read(void *opaque, hwaddr addr, unsigned size) static MemTxResult systick_read(void *opaque, hwaddr addr, uint64_t *data,
unsigned size, MemTxAttrs attrs)
{ {
SysTickState *s = opaque; SysTickState *s = opaque;
uint32_t val; uint32_t val;
if (attrs.user) {
/* Generate BusFault for unprivileged accesses */
return MEMTX_ERROR;
}
switch (addr) { switch (addr) {
case 0x0: /* SysTick Control and Status. */ case 0x0: /* SysTick Control and Status. */
val = s->control; val = s->control;
@ -121,14 +127,21 @@ static uint64_t systick_read(void *opaque, hwaddr addr, unsigned size)
} }
trace_systick_read(addr, val, size); trace_systick_read(addr, val, size);
return val; *data = val;
return MEMTX_OK;
} }
static void systick_write(void *opaque, hwaddr addr, static MemTxResult systick_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size) uint64_t value, unsigned size,
MemTxAttrs attrs)
{ {
SysTickState *s = opaque; SysTickState *s = opaque;
if (attrs.user) {
/* Generate BusFault for unprivileged accesses */
return MEMTX_ERROR;
}
trace_systick_write(addr, value, size); trace_systick_write(addr, value, size);
switch (addr) { switch (addr) {
@ -172,11 +185,12 @@ static void systick_write(void *opaque, hwaddr addr,
qemu_log_mask(LOG_GUEST_ERROR, qemu_log_mask(LOG_GUEST_ERROR,
"SysTick: Bad write offset 0x%" HWADDR_PRIx "\n", addr); "SysTick: Bad write offset 0x%" HWADDR_PRIx "\n", addr);
} }
return MEMTX_OK;
} }
static const MemoryRegionOps systick_ops = { static const MemoryRegionOps systick_ops = {
.read = systick_read, .read_with_attrs = systick_read,
.write = systick_write, .write_with_attrs = systick_write,
.endianness = DEVICE_NATIVE_ENDIAN, .endianness = DEVICE_NATIVE_ENDIAN,
.valid.min_access_size = 4, .valid.min_access_size = 4,
.valid.max_access_size = 4, .valid.max_access_size = 4,