syscalls: remove policy from handler checks

The various macros to do checks in system call handlers all
implictly would generate a kernel oops if a check failed.
This is undesirable for a few reasons:

* System call handlers that acquire resources in the handler
  have no good recourse for cleanup if a check fails.
* In some cases we may want to propagate a return value back
  to the caller instead of just killing the calling thread,
  even though the base API doesn't do these checks.

These macros now all return a value, if nonzero is returned
the check failed. K_OOPS() now wraps these calls to generate
a kernel oops.

At the moment, the policy for all APIs has not changed. They
still all oops upon a failed check/

The macros now use the Z_ notation for private APIs.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2018-05-04 15:57:57 -07:00 committed by Anas Nashif
commit 8345e5ebf0
31 changed files with 365 additions and 330 deletions

View file

@ -7,34 +7,36 @@
#include <adc.h> #include <adc.h>
#include <syscall_handler.h> #include <syscall_handler.h>
_SYSCALL_HANDLER(adc_enable, dev) Z_SYSCALL_HANDLER(adc_enable, dev)
{ {
_SYSCALL_DRIVER_ADC(dev, enable); Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, enable));
_impl_adc_enable((struct device *)dev); _impl_adc_enable((struct device *)dev);
return 0; return 0;
} }
_SYSCALL_HANDLER(adc_disable, dev) Z_SYSCALL_HANDLER(adc_disable, dev)
{ {
_SYSCALL_DRIVER_ADC(dev, disable); Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, disable));
_impl_adc_disable((struct device *)dev); _impl_adc_disable((struct device *)dev);
return 0; return 0;
} }
_SYSCALL_HANDLER(adc_read, dev, seq_table_p) Z_SYSCALL_HANDLER(adc_read, dev, seq_table_p)
{ {
struct adc_seq_entry *entry; struct adc_seq_entry *entry;
struct adc_seq_table *seq_table = (struct adc_seq_table *)seq_table_p; struct adc_seq_table *seq_table = (struct adc_seq_table *)seq_table_p;
int i; int i;
_SYSCALL_DRIVER_ADC(dev, read); Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, read));
_SYSCALL_MEMORY_READ(seq_table, sizeof(struct adc_seq_table)); Z_OOPS(Z_SYSCALL_MEMORY_READ(seq_table, sizeof(struct adc_seq_table)));
_SYSCALL_MEMORY_ARRAY_READ(seq_table->entries, seq_table->num_entries, Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(seq_table->entries,
sizeof(struct adc_seq_entry)); seq_table->num_entries,
sizeof(struct adc_seq_entry)));
for (entry = seq_table->entries, i = 0; i < seq_table->num_entries; for (entry = seq_table->entries, i = 0; i < seq_table->num_entries;
i++, entry++) { i++, entry++) {
_SYSCALL_MEMORY_WRITE(entry->buffer, entry->buffer_length); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(entry->buffer,
entry->buffer_length));
} }
return _impl_adc_read((struct device *)dev, seq_table); return _impl_adc_read((struct device *)dev, seq_table);

View file

@ -7,14 +7,14 @@
#include <syscall_handler.h> #include <syscall_handler.h>
#include <aio_comparator.h> #include <aio_comparator.h>
_SYSCALL_HANDLER(aio_cmp_disable, dev, index) Z_SYSCALL_HANDLER(aio_cmp_disable, dev, index)
{ {
_SYSCALL_DRIVER_AIO_CMP(dev, disable); Z_OOPS(Z_SYSCALL_DRIVER_AIO_CMP(dev, disable));
return _impl_aio_cmp_disable((struct device *)dev, index); return _impl_aio_cmp_disable((struct device *)dev, index);
} }
_SYSCALL_HANDLER(aio_cmp_get_pending_int, dev) Z_SYSCALL_HANDLER(aio_cmp_get_pending_int, dev)
{ {
_SYSCALL_DRIVER_AIO_CMP(dev, get_pending_int); Z_OOPS(Z_SYSCALL_DRIVER_AIO_CMP(dev, get_pending_int));
return _impl_aio_get_pending_int((struct device *)dev, index); return _impl_aio_get_pending_int((struct device *)dev, index);
} }

View file

@ -11,9 +11,9 @@
* instance and return an integral value * instance and return an integral value
*/ */
#define COUNTER_HANDLER(name) \ #define COUNTER_HANDLER(name) \
_SYSCALL_HANDLER(counter_ ## name, dev) \ Z_SYSCALL_HANDLER(counter_ ## name, dev) \
{ \ { \
_SYSCALL_DRIVER_COUNTER(dev, name); \ Z_OOPS(Z_SYSCALL_DRIVER_COUNTER(dev, name)); \
return _impl_counter_ ## name((struct device *)dev); \ return _impl_counter_ ## name((struct device *)dev); \
} }

View file

@ -11,15 +11,15 @@
* the validity of the channel ID and returning -errno if it's bogus * the validity of the channel ID and returning -errno if it's bogus
*/ */
_SYSCALL_HANDLER(dma_start, dev, channel) Z_SYSCALL_HANDLER(dma_start, dev, channel)
{ {
_SYSCALL_DRIVER_DMA(dev, start); Z_OOPS(Z_SYSCALL_DRIVER_DMA(dev, start));
return _impl_dma_start((struct device *)dev, channel); return _impl_dma_start((struct device *)dev, channel);
} }
_SYSCALL_HANDLER(dma_stop, dev, channel) Z_SYSCALL_HANDLER(dma_stop, dev, channel)
{ {
_SYSCALL_DRIVER_DMA(dev, stop); Z_OOPS(Z_SYSCALL_DRIVER_DMA(dev, stop));
return _impl_dma_stop((struct device *)dev, channel); return _impl_dma_stop((struct device *)dev, channel);
} }

View file

@ -7,10 +7,10 @@
#include <entropy.h> #include <entropy.h>
#include <syscall_handler.h> #include <syscall_handler.h>
_SYSCALL_HANDLER(entropy_get_entropy, dev, buffer, len) Z_SYSCALL_HANDLER(entropy_get_entropy, dev, buffer, len)
{ {
_SYSCALL_DRIVER_ENTROPY(dev, get_entropy); Z_OOPS(Z_SYSCALL_DRIVER_ENTROPY(dev, get_entropy));
_SYSCALL_MEMORY_WRITE(buffer, len); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buffer, len));
return _impl_entropy_get_entropy((struct device *)dev, (u8_t *)buffer, return _impl_entropy_get_entropy((struct device *)dev, (u8_t *)buffer,
len); len);
} }

View file

@ -7,51 +7,51 @@
#include <syscall_handler.h> #include <syscall_handler.h>
#include <flash.h> #include <flash.h>
_SYSCALL_HANDLER(flash_read, dev, offset, data, len) Z_SYSCALL_HANDLER(flash_read, dev, offset, data, len)
{ {
_SYSCALL_DRIVER_FLASH(dev, read); Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, read));
_SYSCALL_MEMORY_WRITE(data, len); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, len));
return _impl_flash_read((struct device *)dev, offset, (void *)data, return _impl_flash_read((struct device *)dev, offset, (void *)data,
len); len);
} }
_SYSCALL_HANDLER(flash_write, dev, offset, data, len) Z_SYSCALL_HANDLER(flash_write, dev, offset, data, len)
{ {
_SYSCALL_DRIVER_FLASH(dev, write); Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, write));
_SYSCALL_MEMORY_READ(data, len); Z_OOPS(Z_SYSCALL_MEMORY_READ(data, len));
return _impl_flash_write((struct device *)dev, offset, return _impl_flash_write((struct device *)dev, offset,
(const void *)data, len); (const void *)data, len);
} }
_SYSCALL_HANDLER(flash_write_protection_set, dev, enable) Z_SYSCALL_HANDLER(flash_write_protection_set, dev, enable)
{ {
_SYSCALL_DRIVER_FLASH(dev, write_protection); Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, write_protection));
return _impl_flash_write_protection_set((struct device *)dev, enable); return _impl_flash_write_protection_set((struct device *)dev, enable);
} }
_SYSCALL_HANDLER1_SIMPLE(flash_get_write_block_size, K_OBJ_DRIVER_FLASH, Z_SYSCALL_HANDLER1_SIMPLE(flash_get_write_block_size, K_OBJ_DRIVER_FLASH,
struct device *); struct device *);
#ifdef CONFIG_FLASH_PAGE_LAYOUT #ifdef CONFIG_FLASH_PAGE_LAYOUT
_SYSCALL_HANDLER(flash_get_page_info_by_offs, dev, offs, info) Z_SYSCALL_HANDLER(flash_get_page_info_by_offs, dev, offs, info)
{ {
_SYSCALL_DRIVER_FLASH(dev, page_layout); Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout));
_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info)));
return _impl_flash_get_page_info_by_offs((struct device *)dev, offs, return _impl_flash_get_page_info_by_offs((struct device *)dev, offs,
(struct flash_pages_info *)info); (struct flash_pages_info *)info);
} }
_SYSCALL_HANDLER(flash_get_page_info_by_idx, dev, idx, info) Z_SYSCALL_HANDLER(flash_get_page_info_by_idx, dev, idx, info)
{ {
_SYSCALL_DRIVER_FLASH(dev, page_layout); Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout));
_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info)));
return _impl_flash_get_page_info_by_idx((struct device *)dev, idx, return _impl_flash_get_page_info_by_idx((struct device *)dev, idx,
(struct flash_pages_info *)info); (struct flash_pages_info *)info);
} }
_SYSCALL_HANDLER(flash_get_page_count, dev) Z_SYSCALL_HANDLER(flash_get_page_count, dev)
{ {
_SYSCALL_DRIVER_FLASH(dev, page_layout); Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout));
return _impl_flash_get_page_count((struct device *)dev); return _impl_flash_get_page_count((struct device *)dev);
} }
#endif #endif

View file

