diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/nvme-core.c | 99 | ||||
-rw-r--r-- | drivers/block/zram/zram_drv.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 2 | ||||
-rw-r--r-- | drivers/hid/hid-microsoft.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-saitek.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 8 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 6 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 7 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 11 | ||||
-rw-r--r-- | drivers/hwmon/ads7828.c | 3 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1685.c | 18 | ||||
-rw-r--r-- | drivers/sh/pm_runtime.c | 2 | ||||
-rw-r--r-- | drivers/xen/Makefile | 2 | ||||
-rw-r--r-- | drivers/xen/preempt.c | 44 | ||||
-rw-r--r-- | drivers/xen/privcmd.c | 2 | ||||
-rw-r--r-- | drivers/xen/xen-scsiback.c | 14 |
17 files changed, 155 insertions, 71 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index b64bccbb78c9..ceb32dd52a6c 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -482,6 +482,7 @@ static int nvme_error_status(u16 status) } } +#ifdef CONFIG_BLK_DEV_INTEGRITY static void nvme_dif_prep(u32 p, u32 v, struct t10_pi_tuple *pi) { if (be32_to_cpu(pi->ref_tag) == v) @@ -538,6 +539,58 @@ static void nvme_dif_remap(struct request *req, kunmap_atomic(pmap); } +static int nvme_noop_verify(struct blk_integrity_iter *iter) +{ + return 0; +} + +static int nvme_noop_generate(struct blk_integrity_iter *iter) +{ + return 0; +} + +struct blk_integrity nvme_meta_noop = { + .name = "NVME_META_NOOP", + .generate_fn = nvme_noop_generate, + .verify_fn = nvme_noop_verify, +}; + +static void nvme_init_integrity(struct nvme_ns *ns) +{ + struct blk_integrity integrity; + + switch (ns->pi_type) { + case NVME_NS_DPS_PI_TYPE3: + integrity = t10_pi_type3_crc; + break; + case NVME_NS_DPS_PI_TYPE1: + case NVME_NS_DPS_PI_TYPE2: + integrity = t10_pi_type1_crc; + break; + default: + integrity = nvme_meta_noop; + break; + } + integrity.tuple_size = ns->ms; + blk_integrity_register(ns->disk, &integrity); + blk_queue_max_integrity_segments(ns->queue, 1); +} +#else /* CONFIG_BLK_DEV_INTEGRITY */ +static void nvme_dif_remap(struct request *req, + void (*dif_swap)(u32 p, u32 v, struct t10_pi_tuple *pi)) +{ +} +static void nvme_dif_prep(u32 p, u32 v, struct t10_pi_tuple *pi) +{ +} +static void nvme_dif_complete(u32 p, u32 v, struct t10_pi_tuple *pi) +{ +} +static void nvme_init_integrity(struct nvme_ns *ns) +{ +} +#endif + static void req_completion(struct nvme_queue *nvmeq, void *ctx, struct nvme_completion *cqe) { @@ -1959,43 +2012,6 @@ static void nvme_config_discard(struct nvme_ns *ns) queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, ns->queue); } -static int nvme_noop_verify(struct blk_integrity_iter *iter) -{ - return 0; -} - -static int nvme_noop_generate(struct blk_integrity_iter *iter) -{ - return 0; -} - -struct blk_integrity nvme_meta_noop = { - .name = "NVME_META_NOOP", - .generate_fn = nvme_noop_generate, - .verify_fn = nvme_noop_verify, -}; - -static void nvme_init_integrity(struct nvme_ns *ns) -{ - struct blk_integrity integrity; - - switch (ns->pi_type) { - case NVME_NS_DPS_PI_TYPE3: - integrity = t10_pi_type3_crc; - break; - case NVME_NS_DPS_PI_TYPE1: - case NVME_NS_DPS_PI_TYPE2: - integrity = t10_pi_type1_crc; - break; - default: - integrity = nvme_meta_noop; - break; - } - integrity.tuple_size = ns->ms; - blk_integrity_register(ns->disk, &integrity); - blk_queue_max_integrity_segments(ns->queue, 1); -} - static int nvme_revalidate_disk(struct gendisk *disk) { struct nvme_ns *ns = disk->private_data; @@ -2036,7 +2052,8 @@ static int nvme_revalidate_disk(struct gendisk *disk) pi_type = ns->ms == sizeof(struct t10_pi_tuple) ? id->dps & NVME_NS_DPS_PI_MASK : 0; - if (disk->integrity && (ns->pi_type != pi_type || ns->ms != old_ms || + if (blk_get_integrity(disk) && (ns->pi_type != pi_type || + ns->ms != old_ms || bs != queue_logical_block_size(disk->queue) || (ns->ms && id->flbas & NVME_NS_FLBAS_META_EXT))) blk_integrity_unregister(disk); @@ -2044,11 +2061,11 @@ static int nvme_revalidate_disk(struct gendisk *disk) ns->pi_type = pi_type; blk_queue_logical_block_size(ns->queue, bs); - if (ns->ms && !disk->integrity && (disk->flags & GENHD_FL_UP) && + if (ns->ms && !blk_get_integrity(disk) && (disk->flags & GENHD_FL_UP) && !(id->flbas & NVME_NS_FLBAS_META_EXT)) nvme_init_integrity(ns); - if (id->ncap == 0 || (ns->ms && !disk->integrity)) + if (id->ncap == 0 || (ns->ms && !blk_get_integrity(disk))) set_capacity(disk, 0); else set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9)); @@ -2652,7 +2669,7 @@ static void nvme_dev_remove(struct nvme_dev *dev) list_for_each_entry(ns, &dev->namespaces, list) { if (ns->disk->flags & GENHD_FL_UP) { - if (ns->disk->integrity) + if (blk_get_integrity(ns->disk)) blk_integrity_unregister(ns->disk); del_gendisk(ns->disk); } diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 8e233edd7a09..871bd3550cb0 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -528,7 +528,7 @@ out_cleanup: static inline void update_used_max(struct zram *zram, const unsigned long pages) { - int old_max, cur_max; + unsigned long old_max, cur_max; old_max = atomic_long_read(&zram->stats.max_used_pages); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index db4fb6e1cc5b..7c669c328c4c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1872,6 +1872,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE7K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, @@ -1926,6 +1927,7 @@ static const struct hid_device_id hid_have_special_driver[] = { #endif #if IS_ENABLED(CONFIG_HID_SAITEK) { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) }, { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 46edb4d3ed28..204312bfab2c 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -654,6 +654,7 @@ #define USB_DEVICE_ID_MS_LK6K 0x00f9 #define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 +#define USB_DEVICE_ID_MS_NE7K 0x071d #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 @@ -802,6 +803,7 @@ #define USB_VENDOR_ID_SAITEK 0x06a3 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 #define USB_DEVICE_ID_SAITEK_PS1000 0x0621 +#define USB_DEVICE_ID_SAITEK_RAT7_OLD 0x0ccb #define USB_DEVICE_ID_SAITEK_RAT7 0x0cd7 #define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0 diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index fbaea6eb882e..af935eb198c9 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -264,6 +264,8 @@ static const struct hid_device_id ms_devices[] = { .driver_data = MS_ERGONOMY }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP), .driver_data = MS_ERGONOMY }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE7K), + .driver_data = MS_ERGONOMY }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K), .driver_data = MS_ERGONOMY | MS_RDESC }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), diff --git a/drivers/hid/hid-saitek.c b/drivers/hid/hid-saitek.c index 5632c54eadf0..a014f21275d8 100644 --- a/drivers/hid/hid-saitek.c +++ b/drivers/hid/hid-saitek.c @@ -177,6 +177,8 @@ static int saitek_event(struct hid_device *hdev, struct hid_field *field, static const struct hid_device_id saitek_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000), .driver_data = SAITEK_FIX_PS1000 }, + { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD), + .driver_data = SAITEK_RELEASE_MODE_RAT7 }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7), .driver_data = SAITEK_RELEASE_MODE_RAT7 }, { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9), diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 6a58b6c723aa..e54ce1097e2c 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -135,8 +135,9 @@ static struct hid_sensor_hub_callbacks *sensor_hub_get_callback( { struct hid_sensor_hub_callbacks_list *callback; struct sensor_hub_data *pdata = hid_get_drvdata(hdev); + unsigned long flags; - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) if (callback->usage_id == usage_id && (collection_index >= @@ -145,10 +146,11 @@ static struct hid_sensor_hub_callbacks *sensor_hub_get_callback( callback->hsdev->end_collection_index)) { *priv = callback->priv; *hsdev = callback->hsdev; - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, + flags); return callback->usage_callback; } - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return NULL; } diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 31e9d2561106..1896c019e302 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -804,7 +804,7 @@ union sixaxis_output_report_01 { #define DS4_REPORT_0x81_SIZE 7 #define SIXAXIS_REPORT_0xF2_SIZE 18 -static spinlock_t sony_dev_list_lock; +static DEFINE_SPINLOCK(sony_dev_list_lock); static LIST_HEAD(sony_device_list); static DEFINE_IDA(sony_device_id_allocator); @@ -1944,6 +1944,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) return -ENOMEM; } + spin_lock_init(&sc->lock); + sc->quirks = quirks; hid_set_drvdata(hdev, sc); sc->hdev = hdev; @@ -2147,8 +2149,8 @@ static void __exit sony_exit(void) { dbg_hid("Sony:%s\n", __func__); - ida_destroy(&sony_device_id_allocator); hid_unregister_driver(&sony_driver); + ida_destroy(&sony_device_id_allocator); } module_init(sony_init); module_exit(sony_exit); diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index d43e967e7533..36053f33d6d9 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -370,7 +370,10 @@ static int i2c_hid_hwreset(struct i2c_client *client) static void i2c_hid_get_input(struct i2c_hid *ihid) { int ret, ret_size; - int size = ihid->bufsize; + int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); + + if (size > ihid->bufsize) + size = ihid->bufsize; ret = i2c_master_recv(ihid->client, ihid->inbuf, size); if (ret != size) { @@ -785,7 +788,7 @@ static int i2c_hid_init_irq(struct i2c_client *client) dev_dbg(&client->dev, "Requesting IRQ: %d\n", client->irq); ret = request_threaded_irq(client->irq, NULL, i2c_hid_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ihid); if (ret < 0) { dev_warn(&client->dev, diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1a6507999a65..046351cf17f3 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -778,6 +778,11 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); + if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } } else if (features->type == CINTIQ_HYBRID) { /* * Do not send hardware buttons under Android. They @@ -2725,9 +2730,9 @@ static const struct wacom_features wacom_features_0xF6 = .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; static const struct wacom_features wacom_features_0x32A = - { "Wacom Cintiq 27QHD", 119740, 67520, 2047, - 63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, - WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; + { "Wacom Cintiq 27QHD", 119740, 67520, 2047, 63, + WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; static const struct wacom_features wacom_features_0x32B = { "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index bce4e9ff21bf..6c99ee7bafa3 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -147,6 +147,9 @@ static int ads7828_probe(struct i2c_client *client, &ads2830_regmap_config); } + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + data->cmd_byte = ext_vref ? ADS7828_CMD_PD1 : ADS7828_CMD_PD3; if (!diff_input) data->cmd_byte |= ADS7828_CMD_SD_SE; diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 8c3bfcb115b7..803869c7d7c2 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -399,21 +399,21 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) * of this RTC chip. We check for it anyways in case support is * added in the future. */ - if (unlikely((seconds >= 0xc0) && (seconds <= 0xff))) + if (unlikely(seconds >= 0xc0)) alrm->time.tm_sec = -1; else alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, RTC_SECS_BCD_MASK, RTC_SECS_BIN_MASK); - if (unlikely((minutes >= 0xc0) && (minutes <= 0xff))) + if (unlikely(minutes >= 0xc0)) alrm->time.tm_min = -1; else alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes, RTC_MINS_BCD_MASK, RTC_MINS_BIN_MASK); - if (unlikely((hours >= 0xc0) && (hours <= 0xff))) + if (unlikely(hours >= 0xc0)) alrm->time.tm_hour = -1; else alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours, @@ -472,13 +472,13 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) * field, and we only support four fields. We put the support * here anyways for the future. */ - if (unlikely((seconds >= 0xc0) && (seconds <= 0xff))) + if (unlikely(seconds >= 0xc0)) seconds = 0xff; - if (unlikely((minutes >= 0xc0) && (minutes <= 0xff))) + if (unlikely(minutes >= 0xc0)) minutes = 0xff; - if (unlikely((hours >= 0xc0) && (hours <= 0xff))) + if (unlikely(hours >= 0xc0)) hours = 0xff; alrm->time.tm_mon = -1; @@ -528,7 +528,6 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) /* ----------------------------------------------------------------------- */ /* /dev/rtcX Interface functions */ -#ifdef CONFIG_RTC_INTF_DEV /** * ds1685_rtc_alarm_irq_enable - replaces ioctl() RTC_AIE on/off. * @dev: pointer to device structure. @@ -557,7 +556,6 @@ ds1685_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -#endif /* ----------------------------------------------------------------------- */ @@ -1612,7 +1610,7 @@ ds1685_rtc_sysfs_time_regs_show(struct device *dev, ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false); /* Make sure we actually matched something. */ - if (!bcd_reg_info && !bin_reg_info) + if (!bcd_reg_info || !bin_reg_info) return -EINVAL; /* bcd_reg_info->reg == bin_reg_info->reg. */ @@ -1650,7 +1648,7 @@ ds1685_rtc_sysfs_time_regs_store(struct device *dev, return -EINVAL; /* Make sure we actually matched something. */ - if (!bcd_reg_info && !bin_reg_info) + if (!bcd_reg_info || !bin_reg_info) return -EINVAL; /* Check for a valid range. */ diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c index f3ee439d6f0e..cd4c293f0dd0 100644 --- a/drivers/sh/pm_runtime.c +++ b/drivers/sh/pm_runtime.c @@ -81,7 +81,9 @@ static int __init sh_pm_runtime_init(void) if (!of_machine_is_compatible("renesas,emev2") && !of_machine_is_compatible("renesas,r7s72100") && !of_machine_is_compatible("renesas,r8a73a4") && +#ifndef CONFIG_PM_GENERIC_DOMAINS_OF !of_machine_is_compatible("renesas,r8a7740") && +#endif !of_machine_is_compatible("renesas,r8a7778") && !of_machine_is_compatible("renesas,r8a7779") && !of_machine_is_compatible("renesas,r8a7790") && diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 2140398a2a8c..2ccd3592d41f 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -2,7 +2,7 @@ ifeq ($(filter y, $(CONFIG_ARM) $(CONFIG_ARM64)),) obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o endif obj-$(CONFIG_X86) += fallback.o -obj-y += grant-table.o features.o balloon.o manage.o +obj-y += grant-table.o features.o balloon.o manage.o preempt.o obj-y += events/ obj-y += xenbus/ diff --git a/drivers/xen/preempt.c b/drivers/xen/preempt.c new file mode 100644 index 000000000000..a1800c150839 --- /dev/null +++ b/drivers/xen/preempt.c @@ -0,0 +1,44 @@ +/* + * Preemptible hypercalls + * + * Copyright (C) 2014 Citrix Systems R&D ltd. + * + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + */ + +#include <linux/sched.h> +#include <xen/xen-ops.h> + +#ifndef CONFIG_PREEMPT + +/* + * Some hypercalls issued by the toolstack can take many 10s of + * seconds. Allow tasks running hypercalls via the privcmd driver to + * be voluntarily preempted even if full kernel preemption is + * disabled. + * + * Such preemptible hypercalls are bracketed by + * xen_preemptible_hcall_begin() and xen_preemptible_hcall_end() + * calls. + */ + +DEFINE_PER_CPU(bool, xen_in_preemptible_hcall); +EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); + +asmlinkage __visible void xen_maybe_preempt_hcall(void) +{ + if (unlikely(__this_cpu_read(xen_in_preemptible_hcall) + && should_resched())) { + /* + * Clear flag as we may be rescheduled on a different + * cpu. + */ + __this_cpu_write(xen_in_preemptible_hcall, false); + _cond_resched(); + __this_cpu_write(xen_in_preemptible_hcall, true); + } +} +#endif /* CONFIG_PREEMPT */ diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 569a13b9e856..59ac71c4a043 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -56,10 +56,12 @@ static long privcmd_ioctl_hypercall(void __user *udata) if (copy_from_user(&hypercall, udata, sizeof(hypercall))) return -EFAULT; + xen_preemptible_hcall_begin(); ret = privcmd_call(hypercall.op, hypercall.arg[0], hypercall.arg[1], hypercall.arg[2], hypercall.arg[3], hypercall.arg[4]); + xen_preemptible_hcall_end(); return ret; } diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 61653a03a8f5..9faca6a60bb0 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -709,12 +709,11 @@ static int prepare_pending_reqs(struct vscsibk_info *info, static int scsiback_do_cmd_fn(struct vscsibk_info *info) { struct vscsiif_back_ring *ring = &info->ring; - struct vscsiif_request *ring_req; + struct vscsiif_request ring_req; struct vscsibk_pend *pending_req; RING_IDX rc, rp; int err, more_to_do; uint32_t result; - uint8_t act; rc = ring->req_cons; rp = ring->sring->req_prod; @@ -735,11 +734,10 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) if (!pending_req) return 1; - ring_req = RING_GET_REQUEST(ring, rc); + ring_req = *RING_GET_REQUEST(ring, rc); ring->req_cons = ++rc; - act = ring_req->act; - err = prepare_pending_reqs(info, ring_req, pending_req); + err = prepare_pending_reqs(info, &ring_req, pending_req); if (err) { switch (err) { case -ENODEV: @@ -755,9 +753,9 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) return 1; } - switch (act) { + switch (ring_req.act) { case VSCSIIF_ACT_SCSI_CDB: - if (scsiback_gnttab_data_map(ring_req, pending_req)) { + if (scsiback_gnttab_data_map(&ring_req, pending_req)) { scsiback_fast_flush_area(pending_req); scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24, 0, pending_req); @@ -768,7 +766,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) break; case VSCSIIF_ACT_SCSI_ABORT: scsiback_device_action(pending_req, TMR_ABORT_TASK, - ring_req->ref_rqid); + ring_req.ref_rqid); break; case VSCSIIF_ACT_SCSI_RESET: scsiback_device_action(pending_req, TMR_LUN_RESET, 0); |