First push
This commit is contained in:
167
SOURCES/0006-NTPatch.patch
Normal file
167
SOURCES/0006-NTPatch.patch
Normal file
@@ -0,0 +1,167 @@
|
||||
This corresponds to the NT syscall NtCreateMutant().
|
||||
|
||||
Signed-off-by: Elizabeth Figura <zfigura@codeweavers.com>
|
||||
---
|
||||
drivers/misc/ntsync.c | 72 +++++++++++++++++++++++++++++++++++++
|
||||
include/uapi/linux/ntsync.h | 8 +++++
|
||||
2 files changed, 80 insertions(+)
|
||||
|
||||
diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
|
||||
index 2685363fae9e..d48f2ef41341 100644
|
||||
--- a/drivers/misc/ntsync.c
|
||||
+++ b/drivers/misc/ntsync.c
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
enum ntsync_type {
|
||||
NTSYNC_TYPE_SEM,
|
||||
+ NTSYNC_TYPE_MUTEX,
|
||||
};
|
||||
|
||||
struct ntsync_obj {
|
||||
@@ -60,6 +61,10 @@ struct ntsync_obj {
|
||||
__u32 count;
|
||||
__u32 max;
|
||||
} sem;
|
||||
+ struct {
|
||||
+ __u32 count;
|
||||
+ __u32 owner;
|
||||
+ } mutex;
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -188,6 +193,10 @@ static bool is_signaled(struct ntsync_obj *obj, __u32 owner)
|
||||
switch (obj->type) {
|
||||
case NTSYNC_TYPE_SEM:
|
||||
return !!obj->u.sem.count;
|
||||
+ case NTSYNC_TYPE_MUTEX:
|
||||
+ if (obj->u.mutex.owner && obj->u.mutex.owner != owner)
|
||||
+ return false;
|
||||
+ return obj->u.mutex.count < UINT_MAX;
|
||||
}
|
||||
|
||||
WARN(1, "bad object type %#x\n", obj->type);
|
||||
@@ -230,6 +239,10 @@ static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q,
|
||||
case NTSYNC_TYPE_SEM:
|
||||
obj->u.sem.count--;
|
||||
break;
|
||||
+ case NTSYNC_TYPE_MUTEX:
|
||||
+ obj->u.mutex.count++;
|
||||
+ obj->u.mutex.owner = q->owner;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
wake_up_process(q->task);
|
||||
@@ -271,6 +284,28 @@ static void try_wake_any_sem(struct ntsync_obj *sem)
|
||||
}
|
||||
}
|
||||
|
||||
+static void try_wake_any_mutex(struct ntsync_obj *mutex)
|
||||
+{
|
||||
+ struct ntsync_q_entry *entry;
|
||||
+
|
||||
+ lockdep_assert_held(&mutex->lock);
|
||||
+
|
||||
+ list_for_each_entry(entry, &mutex->any_waiters, node) {
|
||||
+ struct ntsync_q *q = entry->q;
|
||||
+
|
||||
+ if (mutex->u.mutex.count == UINT_MAX)
|
||||
+ break;
|
||||
+ if (mutex->u.mutex.owner && mutex->u.mutex.owner != q->owner)
|
||||
+ continue;
|
||||
+
|
||||
+ if (atomic_cmpxchg(&q->signaled, -1, entry->index) == -1) {
|
||||
+ mutex->u.mutex.count++;
|
||||
+ mutex->u.mutex.owner = q->owner;
|
||||
+ wake_up_process(q->task);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
|
||||
{
|
||||
struct ntsync_sem_args __user *user_args = argp;
|
||||
@@ -303,6 +338,38 @@ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
|
||||
return put_user(id, &user_args->sem);
|
||||
}
|
||||
|
||||
+static int ntsync_create_mutex(struct ntsync_device *dev, void __user *argp)
|
||||
+{
|
||||
+ struct ntsync_mutex_args __user *user_args = argp;
|
||||
+ struct ntsync_mutex_args args;
|
||||
+ struct ntsync_obj *mutex;
|
||||
+ __u32 id;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (copy_from_user(&args, argp, sizeof(args)))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ if (!args.owner != !args.count)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mutex = kzalloc(sizeof(*mutex), GFP_KERNEL);
|
||||
+ if (!mutex)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ init_obj(mutex);
|
||||
+ mutex->type = NTSYNC_TYPE_MUTEX;
|
||||
+ mutex->u.mutex.count = args.count;
|
||||
+ mutex->u.mutex.owner = args.owner;
|
||||
+
|
||||
+ ret = xa_alloc(&dev->objects, &id, mutex, xa_limit_32b, GFP_KERNEL);
|
||||
+ if (ret < 0) {
|
||||
+ kfree(mutex);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return put_user(id, &user_args->mutex);
|
||||
+}
|
||||
+
|
||||
static int ntsync_delete(struct ntsync_device *dev, void __user *argp)
|
||||
{
|
||||
struct ntsync_obj *obj;
|
||||
@@ -497,6 +564,9 @@ static void try_wake_any_obj(struct ntsync_obj *obj)
|
||||
case NTSYNC_TYPE_SEM:
|
||||
try_wake_any_sem(obj);
|
||||
break;
|
||||
+ case NTSYNC_TYPE_MUTEX:
|
||||
+ try_wake_any_mutex(obj);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,6 +732,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
|
||||
void __user *argp = (void __user *)parm;
|
||||
|
||||
switch (cmd) {
|
||||
+ case NTSYNC_IOC_CREATE_MUTEX:
|
||||
+ return ntsync_create_mutex(dev, argp);
|
||||
case NTSYNC_IOC_CREATE_SEM:
|
||||
return ntsync_create_sem(dev, argp);
|
||||
case NTSYNC_IOC_DELETE:
|
||||
diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h
|
||||
index a5bed5a39b21..26d1b3d4847f 100644
|
||||
--- a/include/uapi/linux/ntsync.h
|
||||
+++ b/include/uapi/linux/ntsync.h
|
||||
@@ -16,6 +16,12 @@ struct ntsync_sem_args {
|
||||
__u32 max;
|
||||
};
|
||||
|
||||
+struct ntsync_mutex_args {
|
||||
+ __u32 mutex;
|
||||
+ __u32 owner;
|
||||
+ __u32 count;
|
||||
+};
|
||||
+
|
||||
struct ntsync_wait_args {
|
||||
__u64 timeout;
|
||||
__u64 objs;
|
||||
@@ -38,5 +44,7 @@ struct ntsync_wait_args {
|
||||
struct ntsync_wait_args)
|
||||
#define NTSYNC_IOC_WAIT_ALL _IOWR(NTSYNC_IOC_BASE, 4, \
|
||||
struct ntsync_wait_args)
|
||||
+#define NTSYNC_IOC_CREATE_MUTEX _IOWR(NTSYNC_IOC_BASE, 5, \
|
||||
+ struct ntsync_mutex_args)
|
||||
|
||||
#endif
|
||||
--
|
||||
2.43.0
|
||||
Reference in New Issue
Block a user