@ -7,42 +7,42 @@
#include <gpio.h> #include <gpio.h>
#include <syscall_handler.h> #include <syscall_handler.h>
_SYSCALL_HANDLER(gpio_config, port, access_op, pin, flags) Z_SYSCALL_HANDLER(gpio_config, port, access_op, pin, flags)
{ {
_SYSCALL_DRIVER_GPIO(port, config); Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, config));
return _impl_gpio_config((struct device *)port, access_op, pin, flags); return _impl_gpio_config((struct device *)port, access_op, pin, flags);
} }
_SYSCALL_HANDLER(gpio_write, port, access_op, pin, value) Z_SYSCALL_HANDLER(gpio_write, port, access_op, pin, value)
{ {
_SYSCALL_DRIVER_GPIO(port, write); Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, write));
return _impl_gpio_write((struct device *)port, access_op, pin, value); return _impl_gpio_write((struct device *)port, access_op, pin, value);
} }
_SYSCALL_HANDLER(gpio_read, port, access_op, pin, value) Z_SYSCALL_HANDLER(gpio_read, port, access_op, pin, value)
{ {
_SYSCALL_DRIVER_GPIO(port, read); Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, read));
_SYSCALL_MEMORY_WRITE(value, sizeof(u32_t)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(value, sizeof(u32_t)));
return _impl_gpio_read((struct device *)port, access_op, pin, return _impl_gpio_read((struct device *)port, access_op, pin,
(u32_t *)value); (u32_t *)value);
} }
_SYSCALL_HANDLER(gpio_enable_callback, port, access_op, pin) Z_SYSCALL_HANDLER(gpio_enable_callback, port, access_op, pin)
{ {
_SYSCALL_DRIVER_GPIO(port, enable_callback); Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, enable_callback));
return _impl_gpio_enable_callback((struct device *)port, access_op, return _impl_gpio_enable_callback((struct device *)port, access_op,
pin); pin);
} }
_SYSCALL_HANDLER(gpio_disable_callback, port, access_op, pin) Z_SYSCALL_HANDLER(gpio_disable_callback, port, access_op, pin)
{ {
_SYSCALL_DRIVER_GPIO(port, disable_callback); Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, disable_callback));
return _impl_gpio_disable_callback((struct device *)port, access_op, return _impl_gpio_disable_callback((struct device *)port, access_op,
pin); pin);
} }
_SYSCALL_HANDLER(gpio_get_pending_int, port) Z_SYSCALL_HANDLER(gpio_get_pending_int, port)
{ {
_SYSCALL_DRIVER_GPIO(port, get_pending_int); Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, get_pending_int));
return _impl_gpio_get_pending_int((struct device *)port); return _impl_gpio_get_pending_int((struct device *)port);
} }

View file

@ -8,9 +8,9 @@
#include <string.h> #include <string.h>
#include <syscall_handler.h> #include <syscall_handler.h>
_SYSCALL_HANDLER(i2c_configure, dev, dev_config) Z_SYSCALL_HANDLER(i2c_configure, dev, dev_config)
{ {
_SYSCALL_DRIVER_I2C(dev, configure); Z_OOPS(Z_SYSCALL_DRIVER_I2C(dev, configure));
return _impl_i2c_configure((struct device *)dev, dev_config); return _impl_i2c_configure((struct device *)dev, dev_config);
} }
@ -30,26 +30,27 @@ static u32_t copy_msgs_and_transfer(struct device *dev,
* that the target buffer be writable * that the target buffer be writable
*/ */
for (i = 0; i < num_msgs; i++) { for (i = 0; i < num_msgs; i++) {
_SYSCALL_MEMORY(copy[i].buf, copy[i].len, Z_OOPS(Z_SYSCALL_MEMORY(copy[i].buf, copy[i].len,
copy[i].flags & I2C_MSG_READ); copy[i].flags & I2C_MSG_READ));
} }
return _impl_i2c_transfer(dev, copy, num_msgs, addr); return _impl_i2c_transfer(dev, copy, num_msgs, addr);
} }
_SYSCALL_HANDLER(i2c_transfer, dev, msgs, num_msgs, addr) Z_SYSCALL_HANDLER(i2c_transfer, dev, msgs, num_msgs, addr)
{ {
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C); Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_I2C));
/* copy_msgs_and_transfer() will allocate a copy on the stack using /* copy_msgs_and_transfer() will allocate a copy on the stack using
* VLA, so ensure this won't blow the stack. Most functions defined * VLA, so ensure this won't blow the stack. Most functions defined
* in i2c.h use only a handful of messages, so up to 32 messages * in i2c.h use only a handful of messages, so up to 32 messages
* should be more than sufficient. * should be more than sufficient.
*/ */
_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32); Z_OOPS(Z_SYSCALL_VERIFY(num_msgs >= 1 && num_msgs < 32));
/* We need to be able to read the overall array of messages */ /* We need to be able to read the overall array of messages */
_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs, sizeof(struct i2c_msg)); Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(msgs, num_msgs,
sizeof(struct i2c_msg)));
return copy_msgs_and_transfer((struct device *)dev, return copy_msgs_and_transfer((struct device *)dev,
(struct i2c_msg *)msgs, (struct i2c_msg *)msgs,

View file

@ -7,28 +7,28 @@
#include <syscall_handler.h> #include <syscall_handler.h>
#include <ipm.h> #include <ipm.h>
_SYSCALL_HANDLER(ipm_send, dev, wait, id, data, size) Z_SYSCALL_HANDLER(ipm_send, dev, wait, id, data, size)
{ {
_SYSCALL_DRIVER_IPM(dev, send); Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, send));
_SYSCALL_MEMORY_READ(data, size); Z_OOPS(Z_SYSCALL_MEMORY_READ(data, size));
return _impl_ipm_send((struct device *)dev, wait, id, return _impl_ipm_send((struct device *)dev, wait, id,
(const void *)data, size); (const void *)data, size);
} }
_SYSCALL_HANDLER(ipm_max_data_size_get, dev) Z_SYSCALL_HANDLER(ipm_max_data_size_get, dev)
{ {
_SYSCALL_DRIVER_IPM(dev, max_data_size_get); Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, max_data_size_get));
return _impl_max_data_size_get((struct device *)dev); return _impl_max_data_size_get((struct device *)dev);
} }
_SYSCALL_HANDLER(ipm_max_id_val_get, dev) Z_SYSCALL_HANDLER(ipm_max_id_val_get, dev)
{ {
_SYSCALL_DRIVER_IPM(dev, max_id_val_get); Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, max_id_val_get));
return _impl_max_id_val_get((struct device *)dev); return _impl_max_id_val_get((struct device *)dev);
} }
_SYSCALL_HANDLER(ipm_set_enabled, dev, enable) Z_SYSCALL_HANDLER(ipm_set_enabled, dev, enable)
{ {
_SYSCALL_DRIVER_IPM(dev, set_enabled); Z_OOPS(Z_SYSCALL_DRIVER_IPM(dev, set_enabled));
return _impl_ipm_set_enabled((struct device *)dev, enable); return _impl_ipm_set_enabled((struct device *)dev, enable);
} }

View file

@ -7,27 +7,27 @@
#include <syscall_handler.h> #include <syscall_handler.h>
#include <led.h> #include <led.h>
_SYSCALL_HANDLER(led_blink, dev, led, delay_on, delay_off) Z_SYSCALL_HANDLER(led_blink, dev, led, delay_on, delay_off)
{ {
_SYSCALL_DRIVER_LED(dev, blink); Z_OOPS(Z_SYSCALL_DRIVER_LED(dev, blink));
return _impl_led_blink((struct device *)dev, led, delay_on, return _impl_led_blink((struct device *)dev, led, delay_on,
delay_off); delay_off);
} }
_SYSCALL_HANDLER(led_set_brightness, dev, led, value) Z_SYSCALL_HANDLER(led_set_brightness, dev, led, value)
{ {
_SYSCALL_DRIVER_LED(dev, set_brightness); Z_OOPS(Z_SYSCALL_DRIVER_LED(dev, set_brightness));
return _impl_led_set_brightness((struct device *)dev, led, value); return _impl_led_set_brightness((struct device *)dev, led, value);
} }
_SYSCALL_HANDLER(led_on, dev, led) Z_SYSCALL_HANDLER(led_on, dev, led)
{ {
_SYSCALL_DRIVER_LED(dev, on); Z_OOPS(Z_SYSCALL_DRIVER_LED(dev, on));
return _impl_led_on((struct device *)dev, led); return _impl_led_on((struct device *)dev, led);
} }
_SYSCALL_HANDLER(led_off, dev, led) Z_SYSCALL_HANDLER(led_off, dev, led)
{ {
_SYSCALL_DRIVER_LED(dev, off); Z_OOPS(Z_SYSCALL_DRIVER_LED(dev, off));
return _impl_led_off((struct device *)dev, led); return _impl_led_off((struct device *)dev, led);
} }

View file

@ -7,17 +7,17 @@
#include <syscall_handler.h> #include <syscall_handler.h>
#include <pwm.h> #include <pwm.h>
_SYSCALL_HANDLER(pwm_pin_set_cycles, dev, pwm, period, pulse) Z_SYSCALL_HANDLER(pwm_pin_set_cycles, dev, pwm, period, pulse)
{ {
_SYSCALL_DRIVER_PWM(dev, pin_set); Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, pin_set));
return _impl_pwm_pin_set_cycles((struct device *)dev, pwm, period, return _impl_pwm_pin_set_cycles((struct device *)dev, pwm, period,
pulse); pulse);
} }
_SYSCALL_HANDLER(pwm_get_cycles_per_sec, dev, pwm, cycles) Z_SYSCALL_HANDLER(pwm_get_cycles_per_sec, dev, pwm, cycles)
{ {
_SYSCALL_DRIVER_PWM(dev, get_cycles_per_sec); Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, get_cycles_per_sec));
_SYSCALL_MEMORY_WRITE(cycles, sizeof(u64_t)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(cycles, sizeof(u64_t)));
return _impl_pwm_get_cycles_per_sec((struct device *)dev, return _impl_pwm_get_cycles_per_sec((struct device *)dev,
pwm, (u64_t *)cycles); pwm, (u64_t *)cycles);
} }

View file

@ -7,32 +7,32 @@
#include <syscall_handler.h> #include <syscall_handler.h>
#include <rtc.h> #include <rtc.h>
_SYSCALL_HANDLER(rtc_read, dev) Z_SYSCALL_HANDLER(rtc_read, dev)
{ {
_SYSCALL_DRIVER_RTC(dev, read); Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, read));
return _impl_rtc_read((struct device *)dev); return _impl_rtc_read((struct device *)dev);
} }
_SYSCALL_HANDLER(rtc_enable, dev) Z_SYSCALL_HANDLER(rtc_enable, dev)
{ {
_SYSCALL_DRIVER_RTC(dev, enable); Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, enable));
return _impl_rtc_enable((struct device *)dev); return _impl_rtc_enable((struct device *)dev);
} }
_SYSCALL_HANDLER(rtc_disable, dev) Z_SYSCALL_HANDLER(rtc_disable, dev)
{ {
_SYSCALL_DRIVER_RTC(dev, disable); Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, disable));
return _impl_rtc_disable((struct device *)dev); return _impl_rtc_disable((struct device *)dev);
} }
_SYSCALL_HANDLER(rtc_set_alarm, dev, alarm_val) Z_SYSCALL_HANDLER(rtc_set_alarm, dev, alarm_val)
{ {
_SYSCALL_DRIVER_RTC(dev, set_alarm); Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, set_alarm));
return _impl_rtc_set_alarm((struct device *)dev, alarm_val); return _impl_rtc_set_alarm((struct device *)dev, alarm_val);
} }
_SYSCALL_HANDLER(rtc_get_pending_int, dev) Z_SYSCALL_HANDLER(rtc_get_pending_int, dev)
{ {
_SYSCALL_DRIVER_RTC(dev, get_pending_int); Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, get_pending_int));
return _impl_rtc_get_pending_int((struct device *)dev); return _impl_rtc_get_pending_int((struct device *)dev);
} }

View file

@ -7,30 +7,30 @@
#include <sensor.h> #include <sensor.h>
#include <syscall_handler.h> #include <syscall_handler.h>
_SYSCALL_HANDLER(sensor_attr_set, dev, chan, attr, val) Z_SYSCALL_HANDLER(sensor_attr_set, dev, chan, attr, val)
{ {
_SYSCALL_DRIVER_SENSOR(dev, attr_set); Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, attr_set));
_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value)); Z_OOPS(Z_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value)));
return _impl_sensor_attr_set((struct device *)dev, chan, attr, return _impl_sensor_attr_set((struct device *)dev, chan, attr,
(const struct sensor_value *)val); (const struct sensor_value *)val);
} }
_SYSCALL_HANDLER(sensor_sample_sample_fetch, dev) Z_SYSCALL_HANDLER(sensor_sample_sample_fetch, dev)
{ {
_SYSCALL_DRIVER_SENSOR(dev, sample_fetch); Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, sample_fetch));
return _impl_sensor_sample_fetch((struct device *)dev); return _impl_sensor_sample_fetch((struct device *)dev);
} }
_SYSCALL_HANDLER(sensor_sample_fetch_chan, dev, type) Z_SYSCALL_HANDLER(sensor_sample_fetch_chan, dev, type)
{ {
_SYSCALL_DRIVER_SENSOR(dev, sample_fetch); Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, sample_fetch));
return _impl_sensor_sample_fetch_chan((struct device *)dev, type); return _impl_sensor_sample_fetch_chan((struct device *)dev, type);
} }
_SYSCALL_HANDLER(sensor_channel_get, dev, chan, val) Z_SYSCALL_HANDLER(sensor_channel_get, dev, chan, val)
{ {
_SYSCALL_DRIVER_SENSOR(dev, channel_get); Z_OOPS(Z_SYSCALL_DRIVER_SENSOR(dev, channel_get));
_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value)));
return _impl_sensor_channel_get((struct device *)dev, chan, return _impl_sensor_channel_get((struct device *)dev, chan,
(struct sensor_value *)val); (struct sensor_value *)val);
} }

View file

@ -8,31 +8,31 @@
#include <syscall_handler.h> #include <syscall_handler.h>
#define UART_SIMPLE(op_) \ #define UART_SIMPLE(op_) \
_SYSCALL_HANDLER(uart_ ## op_, dev) { \ Z_SYSCALL_HANDLER(uart_ ## op_, dev) { \
_SYSCALL_DRIVER_UART(dev, op_); \ Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, op_)); \
return _impl_uart_ ## op_((struct device *)dev); \ return _impl_uart_ ## op_((struct device *)dev); \
} }
#define UART_SIMPLE_VOID(op_) \ #define UART_SIMPLE_VOID(op_) \
_SYSCALL_HANDLER(uart_ ## op_, dev) { \ Z_SYSCALL_HANDLER(uart_ ## op_, dev) { \
_SYSCALL_DRIVER_UART(dev, op_); \ Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, op_)); \
_impl_uart_ ## op_((struct device *)dev); \ _impl_uart_ ## op_((struct device *)dev); \
return 0; \ return 0; \
} }
UART_SIMPLE(err_check) UART_SIMPLE(err_check)
_SYSCALL_HANDLER(uart_poll_in, dev, p_char) Z_SYSCALL_HANDLER(uart_poll_in, dev, p_char)
{ {
_SYSCALL_DRIVER_UART(dev, poll_in); Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, poll_in));
_SYSCALL_MEMORY_WRITE(p_char, sizeof(unsigned char)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(p_char, sizeof(unsigned char)));
return _impl_uart_poll_in((struct device *)dev, return _impl_uart_poll_in((struct device *)dev,
(unsigned char *)p_char); (unsigned char *)p_char);
} }
_SYSCALL_HANDLER(uart_poll_out, dev, out_char) Z_SYSCALL_HANDLER(uart_poll_out, dev, out_char)
{ {
_SYSCALL_DRIVER_UART(dev, poll_out); Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, poll_out));
return _impl_uart_poll_out((struct device *)dev, out_char); return _impl_uart_poll_out((struct device *)dev, out_char);
} }
@ -48,25 +48,25 @@ UART_SIMPLE(irq_update)
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
#ifdef CONFIG_UART_LINE_CTRL #ifdef CONFIG_UART_LINE_CTRL
_SYSCALL_HANDLER(uart_line_ctrl_set, dev, ctrl, val) Z_SYSCALL_HANDLER(uart_line_ctrl_set, dev, ctrl, val)
{ {
_SYSCALL_DRIVER_UART(dev, line_ctrl_set); Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, line_ctrl_set));
return _impl_uart_line_ctrl_set((struct device *)dev, ctrl, val); return _impl_uart_line_ctrl_set((struct device *)dev, ctrl, val);
} }
_SYSCALL_HANDLER(uart_line_ctrl_get, dev, ctrl, val); Z_SYSCALL_HANDLER(uart_line_ctrl_get, dev, ctrl, val);
{ {
_SYSCALL_DRIVER_UART(dev, line_ctrl_get); Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, line_ctrl_get));
_SYSCALL_MEMORY_WRITE(val, sizeof(u32_t)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(val, sizeof(u32_t)));
return _impl_uart_line_ctrl_get((struct device *)dev, ctrl, return _impl_uart_line_ctrl_get((struct device *)dev, ctrl,
(u32_t *)val); (u32_t *)val);
} }
#endif /* CONFIG_UART_LINE_CTRL */ #endif /* CONFIG_UART_LINE_CTRL */
#ifdef CONFIG_UART_DRV_CMD #ifdef CONFIG_UART_DRV_CMD
_SYSCALL_HANDLER(uart_drv_cmd, dev, cmd, p) Z_SYSCALL_HANDLER(uart_drv_cmd, dev, cmd, p)
{ {
_SYSCALL_DRIVER_UART(dev, drv_cmd); Z_OOPS(Z_SYSCALL_DRIVER_UART(dev, drv_cmd));
return _impl_uart_drv_cmd((struct device *)dev, cmd, p); return _impl_uart_drv_cmd((struct device *)dev, cmd, p);
} }
#endif /* CONFIG_UART_DRV_CMD */ #endif /* CONFIG_UART_DRV_CMD */

View file

@ -22,9 +22,9 @@ static void copy_and_check(struct spi_buf_set *bufs,
} }
/* Validate the array of struct spi_buf instances */ /* Validate the array of struct spi_buf instances */
_SYSCALL_MEMORY_ARRAY_READ(bufs->buffers, Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_READ(bufs->buffers,
bufs->count, bufs->count,
sizeof(struct spi_buf)); sizeof(struct spi_buf)));;
/* Not worried abuot overflow here: _SYSCALL_MEMORY_ARRAY_READ() /* Not worried abuot overflow here: _SYSCALL_MEMORY_ARRAY_READ()
* takes care of it. * takes care of it.
@ -39,7 +39,7 @@ static void copy_and_check(struct spi_buf_set *bufs,
*/ */
struct spi_buf *buf = &bufs->buffers[i]; struct spi_buf *buf = &bufs->buffers[i];
_SYSCALL_MEMORY(buf->buf, buf->len, writable); Z_OOPS(Z_SYSCALL_MEMORY(buf->buf, buf->len, writable));
} }
} }
@ -65,23 +65,24 @@ static u32_t copy_bufs_and_transceive(struct device *dev,
tx_bufs, rx_bufs); tx_bufs, rx_bufs);
} }
_SYSCALL_HANDLER(spi_transceive, dev, config_p, tx_bufs, rx_bufs) Z_SYSCALL_HANDLER(spi_transceive, dev, config_p, tx_bufs, rx_bufs)
{ {
const struct spi_config *config = (const struct spi_config *)config_p; const struct spi_config *config = (const struct spi_config *)config_p;
struct spi_buf_set tx_bufs_copy; struct spi_buf_set tx_bufs_copy;
struct spi_buf_set rx_bufs_copy; struct spi_buf_set rx_bufs_copy;
struct spi_config config_copy; struct spi_config config_copy;
_SYSCALL_MEMORY_READ(config, sizeof(*config)); Z_OOPS(Z_SYSCALL_MEMORY_READ(config, sizeof(*config)));
_SYSCALL_DRIVER_SPI(dev, transceive); Z_OOPS(Z_SYSCALL_DRIVER_SPI(dev, transceive));
if (tx_bufs) { if (tx_bufs) {
const struct spi_buf_set *tx = const struct spi_buf_set *tx =
(const struct spi_buf_set *)tx_bufs; (const struct spi_buf_set *)tx_bufs;
_SYSCALL_MEMORY_READ(tx_bufs, sizeof(struct spi_buf_set)); Z_OOPS(Z_SYSCALL_MEMORY_READ(tx_bufs,
sizeof(struct spi_buf_set)));
memcpy(&tx_bufs_copy, tx, sizeof(tx_bufs_copy)); memcpy(&tx_bufs_copy, tx, sizeof(tx_bufs_copy));
_SYSCALL_VERIFY(tx_bufs_copy.count < 32); Z_OOPS(Z_SYSCALL_VERIFY(tx_bufs_copy.count < 32));
} else { } else {
memset(&tx_bufs_copy, 0, sizeof(tx_bufs_copy)); memset(&tx_bufs_copy, 0, sizeof(tx_bufs_copy));
} }
@ -90,9 +91,10 @@ _SYSCALL_HANDLER(spi_transceive, dev, config_p, tx_bufs, rx_bufs)
const struct spi_buf_set *rx = const struct spi_buf_set *rx =
(const struct spi_buf_set *)rx_bufs; (const struct spi_buf_set *)rx_bufs;
_SYSCALL_MEMORY_READ(rx_bufs, sizeof(struct spi_buf_set)); Z_OOPS(Z_SYSCALL_MEMORY_READ(rx_bufs,
sizeof(struct spi_buf_set)));
memcpy(&rx_bufs_copy, rx, sizeof(rx_bufs_copy)); memcpy(&rx_bufs_copy, rx, sizeof(rx_bufs_copy));
_SYSCALL_VERIFY(rx_bufs_copy.count < 32); Z_OOPS(Z_SYSCALL_VERIFY(rx_bufs_copy.count < 32));
} else { } else {
memset(&rx_bufs_copy, 0, sizeof(rx_bufs_copy)); memset(&rx_bufs_copy, 0, sizeof(rx_bufs_copy));
} }
@ -101,9 +103,9 @@ _SYSCALL_HANDLER(spi_transceive, dev, config_p, tx_bufs, rx_bufs)
if (config_copy.cs) { if (config_copy.cs) {
const struct spi_cs_control *cs = config_copy.cs; const struct spi_cs_control *cs = config_copy.cs;
_SYSCALL_MEMORY_READ(cs, sizeof(*cs)); Z_OOPS(Z_SYSCALL_MEMORY_READ(cs, sizeof(*cs)));
if (cs->gpio_dev) { if (cs->gpio_dev) {
_SYSCALL_OBJ(cs->gpio_dev, K_OBJ_DRIVER_GPIO); Z_OOPS(Z_SYSCALL_OBJ(cs->gpio_dev, K_OBJ_DRIVER_GPIO));
} }
} }
@ -117,11 +119,11 @@ _SYSCALL_HANDLER(spi_transceive, dev, config_p, tx_bufs, rx_bufs)
ssf); ssf);
} }
_SYSCALL_HANDLER(spi_release, dev, config_p) Z_SYSCALL_HANDLER(spi_release, dev, config_p)
{ {
const struct spi_config *config = (const struct spi_config *)config_p; const struct spi_config *config = (const struct spi_config *)config_p;
_SYSCALL_MEMORY_READ(config, sizeof(*config)); Z_OOPS(Z_SYSCALL_MEMORY_READ(config, sizeof(*config)));
_SYSCALL_DRIVER_SPI(dev, release); Z_OOPS(Z_SYSCALL_DRIVER_SPI(dev, release));
return _impl_spi_release((struct device *)dev, config); return _impl_spi_release((struct device *)dev, config);
} }

View file

@ -92,7 +92,7 @@ void _impl_k_alert_send(struct k_alert *alert)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_alert_send, K_OBJ_ALERT, struct k_alert *); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_alert_send, K_OBJ_ALERT, struct k_alert *);
#endif #endif
int _impl_k_alert_recv(struct k_alert *alert, s32_t timeout) int _impl_k_alert_recv(struct k_alert *alert, s32_t timeout)
@ -101,9 +101,9 @@ int _impl_k_alert_recv(struct k_alert *alert, s32_t timeout)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_alert_recv, alert, timeout) Z_SYSCALL_HANDLER(k_alert_recv, alert, timeout)
{ {
_SYSCALL_OBJ(alert, K_OBJ_ALERT); Z_OOPS(Z_SYSCALL_OBJ(alert, K_OBJ_ALERT));
return _impl_k_alert_recv((struct k_alert *)alert, timeout); return _impl_k_alert_recv((struct k_alert *)alert, timeout);
} }
#endif #endif

View file

@ -125,6 +125,27 @@ extern void _thread_perms_all_clear(struct k_thread *thread);
*/ */
void _k_object_uninit(void *obj); void _k_object_uninit(void *obj);
#define Z_OOPS(expr) \
do { \
if (expr) { \
_arch_syscall_oops(ssf); \
} \
} while (0)
static inline __attribute__((warn_unused_result)) __printf_like(2, 3)
bool z_syscall_verify_msg(bool expr, const char *fmt, ...)
{
va_list ap;
if (expr) {
va_start(ap, fmt);
vprintk(fmt, ap);
va_end(ap);
}
return expr;
}
/** /**
* @brief Runtime expression check for system call arguments * @brief Runtime expression check for system call arguments
* *
@ -136,15 +157,11 @@ void _k_object_uninit(void *obj);
* oops * oops
* @param fmt Printf-style format string (followed by appropriate variadic * @param fmt Printf-style format string (followed by appropriate variadic
* arguments) to print on verification failure * arguments) to print on verification failure
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_VERIFY_MSG(expr, fmt, ...) \ #define Z_SYSCALL_VERIFY_MSG(expr, fmt, ...) \
do { \ z_syscall_verify_msg(!(expr), "syscall %s failed check: " fmt "\n", \
if (!(expr)) { \ __func__, ##__VA_ARGS__)
printk("FATAL: syscall %s failed check: " fmt "\n", \
__func__, ##__VA_ARGS__); \
_arch_syscall_oops(ssf); \
} \
} while (0)
/** /**
* @brief Runtime expression check for system call arguments * @brief Runtime expression check for system call arguments
@ -154,11 +171,12 @@ void _k_object_uninit(void *obj);
* *
* @param expr Boolean expression to verify, a false result will trigger an * @param expr Boolean expression to verify, a false result will trigger an
* oops. A stringified version of this expression will be printed. * oops. A stringified version of this expression will be printed.
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_VERIFY(expr) _SYSCALL_VERIFY_MSG(expr, #expr) #define Z_SYSCALL_VERIFY(expr) Z_SYSCALL_VERIFY_MSG(expr, #expr)
#define _SYSCALL_MEMORY(ptr, size, write) \ #define Z_SYSCALL_MEMORY(ptr, size, write) \
_SYSCALL_VERIFY_MSG(!_arch_buffer_validate((void *)ptr, size, write), \ Z_SYSCALL_VERIFY_MSG(!_arch_buffer_validate((void *)ptr, size, write), \
"Memory region %p (size %u) %s access denied", \ "Memory region %p (size %u) %s access denied", \
(void *)(ptr), (u32_t)(size), \ (void *)(ptr), (u32_t)(size), \
write ? "write" : "read") write ? "write" : "read")
@ -176,9 +194,10 @@ void _k_object_uninit(void *obj);
* @param size Size of the memory area * @param size Size of the memory area
* @param write If the thread should be able to write to this memory, not just * @param write If the thread should be able to write to this memory, not just
* read it * read it
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_MEMORY_READ(ptr, size) \ #define Z_SYSCALL_MEMORY_READ(ptr, size) \
_SYSCALL_MEMORY(ptr, size, 0) Z_SYSCALL_MEMORY(ptr, size, 0)
/** /**
* @brief Runtime check that a user thread has write permission to a memory area * @brief Runtime check that a user thread has write permission to a memory area
@ -193,20 +212,21 @@ void _k_object_uninit(void *obj);
* @param size Size of the memory area * @param size Size of the memory area
* @param write If the thread should be able to write to this memory, not just * @param write If the thread should be able to write to this memory, not just
* read it * read it
* @param 0 on success, nonzero on failure
*/ */
#define _SYSCALL_MEMORY_WRITE(ptr, size) \ #define Z_SYSCALL_MEMORY_WRITE(ptr, size) \
_SYSCALL_MEMORY(ptr, size, 1) Z_SYSCALL_MEMORY(ptr, size, 1)
#define _SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \ #define Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \
do { \ ({ \
u32_t product; \ u32_t product; \
_SYSCALL_VERIFY_MSG(!__builtin_umul_overflow((u32_t)(nmemb), \ Z_SYSCALL_VERIFY_MSG(!__builtin_umul_overflow((u32_t)(nmemb), \
(u32_t)(size), \ (u32_t)(size), \
&product), \ &product), \
"%ux%u array is too large", \ "%ux%u array is too large", \
(u32_t)(nmemb), (u32_t)(size)); \ (u32_t)(nmemb), (u32_t)(size)) || \
_SYSCALL_MEMORY(ptr, product, write); \ Z_SYSCALL_MEMORY(ptr, product, write); \
} while (0) })
/** /**
* @brief Validate user thread has read permission for sized array * @brief Validate user thread has read permission for sized array
@ -218,9 +238,10 @@ void _k_object_uninit(void *obj);
* @param ptr Memory area to examine * @param ptr Memory area to examine
* @param nmemb Number of elements in the array * @param nmemb Number of elements in the array
* @param size Size of each array element * @param size Size of each array element
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size) \ #define Z_SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size) \
_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0) Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0)
/** /**
* @brief Validate user thread has read/write permission for sized array * @brief Validate user thread has read/write permission for sized array
@ -232,9 +253,10 @@ void _k_object_uninit(void *obj);
* @param ptr Memory area to examine * @param ptr Memory area to examine
* @param nmemb Number of elements in the array * @param nmemb Number of elements in the array
* @param size Size of each array element * @param size Size of each array element
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \ #define Z_SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \
_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1) Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1)
static inline int _obj_validation_check(struct _k_object *ko, static inline int _obj_validation_check(struct _k_object *ko,
void *obj, void *obj,
@ -256,8 +278,8 @@ static inline int _obj_validation_check(struct _k_object *ko,
return ret; return ret;
} }
#define _SYSCALL_IS_OBJ(ptr, type, init) \ #define Z_SYSCALL_IS_OBJ(ptr, type, init) \
_SYSCALL_VERIFY_MSG( \ Z_SYSCALL_VERIFY_MSG( \
!_obj_validation_check(_k_object_find((void *)ptr), (void *)ptr, \ !_obj_validation_check(_k_object_find((void *)ptr), (void *)ptr, \
type, init), "access denied") type, init), "access denied")
@ -269,16 +291,17 @@ static inline int _obj_validation_check(struct _k_object *ko,
* @param ptr Untrusted device instance object pointer * @param ptr Untrusted device instance object pointer
* @param api_struct Name of the driver API struct (e.g. gpio_driver_api) * @param api_struct Name of the driver API struct (e.g. gpio_driver_api)
* @param op Driver operation (e.g. manage_callback) * @param op Driver operation (e.g. manage_callback)
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_DRIVER_OP(ptr, api_name, op) \ #define Z_SYSCALL_DRIVER_OP(ptr, api_name, op) \
do { \ ({ \
struct api_name *__device__ = (struct api_name *) \ struct api_name *__device__ = (struct api_name *) \
((struct device *)ptr)->driver_api; \ ((struct device *)ptr)->driver_api; \
_SYSCALL_VERIFY_MSG(__device__->op != NULL, \ Z_SYSCALL_VERIFY_MSG(__device__->op != NULL, \
"Operation %s not defined for driver " \ "Operation %s not defined for driver " \
"instance %p", \ "instance %p", \
# op, __device__); \ # op, __device__); \
} while (0) })
/** /**
* @brief Runtime check kernel object pointer for non-init functions * @brief Runtime check kernel object pointer for non-init functions
@ -289,9 +312,10 @@ static inline int _obj_validation_check(struct _k_object *ko,
* *
* @param ptr Untrusted kernel object pointer * @param ptr Untrusted kernel object pointer
* @param type Expected kernel object type * @param type Expected kernel object type
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_OBJ(ptr, type) \ #define Z_SYSCALL_OBJ(ptr, type) \
_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_TRUE) Z_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_TRUE)
/** /**
* @brief Runtime check kernel object pointer for non-init functions * @brief Runtime check kernel object pointer for non-init functions
@ -301,10 +325,11 @@ static inline int _obj_validation_check(struct _k_object *ko,
* *
* @param ptr Untrusted kernel object pointer * @param ptr Untrusted kernel object pointer
* @param type Expected kernel object type * @param type Expected kernel object type
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_OBJ_INIT(ptr, type) \ #define Z_SYSCALL_OBJ_INIT(ptr, type) \
_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_ANY) Z_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_ANY)
/** /**
* @brief Runtime check kernel object pointer for non-init functions * @brief Runtime check kernel object pointer for non-init functions
@ -316,10 +341,11 @@ static inline int _obj_validation_check(struct _k_object *ko,
* *
* @param ptr Untrusted kernel object pointer * @param ptr Untrusted kernel object pointer
* @param type Expected kernel object type * @param type Expected kernel object type
* @return 0 on success, nonzero on failure
*/ */
#define _SYSCALL_OBJ_NEVER_INIT(ptr, type) \ #define Z_SYSCALL_OBJ_NEVER_INIT(ptr, type) \
_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_FALSE) Z_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_FALSE)
/* /*
* Handler definition macros * Handler definition macros
@ -410,7 +436,7 @@ static inline int _obj_validation_check(struct _k_object *ko,
#define __SYSCALL_ARG_N(_1, _2, _3, _4, _5, _6, _7, N, ...) N #define __SYSCALL_ARG_N(_1, _2, _3, _4, _5, _6, _7, N, ...) N
#define __SYSCALL_RSEQ_N() 6, 5, 4, 3, 2, 1, 0 #define __SYSCALL_RSEQ_N() 6, 5, 4, 3, 2, 1, 0
#define _SYSCALL_HANDLER(...) \ #define Z_SYSCALL_HANDLER(...) \
_SYSCALL_CONCAT(__SYSCALL_HANDLER, \ _SYSCALL_CONCAT(__SYSCALL_HANDLER, \
_SYSCALL_NARG(__VA_ARGS__))(__VA_ARGS__) _SYSCALL_NARG(__VA_ARGS__))(__VA_ARGS__)
@ -420,25 +446,25 @@ static inline int _obj_validation_check(struct _k_object *ko,
* and call the implementation. * and call the implementation.
*/ */
#define _SYSCALL_HANDLER1_SIMPLE(name_, obj_enum_, obj_type_) \ #define Z_SYSCALL_HANDLER1_SIMPLE(name_, obj_enum_, obj_type_) \
__SYSCALL_HANDLER1(name_, arg1) { \ __SYSCALL_HANDLER1(name_, arg1) { \
_SYSCALL_OBJ(arg1, obj_enum_); \ Z_OOPS(Z_SYSCALL_OBJ(arg1, obj_enum_)); \
return (u32_t)_impl_ ## name_((obj_type_)arg1); \ return (u32_t)_impl_ ## name_((obj_type_)arg1); \
} }
#define _SYSCALL_HANDLER1_SIMPLE_VOID(name_, obj_enum_, obj_type_) \ #define Z_SYSCALL_HANDLER1_SIMPLE_VOID(name_, obj_enum_, obj_type_) \
__SYSCALL_HANDLER1(name_, arg1) { \ __SYSCALL_HANDLER1(name_, arg1) { \
_SYSCALL_OBJ(arg1, obj_enum_); \ Z_OOPS(Z_SYSCALL_OBJ(arg1, obj_enum_)); \
_impl_ ## name_((obj_type_)arg1); \ _impl_ ## name_((obj_type_)arg1); \
return 0; \ return 0; \
} }
#define _SYSCALL_HANDLER0_SIMPLE(name_) \ #define Z_SYSCALL_HANDLER0_SIMPLE(name_) \
__SYSCALL_HANDLER0(name_) { \ __SYSCALL_HANDLER0(name_) { \
return (u32_t)_impl_ ## name_(); \ return (u32_t)_impl_ ## name_(); \
} }
#define _SYSCALL_HANDLER0_SIMPLE_VOID(name_) \ #define Z_SYSCALL_HANDLER0_SIMPLE_VOID(name_) \
__SYSCALL_HANDLER0(name_) { \ __SYSCALL_HANDLER0(name_) { \
_impl_ ## name_(); \ _impl_ ## name_(); \
return 0; \ return 0; \

View file

@ -89,9 +89,9 @@ int _impl_k_msgq_alloc_init(struct k_msgq *q, size_t msg_size,
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_msgq_alloc_init, q, msg_size, max_msgs) Z_SYSCALL_HANDLER(k_msgq_alloc_init, q, msg_size, max_msgs)
{ {
_SYSCALL_OBJ_NEVER_INIT(q, K_OBJ_MSGQ); Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(q, K_OBJ_MSGQ));
return _impl_k_msgq_alloc_init((struct k_msgq *)q, msg_size, max_msgs); return _impl_k_msgq_alloc_init((struct k_msgq *)q, msg_size, max_msgs);
} }
@ -153,12 +153,12 @@ int _impl_k_msgq_put(struct k_msgq *q, void *data, s32_t timeout)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_msgq_put, msgq_p, data, timeout) Z_SYSCALL_HANDLER(k_msgq_put, msgq_p, data, timeout)
{ {
struct k_msgq *q = (struct k_msgq *)msgq_p; struct k_msgq *q = (struct k_msgq *)msgq_p;
_SYSCALL_OBJ(q, K_OBJ_MSGQ); Z_OOPS(Z_SYSCALL_OBJ(q, K_OBJ_MSGQ));
_SYSCALL_MEMORY_READ(data, q->msg_size); Z_OOPS(Z_SYSCALL_MEMORY_READ(data, q->msg_size));
return _impl_k_msgq_put(q, (void *)data, timeout); return _impl_k_msgq_put(q, (void *)data, timeout);
} }
@ -172,12 +172,12 @@ void _impl_k_msgq_get_attrs(struct k_msgq *q, struct k_msgq_attrs *attrs)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_msgq_get_attrs, msgq_p, attrs) Z_SYSCALL_HANDLER(k_msgq_get_attrs, msgq_p, attrs)
{ {
struct k_msgq *q = (struct k_msgq *)msgq_p; struct k_msgq *q = (struct k_msgq *)msgq_p;
_SYSCALL_OBJ(q, K_OBJ_MSGQ); Z_OOPS(Z_SYSCALL_OBJ(q, K_OBJ_MSGQ));
_SYSCALL_MEMORY_WRITE(attrs, sizeof(struct k_msgq_attrs)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(attrs, sizeof(struct k_msgq_attrs)));
_impl_k_msgq_get_attrs(q, (struct k_msgq_attrs *) attrs); _impl_k_msgq_get_attrs(q, (struct k_msgq_attrs *) attrs);
return 0; return 0;
} }
@ -234,12 +234,12 @@ int _impl_k_msgq_get(struct k_msgq *q, void *data, s32_t timeout)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_msgq_get, msgq_p, data, timeout) Z_SYSCALL_HANDLER(k_msgq_get, msgq_p, data, timeout)
{ {
struct k_msgq *q = (struct k_msgq *)msgq_p; struct k_msgq *q = (struct k_msgq *)msgq_p;
_SYSCALL_OBJ(q, K_OBJ_MSGQ); Z_OOPS(Z_SYSCALL_OBJ(q, K_OBJ_MSGQ));
_SYSCALL_MEMORY_WRITE(data, q->msg_size); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, q->msg_size));
return _impl_k_msgq_get(q, (void *)data, timeout); return _impl_k_msgq_get(q, (void *)data, timeout);
} }
@ -263,7 +263,7 @@ void _impl_k_msgq_purge(struct k_msgq *q)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_msgq_purge, K_OBJ_MSGQ, struct k_msgq *); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_msgq_purge, K_OBJ_MSGQ, struct k_msgq *);
_SYSCALL_HANDLER1_SIMPLE(k_msgq_num_free_get, K_OBJ_MSGQ, struct k_msgq *); Z_SYSCALL_HANDLER1_SIMPLE(k_msgq_num_free_get, K_OBJ_MSGQ, struct k_msgq *);
_SYSCALL_HANDLER1_SIMPLE(k_msgq_num_used_get, K_OBJ_MSGQ, struct k_msgq *); Z_SYSCALL_HANDLER1_SIMPLE(k_msgq_num_used_get, K_OBJ_MSGQ, struct k_msgq *);
#endif #endif

View file

@ -82,9 +82,9 @@ void _impl_k_mutex_init(struct k_mutex *mutex)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_mutex_init, mutex) Z_SYSCALL_HANDLER(k_mutex_init, mutex)
{ {
_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX); Z_OOPS(Z_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX));
_impl_k_mutex_init((struct k_mutex *)mutex); _impl_k_mutex_init((struct k_mutex *)mutex);
return 0; return 0;
@ -192,9 +192,9 @@ int _impl_k_mutex_lock(struct k_mutex *mutex, s32_t timeout)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_mutex_lock, mutex, timeout) Z_SYSCALL_HANDLER(k_mutex_lock, mutex, timeout)
{ {
_SYSCALL_OBJ(mutex, K_OBJ_MUTEX); Z_OOPS(Z_SYSCALL_OBJ(mutex, K_OBJ_MUTEX));
return _impl_k_mutex_lock((struct k_mutex *)mutex, (s32_t)timeout); return _impl_k_mutex_lock((struct k_mutex *)mutex, (s32_t)timeout);
} }
#endif #endif
@ -252,11 +252,11 @@ void _impl_k_mutex_unlock(struct k_mutex *mutex)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_mutex_unlock, mutex) Z_SYSCALL_HANDLER(k_mutex_unlock, mutex)
{ {
_SYSCALL_OBJ(mutex, K_OBJ_MUTEX); Z_OOPS(Z_SYSCALL_OBJ(mutex, K_OBJ_MUTEX));
_SYSCALL_VERIFY(((struct k_mutex *)mutex)->lock_count > 0); Z_OOPS(Z_SYSCALL_VERIFY(((struct k_mutex *)mutex)->lock_count > 0));
_SYSCALL_VERIFY(((struct k_mutex *)mutex)->owner == _current); Z_OOPS(Z_SYSCALL_VERIFY(((struct k_mutex *)mutex)->owner == _current));
_impl_k_mutex_unlock((struct k_mutex *)mutex); _impl_k_mutex_unlock((struct k_mutex *)mutex);
return 0; return 0;
} }

View file

@ -165,9 +165,9 @@ int _impl_k_pipe_alloc_init(struct k_pipe *pipe, size_t size)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_pipe_alloc_init, pipe, size) Z_SYSCALL_HANDLER(k_pipe_alloc_init, pipe, size)
{ {
_SYSCALL_OBJ_NEVER_INIT(pipe, K_OBJ_PIPE); Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(pipe, K_OBJ_PIPE));
return _impl_k_pipe_alloc_init((struct k_pipe *)pipe, size); return _impl_k_pipe_alloc_init((struct k_pipe *)pipe, size);
} }
@ -714,16 +714,16 @@ int _impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_pipe_get, Z_SYSCALL_HANDLER(k_pipe_get,
pipe, data, bytes_to_read, bytes_read_p, min_xfer_p, timeout) pipe, data, bytes_to_read, bytes_read_p, min_xfer_p, timeout)
{ {
size_t *bytes_read = (size_t *)bytes_read_p; size_t *bytes_read = (size_t *)bytes_read_p;
size_t min_xfer = (size_t)min_xfer_p; size_t min_xfer = (size_t)min_xfer_p;
_SYSCALL_OBJ(pipe, K_OBJ_PIPE); Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read)));
_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read); Z_OOPS(Z_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read));
_SYSCALL_VERIFY(min_xfer <= bytes_to_read); Z_OOPS(Z_SYSCALL_VERIFY(min_xfer <= bytes_to_read));
return _impl_k_pipe_get((struct k_pipe *)pipe, (void *)data, return _impl_k_pipe_get((struct k_pipe *)pipe, (void *)data,
bytes_to_read, bytes_read, min_xfer, bytes_to_read, bytes_read, min_xfer,
@ -743,16 +743,16 @@ int _impl_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_pipe_put, pipe, data, bytes_to_write, bytes_written_p, Z_SYSCALL_HANDLER(k_pipe_put, pipe, data, bytes_to_write, bytes_written_p,
min_xfer_p, timeout) min_xfer_p, timeout)
{ {
size_t *bytes_written = (size_t *)bytes_written_p; size_t *bytes_written = (size_t *)bytes_written_p;
size_t min_xfer = (size_t)min_xfer_p; size_t min_xfer = (size_t)min_xfer_p;
_SYSCALL_OBJ(pipe, K_OBJ_PIPE); Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written)));
_SYSCALL_MEMORY_READ((void *)data, bytes_to_write); Z_OOPS(Z_SYSCALL_MEMORY_READ((void *)data, bytes_to_write));
_SYSCALL_VERIFY(min_xfer <= bytes_to_write); Z_OOPS(Z_SYSCALL_VERIFY(min_xfer <= bytes_to_write));
return _impl_k_pipe_put((struct k_pipe *)pipe, (void *)data, return _impl_k_pipe_put((struct k_pipe *)pipe, (void *)data,
bytes_to_write, bytes_written, min_xfer, bytes_to_write, bytes_written, min_xfer,

View file

@ -94,11 +94,11 @@ void _impl_k_queue_init(struct k_queue *queue)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_queue_init, queue_ptr) Z_SYSCALL_HANDLER(k_queue_init, queue_ptr)
{ {
struct k_queue *queue = (struct k_queue *)queue_ptr; struct k_queue *queue = (struct k_queue *)queue_ptr;
_SYSCALL_OBJ_NEVER_INIT(queue, K_OBJ_QUEUE); Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(queue, K_OBJ_QUEUE));
_impl_k_queue_init(queue); _impl_k_queue_init(queue);
return 0; return 0;
} }
@ -138,7 +138,7 @@ void _impl_k_queue_cancel_wait(struct k_queue *queue)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_queue_cancel_wait, K_OBJ_QUEUE, Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_queue_cancel_wait, K_OBJ_QUEUE,
struct k_queue *); struct k_queue *);
#endif #endif
@ -204,9 +204,9 @@ int _impl_k_queue_alloc_append(struct k_queue *queue, void *data)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_queue_alloc_append, queue, data) Z_SYSCALL_HANDLER(k_queue_alloc_append, queue, data)
{ {
_SYSCALL_OBJ(queue, K_OBJ_QUEUE); Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE));
return _impl_k_queue_alloc_append((struct k_queue *)queue, return _impl_k_queue_alloc_append((struct k_queue *)queue,
(void *)data); (void *)data);
@ -219,9 +219,9 @@ int _impl_k_queue_alloc_prepend(struct k_queue *queue, void *data)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_queue_alloc_prepend, queue, data) Z_SYSCALL_HANDLER(k_queue_alloc_prepend, queue, data)
{ {
_SYSCALL_OBJ(queue, K_OBJ_QUEUE); Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE));
return _impl_k_queue_alloc_prepend((struct k_queue *)queue, return _impl_k_queue_alloc_prepend((struct k_queue *)queue,
(void *)data); (void *)data);
@ -338,16 +338,16 @@ void *_impl_k_queue_get(struct k_queue *queue, s32_t timeout)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_queue_get, queue, timeout_p) Z_SYSCALL_HANDLER(k_queue_get, queue, timeout_p)
{ {
s32_t timeout = timeout_p; s32_t timeout = timeout_p;
_SYSCALL_OBJ(queue, K_OBJ_QUEUE); Z_OOPS(Z_SYSCALL_OBJ(queue, K_OBJ_QUEUE));
return (u32_t)_impl_k_queue_get((struct k_queue *)queue, timeout); return (u32_t)_impl_k_queue_get((struct k_queue *)queue, timeout);
} }
_SYSCALL_HANDLER1_SIMPLE(k_queue_is_empty, K_OBJ_QUEUE, struct k_queue *); Z_SYSCALL_HANDLER1_SIMPLE(k_queue_is_empty, K_OBJ_QUEUE, struct k_queue *);
_SYSCALL_HANDLER1_SIMPLE(k_queue_peek_head, K_OBJ_QUEUE, struct k_queue *); Z_SYSCALL_HANDLER1_SIMPLE(k_queue_peek_head, K_OBJ_QUEUE, struct k_queue *);
_SYSCALL_HANDLER1_SIMPLE(k_queue_peek_tail, K_OBJ_QUEUE, struct k_queue *); Z_SYSCALL_HANDLER1_SIMPLE(k_queue_peek_tail, K_OBJ_QUEUE, struct k_queue *);
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */

View file

@ -354,7 +354,7 @@ int _impl_k_thread_priority_get(k_tid_t thread)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE(k_thread_priority_get, K_OBJ_THREAD, Z_SYSCALL_HANDLER1_SIMPLE(k_thread_priority_get, K_OBJ_THREAD,
struct k_thread *); struct k_thread *);
#endif #endif
@ -375,16 +375,16 @@ void _impl_k_thread_priority_set(k_tid_t tid, int prio)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_thread_priority_set, thread_p, prio) Z_SYSCALL_HANDLER(k_thread_priority_set, thread_p, prio)
{ {
struct k_thread *thread = (struct k_thread *)thread_p; struct k_thread *thread = (struct k_thread *)thread_p;
_SYSCALL_OBJ(thread, K_OBJ_THREAD); Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD));
_SYSCALL_VERIFY_MSG(_is_valid_prio(prio, NULL), Z_OOPS(Z_SYSCALL_VERIFY_MSG(_is_valid_prio(prio, NULL),
"invalid thread priority %d", (int)prio); "invalid thread priority %d", (int)prio));
_SYSCALL_VERIFY_MSG((s8_t)prio >= thread->base.prio, Z_OOPS(Z_SYSCALL_VERIFY_MSG((s8_t)prio >= thread->base.prio,
"thread priority may only be downgraded (%d < %d)", "thread priority may only be downgraded (%d < %d)",
prio, thread->base.prio); prio, thread->base.prio));
_impl_k_thread_priority_set((k_tid_t)thread, prio); _impl_k_thread_priority_set((k_tid_t)thread, prio);
return 0; return 0;
@ -438,7 +438,7 @@ void _impl_k_yield(void)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER0_SIMPLE_VOID(k_yield); Z_SYSCALL_HANDLER0_SIMPLE_VOID(k_yield);
#endif #endif
void _impl_k_sleep(s32_t duration) void _impl_k_sleep(s32_t duration)
@ -472,13 +472,13 @@ void _impl_k_sleep(s32_t duration)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_sleep, duration) Z_SYSCALL_HANDLER(k_sleep, duration)
{ {
/* FIXME there were some discussions recently on whether we should /* FIXME there were some discussions recently on whether we should
* relax this, thread would be unscheduled until k_wakeup issued * relax this, thread would be unscheduled until k_wakeup issued
*/ */
_SYSCALL_VERIFY_MSG(duration != K_FOREVER, Z_OOPS(Z_SYSCALL_VERIFY_MSG(duration != K_FOREVER,
"sleeping forever not allowed"); "sleeping forever not allowed"));
_impl_k_sleep(duration); _impl_k_sleep(duration);
return 0; return 0;
@ -510,7 +510,7 @@ void _impl_k_wakeup(k_tid_t thread)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_wakeup, K_OBJ_THREAD, k_tid_t); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_wakeup, K_OBJ_THREAD, k_tid_t);
#endif #endif
k_tid_t _impl_k_current_get(void) k_tid_t _impl_k_current_get(void)
@ -519,7 +519,7 @@ k_tid_t _impl_k_current_get(void)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER0_SIMPLE(k_current_get); Z_SYSCALL_HANDLER0_SIMPLE(k_current_get);
#endif #endif
#ifdef CONFIG_TIMESLICING #ifdef CONFIG_TIMESLICING
@ -591,7 +591,7 @@ int _impl_k_is_preempt_thread(void)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER0_SIMPLE(k_is_preempt_thread); Z_SYSCALL_HANDLER0_SIMPLE(k_is_preempt_thread);
#endif #endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP

View file

@ -73,10 +73,10 @@ void _impl_k_sem_init(struct k_sem *sem, unsigned int initial_count,
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_sem_init, sem, initial_count, limit) Z_SYSCALL_HANDLER(k_sem_init, sem, initial_count, limit)
{ {
_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM); Z_OOPS(Z_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM));
_SYSCALL_VERIFY(limit != 0 && initial_count <= limit); Z_OOPS(Z_SYSCALL_VERIFY(limit != 0 && initial_count <= limit));
_impl_k_sem_init((struct k_sem *)sem, initial_count, limit); _impl_k_sem_init((struct k_sem *)sem, initial_count, limit);
return 0; return 0;
} }
@ -139,7 +139,7 @@ void _impl_k_sem_give(struct k_sem *sem)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_sem_give, K_OBJ_SEM, struct k_sem *); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_sem_give, K_OBJ_SEM, struct k_sem *);
#endif #endif
int _impl_k_sem_take(struct k_sem *sem, s32_t timeout) int _impl_k_sem_take(struct k_sem *sem, s32_t timeout)
@ -163,12 +163,12 @@ int _impl_k_sem_take(struct k_sem *sem, s32_t timeout)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_sem_take, sem, timeout) Z_SYSCALL_HANDLER(k_sem_take, sem, timeout)
{ {
_SYSCALL_OBJ(sem, K_OBJ_SEM); Z_OOPS(Z_SYSCALL_OBJ(sem, K_OBJ_SEM));
return _impl_k_sem_take((struct k_sem *)sem, timeout); return _impl_k_sem_take((struct k_sem *)sem, timeout);
} }
_SYSCALL_HANDLER1_SIMPLE_VOID(k_sem_reset, K_OBJ_SEM, struct k_sem *); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_sem_reset, K_OBJ_SEM, struct k_sem *);
_SYSCALL_HANDLER1_SIMPLE(k_sem_count_get, K_OBJ_SEM, struct k_sem *); Z_SYSCALL_HANDLER1_SIMPLE(k_sem_count_get, K_OBJ_SEM, struct k_sem *);
#endif #endif

View file

@ -74,10 +74,10 @@ int _impl_k_stack_alloc_init(struct k_stack *stack, unsigned int num_entries)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_stack_alloc_init, stack, num_entries) Z_SYSCALL_HANDLER(k_stack_alloc_init, stack, num_entries)
{ {
_SYSCALL_OBJ_NEVER_INIT(stack, K_OBJ_STACK); Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(stack, K_OBJ_STACK));
_SYSCALL_VERIFY(num_entries > 0); Z_OOPS(Z_SYSCALL_VERIFY(num_entries > 0));
_impl_k_stack_alloc_init((struct k_stack *)stack, num_entries); _impl_k_stack_alloc_init((struct k_stack *)stack, num_entries);
return 0; return 0;
@ -122,12 +122,13 @@ void _impl_k_stack_push(struct k_stack *stack, u32_t data)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_stack_push, stack_p, data) Z_SYSCALL_HANDLER(k_stack_push, stack_p, data)
{ {
struct k_stack *stack = (struct k_stack *)stack_p; struct k_stack *stack = (struct k_stack *)stack_p;
_SYSCALL_OBJ(stack, K_OBJ_STACK); Z_OOPS(Z_SYSCALL_OBJ(stack, K_OBJ_STACK));
_SYSCALL_VERIFY_MSG(stack->next != stack->top, "stack is full"); Z_OOPS(Z_SYSCALL_VERIFY_MSG(stack->next != stack->top,
"stack is full"));
_impl_k_stack_push(stack, data); _impl_k_stack_push(stack, data);
return 0; return 0;
@ -162,10 +163,10 @@ int _impl_k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_stack_pop, stack, data, timeout) Z_SYSCALL_HANDLER(k_stack_pop, stack, data, timeout)
{ {
_SYSCALL_OBJ(stack, K_OBJ_STACK); Z_OOPS(Z_SYSCALL_OBJ(stack, K_OBJ_STACK));
_SYSCALL_MEMORY_WRITE(data, sizeof(u32_t)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, sizeof(u32_t)));
return _impl_k_stack_pop((struct k_stack *)stack, (u32_t *)data, return _impl_k_stack_pop((struct k_stack *)stack, (u32_t *)data,
timeout); timeout);

View file

@ -79,10 +79,10 @@ u32_t _impl_k_uptime_get_32(void)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_uptime_get_32) Z_SYSCALL_HANDLER(k_uptime_get_32)
{ {
#ifdef CONFIG_TICKLESS_KERNEL #ifdef CONFIG_TICKLESS_KERNEL
_SYSCALL_VERIFY(_sys_clock_always_on); Z_OOPS(Z_SYSCALL_VERIFY(_sys_clock_always_on));
#endif #endif
return _impl_k_uptime_get_32(); return _impl_k_uptime_get_32();
} }
@ -126,11 +126,11 @@ s64_t _impl_k_uptime_get(void)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_uptime_get, ret_p) Z_SYSCALL_HANDLER(k_uptime_get, ret_p)
{ {
u64_t *ret = (u64_t *)ret_p; u64_t *ret = (u64_t *)ret_p;
_SYSCALL_MEMORY_WRITE(ret, sizeof(*ret)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(ret, sizeof(*ret)));
*ret = _impl_k_uptime_get(); *ret = _impl_k_uptime_get();
return 0; return 0;
} }

View file

@ -131,7 +131,7 @@ void _impl_k_thread_custom_data_set(void *value)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_thread_custom_data_set, data) Z_SYSCALL_HANDLER(k_thread_custom_data_set, data)
{ {
_impl_k_thread_custom_data_set((void *)data); _impl_k_thread_custom_data_set((void *)data);
return 0; return 0;
@ -144,7 +144,7 @@ void *_impl_k_thread_custom_data_get(void)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER0_SIMPLE(k_thread_custom_data_get); Z_SYSCALL_HANDLER0_SIMPLE(k_thread_custom_data_get);
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
#endif /* CONFIG_THREAD_CUSTOM_DATA */ #endif /* CONFIG_THREAD_CUSTOM_DATA */
@ -224,7 +224,7 @@ void _impl_k_thread_start(struct k_thread *thread)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_start, K_OBJ_THREAD, struct k_thread *); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_start, K_OBJ_THREAD, struct k_thread *);
#endif #endif
#endif #endif
@ -336,7 +336,7 @@ k_tid_t _impl_k_thread_create(struct k_thread *new_thread,
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_thread_create, Z_SYSCALL_HANDLER(k_thread_create,
new_thread_p, stack_p, stack_size, entry, p1, more_args) new_thread_p, stack_p, stack_size, entry, p1, more_args)
{ {
int prio; int prio;
@ -352,12 +352,12 @@ _SYSCALL_HANDLER(k_thread_create,
k_thread_stack_t *stack = (k_thread_stack_t *)stack_p; k_thread_stack_t *stack = (k_thread_stack_t *)stack_p;
/* The thread and stack objects *must* be in an uninitialized state */ /* The thread and stack objects *must* be in an uninitialized state */
_SYSCALL_OBJ_NEVER_INIT(new_thread, K_OBJ_THREAD); Z_OOPS(Z_SYSCALL_OBJ_NEVER_INIT(new_thread, K_OBJ_THREAD));
stack_object = _k_object_find(stack); stack_object = _k_object_find(stack);
_SYSCALL_VERIFY_MSG(!_obj_validation_check(stack_object, stack, Z_OOPS(Z_SYSCALL_VERIFY_MSG(!_obj_validation_check(stack_object, stack,
K_OBJ__THREAD_STACK_ELEMENT, K_OBJ__THREAD_STACK_ELEMENT,
_OBJ_INIT_FALSE), _OBJ_INIT_FALSE),
"bad stack object"); "bad stack object"));
#ifndef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT #ifndef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT
/* Verify that the stack size passed in is OK by computing the total /* Verify that the stack size passed in is OK by computing the total
@ -368,20 +368,21 @@ _SYSCALL_HANDLER(k_thread_create,
* size and not allocated in addition to the stack size * size and not allocated in addition to the stack size
*/ */
guard_size = (u32_t)K_THREAD_STACK_BUFFER(stack) - (u32_t)stack; guard_size = (u32_t)K_THREAD_STACK_BUFFER(stack) - (u32_t)stack;
_SYSCALL_VERIFY_MSG(!__builtin_uadd_overflow(guard_size, stack_size, Z_OOPS(Z_SYSCALL_VERIFY_MSG(!__builtin_uadd_overflow(guard_size,
stack_size,
&total_size), &total_size),
"stack size overflow (%u+%u)", stack_size, "stack size overflow (%u+%u)", stack_size,
guard_size); guard_size));
#else #else
total_size = stack_size; total_size = stack_size;
#endif #endif
/* They really ought to be equal, make this more strict? */ /* They really ought to be equal, make this more strict? */
_SYSCALL_VERIFY_MSG(total_size <= stack_object->data, Z_OOPS(Z_SYSCALL_VERIFY_MSG(total_size <= stack_object->data,
"stack size %u is too big, max is %u", "stack size %u is too big, max is %u",
total_size, stack_object->data); total_size, stack_object->data));
/* Verify the struct containing args 6-10 */ /* Verify the struct containing args 6-10 */
_SYSCALL_MEMORY_READ(margs, sizeof(*margs)); Z_OOPS(Z_SYSCALL_MEMORY_READ(margs, sizeof(*margs)));
/* Stash struct arguments in local variables to prevent switcheroo /* Stash struct arguments in local variables to prevent switcheroo
* attacks * attacks
@ -394,14 +395,15 @@ _SYSCALL_HANDLER(k_thread_create,
/* User threads may only create other user threads and they can't /* User threads may only create other user threads and they can't
* be marked as essential * be marked as essential
*/ */
_SYSCALL_VERIFY(options & K_USER); Z_OOPS(Z_SYSCALL_VERIFY(options & K_USER));
_SYSCALL_VERIFY(!(options & K_ESSENTIAL)); Z_OOPS(Z_SYSCALL_VERIFY(!(options & K_ESSENTIAL)));
/* Check validity of prio argument; must be the same or worse priority /* Check validity of prio argument; must be the same or worse priority
* than the caller * than the caller
*/ */
_SYSCALL_VERIFY(_is_valid_prio(prio, NULL)); Z_OOPS(Z_SYSCALL_VERIFY(_is_valid_prio(prio, NULL)));
_SYSCALL_VERIFY(_is_prio_lower_or_equal(prio, _current->base.prio)); Z_OOPS(Z_SYSCALL_VERIFY(_is_prio_lower_or_equal(prio,
_current->base.prio)));
_setup_new_thread((struct k_thread *)new_thread, stack, stack_size, _setup_new_thread((struct k_thread *)new_thread, stack, stack_size,
(k_thread_entry_t)entry, (void *)p1, (k_thread_entry_t)entry, (void *)p1,
@ -438,7 +440,7 @@ int _impl_k_thread_cancel(k_tid_t tid)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE(k_thread_cancel, K_OBJ_THREAD, struct k_thread *); Z_SYSCALL_HANDLER1_SIMPLE(k_thread_cancel, K_OBJ_THREAD, struct k_thread *);
#endif #endif
void _k_thread_single_suspend(struct k_thread *thread) void _k_thread_single_suspend(struct k_thread *thread)
@ -464,7 +466,7 @@ void _impl_k_thread_suspend(struct k_thread *thread)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_suspend, K_OBJ_THREAD, k_tid_t); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_suspend, K_OBJ_THREAD, k_tid_t);
#endif #endif
void _k_thread_single_resume(struct k_thread *thread) void _k_thread_single_resume(struct k_thread *thread)
@ -483,7 +485,7 @@ void _impl_k_thread_resume(struct k_thread *thread)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_resume, K_OBJ_THREAD, k_tid_t); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_resume, K_OBJ_THREAD, k_tid_t);
#endif #endif
void _k_thread_single_abort(struct k_thread *thread) void _k_thread_single_abort(struct k_thread *thread)

View file

@ -52,12 +52,12 @@ void _impl_k_thread_abort(k_tid_t thread)
#endif #endif
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_thread_abort, thread_p) Z_SYSCALL_HANDLER(k_thread_abort, thread_p)
{ {
struct k_thread *thread = (struct k_thread *)thread_p; struct k_thread *thread = (struct k_thread *)thread_p;
_SYSCALL_OBJ(thread, K_OBJ_THREAD); Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD));
_SYSCALL_VERIFY_MSG(!(thread->base.user_options & K_ESSENTIAL), Z_OOPS(Z_SYSCALL_VERIFY_MSG(!(thread->base.user_options & K_ESSENTIAL),
"aborting essential thread %p", thread); "aborting essential thread %p", thread));
_impl_k_thread_abort((struct k_thread *)thread); _impl_k_thread_abort((struct k_thread *)thread);
return 0; return 0;

View file

@ -133,16 +133,16 @@ void _impl_k_timer_start(struct k_timer *timer, s32_t duration, s32_t period)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_timer_start, timer, duration_p, period_p) Z_SYSCALL_HANDLER(k_timer_start, timer, duration_p, period_p)
{ {
s32_t duration, period; s32_t duration, period;
duration = (s32_t)duration_p; duration = (s32_t)duration_p;
period = (s32_t)period_p; period = (s32_t)period_p;
_SYSCALL_VERIFY(duration >= 0 && period >= 0 && Z_OOPS(Z_SYSCALL_VERIFY(duration >= 0 && period >= 0 &&
(duration != 0 || period != 0)); (duration != 0 || period != 0)));
_SYSCALL_OBJ(timer, K_OBJ_TIMER); Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER));
_impl_k_timer_start((struct k_timer *)timer, duration, period); _impl_k_timer_start((struct k_timer *)timer, duration, period);
return 0; return 0;
} }
@ -178,7 +178,7 @@ void _impl_k_timer_stop(struct k_timer *timer)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE_VOID(k_timer_stop, K_OBJ_TIMER, struct k_timer *); Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_timer_stop, K_OBJ_TIMER, struct k_timer *);
#endif #endif
u32_t _impl_k_timer_status_get(struct k_timer *timer) u32_t _impl_k_timer_status_get(struct k_timer *timer)
@ -193,7 +193,7 @@ u32_t _impl_k_timer_status_get(struct k_timer *timer)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE(k_timer_status_get, K_OBJ_TIMER, struct k_timer *); Z_SYSCALL_HANDLER1_SIMPLE(k_timer_status_get, K_OBJ_TIMER, struct k_timer *);
#endif #endif
u32_t _impl_k_timer_status_sync(struct k_timer *timer) u32_t _impl_k_timer_status_sync(struct k_timer *timer)
@ -225,7 +225,7 @@ u32_t _impl_k_timer_status_sync(struct k_timer *timer)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE(k_timer_status_sync, K_OBJ_TIMER, struct k_timer *); Z_SYSCALL_HANDLER1_SIMPLE(k_timer_status_sync, K_OBJ_TIMER, struct k_timer *);
#endif #endif
s32_t _timeout_remaining_get(struct _timeout *timeout) s32_t _timeout_remaining_get(struct _timeout *timeout)
@ -256,12 +256,12 @@ s32_t _timeout_remaining_get(struct _timeout *timeout)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE(k_timer_remaining_get, K_OBJ_TIMER, struct k_timer *); Z_SYSCALL_HANDLER1_SIMPLE(k_timer_remaining_get, K_OBJ_TIMER, struct k_timer *);
_SYSCALL_HANDLER1_SIMPLE(k_timer_user_data_get, K_OBJ_TIMER, struct k_timer *); Z_SYSCALL_HANDLER1_SIMPLE(k_timer_user_data_get, K_OBJ_TIMER, struct k_timer *);
_SYSCALL_HANDLER(k_timer_user_data_set, timer, user_data) Z_SYSCALL_HANDLER(k_timer_user_data_set, timer, user_data)
{ {
_SYSCALL_OBJ(timer, K_OBJ_TIMER); Z_OOPS(Z_SYSCALL_OBJ(timer, K_OBJ_TIMER));
_impl_k_timer_user_data_set((struct k_timer *)timer, (void *)user_data); _impl_k_timer_user_data_set((struct k_timer *)timer, (void *)user_data);
return 0; return 0;
} }

View file

@ -36,34 +36,36 @@ static struct _k_object *validate_any_object(void *obj)
* To avoid double _k_object_find() lookups, we don't call the implementation * To avoid double _k_object_find() lookups, we don't call the implementation
* function, but call a level deeper. * function, but call a level deeper.
*/ */
_SYSCALL_HANDLER(k_object_access_grant, object, thread) Z_SYSCALL_HANDLER(k_object_access_grant, object, thread)
{ {
struct _k_object *ko; struct _k_object *ko;
_SYSCALL_OBJ_INIT(thread, K_OBJ_THREAD); Z_OOPS(Z_SYSCALL_OBJ_INIT(thread, K_OBJ_THREAD));
ko = validate_any_object((void *)object); ko = validate_any_object((void *)object);
_SYSCALL_VERIFY_MSG(ko, "object %p access denied", (void *)object); Z_OOPS(Z_SYSCALL_VERIFY_MSG(ko, "object %p access denied",
(void *)object));
_thread_perms_set(ko, (struct k_thread *)thread); _thread_perms_set(ko, (struct k_thread *)thread);
return 0; return 0;
} }
_SYSCALL_HANDLER(k_object_release, object) Z_SYSCALL_HANDLER(k_object_release, object)
{ {
struct _k_object *ko; struct _k_object *ko;
ko = validate_any_object((void *)object); ko = validate_any_object((void *)object);
_SYSCALL_VERIFY_MSG(ko, "object %p access denied", (void *)object); Z_OOPS(Z_SYSCALL_VERIFY_MSG(ko, "object %p access denied",
(void *)object));
_thread_perms_clear(ko, _current); _thread_perms_clear(ko, _current);
return 0; return 0;
} }
_SYSCALL_HANDLER(k_object_alloc, otype) Z_SYSCALL_HANDLER(k_object_alloc, otype)
{ {
_SYSCALL_VERIFY_MSG(otype > K_OBJ_ANY && otype < K_OBJ_LAST && Z_OOPS(Z_SYSCALL_VERIFY_MSG(otype > K_OBJ_ANY && otype < K_OBJ_LAST &&
otype != K_OBJ__THREAD_STACK_ELEMENT, otype != K_OBJ__THREAD_STACK_ELEMENT,
"bad object type %d requested", otype); "bad object type %d requested", otype));
return (u32_t)_impl_k_object_alloc(otype); return (u32_t)_impl_k_object_alloc(otype);
} }

View file

@ -305,9 +305,9 @@ void _impl_k_str_out(char *c, size_t n)
} }
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER(k_str_out, c, n) Z_SYSCALL_HANDLER(k_str_out, c, n)
{ {
_SYSCALL_MEMORY_READ(c, n); Z_OOPS(Z_SYSCALL_MEMORY_READ(c, n));
_impl_k_str_out((char *)c, n); _impl_k_str_out((char *)c, n);
return 0; return 0;

View file

@ -120,18 +120,17 @@ def write_gperf_table(fp, eh, objs, static_begin, static_end):
driver_macro_tpl = """ driver_macro_tpl = """
#define _SYSCALL_DRIVER_%(driver_upper)s(ptr, op) _SYSCALL_DRIVER_GEN(ptr, op, %(driver_lower)s, %(driver_upper)s) #define Z_SYSCALL_DRIVER_%(driver_upper)s(ptr, op) Z_SYSCALL_DRIVER_GEN(ptr, op, %(driver_lower)s, %(driver_upper)s)
""" """
def write_validation_output(fp): def write_validation_output(fp):
fp.write("#ifndef __DRIVER_VALIDATION_GEN_H__\n") fp.write("#ifndef __DRIVER_VALIDATION_GEN_H__\n")
fp.write("#define __DRIVER_VALIDATION_GEN_H__\n") fp.write("#define __DRIVER_VALIDATION_GEN_H__\n")
fp.write("""#define _SYSCALL_DRIVER_GEN(ptr, op, driver_lower_case, driver_upper_case) \\ fp.write("""#define Z_SYSCALL_DRIVER_GEN(ptr, op, driver_lower_case, driver_upper_case) \\
do { \\ (Z_SYSCALL_OBJ(ptr, K_OBJ_DRIVER_##driver_upper_case) || \\
_SYSCALL_OBJ(ptr, K_OBJ_DRIVER_##driver_upper_case); \\ Z_SYSCALL_DRIVER_OP(ptr, driver_lower_case##_driver_api, op))
_SYSCALL_DRIVER_OP(ptr, driver_lower_case##_driver_api, op); \\ """)
} while (0)\n\n""");
for subsystem in subsystems: for subsystem in subsystems:
subsystem = subsystem.replace("_driver_api", "") subsystem = subsystem.replace("_driver_api", "")